> ## 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.

# Bridge

> Cross-chain swap: move USDC from Arbitrum to Base with quote, build, sign, and status.

Bridging is the same flow as a [swap](/cookbook/trade/swap), you just set `toChain` to a different chain. Settlement is asynchronous, so the status step polls. Pick a chain below; the tabs stay in sync across Setup, Steps, End-to-end, and API usage.

## Setup

<Snippet file="install-sdk.mdx" />

<Tabs>
  <Tab title="EVM">
    Bridge USDC from Arbitrum to Base.

    ```ts theme={null}
    import { DZapClient, Services, ApprovalModes, TxnStatus } 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';
    const AMOUNT = '50000000';                            // 50 USDC (6 decimals)
    ```
  </Tab>

  <Tab title="Solana">
    Bridge USDC from Solana to Base. `toChain` is an EVM chain and `recipient` is an EVM address. Needs `@solana/web3.js` alongside the SDK.

    ```ts theme={null}
    import { DZapClient } from '@dzapio/sdk';
    import { Connection, VersionedTransaction } from '@solana/web3.js';

    const dzap = DZapClient.getInstance();
    const connection = new Connection('https://api.mainnet-beta.solana.com');

    // your Solana wallet adapter (wallet-standard, Keypair, etc.)
    const account = wallet.publicKey.toBase58();
    const recipient = '0x46b24b781f9Ac1344e594A313671e5CDb1459646'; // EVM address on Base
    const USDC_SOL = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
    const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
    const AMOUNT = '50000000';                                       // 50 USDC (6 decimals)
    ```
  </Tab>

  <Tab title="Bitcoin">
    Bridge native BTC to an EVM chain. Bitcoin is bridge-only (no same-chain swap) and UTXO-based, so there are no approvals: the build returns a PSBT you sign, then broadcast.

    ```ts theme={null}
    import { DZapClient } from '@dzapio/sdk';

    const dzap = DZapClient.getInstance();

    const account = 'bc1q...';
    const publicKey = '02...';                                   // compressed pubkey for `account`
    const recipient = '0x46b24b781f9Ac1344e594A313671e5CDb1459646'; // EVM address on Base
    const BTC = '<native BTC address, from GET /v1/chains>';
    const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
    const AMOUNT = '100000';                                     // 0.001 BTC (satoshis)
    ```
  </Tab>
</Tabs>

## Steps

