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:
Recommended flow
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 operations —
getAllowanceandapproveboth accept arrays. Don’t loop one-by-one; you’ll trigger N wallet popups. - Service must match —
service: Services.tradechecks the trade router;service: Services.zapchecks the zap router. They differ on some chains.Servicesonly hastrade,dca, andzap— there is no'swap'value. - Permit deadlines — gasless permits include a deadline. Sign close to execution.