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
| Parameter | Type | Required | Description |
|---|
vaultName | string | Yes | Vault name from AmplifyVault.name |
depositAsset | Address | Yes | Token contract address |
depositAmount | string | Yes | Amount to deposit as decimal string (e.g., "100.25") |
to | Address | Yes | Recipient address for vault shares |
chainId | number | Yes | Blockchain network ID |
deadline | bigint | No | Permit deadline in seconds (default: 1 hour from now) |
nonce | bigint | No | Token permit nonce (fetched on-chain if omitted) |
decimals | number | No | Token decimals (fetched on-chain if omitted) |
tokenName | string | No | EIP-712 domain token name (fetched on-chain if omitted) |
tokenVersion | string | No | EIP-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,
});
import { useWallets } from "@privy-io/react-auth";
import {
getVaultsByConfig,
prepareDepositPermitSignature,
prepareDepositWithPermitTxData,
toEthSignTypedDataV4,
YieldType,
} from "@paxoslabs/amplify-sdk";
const { wallets } = useWallets();
const wallet = wallets[0];
const owner = wallet.address as `0x${string}`;
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as const;
const [vault] = await getVaultsByConfig({
yieldType: YieldType.CORE,
chainId: 1,
depositAssetAddress: USDC,
});
const permitData = await prepareDepositPermitSignature({
vaultName: vault.name,
depositAsset: USDC,
depositAmount: "1000",
to: owner,
chainId: 1,
});
// Use toEthSignTypedDataV4 to serialize for eth_signTypedData_v4
const provider = await wallet.getEthereumProvider();
const signature = await provider.request({
method: "eth_signTypedData_v4",
params: [owner, toEthSignTypedDataV4(permitData)],
}) as `0x${string}`;
const txData = await prepareDepositWithPermitTxData({
vaultName: vault.name,
depositAsset: USDC,
depositAmount: "1000",
to: owner,
chainId: 1,
signature,
deadline: permitData.message.deadline,
});
// If you already have token metadata, pass it to avoid extra RPC calls
const permitData = await prepareDepositPermitSignature({
vaultName: vault.name,
depositAsset: USDC,
depositAmount: "1000",
to: userAddress,
chainId: 1,
// Pre-fetched values skip on-chain reads
nonce: 5n,
decimals: 6,
tokenName: "USD Coin",
tokenVersion: "2",
});
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 Pattern | Description | Resolution |
|---|
"SDK not initialized" | SDK used before init | Call initAmplifySDK() first |
"Vault not found" | No vault matches vaultName | Verify vault name via getVaultsByConfig() |
"Token does not support permits" | Token not on permit allowlist | Use approval flow |