Skip to main content
When the deposit token supports permit, you can replace the approval + deposit sequence with a signature and a single depositWithPermit call.

Helper Sequence

const permit = await prepareDepositPermitSignature({
  yieldType, // e.g. YieldType.CORE
  depositToken, // token that supports permit()
  depositAmount, // decimal string
  recipientAddress, // owner field
  chainId,
  deadline, // optional bigint (seconds)
});

const tx = await prepareDepositWithPermitTxData({
  yieldType,
  recipientAddress, // same as permit.message.owner
  depositToken,
  depositAmount,
  chainId,
  signature, // raw 0x signature from the wallet
  deadline, // must match the signed permit
  slippage, // optional bps, defaults to 100
});
  • prepareDepositPermitSignature returns { domain, types, message, primaryType } for typed-data signing.
  • prepareDepositWithPermitTxData returns { abi, address, functionName: 'depositWithPermit', args, chainId }.
  • Supply the raw hex signature; the helper parses (v, r, s) internally.

React with Privy

import { encodeFunctionData } from "viem";
import { mainnet } from "viem/chains";
import {
  prepareDepositPermitSignature,
  prepareDepositWithPermitTxData,
  YieldType,
} from "@paxoslabs/amplify-sdk";
import { usePrivy, useWallets } from "@privy-io/react-auth";

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 depositToken = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC
const chainId = mainnet.id;

const permit = await prepareDepositPermitSignature({
  yieldType: YieldType.CORE,
  depositToken,
  depositAmount: "1000",
  recipientAddress: owner,
  chainId,
});

const provider = await wallet.getEthereumProvider();
const signature = (await provider.request({
  method: "eth_signTypedData_v4",
  params: [
    owner,
    JSON.stringify({
      domain: permit.domain,
      types: permit.types,
      primaryType: permit.primaryType,
      message: permit.message,
    }),
  ],
})) as `0x${string}`;

const tx = await prepareDepositWithPermitTxData({
  yieldType: YieldType.CORE,
  recipientAddress: owner,
  depositToken,
  depositAmount: "1000",
  chainId,
  signature,
  deadline: permit.message.deadline,
  slippage: 75,
});

await sendTransaction({
  chainId: tx.chainId,
  to: tx.address,
  data: encodeFunctionData({
    abi: tx.abi,
    functionName: tx.functionName,
    args: tx.args,
  }),
});

React with wagmi

import { encodeFunctionData } from "viem";
import {
  prepareDepositPermitSignature,
  prepareDepositWithPermitTxData,
  YieldType,
} from "@paxoslabs/amplify-sdk";
import { useAccount, useSendTransaction, useSignTypedData } from "wagmi";

const { address, chainId } = useAccount();
const { signTypedDataAsync } = useSignTypedData();
const { sendTransactionAsync } = useSendTransaction();
if (!address || !chainId) {
  throw new Error("Connect a wallet before preparing transactions.");
}

const permit = await prepareDepositPermitSignature({
  yieldType: YieldType.CORE,
  depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
  depositAmount: "1000",
  recipientAddress: address,
  chainId,
});

const signature = await signTypedDataAsync({
  account: permit.message.owner,
  domain: permit.domain,
  types: permit.types,
  primaryType: permit.primaryType,
  message: permit.message,
});

const tx = await prepareDepositWithPermitTxData({
  yieldType: YieldType.CORE,
  recipientAddress: address,
  depositToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
  depositAmount: "1000",
  chainId,
  signature,
  deadline: permit.message.deadline,
  slippage: 75,
});

await sendTransactionAsync({
  to: tx.address,
  data: encodeFunctionData({
    abi: tx.abi,
    functionName: tx.functionName,
    args: tx.args,
  }),
  chainId: tx.chainId,
});

React with viem

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

// ethereum is window.ethereum from an injected wallet.
const [account] = (await ethereum.request({
  method: "eth_requestAccounts",
})) as `0x${string}`[];

const depositToken = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"; // USDC

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

const permit = await prepareDepositPermitSignature({
  yieldType: YieldType.CORE,
  depositToken,
  depositAmount: "1000",
  recipientAddress: account,
  chainId: mainnet.id,
});

const signature = await client.signTypedData({
  account,
  domain: permit.domain,
  types: permit.types,
  primaryType: permit.primaryType,
  message: permit.message,
});

const tx = await prepareDepositWithPermitTxData({
  yieldType: YieldType.CORE,
  recipientAddress: account,
  depositToken,
  depositAmount: "1000",
  chainId: mainnet.id,
  signature,
  deadline: permit.message.deadline,
  slippage: 75,
});

await client.sendTransaction({
  account,
  to: tx.address,
  data: encodeFunctionData({
    abi: tx.abi,
    functionName: tx.functionName,
    args: tx.args,
  }),
});
Both helpers throw APIError with an endpoint field when the vault, token, or chain is unsupported—surface that metadata so users can fall back to the Approve & Deposit flow.***