npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@prism-ing/onebalance

v1.0.2

Published

OneBalance account abstraction provider for @prism-ing/wallet.

Downloads

452

Readme

@prism-ing/onebalance

OneBalance account abstraction provider for @prism-ing/wallet. Adds ERC-4337 smart account addresses, cross-chain balances, deposits, swaps, and client-side quote verification.

Install

pnpm add @prism-ing/onebalance @prism-ing/wallet

API key: Get your OneBalance API key from the OneBalance dashboard. Set it as ONEBALANCE_API_KEY in your environment.

API terms: This package integrates with the OneBalance API. OneBalance's public developer terms have not been formally published at time of writing. Review their current terms at docs.onebalance.io and confirm acceptable use with OneBalance before production deployment.

Quickstart

import { createProductionWallet } from '@prism-ing/wallet';
import { createOneBalanceProvider } from '@prism-ing/onebalance';

const provider = createOneBalanceProvider({
  apiKey: process.env.ONEBALANCE_API_KEY,
});

const result = await createProductionWallet(
  { signer: { walletName: 'my-agent' } },
  { accountAbstraction: provider },
);

if (!result.ok) {
  console.error(result.error.code);
  process.exit(1);
}

const wallet = result.value;
console.log('EOA:', wallet.evmAddress);
console.log('Smart account:', wallet.smartAccountAddress);

// Balance, deposit, and status — all powered by OneBalance
const balance = await wallet.getBalance();
console.log(`Balance: $${balance.totalUsd}`);

Full-Stack Bootstrap (wallet + onebalance + swap-router)

Combine all three packages to get a wallet with best-in-class security, cross-chain balance, and instant swaps in ~20 lines:

import { createProductionWallet } from '@prism-ing/wallet';
import { createOneBalanceProvider } from '@prism-ing/onebalance';
import { createSwapRouter } from '@prism-ing/swap-router';

// 1. Account abstraction provider (adds smart account + cross-chain balance)
const provider = createOneBalanceProvider({
  apiKey: process.env.ONEBALANCE_API_KEY,
});

// 2. Wallet — OWS persistent keys on Node.js, Secure Enclave on iOS
const walletResult = await createProductionWallet(
  { signer: { walletName: 'my-agent' } },
  { accountAbstraction: provider },
);
if (!walletResult.ok) throw new Error(walletResult.error.code);
const wallet = walletResult.value;

// 3. Swap router — points at your Prism aggregator instance
const router = createSwapRouter({
  baseUrl: 'https://your-aggregator.fly.dev/v1',
  signer: wallet.signer,           // PrismSigner satisfies SwapSigner directly
  evmRpcUrls: { 8453: process.env.BASE_RPC_URL },
});

// 4. Quote a cross-chain swap (USDC on Base → USDT on Arbitrum)
const quote = await router.quote({
  fromAsset: 'USDC:base',
  toAsset:   'USDT:arbitrum',
  amount:    '1000000',            // 1 USDC (6 decimals)
  sender:    wallet.evmAddress,
  // Pass your smart account for OneBalance cross-chain routing:
  accounts:  [{ type: 'kernel-v3.1-ecdsa', accountAddress: wallet.smartAccountAddress, signerAddress: wallet.evmAddress }],
});

// 5. Execute — signs, broadcasts, and polls until COMPLETED
if (quote.ok) {
  const exec = await router.execute(quote.value);
  console.log(exec.ok ? exec.value.status : exec.error.code);
}

Security properties of this stack:

  • Private keys never leave the OWS vault (~/.ows/) — hardware-backed on iOS via Secure Enclave
  • Quote integrity verified before any signing (prevents blind-signing attacks)
  • Cross-chain operations signed client-side; OneBalance only sees EIP-712 signatures

How It Works

createOneBalanceProvider returns an AccountAbstractionProvider — the interface defined by @prism-ing/wallet. When injected into createWallet or createProductionWallet, it enables:

Execution Flow

  Your Agent
      │
      ▼
  createProductionWallet()          ← OWS keys, never leave ~/.ows/
      │
      ▼
  wallet.deposit() or router.quote()
      │
      ▼
  OneBalance API ── getQuote ──► quote + EIP-712 payload
      │
      ▼
  verifyQuoteIntegrity()            ← 6 checks: expiry, amount, asset, sender
      │  (FAILS FAST if tampered)
      ▼
  wallet.signer.signTypedData()     ← client-side signing, key never leaves
      │
      ▼
  OneBalance API ── executeQuote
      │
      ▼
  Cross-chain settlement            ← Resource Locks, no custody handoff

