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

# Swap

> Same-chain swap end to end: quote, build, sign, and status.

A complete same-chain swap end to end: quote a route, build, sign, and confirm (EVM approves the token first). 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">
    A same-chain swap on Arbitrum: 100 USDC → WETH.

    ```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 = '0xaf88d065e77c8cC2239327C5EDb3A432268e5831';
    const WETH = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1';
    const AMOUNT = '100000000';                           // 100 USDC (6 decimals)
    ```
  </Tab>

  <Tab title="Solana">
    A same-chain swap on Solana: 100 USDC → SOL. No approval step, SPL tokens don't need one. 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 USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
    const SOL = '11111111111111111111111111111111';                 // native SOL
    const AMOUNT = '100000000';                                     // 100 USDC (6 decimals)
    ```
  </Tab>
</Tabs>

## Steps

<Tabs>
  <Tab title="EVM">
    <Steps>
      <Step title="Quote">
        Ask for the best route. The response is keyed by pair: read `recommendedSource`, then pull that route out of `quoteRates`.

        ```ts theme={null}
        const quotes = await dzap.getTradeQuotes({
          fromChain: 42161,
          account: account.address,
          data: [{
            srcToken: USDC,
            destToken: WETH,
            amount: AMOUNT,
            toChain: 42161,        // same chain as fromChain = swap
            slippage: 1,           // 1 = 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}, out ${best?.destAmount}`);
        ```

        <Note>
          Provider allow/deny lists, `filter`, and quote-timing knobs are optional. See [advanced quote fields](/sdk/trade/request-quotes#advanced-quote-configuration).
        </Note>
      </Step>

      <Step title="Approve">
        Give the router an allowance for the source token. `AutoPermit` picks EIP-2612 or Permit2 automatically, so most tokens need no on-chain approval at all.

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

        const entry = data[USDC];
        const needsApproval = entry.type !== 'eip2612' && entry.allowance < BigInt(AMOUNT);

        if (needsApproval) {
          await dzap.approve({
            chainId: 42161,
            signer: walletClient,
            sender: account.address,
            tokens: [{ address: USDC, amount: AMOUNT }],
            service: Services.trade,
            mode: ApprovalModes.AutoPermit,
          });
        }
        ```

        <Note>
          Permit2 vs EIP-2612 vs plain approvals, and gasless permit signing, are in [Check allowance](/sdk/approvals/check-allowance) and [Approval mechanisms](/sdk/approval-mechanisms).
        </Note>
      </Step>

      <Step title="Build & send">
        `trade()` builds the transaction from the request, then signs and sends it in one call.

        ```ts theme={null}
        const request = {
          fromChain: 42161,
          sender: account.address,
          refundee: account.address,
          gasless: false,
          data: [{
            srcToken: USDC,
            destToken: WETH,
            amount: AMOUNT,
            toChain: 42161,
            protocol: source,          // provider ID from the quote
            recipient: account.address,
            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`. Full field list, gasless variant, and the `TRY_ANOTHER_ROUTE` retry are in [Execute trade](/sdk/trade/execute-trade).
        </Note>
      </Step>

      <Step title="Status">
        Confirm settlement. `chainId` is a number, and the terminal states are uppercase.

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

        console.log(status.status);   // 'COMPLETED' once mined
        ```

        <Note>
          Same-chain swaps settle in one block. For the full response shape and multi-tx polling, see [Track trade status](/sdk/trade/status-tracking).
        </Note>
      </Step>
    </Steps>
  </Tab>

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

        ```ts theme={null}
        const quotes = await dzap.getTradeQuotes({
          fromChain: 7565164,
          account,
          data: [{
            srcToken: USDC,
            destToken: SOL,
            amount: AMOUNT,
            toChain: 7565164,      // same chain as fromChain = swap
            slippage: 1,           // 1 = 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}, out ${best?.destAmount}`);
        ```
      </Step>

      <Step title="Build">
        No approval on Solana, go straight to build. The response carries a base64 Solana transaction in `transaction.data`.

        ```ts theme={null}
        const built = await dzap.buildTradeTxn({
          fromChain: 7565164,
          sender: account,
          refundee: account,
          gasless: false,
          data: [{
            srcToken: USDC,
            destToken: SOL,
            amount: AMOUNT,
            toChain: 7565164,
            protocol: source,          // provider ID from the quote
            recipient: account,
            slippage: 1,
          }],
        });
        ```
      </Step>

      <Step title="Sign & send">
        Deserialize the built transaction, sign it with your 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">
        Track it with the returned hash.

        ```ts theme={null}
        const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 7565164 });
        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 = '0xaf88d065e77c8cC2239327C5EDb3A432268e5831';
    const WETH = '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1';
    const AMOUNT = '100000000'; // 100 USDC

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

    // 2. Approve (if needed)
    const { data } = await dzap.getAllowance({
      chainId: 42161,
      sender: account.address,
      tokens: [{ address: USDC, amount: AMOUNT }],
      service: Services.trade,
      mode: ApprovalModes.AutoPermit,
    });
    const entry = data[USDC];
    if (entry.type !== 'eip2612' && entry.allowance < BigInt(AMOUNT)) {
      await dzap.approve({
        chainId: 42161,
        signer: walletClient,
        sender: account.address,
        tokens: [{ address: USDC, 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, destToken: WETH, amount: AMOUNT, toChain: 42161, 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 ?? 'swap failed');

    // 4. Status
    const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 42161 });
    console.log('settled:', status.status);
    ```
  </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 USDC = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
    const SOL = '11111111111111111111111111111111'; // native SOL
    const AMOUNT = '100000000'; // 100 USDC

    // 1. Quote
    const quotes = await dzap.getTradeQuotes({
      fromChain: 7565164,
      account,
      data: [{ srcToken: USDC, destToken: SOL, amount: AMOUNT, toChain: 7565164, 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, destToken: SOL, amount: AMOUNT, toChain: 7565164, protocol: source, recipient: account, 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. Status
    const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 7565164 });
    console.log('settled:', status.status);
    ```
  </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": "100000000",
            "srcToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
            "destToken": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
            "toChain": 42161,
            "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": "100000000",
            "srcToken": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
            "destToken": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
            "toChain": 42161,
            "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": "100000000",
            "srcToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "destToken": "11111111111111111111111111111111",
            "toChain": 7565164,
            "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": "100000000",
            "srcToken": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
            "destToken": "11111111111111111111111111111111",
            "toChain": 7565164,
            "protocol": "<recommendedSource from quote>",
            "recipient": "8AsEhwyveydfzqnuUTjoCYjpxydpKPUXLqgyKdTPWV8v",
            "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>
</Tabs>

## What can go wrong

* **No route returned**, the pair is thin or unsupported. Try a different amount or token, or widen `slippage`.
* **Approval fails**, make sure the wallet holds gas (ETH on Arbitrum).
* **`TRY_ANOTHER_ROUTE`** on the trade response, retry with `pair.bestReturnSource`. See [Execute trade](/sdk/trade/execute-trade).

See [Error codes](/api/error-codes) for the full catalog.
