Skip to main content
Builds the EIP-712 typed data needed to sign a permit for a deposit. Returns structured data ready to pass to signTypedData or eth_signTypedData_v4.
In most cases you should use prepareDepositAuthorization() which calls this function internally and returns the permit data as part of its result. Use prepareDepositPermitSignature directly when you need fine-grained control over the permit parameters, or need to pre-fetch token metadata to avoid extra RPC calls.

Import

import { prepareDepositPermitSignature } from "@paxoslabs/amplify-sdk";

Usage

const [vault] = await getVaultsByConfig({
  yieldType: YieldType.CORE,
  chainId: 1,
  depositAssetAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
});

const permitData = await prepareDepositPermitSignature({
  vaultName: vault.name,
  depositAsset: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  depositAmount: "1000",
  to: userAddress,
  chainId: 1,
});

// Sign with wallet
const signature = await walletClient.signTypedData({
  account: userAddress,
  ...permitData,
});

Parameters

ParameterTypeRequiredDescription
vaultNamestringYesVault name from AmplifyVault.name
depositAssetAddressYesToken contract address
depositAmountstringYesAmount to deposit as decimal string (e.g., "100.25")
toAddressYesRecipient address for vault shares
chainIdnumberYesBlockchain network ID
deadlinebigintNoPermit deadline in seconds (default: 1 hour from now)
noncebigintNoToken permit nonce (fetched on-chain if omitted)
decimalsnumberNoToken decimals (fetched on-chain if omitted)
tokenNamestringNoEIP-712 domain token name (fetched on-chain if omitted)
tokenVersionstringNoEIP-712 domain token version (fetched on-chain if omitted)
interface PrepareDepositPermitSignatureParams {
  /** Vault name (from AmplifyVault.name) */
  vaultName: string;
  /** Token contract address */
  depositAsset: Address;
  /** Amount to deposit as decimal string */
  depositAmount: string;
  /** Recipient address for vault shares */
  to: Address;
  /** Blockchain network ID */
  chainId: number;
  /** Permit deadline in seconds (default: now + 3600) */
  deadline?: bigint;
  /** Pre-fetched token nonce (skips on-chain call) */
  nonce?: bigint;
  /** Pre-fetched token decimals (skips on-chain call) */
  decimals?: number;
  /** Pre-fetched EIP-712 token name (skips on-chain call) */
  tokenName?: string;
  /** Pre-fetched EIP-712 token version (skips on-chain call) */
  tokenVersion?: string;
}
The optional nonce, decimals, tokenName, and tokenVersion parameters are performance optimizations. When provided, they skip the corresponding on-chain multicall reads, reducing latency in applications that already have this token metadata.

Return Type

interface PermitSignatureData {
  /** User's wallet address (permit signer) */
  account: Address;
  /** EIP-712 domain */
  domain: EIP712Domain;
  /** EIP-712 types */
  types: typeof PERMIT_TYPES;
  /** Permit message */
  message: {
    owner: Address;
    spender: Address;
    value: bigint;
    nonce: bigint;
    deadline: bigint;
  };
  /** Primary type */
  primaryType: "Permit";
}
The returned object is directly compatible with viem’s signTypedData, wagmi’s useSignTypedData, and eth_signTypedData_v4. The account field is the user address passed as the to parameter.

Examples

import { createWalletClient, custom } from "viem";
import { mainnet } from "viem/chains";
import {
  getVaultsByConfig,
  prepareDepositPermitSignature,
  prepareDepositWithPermitTxData,
  YieldType,
} from "@paxoslabs/amplify-sdk";

const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: custom(window.ethereum),
});

const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as const;

const [vault] = await getVaultsByConfig({
  yieldType: YieldType.CORE,
  chainId: mainnet.id,
  depositAssetAddress: USDC,
});

// Build permit data
const permitData = await prepareDepositPermitSignature({
  vaultName: vault.name,
  depositAsset: USDC,
  depositAmount: "1000",
  to: account,
  chainId: mainnet.id,
});

// Sign
const signature = await walletClient.signTypedData({
  account,
  ...permitData,
});

// Build deposit tx
const txData = await prepareDepositWithPermitTxData({
  vaultName: vault.name,
  depositAsset: USDC,
  depositAmount: "1000",
  to: account,
  chainId: mainnet.id,
  signature,
  deadline: permitData.message.deadline,
});

await walletClient.writeContract({
  address: txData.address,
  abi: txData.data.abi,
  functionName: txData.data.functionName,
  args: txData.data.args,
  account,
});

Helper: toEthSignTypedDataV4

import { toEthSignTypedDataV4 } from "@paxoslabs/amplify-sdk";
Converts PermitSignatureData to a JSON string format compatible with eth_signTypedData_v4 (adds the EIP712Domain type entry and serializes bigints as strings):
const jsonStr = toEthSignTypedDataV4(permitData);

const signature = await provider.request({
  method: "eth_signTypedData_v4",
  params: [address, jsonStr],
});

Helper: parsePermitSignature

import { parsePermitSignature } from "@paxoslabs/amplify-sdk";
Splits a hex permit signature into its v, r, s components:
const { v, r, s } = parsePermitSignature("0xabc...def");
Handles both legacy v-based and modern yParity-based signature formats.

Error Handling

Error Message PatternDescriptionResolution
"SDK not initialized"SDK used before initCall initAmplifySDK() first
"Vault not found"No vault matches vaultNameVerify vault name via getVaultsByConfig()
"Token does not support permits"Token not on permit allowlistUse approval flow