Signing stays client-side. OneBalance only sees signed EIP-712 payloads. It never has access to your private key.

| Capability | Method | What OneBalance Does | |------------|--------|---------------------| | Smart account address | predictAddress() | Computes counterfactual ERC-4337 address from signer's public key | | Balance | getBalance() | Aggregates balances across all supported chains | | Deposit | deposit() | Executes via OneBalance Resource Locks (quote -> sign -> execute) | | Transaction status | getTransactionStatus() | Polls OneBalance execution status |

Signing stays client-side. OneBalance never sees your private keys. It receives only signed payloads (EIP-712 for EVM, transaction signatures for Solana).

Supported Chains

| Chain | Chain ID | CAIP-2 | |-------|----------|--------| | Ethereum | 1 | eip155:1 | | Optimism | 10 | eip155:10 | | BNB Chain | 56 | eip155:56 | | Polygon | 137 | eip155:137 | | Base | 8453 | eip155:8453 | | Arbitrum One | 42161 | eip155:42161 | | Avalanche C-Chain | 43114 | eip155:43114 | | Linea | 59144 | eip155:59144 | | Blast | 81457 | eip155:81457 | | Solana | — | solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp |

Use toCaip2(chainId) to convert numeric chain IDs, or import SOLANA_CAIP2 for Solana.

Asset IDs

OneBalance accepts two asset identifier formats:

| Format | Example | When to Use | |--------|---------|-------------| | Aggregated (ob:) | 'ob:usdc', 'ob:eth' | Cross-chain operations — OneBalance resolves to the best chain automatically | | CAIP-19 | 'eip155:8453/erc20:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' | When you need a specific token on a specific chain |

Use ob: shorthand for cross-chain swaps. Use CAIP-19 when you need chain-specific precision.

Depositing into Your Smart Account

Before executing cross-chain swaps, your smart account needs funds. Use wallet.deposit() to move tokens from your EOA into the OneBalance smart account:

import { createProductionWallet } from '@prism-ing/wallet';
import { createOneBalanceProvider } from '@prism-ing/onebalance';

const provider = createOneBalanceProvider({ apiKey: process.env.ONEBALANCE_API_KEY });
const result = await createProductionWallet(
  { signer: { walletName: 'my-agent' } },
  { accountAbstraction: provider },
);
if (!result.ok) throw new Error(result.error.code);
const wallet = result.value;

// Deposit 10 USDC from your EOA into the smart account on Base
const deposit = await wallet.deposit({
  asset: 'ob:usdc',      // works across all chains — OneBalance routes automatically
  amount: '10000000',    // 10 USDC (6 decimals)
  chainId: 8453,         // source chain for this deposit
});

if (!deposit.ok) {
  console.error('Deposit failed:', deposit.error.code);
} else {
  console.log('Deposited:', deposit.value.quoteId);
  // Poll for confirmation
  const status = await wallet.getTransactionStatus(deposit.value.quoteId);
}

Agent integration note: The ob:usdc asset ID works across all chains — you don't need to specify which chain you're depositing from when using aggregated IDs. OneBalance resolves the best chain automatically based on your available balances.

Cross-Chain Execution

For direct cross-chain swaps outside the wallet abstraction:

import { executeCrossChain } from '@prism-ing/onebalance';

const result = await executeCrossChain(
  oneBalanceClient,
  wallet.signer,
  {
    fromAsset: 'ob:usdc',
    toAsset: 'ob:eth',
    amount: '1000000',        // smallest unit (e.g., 1 USDC = 1000000)
    slippageTolerance: 50,    // basis points (50 = 0.5%)
    accountAddress: wallet.smartAccountAddress,
  },
  accounts,
);

if (result.ok) {
  console.log('Quote ID:', result.value.quoteId);
}

The flow is: get quote -> verify integrity -> sign operations -> submit to OneBalance.

Quote Verification

executeCrossChain automatically verifies OneBalance quotes before signing. This prevents blind-signing attacks where a compromised API could present malicious EIP-712 payloads.

