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

# Approvals

> ERC20, Permit2, EIP-2612, and AutoPermit modes.

Before any swap/bridge/zap that spends ERC20s, the DZap router must be approved. The SDK supports four modes — pick `AutoPermit` unless you have a reason not to.

## The four modes

| Mode            | How                                         | Gas                              | Spender          |
| --------------- | ------------------------------------------- | -------------------------------- | ---------------- |
| `Default`       | Standard ERC20 `approve()`                  | Yes (one-time)                   | DZap router      |
| `Permit2`       | One-time approve to Permit2; sign per-trade | Initial yes, then signature only | Permit2 contract |
| `EIP2612Permit` | Sign permit message; no approval tx         | None (signature only)            | DZap router      |
| `AutoPermit`    | EIP2612 if supported, fallback to Permit2   | Best-of-both                     | Auto             |

Most modern tokens support EIP-2612 or are routable through Permit2, so `AutoPermit` covers the long tail.

## Check allowance

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

const { status, data } = await dzap.getAllowance({
  chainId: 42161,
  sender: '0xUser',
  tokens: [{ address: '0xaf88...', amount: 1_000_000n }],
  service: 'swap',
  mode: ApprovalModes.AutoPermit,
});

// data['0xaf88...'] => { allowance: bigint, type: 'dzap' | 'permit2' | 'eip2612' }
```

`type` tells you whether the token will use a direct DZap approval, a Permit2 approval, or an EIP-2612 permit.

## Approve

```ts theme={null}
if (data['0xaf88...'].allowance < 1_000_000n) {
  await dzap.approve({
    chainId: 42161,
    signer: walletClient,
    sender: '0xUser',
    tokens: [{ address: '0xaf88...', amount: 1_000_000n }],
    service: 'swap',
    mode: ApprovalModes.AutoPermit,
    approvalTxnCallback: ({ status, txHash }) => {
      console.log('approval', status, txHash);
    },
  });
}
```

## Sign (gasless permits)

For EIP-2612 / Permit2 paths:

```ts theme={null}
const { data: permits } = await dzap.sign({
  chainId: 42161,
  sender: '0xUser',
  tokens: [{ address: '0xaf88...', amount: '1000000' }],
  service: 'swap',
  signer: walletClient,
});

// permits['0xaf88...'].permitData → pass to trade()/zap() as `permit`
```

## Recommended flow

<Steps>
  <Step title="Check">
    `getAllowance()` with `mode: AutoPermit`.
  </Step>

  <Step title="Approve or sign">
    If `allowance < amount`: `approve()` for on-chain or `sign()` for gasless.
  </Step>

  <Step title="Execute">
    Pass the `permit` payload (if any) into `trade()` / `zap()`.
  </Step>
</Steps>

## Common pitfalls

* **Multi-token swaps** — `getAllowance` and `approve` both accept arrays. Don't loop one-by-one; you'll trigger N wallet popups.
* **Service must match** — `service: 'swap'` checks the swap router; `service: 'zap'` checks the zap router. They differ on some chains.
* **Permit deadlines** — gasless permits include a deadline (default \~1 hour). Sign close to execution.
