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

# Private

> Private bridging (Ghost Mode): route around the public mempool with a single flag.

Ghost Mode routes your trade through private relays instead of the public mempool: no front-running, no copy-trading, no tipping off screeners before settlement. It is the standard [bridge](/cookbook/trade/bridge) flow with one addition: `private: true` on the quote and the build.

<Note>Ghost Mode is EVM-only today. Non-EVM chains (Solana, Bitcoin, Sui) route through the public flow, `private: true` is ignored.</Note>

## Setup

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

```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 = '1000000000';                          // 1,000 USDC (6 decimals)
```

## Steps

<Steps>
  <Step title="Quote">
    Request a private quote by setting `private: true` at the top level. Routing is restricted to providers that support a private mempool.

    ```ts theme={null}
    const quotes = await dzap.getTradeQuotes({
      fromChain: 42161,
      account: account.address,
      private: true,             // Ghost Mode
      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;
    ```

    <Note>
      `private` is a top-level flag, not a per-leg one. Other quote options are in [advanced quote fields](/sdk/trade/request-quotes#advanced-quote-configuration).
    </Note>
  </Step>

  <Step title="Approve">
    Identical to a normal bridge: approval is on the source chain, and `AutoPermit` stays 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>
      Approvals are public by design: only the trade itself is routed privately. Other approval flows: [Check allowance](/sdk/approvals/check-allowance) and [Approval mechanisms](/sdk/approval-mechanisms).
    </Note>
  </Step>

  <Step title="Build">
    Carry the flag through to the build, set `private: true` on the request too, so the transaction is submitted through the private relay.

    ```ts theme={null}
    const request = {
      fromChain: 42161,
      sender: account.address,
      refundee: account.address,
      gasless: false,
      private: true,             // submit through the private relay
      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 });
    console.log(`Sent privately: ${result.txnHash}`);
    ```

    <Note>
      Set `private` on both the quote and the build. The response echoes `private` back so you can confirm the route was honored. Full request shape: [Execute trade](/sdk/trade/execute-trade).
    </Note>
  </Step>

  <Step title="Status">
    Track it exactly like a normal bridge: poll to a terminal state.

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

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

    <Note>
      Private routing can add slight latency versus the public mempool. See [Track trade status](/sdk/trade/status-tracking) for the polling helper.
    </Note>
  </Step>
</Steps>

## End-to-end

```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 = '1000000000'; // 1,000 USDC

// 1. Private quote
const quotes = await dzap.getTradeQuotes({
  fromChain: 42161,
  account: account.address,
  private: true,
  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 privately
const request = {
  fromChain: 42161,
  sender: account.address,
  refundee: account.address,
  gasless: false,
  private: true,
  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 ?? 'private bridge failed');

// 4. Status
const status = await dzap.getTradeTxnStatus({ txHash: result.txnHash!, chainId: 42161 });
console.log('settled:', status.status);
```

## API usage

Set `"private": true` on both the quote and the build; status is unchanged.

<CodeGroup>
  ```bash Quote theme={null}
  curl -X POST https://api.dzap.io/v1/quotes \
    -H "Content-Type: application/json" \
    -d '{
      "fromChain": 42161,
      "private": true,
      "data": [{
        "amount": "1000000000",
        "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,
      "private": true,
      "data": [{
        "amount": "1000000000",
        "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>

Full reference: [Quote](/api/trade/quote), [Build Tx](/api/trade/build-tx), [Status](/api/trade/status).

## Public vs Ghost Mode

|                      | Public Bridge | Ghost Mode        |
| -------------------- | ------------- | ----------------- |
| Front-run protection | Partial       | Full              |
| Settlement latency   | Seconds       | Slightly higher   |
| Solver liquidity     | Open          | Permissioned pool |
| Fees                 | Standard      | Slight premium    |

Read more in [Ghost Mode](/products/dzap-core/ghost-mode).
