TypeScript SDK for the C-Address Onboarding Bridge Soroban contract.

Provides typed wrappers around every contract function. Mutating methods return a TransactionResult and never throw — errors are surfaced through result.status === 'failed'. Read-only query methods throw on RPC or contract error so you can use standard try/catch patterns.

All RPC calls are automatically retried on transient network failures using exponential backoff with full jitter (see withRpcRetry). The retry policy is configurable via BridgeConfig.retry.

import { OnboardingBridgeSDK } from '@stellar/c-address-onboarding-bridge-sdk';
import { Keypair, Networks } from '@stellar/stellar-sdk';

const sdk = new OnboardingBridgeSDK({
contractId: 'CA...',
rpcUrl: 'https://soroban-testnet.stellar.org',
networkPassphrase: Networks.TESTNET,
});

const keypair = Keypair.fromSecret(process.env.SECRET!);
const result = await sdk.fundCAddress(
{ source: keypair.publicKey(), target: 'CC...', asset: 'CD...', amount: '1000000' },
keypair,
);
if (result.status === 'failed') console.error(result.error);

Constructors

  • Create a new SDK instance.

    Validates config.contractId immediately and throws if it is not a valid Stellar C-address. No network call is made during construction.

    Parameters

    • config: BridgeConfig

      SDK configuration: contract ID, RPC URL, network passphrase, and optional timeout / retry settings.

    Returns OnboardingBridgeSDK

    If config.contractId is not a valid contract address.

    const sdk = new OnboardingBridgeSDK({
    contractId: 'CA...',
    rpcUrl: 'https://soroban-testnet.stellar.org',
    networkPassphrase: Networks.TESTNET,
    retry: { maxRetries: 5 },
    });

