prepareDepositAuthorization() to determine the method, then prepareDepositTxData() or prepareDepositWithPermitTxData() to execute.
DepositAuthMethod
Copy
Ask AI
export const DepositAuthMethod = {
PERMIT: "permit", // EIP-2612 off-chain signature (gas efficient)
APPROVAL: "approval", // Traditional ERC20 approval (two transactions)
ALREADY_APPROVED: "already_approved", // Existing allowance sufficient
} as const;
export type DepositAuthMethod =
(typeof DepositAuthMethod)[keyof typeof DepositAuthMethod];
prepareDepositAuthorization()
Determines the optimal authorization method for a deposit operation.Function Signature
Copy
Ask AI
export async function prepareDepositAuthorization(
params: PrepareDepositAuthorizationParams
): Promise<DepositAuthorizationResult>;
Parameters
Copy
Ask AI
export interface PrepareDepositAuthorizationParams {
/** Yield strategy type (e.g., YieldType.CORE) */
yieldType: YieldType;
/** Token contract address to deposit */
depositToken: Address;
/** Amount of assets to deposit as decimal string (e.g., "100.25") */
depositAmount: string;
/** User's wallet address (permit owner / approval sender) */
recipientAddress: Address;
/** Blockchain network ID */
chainId: ChainId;
/** Optional deadline for permit signature (defaults to 1 hour from now) */
deadline?: bigint;
/** Force specific authorization method (bypasses automatic detection) */
forceMethod?: "permit" | "approval";
}
Return Type (Discriminated Union)
Copy
Ask AI
export type DepositAuthorizationResult =
| PermitAuthorizationResult
| ApprovalAuthorizationResult
| AlreadyApprovedAuthorizationResult;
/** Returned when token supports EIP-2612 permit */
export interface PermitAuthorizationResult {
method: DepositAuthMethod.PERMIT;
/** EIP-712 typed data ready for wallet signing */
permitData: PermitSignatureData;
}
/** Returned when an ERC20 approval transaction is needed */
export interface ApprovalAuthorizationResult {
method: DepositAuthMethod.APPROVAL;
/** Transaction data for ERC20 approve() call */
txData: ApproveDepositTokenTxData;
/** Current allowance (human-readable) */
currentAllowance: string;
/** Current allowance as BigInt string */
currentAllowanceAsBigInt: string;
}
/** Returned when existing allowance is sufficient */
export interface AlreadyApprovedAuthorizationResult {
method: DepositAuthMethod.ALREADY_APPROVED;
/** Current allowance (human-readable) */
allowance: string;
/** Current allowance as BigInt string */
allowanceAsBigInt: string;
}
Decision Logic
The function follows this priority order:- Check
forceMethod- If specified, use that method - Check permit support - If token is in permit allowlist, return permit data
- Check existing allowance - If sufficient, return
ALREADY_APPROVED - Default to approval - Return approval transaction data
prepareDepositTxData()
Prepares transaction data for a standard deposit (after approval).Function Signature
Copy
Ask AI
export async function prepareDepositTxData(
params: PrepareDepositParams
): Promise<DepositTxData>;
Parameters
Copy
Ask AI
export interface PrepareDepositParams {
/** Yield strategy type (e.g., YieldType.PRIME) */
yieldType: YieldType;
/** Token contract address to deposit */
depositToken: Address;
/** Amount of assets to deposit as decimal string (e.g., "100.25") */
depositAmount: string;
/** Recipient address for vault shares */
recipientAddress: Address;
/** Blockchain network ID */
chainId: ChainId;
/** Optional slippage in basis points (default: 50 = 0.5%) */
slippage?: number;
/** Optional partner code for fee attribution */
partnerCode?: string;
}
Return Type
Copy
Ask AI
export interface DepositTxData {
abi: Abi;
address: Address;
functionName: string;
args: unknown[];
chainId: number;
}
prepareDepositWithPermitTxData()
Prepares transaction data for a permit-based deposit (single transaction).Function Signature
Copy
Ask AI
export async function prepareDepositWithPermitTxData(
params: PrepareDepositWithPermitParams
): Promise<PermitDepositTxData>;
Parameters
Copy
Ask AI
export interface PrepareDepositWithPermitParams {
/** Yield strategy type (e.g., YieldType.PRIME) */
yieldType: YieldType;
/** Token contract address to deposit */
depositToken: Address;
/** Amount of assets to deposit as decimal string (e.g., "100.25") */
depositAmount: string;
/** Recipient address for vault shares */
recipientAddress: Address;
/** Blockchain network ID */
chainId: ChainId;
/** Permit signature (hex string from wallet signing) */
signature: Hex;
/** Permit deadline (must match signature deadline) */
deadline: bigint;
/** Optional slippage in basis points (default: 50 = 0.5%) */
slippage?: number;
/** Optional partner code for fee attribution */
partnerCode?: string;
}
Return Type
Copy
Ask AI
export interface PermitDepositTxData {
address: Address;
chainId: number;
data: {
abi: Abi;
functionName: string;
args: unknown[];
};
}
Complete Flow Examples
React with Privy
Copy
Ask AI
import { encodeFunctionData } from "viem";
import { mainnet } from "viem/chains";
import {
initAmplifySDK,
prepareDepositAuthorization,
prepareDepositTxData,
prepareDepositWithPermitTxData,
DepositAuthMethod,
YieldType,
} from "@paxoslabs/amplify-sdk";
import { usePrivy, useWallets } from "@privy-io/react-auth";
// Initialize SDK (call once at app startup)
await initAmplifySDK("pxl_your_api_key");
const { sendTransaction } = usePrivy();
const { wallets } = useWallets();
const wallet = wallets[0];
if (!wallet) {
throw new Error("Connect a wallet before preparing transactions.");
}
const owner = wallet.address as `0x${string}`;
const params = {
yieldType: YieldType.PRIME,
depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as `0x${string}`, // USDC
depositAmount: "1000",
recipientAddress: owner,
chainId: mainnet.id,
};
// Step 1: Get authorization method
const auth = await prepareDepositAuthorization(params);
// Step 2: Handle based on method
switch (auth.method) {
case DepositAuthMethod.PERMIT: {
// Sign permit off-chain
const provider = await wallet.getEthereumProvider();
const signature = (await provider.request({
method: "eth_signTypedData_v4",
params: [
owner,
JSON.stringify({
domain: auth.permitData.domain,
types: auth.permitData.types,
primaryType: auth.permitData.primaryType,
message: auth.permitData.message,
}),
],
})) as `0x${string}`;
// Deposit with permit (single transaction)
const permitTx = await prepareDepositWithPermitTxData({
...params,
signature,
deadline: BigInt(auth.permitData.message.deadline),
});
const { abi: permitAbi, functionName: permitFn, args: permitArgs } = permitTx.data;
await sendTransaction({
chainId: permitTx.chainId,
to: permitTx.address,
data: encodeFunctionData({
abi: permitAbi,
functionName: permitFn,
args: permitArgs,
}),
});
break;
}
case DepositAuthMethod.APPROVAL: {
// Send approval transaction first
const { abi: approvalAbi, functionName: approvalFn, args: approvalArgs } = auth.txData;
await sendTransaction({
chainId: mainnet.id,
to: auth.txData.address,
data: encodeFunctionData({
abi: approvalAbi,
functionName: approvalFn,
args: approvalArgs,
}),
});
// Then deposit
const depositTx = await prepareDepositTxData(params);
const { abi: depositAbi, functionName: depositFn, args: depositArgs } = depositTx;
await sendTransaction({
chainId: depositTx.chainId,
to: depositTx.address,
data: encodeFunctionData({
abi: depositAbi,
functionName: depositFn,
args: depositArgs,
}),
});
break;
}
case DepositAuthMethod.ALREADY_APPROVED: {
// Deposit directly
const directTx = await prepareDepositTxData(params);
const { abi, functionName, args } = directTx;
await sendTransaction({
chainId: directTx.chainId,
to: directTx.address,
data: encodeFunctionData({ abi, functionName, args }),
});
break;
}
}
React with wagmi
Copy
Ask AI
import {
useAccount,
useWriteContract,
useSignTypedData,
} from "wagmi";
import { encodeFunctionData } from "viem";
import {
initAmplifySDK,
prepareDepositAuthorization,
prepareDepositTxData,
prepareDepositWithPermitTxData,
DepositAuthMethod,
YieldType,
} from "@paxoslabs/amplify-sdk";
// Initialize SDK
await initAmplifySDK("pxl_your_api_key");
const { address, chainId } = useAccount();
const { writeContractAsync } = useWriteContract();
const { signTypedDataAsync } = useSignTypedData();
if (!address || !chainId) {
throw new Error("Connect a wallet before preparing transactions.");
}
const params = {
yieldType: YieldType.PRIME,
depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as `0x${string}`,
depositAmount: "1000",
recipientAddress: address,
chainId,
};
const auth = await prepareDepositAuthorization(params);
switch (auth.method) {
case DepositAuthMethod.PERMIT: {
const signature = await signTypedDataAsync(auth.permitData);
const permitTx = await prepareDepositWithPermitTxData({
...params,
signature,
deadline: BigInt(auth.permitData.message.deadline),
});
await writeContractAsync({
address: permitTx.address,
abi: permitTx.data.abi,
functionName: permitTx.data.functionName,
args: permitTx.data.args,
account: address,
});
break;
}
case DepositAuthMethod.APPROVAL: {
await writeContractAsync({ ...auth.txData, account: address });
const depositTx = await prepareDepositTxData(params);
await writeContractAsync({ ...depositTx, account: address });
break;
}
case DepositAuthMethod.ALREADY_APPROVED: {
const directTx = await prepareDepositTxData(params);
await writeContractAsync({ ...directTx, account: address });
break;
}
}
React with viem
Copy
Ask AI
import { createWalletClient, custom } from "viem";
import { mainnet } from "viem/chains";
import {
initAmplifySDK,
prepareDepositAuthorization,
prepareDepositTxData,
prepareDepositWithPermitTxData,
DepositAuthMethod,
YieldType,
} from "@paxoslabs/amplify-sdk";
// Initialize SDK
await initAmplifySDK("pxl_your_api_key");
const [account] = (await ethereum.request({
method: "eth_requestAccounts",
})) as `0x${string}`[];
const client = createWalletClient({
account,
chain: mainnet,
transport: custom(ethereum),
});
const params = {
yieldType: YieldType.PRIME,
depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as `0x${string}`,
depositAmount: "1000",
recipientAddress: account,
chainId: mainnet.id,
};
const auth = await prepareDepositAuthorization(params);
switch (auth.method) {
case DepositAuthMethod.PERMIT: {
const signature = await client.signTypedData({
account,
...auth.permitData,
});
const permitTx = await prepareDepositWithPermitTxData({
...params,
signature,
deadline: BigInt(auth.permitData.message.deadline),
});
await client.writeContract({
address: permitTx.address,
abi: permitTx.data.abi,
functionName: permitTx.data.functionName,
args: permitTx.data.args,
account,
});
break;
}
case DepositAuthMethod.APPROVAL: {
await client.writeContract({ ...auth.txData, account });
const depositTx = await prepareDepositTxData(params);
await client.writeContract({ ...depositTx, account });
break;
}
case DepositAuthMethod.ALREADY_APPROVED: {
const directTx = await prepareDepositTxData(params);
await client.writeContract({ ...directTx, account });
break;
}
}
Force Specific Method
Override automatic detection when needed:Copy
Ask AI
// Force permit even if automatic detection would choose approval
const authForcePermit = await prepareDepositAuthorization({
...params,
forceMethod: "permit",
});
// Always returns DepositAuthMethod.PERMIT
// Force approval even for permit-supporting tokens
const authForceApproval = await prepareDepositAuthorization({
...params,
forceMethod: "approval",
});
// Returns APPROVAL or ALREADY_APPROVED
Slippage Configuration
The default slippage is 50 basis points (0.5%). Override when needed:Copy
Ask AI
const depositResult = await prepareDeposit({
...params,
slippage: 100, // 1% slippage
});
Error Handling
Both helpers throwAPIError with actionable metadata:
Copy
Ask AI
try {
const auth = await prepareDepositAuthorization(params);
} catch (error) {
if (error.code === "VAULT_NOT_FOUND") {
console.error("No vault matches parameters");
}
if (error.code === "PERMIT_NOT_SUPPORTED") {
// Fall back to approval flow
}
}
| Error Code | Description | Resolution |
|---|---|---|
SDK_NOT_INITIALIZED | SDK used before init | Call initAmplifySDK() first |
VAULT_NOT_FOUND | No vault matches params | Verify yieldType, token, chainId |
PERMIT_NOT_SUPPORTED | Token doesn’t support EIP-2612 | Use approval flow instead |
INSUFFICIENT_ALLOWANCE | Approval amount too low | Increase approval or use permit |