Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dzap.io/llms.txt

Use this file to discover all available pages before exploring further.

Bridging on DZap is the same getTradeQuotes / trade flow as a swap — you just set toChain.

End-to-end

import { DZapClient, ApprovalModes } from '@dzapio/sdk';
import { createWalletClient, http } from 'viem';
import { arbitrum } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const walletClient = createWalletClient({ account, chain: arbitrum, transport: http() });
const dzap = DZapClient.getInstance();

const USDC_ARB = '0xaf88d065e77c8cC2239327C5EDb3A432268e5831';
const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';

// 1. Quote
const quotes = await dzap.getTradeQuotes({
  fromChain: 42161,
  account: account.address,
  data: [{
    srcToken: USDC_ARB,
    destToken: USDC_BASE,
    amount: '50000000',                    // 50 USDC
    toChain: 8453,
    slippage: 1,
  }],
});
const best = quotes[0].quotes[0];

// 2. Approve
await dzap.approve({
  chainId: 42161,
  signer: walletClient,
  sender: account.address,
  tokens: [{ address: USDC_ARB, amount: 50_000_000n }],
  service: 'swap',
  mode: ApprovalModes.AutoPermit,
});

// 3. Bridge
const result = await dzap.trade({
  request: {
    fromChain: 42161,
    sender: account.address,
    refundee: account.address,             // refund here if destination fails
    data: [{
      srcToken: USDC_ARB,
      destToken: USDC_BASE,
      amount: '50000000',
      toChain: 8453,
      protocol: best.protocol,
      recipient: account.address,           // could be a different address
      slippage: 1,
    }],
  },
  signer: walletClient,
});

// 4. Track (cross-chain settlement is async)
async function waitForSettlement() {
  for (let i = 0; i < 60; i++) {
    const status = await dzap.getTradeTxnStatus({
      txIds: `42161-${result.txnHash}`,
    });
    if (status.status === 'completed') return status;
    if (status.status === 'failed') throw new Error('bridge failed');
    await new Promise(r => setTimeout(r, 5000));
  }
  throw new Error('timeout');
}

const finalStatus = await waitForSettlement();
console.log('settled:', finalStatus);

Bridge quirks

  • refundee matters. If the destination side fails, funds return to refundee on the source chain. Use a wallet you control.
  • recipient can differ from sender. Useful when you’re paying on someone else’s behalf — they receive on the destination chain.
  • Settlement time varies. Across is seconds; CCTP is ~13 minutes; Allbridge varies by route. Check quotes[0].quotes[0].estimatedDuration.
  • Pre-bridge approval is on source chain only. No additional approval needed on the destination side; the bridge contract handles destination disbursement.

When to use Fuse instead

If your goal is “bridge, then do something on the destination” (e.g. add liquidity, mint NFT), use Fuse Bundle — one signature for the whole journey.

Next