Skip to main content
Before any swap/bridge/zap that spends ERC20s, a spender must be approved. The SDK supports several modes via getAllowance(), approve(), and sign() — pick AutoPermit unless you have a reason not to.

The modes

approve()’s mode param takes an ApprovalModes value; sign()’s permitType param takes a PermitTypes value. They’re closely related but not identical sets: Most modern tokens support EIP-2612 or are routable through Permit2, so AutoPermit covers the long tail. ApprovalModes has no EIP2612Permit member — a token that supports EIP-2612 never needs an approve() call at all, only a sign() call.

Check allowance

type tells you whether the token will use a direct DZap approval, a Permit2 approval, or an EIP-2612 permit. There is no approvalNeeded/signatureNeeded field — derive that yourself:

Approve

approvalTxnCallback fires once per token (viem WalletClient signers only). If it returns a TxnStatus other than success, remaining tokens in the batch are skipped.

Sign (gasless permits)

For Permit2/EIP-2612 paths — returns the permit response directly, not wrapped in .data:
1

Check

getAllowance() with mode: AutoPermit, then derive needsApproval/needsSignature from allowance/type as shown above.
2

Approve or sign

If needsApproval: approve(). If needsSignature: sign().
3

Execute

Pass the resulting permitData (per-token) into the matching data[].permitData field of your trade()/zap() request.

Common pitfalls

  • Multi-token operationsgetAllowance and approve both accept arrays. Don’t loop one-by-one; you’ll trigger N wallet popups.
  • Service must matchservice: Services.trade checks the trade router; service: Services.zap checks the zap router. They differ on some chains. Services only has trade, dca, and zap — there is no 'swap' value.
  • Permit deadlines — gasless permits include a deadline. Sign close to execution.
Last modified on July 14, 2026