<Tabs>
  <Tab title="EVM">
    <Steps>
      <Step title="Quote">
        Quote across bridge providers. Setting `toChain` to a different chain than `fromChain` is what makes this a bridge.

        ```ts theme={null}
        const quotes = await dzap.getTradeQuotes({
          fromChain: 42161,
          account: account.address,
          data: [{
            srcToken: USDC_ARB,
            destToken: USDC_BASE,
            amount: AMOUNT,
            toChain: 8453,         // Base, different chain = bridge
            slippage: 1,
          }],
        });

        const pair = quotes[Object.keys(quotes)[0]];
        const source = pair.recommendedSource ?? pair.bestReturnSource;
        const best = pair.quoteRates?.[source];
        console.log(`Best: ${best?.providerDetails.name}, ~${best?.duration}s`);
        ```

        <Note>
          To bias toward speed or a specific bridge, use `filter: 'fastest'` or provider allow/deny lists, see [advanced quote fields](/sdk/trade/request-quotes#advanced-quote-configuration).
        </Note>
      </Step>

      <Step title="Approve">
        Approval is on the **source chain only**: the bridge handles disbursement on the destination side. `AutoPermit` keeps it gasless where the token allows.

        ```ts theme={null}
        const { data } = await dzap.getAllowance({
          chainId: 42161,
          sender: account.address,
          tokens: [{ address: USDC_ARB, amount: AMOUNT }],
          service: Services.trade,
          mode: ApprovalModes.AutoPermit,
        });

        const entry = data[USDC_ARB];
        if (entry.type !== 'eip2612' && entry.allowance < BigInt(AMOUNT)) {
          await dzap.approve({
            chainId: 42161,
            signer: walletClient,
            sender: account.address,
            tokens: [{ address: USDC_ARB, amount: AMOUNT }],
            service: Services.trade,
            mode: ApprovalModes.AutoPermit,
          });
        }
        ```

        <Note>
          Other approval flows (Permit2, EIP-2612, gasless permits) are in [Check allowance](/sdk/approvals/check-allowance) and [Approval mechanisms](/sdk/approval-mechanisms).
        </Note>
      </Step>

      <Step title="Build & send">
        `trade()` builds the bridge transaction, then signs and sends it in one call. `refundee` and `recipient` matter more here than on a same-chain swap.

        ```ts theme={null}
        const request = {
          fromChain: 42161,
          sender: account.address,
          refundee: account.address,     // funds return here if the destination leg fails
          gasless: false,
          data: [{
            srcToken: USDC_ARB,
            destToken: USDC_BASE,
            amount: AMOUNT,
            toChain: 8453,
            protocol: source,
            recipient: account.address,  // can be a different address on Base
            slippage: 1,
          }],
        };

        const result = await dzap.trade({ request, signer: walletClient });
        console.log(`Sent: ${result.txnHash}`);
        ```

        <Note>
          `trade()` builds and sends in one call. Call `buildTradeTxn` first only to preview the transaction or reuse it via `txnData`. Use a `refundee` you control on the source chain, and set `recipient` to the address that should receive funds on the destination. Full request shape: [Execute trade](/sdk/trade/execute-trade).
        </Note>
      </Step>

      <Step title="Status">
        Cross-chain settlement is asynchronous: poll `getTradeTxnStatus` until it reaches a terminal state.

        ```ts theme={null}
        const status = await dzap.getTradeTxnStatus({
          txHash: result.txnHash!,
          chainId: 42161,              // source chain, as a number
        });

        console.log(status.status);    // PENDING → COMPLETED (or FAILED / REFUNDED)
        ```

        <Note>
          Terminal states are `COMPLETED`, `FAILED`, `PARTIAL`, and `REFUNDED`. See [Track trade status](/sdk/trade/status-tracking) for a ready-made polling helper.
        </Note>
      </Step>
    </Steps>
  </Tab>

  <Tab title="Solana">
    <Steps>
      <Step title="Quote">
        Same call as EVM, with Solana's chain ID (`7565164`); `toChain` stays the EVM destination. The response is keyed by pair: read `recommendedSource` (or `bestReturnSource`).

        ```ts theme={null}
        const quotes = await dzap.getTradeQuotes({
          fromChain: 7565164,
          account,
          data: [{
            srcToken: USDC_SOL,
            destToken: USDC_BASE,
            amount: AMOUNT,
            toChain: 8453,         // Base, different chain = bridge
            slippage: 1,
          }],
        });
        const pair = quotes[Object.keys(quotes)[0]];
        const source = pair.recommendedSource ?? pair.bestReturnSource;
        const best = pair.quoteRates?.[source];
        console.log(`Best: ${best?.providerDetails.name}, ~${best?.duration}s`);
        ```
      </Step>

      <Step title="Build">
        No approval on Solana. Build returns a base64 Solana transaction in `transaction.data`.

        ```ts theme={null}
        const built = await dzap.buildTradeTxn({
          fromChain: 7565164,
          sender: account,
          refundee: account,           // funds return here on Solana if the destination leg fails
          gasless: false,
          data: [{
            srcToken: USDC_SOL,
            destToken: USDC_BASE,
            amount: AMOUNT,
            toChain: 8453,
            protocol: source,
            recipient,
            slippage: 1,
          }],
        });
        ```
      </Step>

      <Step title="Sign & send">
        Deserialize the built transaction, sign it with your Solana wallet, then hand it back to DZap to broadcast. `broadcastTradeTx` returns the on-chain `txnHash` and routes Jito trades through the Jito block engine for you.

        ```ts theme={null}
        const tx = VersionedTransaction.deserialize(Buffer.from(built.transaction.data, 'base64'));
        const signed = await wallet.signTransaction(tx);   // your Solana wallet adapter (wallet-standard, Keypair, etc.)

        const result = await dzap.broadcastTradeTx({
          txId: built.txId,
          chainId: 7565164,
          txData: Buffer.from(signed.serialize()).toString('base64'),
        });
        ```

        <Note>
          Prefer to submit it yourself? Send the signed transaction over your own RPC instead, then track by that signature: `const sig = await connection.sendRawTransaction(signed.serialize()); await connection.confirmTransaction(sig, 'confirmed');`. See [Broadcast](/api/trade/broadcast).
        </Note>
      </Step>

      <Step title="Status">
        Cross-chain settlement is async, poll to a terminal state.

        ```ts theme={null}
        const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 7565164 });
        console.log(status.status);   // PENDING to COMPLETED (or FAILED / REFUNDED)
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Bitcoin">
    <Steps>
      <Step title="Quote">
        Bitcoin's chain ID is `1000` and amounts are in satoshis. The response is keyed by pair: read `recommendedSource` (or `bestReturnSource`).

        ```ts theme={null}
        const quotes = await dzap.getTradeQuotes({
          fromChain: 1000,
          account,
          data: [{
            srcToken: BTC,
            destToken: USDC_BASE,
            amount: AMOUNT,
            toChain: 8453,         // Base, different chain = bridge
            slippage: 1,
          }],
        });
        const pair = quotes[Object.keys(quotes)[0]];
        const source = pair.recommendedSource ?? pair.bestReturnSource;
        const best = pair.quoteRates?.[source];
        console.log(`Best: ${best?.providerDetails.name}, ~${best?.duration}s`);
        ```
      </Step>

      <Step title="Build">
        Pass `publicKey` (Bitcoin only). The response carries a PSBT in `transaction`: `{ inputs, outputs, feeRate }`.

        ```ts theme={null}
        const built = await dzap.buildTradeTxn({
          fromChain: 1000,
          sender: account,
          refundee: account,
          gasless: false,
          publicKey,                    // required for Bitcoin
          data: [{
            srcToken: BTC,
            destToken: USDC_BASE,
            amount: AMOUNT,
            toChain: 8453,
            protocol: source,
            recipient,
            slippage: 1,
          }],
        });
        ```
      </Step>

      <Step title="Sign & broadcast">
        Assemble and sign the PSBT from `built.transaction` with your Bitcoin wallet (`signPsbt`, bitcoinjs-lib, etc.), then hand the signed transaction to DZap to broadcast.

        ```ts theme={null}
        // built.transaction holds the PSBT ({ inputs, outputs, feeRate }); sign it with your BTC wallet to get the raw signed tx
        const result = await dzap.broadcastTradeTx({
          txId: built.txId,
          chainId: 1000,
          txData: signedTxHex,          // your signed Bitcoin transaction
        });
        ```
      </Step>

      <Step title="Status">
        Poll with the returned `txnHash` until it reaches a terminal state (cross-chain settlement is asynchronous).

        ```ts theme={null}
        const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 1000 });
        console.log(status.status);
        ```
      </Step>
    </Steps>
  </Tab>
</Tabs>

## End-to-end

<Tabs>
  <Tab title="EVM">
    ```ts theme={null}
    import { DZapClient, Services, ApprovalModes, TxnStatus } 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';
    const AMOUNT = '50000000'; // 50 USDC

    // 1. Quote
    const quotes = await dzap.getTradeQuotes({
      fromChain: 42161,
      account: account.address,
      data: [{ srcToken: USDC_ARB, destToken: USDC_BASE, amount: AMOUNT, toChain: 8453, slippage: 1 }],
    });
    const pair = quotes[Object.keys(quotes)[0]];
    const source = pair.recommendedSource ?? pair.bestReturnSource;

    // 2. Approve (source chain only)
    const { data } = await dzap.getAllowance({
      chainId: 42161,
      sender: account.address,
      tokens: [{ address: USDC_ARB, amount: AMOUNT }],
      service: Services.trade,
      mode: ApprovalModes.AutoPermit,
    });
    const entry = data[USDC_ARB];
    if (entry.type !== 'eip2612' && entry.allowance < BigInt(AMOUNT)) {
      await dzap.approve({
        chainId: 42161,
        signer: walletClient,
        sender: account.address,
        tokens: [{ address: USDC_ARB, amount: AMOUNT }],
        service: Services.trade,
        mode: ApprovalModes.AutoPermit,
      });
    }

    // 3. Build + send
    const request = {
      fromChain: 42161,
      sender: account.address,
      refundee: account.address,
      gasless: false,
      data: [{ srcToken: USDC_ARB, destToken: USDC_BASE, amount: AMOUNT, toChain: 8453, protocol: source, recipient: account.address, slippage: 1 }],
    };
    const result = await dzap.trade({ request, signer: walletClient });
    if (result.status !== TxnStatus.success) throw new Error(result.errorMsg ?? 'bridge failed');

    // 4. Poll until settled (cross-chain is async)
    for (let i = 0; i < 60; i++) {
      const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 42161 });
      if (['COMPLETED', 'PARTIAL', 'FAILED', 'REFUNDED'].includes(status.status)) {
        console.log('settled:', status.status);
        break;
      }
      await new Promise((r) => setTimeout(r, 5000));
    }
    ```
  </Tab>

  <Tab title="Solana">
    ```ts theme={null}
    import { DZapClient } from '@dzapio/sdk';
    import { Connection, VersionedTransaction } from '@solana/web3.js';

    const dzap = DZapClient.getInstance();
    const connection = new Connection('https://api.mainnet-beta.solana.com');

    // your Solana wallet adapter (wallet-standard, Keypair, etc.)
    const account = wallet.publicKey.toBase58();
    const recipient = '0x46b24b781f9Ac1344e594A313671e5CDb1459646'; // EVM address on Base
    const USDC_SOL = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
    const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
    const AMOUNT = '50000000'; // 50 USDC

    // 1. Quote
    const quotes = await dzap.getTradeQuotes({
      fromChain: 7565164,
      account,
      data: [{ srcToken: USDC_SOL, destToken: USDC_BASE, amount: AMOUNT, toChain: 8453, slippage: 1 }],
    });
    const pair = quotes[Object.keys(quotes)[0]];
    const source = pair.recommendedSource ?? pair.bestReturnSource;

    // 2. Build (no approval on Solana)
    const built = await dzap.buildTradeTxn({
      fromChain: 7565164,
      sender: account,
      refundee: account,
      gasless: false,
      data: [{ srcToken: USDC_SOL, destToken: USDC_BASE, amount: AMOUNT, toChain: 8453, protocol: source, recipient, slippage: 1 }],
    });

    // 3. Sign + broadcast via DZap
    const tx = VersionedTransaction.deserialize(Buffer.from(built.transaction.data, 'base64'));
    const signed = await wallet.signTransaction(tx);
    const result = await dzap.broadcastTradeTx({
      txId: built.txId,
      chainId: 7565164,
      txData: Buffer.from(signed.serialize()).toString('base64'),
    });

    // 4. Poll until settled (cross-chain is async)
    for (let i = 0; i < 60; i++) {
      const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 7565164 });
      if (['COMPLETED', 'PARTIAL', 'FAILED', 'REFUNDED'].includes(status.status)) {
        console.log('settled:', status.status);
        break;
      }
      await new Promise((r) => setTimeout(r, 5000));
    }
    ```
  </Tab>

  <Tab title="Bitcoin">
    ```ts theme={null}
    import { DZapClient } from '@dzapio/sdk';

    const dzap = DZapClient.getInstance();

    const account = 'bc1q...';
    const publicKey = '02...';                                   // compressed pubkey for `account`
    const recipient = '0x46b24b781f9Ac1344e594A313671e5CDb1459646'; // EVM address on Base
    const BTC = '<native BTC address, from GET /v1/chains>';
    const USDC_BASE = '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913';
    const AMOUNT = '100000'; // 0.001 BTC (satoshis)

    // 1. Quote
    const quotes = await dzap.getTradeQuotes({
      fromChain: 1000,
      account,
      data: [{ srcToken: BTC, destToken: USDC_BASE, amount: AMOUNT, toChain: 8453, slippage: 1 }],
    });
    const pair = quotes[Object.keys(quotes)[0]];
    const source = pair.recommendedSource ?? pair.bestReturnSource;

    // 2. Build (pass publicKey; response carries a PSBT)
    const built = await dzap.buildTradeTxn({
      fromChain: 1000,
      sender: account,
      refundee: account,
      gasless: false,
      publicKey,
      data: [{ srcToken: BTC, destToken: USDC_BASE, amount: AMOUNT, toChain: 8453, protocol: source, recipient, slippage: 1 }],
    });

    // 3. Sign the PSBT (built.transaction) with your BTC wallet, then broadcast the raw signed tx
    const result = await dzap.broadcastTradeTx({ txId: built.txId, chainId: 1000, txData: signedTxHex });

    // 4. Poll until settled (cross-chain is async)
    for (let i = 0; i < 60; i++) {
      const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 1000 });
      if (['COMPLETED', 'PARTIAL', 'FAILED', 'REFUNDED'].includes(status.status)) {
        console.log('settled:', status.status);
        break;
      }
      await new Promise((r) => setTimeout(r, 5000));
    }
    ```
  </Tab>
</Tabs>

## API usage

The same flow over REST. Non-EVM chains build a chain-specific transaction you sign locally, then submit via [Broadcast](/api/trade/broadcast).

<Tabs>
  <Tab title="EVM">
    <CodeGroup>
      ```bash Quote theme={null}
      curl -X POST https://api.dzap.io/v1/quotes \
        -H "Content-Type: application/json" \
        -d '{
          "fromChain": 42161,
          "data": [{
            "amount": "50000000",
            "srcToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
            "destToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "toChain": 8453,
            "slippage": 1
          }],
          "account": "0xUser"
        }'
      ```

      ```bash Build theme={null}
      curl -X POST https://api.dzap.io/v1/buildTx \
        -H "Content-Type: application/json" \
        -d '{
          "sender": "0xUser",
          "refundee": "0xUser",
          "fromChain": 42161,
          "gasless": false,
          "data": [{
            "amount": "50000000",
            "srcToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
            "destToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "toChain": 8453,
            "protocol": "<recommendedSource from quote>",
            "recipient": "0xUser",
            "slippage": 1
          }]
        }'
      ```

      ```bash Status theme={null}
      curl "https://api.dzap.io/v1/status?txHash=0xabc...&chainId=42161"
      ```
    </CodeGroup>

    Sign and broadcast the `transaction` from the build response with your own signer. Full reference: [Quote](/api/trade/quote), [Build Tx](/api/trade/build-tx), [Status](/api/trade/status).
  </Tab>

  <Tab title="Solana">
    <CodeGroup>
      ```bash Quote theme={null}
      curl -X POST https://api.dzap.io/v1/quotes \
        -H "Content-Type: application/json" \
        -d '{
          "fromChain": 7565164,
          "data": [{
            "amount": "50000000",
            "srcToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "destToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "toChain": 8453,
            "slippage": 1
          }],
          "account": "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v"
        }'
      ```

      ```bash Build theme={null}
      curl -X POST https://api.dzap.io/v1/buildTx \
        -H "Content-Type: application/json" \
        -d '{
          "sender": "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
          "refundee": "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
          "fromChain": 7565164,
          "gasless": false,
          "data": [{
            "amount": "50000000",
            "srcToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "destToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "toChain": 8453,
            "protocol": "<recommendedSource from quote>",
            "recipient": "0x46b24b781f9Ac1344e594A313671e5CDb1459646",
            "slippage": 1
          }]
        }'
      ```

      ```bash Broadcast theme={null}
      # sign the base64 transaction from the build response, then submit it
      curl -X POST https://api.dzap.io/v1/broadcast \
        -H "Content-Type: application/json" \
        -d '{
          "txId": "<txId from build>",
          "chainId": 7565164,
          "txData": "<signed transaction>"
        }'
      ```

      ```bash Status theme={null}
      curl "https://api.dzap.io/v1/status?txHash=<signature>&chainId=7565164"
      ```
    </CodeGroup>

    The build returns a base64 Solana transaction; sign it with your wallet before broadcasting. Full reference: [Quote](/api/trade/quote), [Build Tx](/api/trade/build-tx), [Broadcast](/api/trade/broadcast), [Status](/api/trade/status).
  </Tab>

  <Tab title="Bitcoin">
    <CodeGroup>
      ```bash Quote theme={null}
      curl -X POST https://api.dzap.io/v1/quotes \
        -H "Content-Type: application/json" \
        -d '{
          "fromChain": 1000,
          "data": [{
            "amount": "100000",
            "srcToken": "<native BTC, from GET /v1/chains>",
            "destToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "toChain": 8453,
            "slippage": 1
          }],
          "account": "bc1q..."
        }'
      ```

      ```bash Build theme={null}
      curl -X POST https://api.dzap.io/v1/buildTx \
        -H "Content-Type: application/json" \
        -d '{
          "sender": "bc1q...",
          "refundee": "bc1q...",
          "fromChain": 1000,
          "gasless": false,
          "publicKey": "02...",
          "data": [{
            "amount": "100000",
            "srcToken": "<native BTC, from GET /v1/chains>",
            "destToken": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
            "toChain": 8453,
            "protocol": "<recommendedSource from quote>",
            "recipient": "0x46b24b781f9Ac1344e594A313671e5CDb1459646",
            "slippage": 1
          }]
        }'
      ```

      ```bash Broadcast theme={null}
      # build returns a PSBT; sign it with your BTC wallet, then submit the raw signed tx
      curl -X POST https://api.dzap.io/v1/broadcast \
        -H "Content-Type: application/json" \
        -d '{
          "txId": "<txId from build>",
          "chainId": 1000,
          "txData": "<signed transaction>"
        }'
      ```

      ```bash Status theme={null}
      curl "https://api.dzap.io/v1/status?txHash=<txnHash>&chainId=1000"
      ```
    </CodeGroup>

    Pass `publicKey` on the build; the response carries a PSBT to sign before broadcasting. Full reference: [Quote](/api/trade/quote), [Build Tx](/api/trade/build-tx), [Broadcast](/api/trade/broadcast), [Status](/api/trade/status).
  </Tab>
</Tabs>

## Bridge quirks

* **`refundee` matters.** If the destination leg fails, funds return to `refundee` on the source chain. Use a wallet you control.
* **`recipient` can differ from `sender`.** Useful when paying on someone else's behalf, they receive on the destination chain.
* **Settlement time varies.** Across is seconds; CCTP is \~13 minutes; others vary by route. Read `best.duration` from the quote.
* **Approval is source-chain only.** No extra approval on the destination side; the bridge contract handles disbursement.

## When to use Fuse instead

If your goal is "bridge, then do something on the destination" (add liquidity, mint, stake), use a [Fuse bundle](/products/dzap-fuse/bundle), one signature for the whole journey.