6 checks performed automatically:

  1. Quote has not expired
  2. OneBalance tamper-proof signature is present
  3. Origin asset matches the requested fromAsset
  4. Origin amount is within 1% of the requested amount (configurable)
  5. Destination asset matches the requested toAsset
  6. EVM operation userOp.sender matches accountAddress (when provided)

For manual verification:

import { verifyQuoteIntegrity, verifyEvmOperation } from '@prism-ing/onebalance';

const error = verifyQuoteIntegrity(quote, {
  fromAsset: 'ob:usdc',
  toAsset: 'ob:eth',
  amount: '1000000',
  accountAddress: '0x1234...',
  maxOriginSlippageFraction: 0.005,  // 0.5% tolerance (default 1%)
});

API Reference

createOneBalanceProvider(config)

Creates an AccountAbstractionProvider backed by OneBalance.

interface OneBalanceProviderConfig {
  apiKey: string;
  baseUrl?: string;      // Default: https://be.onebalance.io/api
  timeoutMs?: number;    // Default: 30000
  maxRetries?: number;   // Default: 3
  baseDelayMs?: number;  // Default: 1000
}

createOneBalanceProviderFromClient(client)

Creates a provider from an existing OneBalanceClient. Useful for testing with mock clients.

createOneBalanceHttpClient(config)

Lower-level: creates a raw OneBalanceClient with retry logic and exponential backoff. Use this when you need direct API access beyond what the provider exposes.

executeCrossChain(client, signer, params, accounts, options?)

Orchestrates the full quote -> verify -> sign -> execute flow. Returns Result<CrossChainResult, CrossChainError>.

verifyQuoteIntegrity(quote, params) / verifyEvmOperation(operation, address)

Client-side quote verification functions. Used automatically by executeCrossChain; exported for custom flows.

Error Handling

All async operations return Result<T, E> — check .ok before using the value:

import { executeCrossChain } from '@prism-ing/onebalance';

const result = await executeCrossChain(client, wallet.signer, params, accounts);

if (!result.ok) {
  switch (result.error.code) {
    case 'SIGNING_REJECTED':
      // User cancelled biometric or denied signing
      console.error('Signing cancelled:', result.error.reason);
      break;
    case 'PROVIDER_TIMEOUT':
      // OneBalance API didn't respond — safe to retry
      console.error(`Timeout after ${result.error.durationMs}ms`);
      break;
    case 'PROVIDER_API_ERROR':
      // OneBalance returned an error — check statusCode
      console.error(`API ${result.error.statusCode}: ${result.error.body}`);
      break;
    case 'QUOTE_VERIFICATION_FAILED':
      // Quote integrity check failed — do NOT sign
      console.error('Quote tampered or expired');
      break;
  }
  return;
}

// result.value is CrossChainResult
console.log('Submitted:', result.value.quoteId);

HTTP-level errors from the client throw OneBalanceHttpError with statusCode, body, and path fields.

Transaction Status Polling

After submitting a swap, poll for execution status:

const swap = result.value;

const poll = async () => {
  const status = await wallet.getTransactionStatus(swap.quoteId);
  switch (status.status) {
    case 'pending':
      // Still processing — poll again
      break;
    case 'completed':
      console.log('Swap completed');
      break;
    case 'failed':
      console.error('Swap failed');
      break;
  }
};

Testing

Use createOneBalanceProviderFromClient to inject a mock client in tests:

import { createOneBalanceProviderFromClient } from '@prism-ing/onebalance';
import type { OneBalanceClient } from '@prism-ing/onebalance';

const mockClient: OneBalanceClient = {
  predictAddress: async () => ({ accounts: [], smartAccountAddress: '0x...' }),
  getQuote: async () => ({ /* mock quote */ }),
  executeQuote: async () => {},
  getExecutionStatus: async () => ({ quoteId: '...', status: 'completed' }),
  getAggregatedBalance: async () => ({ totalUsd: '100.00', breakdown: [] }),
};

const provider = createOneBalanceProviderFromClient(mockClient);

Network Resilience

The HTTP client includes:

  • Exponential backoff with jitter (3 retries, base delay 1s -> 2s -> 4s + random jitter)
  • Retries only on: timeouts (AbortError), network errors (TypeError), and 5xx server errors
  • No retry on 4xx client errors (bad request, auth failure, validation)
  • Configurable via OneBalanceProviderConfig

Documentation

  • SPEC.md — Design decisions, security model, API types

License

MIT