Methods

  • Register an Ed25519 relayer public key on the contract (admin only).

    Registered relayers are authorised to submit attestation signatures for cross-chain events via fundCrosschain. After adding, update the threshold with setRelayerThreshold if needed.

    Parameters

    • options: RelayerManagementOptions

      Contains the 32-byte Ed25519 pubkey as a hex string.

    • adminKeypair: Keypair

      Keypair of the admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

  • Fund multiple C-addresses from a single source account, automatically splitting large batches across multiple transactions.

    When the number of options.targets exceeds BATCH_TX_LIMIT, the list is split into chunks of at most BATCH_TX_LIMIT entries and one on-chain batch_fund_c_address transaction is submitted per chunk. This means a single call to batchFundCAddresses may submit multiple transactions and returns an array of TransactionResult — one entry per submitted transaction, in order.

    Within each chunk the contract pulls the sum of that chunk's amounts from source upfront. For targets that fail access control the corresponding amount is refunded to source and a BatchTransferFailed event is emitted. A BatchCompleted event is emitted at the end of each on-chain transaction.

    options.targets and options.amounts must be the same length.

    Parameters

    • options: BatchFundCOptions

      Batch transfer parameters: source, targets, amounts, asset.

    • sourceKeypair: Keypair

      Keypair of the source account used to sign every transaction.

    • OptionalonProgress: BatchProgressCallback

      Optional callback invoked after each transaction is submitted. Receives the cumulative count of recipients processed, the total recipient count, and the tx hash (or undefined if submission failed before a hash was returned).

    Returns Promise<TransactionResult[]>

    An array of TransactionResult, one per submitted transaction. If the entire batch fits in a single transaction the array has one element. On a per-chunk submission error the corresponding element has status: 'failed'; processing continues with the remaining chunks.

    Never — errors are returned as status: 'failed' in the results array.

    // Small batch — fits in one tx
    const [result] = await sdk.batchFundCAddresses(
    {
    source: keypair.publicKey(),
    targets: ['CC...1', 'CC...2', 'CC...3'],
    amounts: ['5000000', '3000000', '2000000'],
    asset: 'CD...usdc',
    },
    keypair,
    );

    // Large batch — auto-split with progress reporting
    const results = await sdk.batchFundCAddresses(
    { source: keypair.publicKey(), targets: largeTargetList, amounts: largeAmountList, asset: 'CD...' },
    keypair,
    (completed, total, txHash) => {
    console.log(`Processed ${completed}/${total} recipients — tx: ${txHash}`);
    },
    );
  • Create a new Soroban smart-contract account (C-address).

    Calls the bridge contract's create_contract helper which deploys a new account contract and derives its C-address from the deployer's address and an optional salt. If options.initialFunds is provided, a fund_c_address call is made immediately after creation so the new account has a starting balance.

    Parameters

    • options: CreateCOptions

      Deployer keypair, optional deterministic salt, and optional initial funding parameters.

    Returns Promise<CreateCAddressResult>

    A CreateCAddressResult with the new C-address and creation tx hash.

    If contract creation or the subsequent fund call fails.

    const { cAddress, txHash } = await sdk.createCAddress({
    deployerKeypair: keypair,
    initialFunds: { asset: 'CD...usdc', amount: '10000000' },
    });
    console.log('New C-address:', cAddress);
  • Internal

    Convert an array of JavaScript values to Soroban ScVal XDR values.

    Handles strings (G-/C-addresses, numeric strings, plain strings), numbers, bigints, Address instances, arrays (→ scvVec), and null/undefined (→ scvVoid).

    Parameters

    Returns Promise<CostEstimate>

    Array of xdr.ScVal suitable for passing to Contract.call.

    Estimate the transaction cost for a fundCAddress call without submitting it to the network.

    Runs simulateTransaction under the hood and extracts the Soroban resource fee, the base inclusion fee, and the minimum account balance required.

    const estimate = await sdk.estimateCost({
    source: keypair.publicKey(),
    target: 'CC...',
    asset: 'CD...',
    amount: '10000000',
    });
    console.log('Resource fee:', estimate.resourceFee, 'stroops');
    console.log('Total fee: ', estimate.fee, 'stroops');
  • Fund a single C-address from a source G-address.

    Transfers options.amount of options.asset from source into the bridge contract, deducts the protocol fee, and forwards the net amount to target. The source account must authorise the token transfer — this is handled automatically by Soroban's require_auth mechanism when the transaction is signed with sourceKeypair.

    Parameters

    • options: FundCOptions

      Transfer parameters: source, target, asset, amount.

    • sourceKeypair: Keypair

      Keypair of the source account. Used to sign the transaction. Must correspond to options.source.

    Returns Promise<TransactionResult>

    A TransactionResult with status: 'pending' on successful submission, or status: 'failed' with an error message. Poll SorobanRpc.Server.getTransaction(result.hash) to confirm finality before showing success to the user.

    Never — errors are returned as status: 'failed'.

    const result = await sdk.fundCAddress(
    {
    source: keypair.publicKey(),
    target: 'CC...',
    asset: 'CD...usdc',
    amount: '10000000', // 1 USDC (7 decimal places)
    },
    keypair,
    );

    if (result.status === 'failed') {
    console.error('Transfer failed:', result.error);
    } else {
    console.log('Submitted tx:', result.hash);
    }
  • Fund a C-address by swapping the source asset into a different target asset first.

    Calls fund_c_address_with_swap on the bridge contract which:

    1. Pulls sourceAmount of sourceAsset from source.
    2. Routes it through the DEX pools in swapRoute.
    3. Deducts the fee in targetAsset and forwards the net to target.

    Parameters

    Returns Promise<TransactionResult>

    const result = await sdk.fundCAddressWithSwap(
    {
    source: keypair.publicKey(),
    target: 'CC...',
    sourceAsset: USDC_CONTRACT,
    targetAsset: XLM_CONTRACT,
    sourceAmount: '10000000', // 1 USDC
    minTargetAmount: '9000000', // 0.9 XLM (10% max slippage)
    swapRoute: [USDC_XLM_POOL],
    },
    keypair,
    );
  • Fund a C-address from a cross-chain event (called by the relayer service). Requires at least threshold valid relayer signatures over the canonical payload hash.

    Parameters

    Returns Promise<TransactionResult>

  • Get the current admin G-address.

    The admin account is authorised to update fee rates, fee collector, admin address, asset whitelist, access control lists, and to upgrade the contract.

    Returns Promise<string>

    The admin G-address as a string.

    On RPC failure or contract error.

    const admin = await sdk.getAdmin();
    console.log('Admin:', admin);
  • Get the contract's token balances for multiple assets in a single RPC call.

    Returns a plain object mapping each asset contract address to its balance string. Useful for dashboard or monitoring use-cases.

    Parameters

    • assets: string[]

      Array of token contract addresses to query.

    Returns Promise<Record<string, string>>

    A Record<assetAddress, balanceString>. Assets with a zero balance are included with value '0'.

    If any address in assets is invalid or on RPC failure.

    const balances = await sdk.getAllBalances(['CD...usdc', 'CD...xlm']);
    // { 'CD...usdc': '1200000', 'CD...xlm': '500000000' }
  • Return a paginated list of addresses on the allowlist.

    When the contract is in allowlist mode, only allowlisted addresses can receive funds. Non-allowlisted targets in batch calls are skipped and their amounts refunded to the source.

    Parameters

    • Optionalcursor: string

      Opaque cursor from a previous call. Omit to start from page 1.

    • limit: number = 20

      Maximum items per page. Defaults to 20.

    Returns Promise<PaginatedResult<string>>

    A PaginatedResult of address strings.

    On RPC failure.

  • Return a paginated list of addresses on the blocklist.

    Blocklisted addresses cannot receive funds via fundCAddress or batch calls. Transfers to them are silently skipped (in batch) or rejected (single).

    Parameters

    • Optionalcursor: string

      Opaque cursor from a previous call. Omit to start from page 1.

    • limit: number = 20

      Maximum items per page. Defaults to 20.

    Returns Promise<PaginatedResult<string>>

    A PaginatedResult of address strings.

    On RPC failure.

  • Query the token balance of any address (G-address or C-address) for a given asset, using the bridge contract's query_balance view function.

    Parameters

    • cAddress: string

      The address to query (G-address or C-address).

    • asset: string

      Token contract address to check the balance for.

    Returns Promise<string>

    The balance in the token's smallest unit as a decimal string.

    If either address is invalid or on RPC failure.

    const balance = await sdk.getCAddressBalance('CC...', 'CD...usdc');
    console.log('Balance:', balance); // e.g. '10000000' = 1 USDC
  • Get the current protocol fee in basis points (bps).

    1 bps = 0.01%, so 50 means a 0.5% fee is deducted from each transfer. The maximum allowed value is 1000 (10%).

    Returns Promise<number>

    The fee in basis points as a number.

    On RPC failure or contract error.

    const feeBps = await sdk.getFee();
    console.log(`Current fee: ${feeBps / 100}%`);
  • Get the accumulated (uncollected) fee balance held by the contract for a specific asset.

    Use this before calling withdrawFees to know the exact withdrawable amount.

    Parameters

    • asset: string

      Token contract address.

    Returns Promise<string>

    The accrued fee balance in the token's smallest unit as a string.

    If asset is not a valid contract address or on RPC failure.

    const fees = await sdk.getFeeBalance('CD...usdc');
    console.log('Uncollected fees:', fees);
  • Get the current fee-collector G-address.

    The fee collector is the only account authorised to call withdrawFees.

    Returns Promise<string>

    The fee-collector G-address as a string.

    On RPC failure or contract error.

    const collector = await sdk.getFeeCollector();
    console.log('Fee collector:', collector);
  • Return a paginated list of fee-exempt addresses.

    Fee-exempt addresses pay zero protocol fee on every transfer regardless of the configured fee_bps. The full list is fetched from the contract and paginated client-side.

    Parameters

    • Optionalcursor: string

      Opaque cursor from a previous call. Omit to start from page 1.

    • limit: number = 20

      Maximum items per page. Defaults to 20.

    Returns Promise<PaginatedResult<string>>

    A PaginatedResult of address strings.

    On RPC failure.

  • Return a paginated list of whitelisted asset contract addresses.

    Only whitelisted assets can be used in fundCAddress and batch calls. The full list is fetched from the contract and paginated client-side.

    Parameters

    • Optionalcursor: string

      Opaque cursor from a previous call. Omit to start from page 1.

    • limit: number = 20

      Maximum items per page. Defaults to 20.

    Returns Promise<PaginatedResult<string>>

    A PaginatedResult containing asset C-addresses for this page.

    On RPC failure.

    let page = await sdk.getWhitelistedAssets();
    while (page.hasMore) {
    page = await sdk.getWhitelistedAssets(page.cursor);
    }
  • Check whether the bridge contract has been initialized.

    The contract must be initialized (via initialize) before any funding operations are permitted. Use this after deployment to verify the contract is ready for use.

    Returns Promise<boolean>

    true if the contract has been initialized, false otherwise.

    On RPC failure.

    const ready = await sdk.isInitialized();
    if (!ready) throw new Error('Contract not initialized yet');
  • Check whether a given Ed25519 public key is a registered relayer.

    Parameters

    • pubkeyHex: string

      32-byte Ed25519 public key as a lowercase hex string.

    Returns Promise<boolean>

    true if the pubkey is registered, false otherwise.

    On RPC failure.

  • Query the current M-of-N relayer threshold.

    Returns Promise<number>

    The threshold as a number (M in M-of-N).

    On RPC failure.

  • Reclaim tokens accidentally sent directly to the bridge contract address.

    Admin only. This is an emergency recovery tool — it moves the contract's raw token balance (minus any accrued fees for that asset) to options.to.

    Parameters

    • options: ReclaimTokensOptions

      Asset, amount, and destination address.

    • adminKeypair: Keypair

      Keypair of the admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

    await sdk.reclaimTokens(
    { asset: 'CD...', amount: '1000000', to: 'G...safeAddress' },
    adminKeypair,
    );
  • Remove a previously registered Ed25519 relayer public key (admin only).

    The removed key can no longer contribute valid signatures for cross-chain attestations. Ensure the remaining relayer set still meets the threshold or lower the threshold first.

    Parameters

    • options: RelayerManagementOptions

      Contains the 32-byte Ed25519 pubkey as a hex string.

    • adminKeypair: Keypair

      Keypair of the admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

  • Transfer the admin role to a new G-address (admin only).

    After this call the old admin loses all privileged access. Ensure the new admin keypair is accessible before calling this — there is no recovery path if the new admin key is lost.

    Parameters

    • newAdmin: string

      G-address of the new admin.

    • adminKeypair: Keypair

      Keypair of the current admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

    await sdk.setAdmin('G...newAdmin', adminKeypair);
    
  • Update the protocol fee rate (admin only).

    The new fee takes effect on the next fund_c_address call. Maximum allowed value is 1000 bps (10%).

    Parameters

    • newFeeBps: number

      New fee in basis points (0–1000).

    • adminKeypair: Keypair

      Keypair of the admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

    await sdk.setFee(75, adminKeypair); // set to 0.75%
    
  • Rotate the fee-collector address (admin only).

    The new fee collector immediately gains the right to call withdrawFees. The old fee collector loses it.

    Parameters

    • newFeeCollector: string

      G-address of the new fee collector.

    • adminKeypair: Keypair

      Keypair of the admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

    await sdk.setFeeCollector('G...newCollector', adminKeypair);
    
  • Set the M-of-N relayer threshold (admin only).

    Cross-chain attestations require at least threshold valid signatures from registered relayers. Must not exceed the total number of registered relayers.

    Parameters

    • threshold: number

      Minimum number of valid relayer signatures required.

    • adminKeypair: Keypair

      Keypair of the admin account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

    // Require 2-of-3 relayers
    await sdk.setRelayerThreshold(2, adminKeypair);
  • Upgrade the contract to a new wasm implementation (admin only). The new_wasm_hash must reference wasm already uploaded to the network. Preserves all instance storage (admin, fee settings, etc.).

    Parameters

    Returns Promise<TransactionResult>

  • Withdraw accumulated protocol fees from the bridge contract.

    Only the configured fee-collector address may call this method. Fees accumulate in the contract after every successful fund_c_address or batch_fund_c_address call.

    Parameters

    • options: WithdrawFeesOptions

      Asset and amount to withdraw.

    • feeCollectorKeypair: Keypair

      Keypair of the fee-collector account.

    Returns Promise<TransactionResult>

    A TransactionResult.

    Never — errors are returned as status: 'failed'.

    const balance = await sdk.getFeeBalance('CD...usdc');
    const result = await sdk.withdrawFees(
    { asset: 'CD...usdc', amount: balance },
    feeCollectorKeypair,
    );