Skip to content

Permit2 SDK

Helpers for interacting with Permit2 — the canonical token approval contract used across PancakeSwap. Supports both allowance transfers (approve once, spend many times) and signature transfers (single-use, off-chain signed permits).

Installation

npm install @pancakeswap/permit2-sdk

Quick start

import { AllowanceTransfer, SignatureTransfer, PERMIT2_ADDRESS } from '@pancakeswap/permit2-sdk'
import { ChainId } from '@pancakeswap/chains'
 
// --- Allowance transfer flow ---
const permitSingle = {
  details: {
    token: '0xTOKEN_ADDRESS',
    amount: BigInt(1e18),
    expiration: Math.floor(Date.now() / 1000) + 60 * 60 * 24, // 24h
    nonce: 0,
  },
  spender: '0xROUTER_ADDRESS',
  sigDeadline: Math.floor(Date.now() / 1000) + 60 * 30,
}
 
const { domain, types, values } = AllowanceTransfer.getPermitData(
  permitSingle,
  PERMIT2_ADDRESS,
  ChainId.BSC,
)
 
const signature = await walletClient.signTypedData({ domain, types, primaryType: 'PermitSingle', message: values })
 
// --- Signature transfer flow ---
const { domain: sDomain, types: sTypes, values: sValues } = SignatureTransfer.getPermitData(
  {
    permitted: { token: '0xTOKEN', amount: BigInt(1e18) },
    spender: '0xROUTER',
    nonce: 1n,
    deadline: BigInt(Math.floor(Date.now() / 1000) + 1800),
  },
  PERMIT2_ADDRESS,
  ChainId.BSC,
)

AllowanceTransfer

Helpers for the approve-once-spend-many allowance model.

MethodSignatureDescription
getPermitData(permit, permit2Address, chainId) → { domain, types, values }Build EIP-712 typed data for a PermitSingle or PermitBatch
hash(permit, permit2Address, chainId) → stringCompute the EIP-712 hash of a permit
encodePermit(permit, signature) → stringABI-encode a permit + signature for on-chain submission
encodeApprove(token, newAmount, newExpiration?) → stringEncode a direct on-chain approval call
encodeLockdown(approvals: TokenSpenderPair[]) → stringEncode a lockdown (revoke) call for one or more (token, spender) pairs
encodeInvalidateNonces(token, spender, newNonce) → stringEncode a nonce invalidation call

PermitSingle structure

interface PermitSingle {
  details: {
    token: string      // ERC-20 token address
    amount: bigint     // max uint160 for unlimited
    expiration: number // unix timestamp; max uint48 for non-expiring
    nonce: number      // current nonce from the contract
  }
  spender: string      // address allowed to spend
  sigDeadline: number  // signature validity deadline (unix timestamp)
}

PermitBatch structure

interface PermitBatch {
  details: PermitDetails[]  // array of token/amount/expiration/nonce
  spender: string
  sigDeadline: number
}

SignatureTransfer

Helpers for single-use, off-chain signed transfers.

MethodSignatureDescription
getPermitData(permit, permit2Address, chainId) → { domain, types, values }Build EIP-712 typed data for a PermitTransferFrom or PermitBatchTransferFrom
hash(permit, permit2Address, chainId) → stringCompute the EIP-712 hash
encodePermitTransferFrom(permit, transferDetails, owner, signature) → stringEncode a single-token transfer call
encodePermitBatchTransferFrom(permit, transferDetails, owner, signature) → stringEncode a multi-token transfer call

PermitTransferFrom structure

interface PermitTransferFrom {
  permitted: {
    token: string    // token address
    amount: bigint   // max amount the spender may transfer
  }
  spender: string    // who may execute the transfer
  nonce: bigint      // unique value (not incremental; any unused bigint)
  deadline: bigint   // unix timestamp; signature expires after this
}

Constants

ExportTypeDescription
PERMIT2_ADDRESSstringCanonical Permit2 contract address (same across all chains)
MaxAllowanceExpirationnumberMax uint48 — use for non-expiring allowances
MaxAllowanceTransferAmountbigintMax uint160 — use for unlimited allowances
MaxSignatureTransferAmountbigintMax uint256 — use for unlimited signature transfers
InstantExpirationnumber0 — use to revoke an allowance immediately

Permit2 contract

See Permit2 addresses for deployed addresses across chains.