Skip to main content
LI.FI supports three token approval strategies on EVM chains. In addition to the classic approve() transaction, integrators can use EIP-2612 Permits or Uniswap Permit2 to authorize token transfers via off-chain signatures, reducing the number of on-chain transactions required.
If you use the LI.FI SDK or Widget, Permit2 is handled automatically. This guide is for integrators building directly against the API who want to understand or implement the permit flow themselves.

Overview of Approval Strategies

Why Permit2?

With the classic approval model, every new dApp interaction requires a separate approve() transaction. Permit2 replaces this with a single, one-time unlimited approval to the canonical Permit2 contract. All subsequent authorizations happen through gasless EIP-712 signatures with per-transfer granularity (exact amount, deadline, nonce).

Architecture

All permit-based flows go through the Permit2Proxy periphery contract, which acts as an intermediary between the user and the LI.FI Diamond: Permit2 Architecture

Key Addresses

Discovering Addresses via the API

API Flow: Permit2 (Standard Self-Execute)

This is the most common permit flow. It works with any ERC-20 token on chains where Permit2 is deployed.
1

Get a quote

Request a quote as usual. The response includes estimate.approvalAddress (the Diamond address for classic approve) and the chain metadata you need.
2

Check and set Permit2 allowance (one-time)

The user needs to approve the Permit2 contract (not the Diamond) once. This only needs to happen if the user hasn’t already approved Permit2 for this token.Resolve the Permit2 and Permit2Proxy addresses from the chains API — do not hardcode them, as several networks use non-canonical deployments.
3

Read the next available nonce

Permit2 uses unordered nonces. The Permit2Proxy contract provides a nextNonce() helper that finds the next unused nonce for the signer.
4

Build and sign the PermitTransferFrom message

Construct the EIP-712 typed data for PermitTransferFrom. The spender is the Permit2Proxy (not the Diamond).
5

Encode and send the transaction to Permit2Proxy

Wrap the Diamond calldata inside a callDiamondWithPermit2 call targeting the Permit2Proxy, not the Diamond.
6

Track the transfer status

Track the transaction status as you normally would using the /status endpoint.

API Flow: EIP-2612 Native Permit

EIP-2612 permits are only available for tokens that implement the permit() function (e.g., USDC, AAVE, UNI). No prior approve() transaction is needed at all.
Not all tokens support EIP-2612. DAI uses a non-standard permit signature that LI.FI does not currently support. If the token does not implement EIP-2612, fall back to classic approve() or Permit2.

Detecting EIP-2612 Support

There is no on-chain registry or ERC-165 interface for EIP-2612. The only reliable method is to probe the token contract for the required functions. If nonces() and DOMAIN_SEPARATOR() both return successfully, the token supports EIP-2612.
Tokens deployed with OpenZeppelin v4.9+ or v5.x also expose eip712Domain() (EIP-5267), which returns all domain fields in a single call. For older tokens, read name(), version(), and DOMAIN_SEPARATOR() separately and recompute the separator to validate it.
1

Get a quote and retrieve diamond calldata

Same as the standard flow: request a quote, then use the transactionRequest.data as your diamond calldata.
2

Read the token's permit nonce

EIP-2612 tokens track nonces per-owner. Read the current nonce from the token contract.
3

Sign the EIP-2612 Permit message

The spender is the Permit2Proxy address.
4

Encode and send via Permit2Proxy

SDK Usage

The @lifi/sdk handles Permit2 automatically during route execution. No manual signature construction is needed.
To disable Permit2 and force classic approve() transactions:

When Permit2 Is Not Used

The SDK skips Permit2 and falls back to classic approve() when:
  • The source chain does not have Permit2 deployed (chain.permit2 is not set)
  • The source chain does not have a Permit2Proxy (chain.permit2Proxy is not set)
  • The source token is the chain’s native token (ETH, MATIC, etc.)
  • Message signing is disabled (disableMessageSigning: true)
  • The transaction uses batched execution (EIP-5792)
  • The step’s estimate has skipApproval: true or skipPermit: true (rare, optional fields only present on certain chain-specific steps such as Hyperliquid)

Reference

Permit2Proxy Contract Functions

EIP-712 Type Definitions

PermitTransferFrom (Permit2 standard flow):
Permit (EIP-2612 native permit):

EIP-712 Domain

Permit2 (for PermitTransferFrom):
EIP-2612 (for native Permit — domain varies per token):