Prepares transaction data for a deposit using an EIP-2612 permit signature. This enables single-transaction deposits without a separate approval step.
Import
import { prepareDepositWithPermitTxData } from '@paxoslabs/amplify-sdk'
Usage
// First discover the vault
const [vault] = await getVaultsByConfig({
yieldType: YieldType.CORE,
chainId: 1,
depositAssetAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
})
const txData = await prepareDepositWithPermitTxData({
vaultName: vault.name,
depositAsset: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
depositAmount: '1000',
to: '0x...',
chainId: 1,
signature: '0x...', // From wallet signing
deadline: 1234567890n,
})
Parameters
| Parameter | Type | Required | Description |
|---|
vaultName | string | Yes | Vault name from AmplifyVault.name (e.g. from getVaultsByConfig()) |
depositAsset | Address | Yes | Token contract address to deposit |
depositAmount | string | Yes | Amount to deposit as decimal string (e.g., "100.50") |
to | Address | Yes | Recipient address for vault shares |
chainId | number | Yes | Blockchain network ID |
signature | Hex | Yes | Permit signature from wallet signing |
deadline | bigint | Yes | Permit deadline (must match signed deadline) |
slippage | number | No | Slippage tolerance in basis points (default: 50) |
distributorCode | string | No | Distributor code for fee attribution |
interface PrepareDepositWithPermitTxDataParams {
/** Vault name (from AmplifyVault.name) */
vaultName: string
/** Token contract address to deposit */
depositAsset: Address
/** Amount to deposit as decimal string */
depositAmount: string
/** Recipient address for vault shares */
to: Address
/** Blockchain network ID */
chainId: number
/** Permit signature (hex string from wallet signing) */
signature: Hex
/** Permit deadline (must match signature deadline) */
deadline: bigint
/** Slippage in basis points (default: 50 = 0.5%) */
slippage?: number
/** Distributor code for fee attribution */
distributorCode?: string
}
Return Type
Returns a discriminated union based on vault configuration, matching the same flat shape as prepareDepositTxData().
Type Definition
Example Response
type DepositWithPermitData =
| StandardDepositWithPermitData
| KytDepositWithPermitData;
interface StandardDepositWithPermitData {
depositType: "standard";
abi: Abi;
address: Address;
functionName: "depositWithPermit";
args: readonly [Address, bigint, bigint, Address, Hex, bigint, number, Hex, Hex];
chainId: number;
}
interface KytDepositWithPermitData {
depositType: "kyt";
abi: Abi;
address: Address;
functionName: "depositWithPermit";
args: readonly [Address, bigint, bigint, Address, Hex, Attestation, bigint, number, Hex, Hex];
chainId: number;
}
{
depositType: "standard",
abi: [...], // DistributorCodeDepositorV0 ABI
address: "0x1234...5678",
functionName: "depositWithPermit",
args: [
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // depositAsset
1000000000n, // depositAmount (in base units)
995000000n, // minimumMint (with slippage applied)
"0xUser...Addr", // to (recipient)
"0x", // distributorCode (hex-encoded)
1234567890n, // deadline
28, // v
"0xr...", // r
"0xs...", // s
],
chainId: 1,
}
As of v0.5.2, the return structure is flat — abi, functionName, and args are top-level properties, matching prepareDepositTxData(). You can spread the result directly into writeContract.
Examples
import { encodeFunctionData } from "viem";
import { usePrivy, useWallets } from "@privy-io/react-auth";
import {
getVaultsByConfig,
prepareDepositAuthorization,
prepareDepositWithPermitTxData,
isPermitAuth,
YieldType,
} from "@paxoslabs/amplify-sdk";
const { sendTransaction } = usePrivy();
const { wallets } = useWallets();
const wallet = wallets[0];
const owner = wallet.address as `0x${string}`;
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as const;
// Discover vault first
const [vault] = await getVaultsByConfig({
yieldType: YieldType.CORE,
chainId: 1,
depositAssetAddress: USDC,
});
const params = {
vaultName: vault.name,
depositAsset: USDC,
depositAmount: "1000",
to: owner,
chainId: 1,
};
// Step 1: Get permit data
const auth = await prepareDepositAuthorization(params);
if (isPermitAuth(auth)) {
// Step 2: Sign the permit
const provider = await wallet.getEthereumProvider();
const signature = await provider.request({
method: "eth_signTypedData_v4",
params: [owner, JSON.stringify(auth.permitData)],
}) as `0x${string}`;
// Step 3: Execute deposit with permit
const txData = await prepareDepositWithPermitTxData({
...params,
signature,
deadline: auth.permitData.message.deadline,
});
await sendTransaction({
chainId: txData.chainId,
to: txData.address,
data: encodeFunctionData({
abi: txData.abi,
functionName: txData.functionName,
args: txData.args,
}),
});
}
import { useAccount, useWriteContract, useSignTypedData } from "wagmi";
import {
getVaultsByConfig,
prepareDepositAuthorization,
prepareDepositWithPermitTxData,
isPermitAuth,
YieldType,
} from "@paxoslabs/amplify-sdk";
const { address, chainId } = useAccount();
const { writeContractAsync } = useWriteContract();
const { signTypedDataAsync } = useSignTypedData();
const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as const;
const [vault] = await getVaultsByConfig({
yieldType: YieldType.CORE,
chainId: chainId!,
depositAssetAddress: USDC,
});
const params = {
vaultName: vault.name,
depositAsset: USDC,
depositAmount: "1000",
to: address!,
chainId: chainId!,
};
const auth = await prepareDepositAuthorization(params);
if (isPermitAuth(auth)) {
const signature = await signTypedDataAsync(auth.permitData);
const txData = await prepareDepositWithPermitTxData({
...params,
signature,
deadline: auth.permitData.message.deadline,
});
await writeContractAsync({
address: txData.address,
abi: txData.abi,
functionName: txData.functionName,
args: txData.args,
account: address,
});
}
import { createWalletClient, custom } from "viem";
import { mainnet } from "viem/chains";
import {
getVaultsByConfig,
prepareDepositAuthorization,
prepareDepositWithPermitTxData,
isPermitAuth,
YieldType,
} from "@paxoslabs/amplify-sdk";
const client = 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,
});
const params = {
vaultName: vault.name,
depositAsset: USDC,
depositAmount: "1000",
to: account,
chainId: mainnet.id,
};
const auth = await prepareDepositAuthorization(params);
if (isPermitAuth(auth)) {
const signature = await client.signTypedData({
account,
...auth.permitData,
});
const txData = await prepareDepositWithPermitTxData({
...params,
signature,
deadline: auth.permitData.message.deadline,
});
await client.writeContract({
address: txData.address,
abi: txData.abi,
functionName: txData.functionName,
args: txData.args,
account,
});
}
Permit Support
Not all tokens support EIP-2612 permits. Use prepareDepositAuthorization() to check:
| Token | Supports Permit |
|---|
| USDC | Yes |
| USDG | Yes |
| pyUSD | Yes |
| USDT | No |
Smart contract wallets (like Privy Smart Wallets or Safe) cannot sign permits.
Use the approval flow with transaction batching instead.
Error Handling
| Error Message Pattern | Description | Resolution |
|---|
"SDK not initialized" | SDK not initialized | Call initAmplifySDK() first |
"Vault not found" | No vault matches vaultName | Verify vault name via getVaultsByConfig() |
"does not support EIP-2612 permit" | Token lacks permit support | Use approval flow instead |
"Invalid permit signature format" | Signature parsing failed | Re-sign with correct typed data |
"Invalid slippage value" | Slippage outside 0–10000 bps | Provide value between 0 and 10000 |