Skip to main content
Prepare transaction data to approve vault shares for withdrawal via the WithdrawQueue contract.
Before withdrawing, you must approve the WithdrawQueue contract to spend your vault shares. Consider using prepareWithdrawalAuthorization for a higher-level API that handles approval checking automatically.

Import

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

Usage

const txData = await prepareApproveWithdrawOrderTxData({
  yieldType: "CORE",
  wantAssetAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
  withdrawAmount: "100.0",
  chainId: 1,
});

// Execute approval
const hash = await walletClient.writeContract(txData);

Parameters

ParameterTypeRequiredDescription
yieldTypeYieldTypeYesYield strategy (CORE, TREASURY, FRONTIER)
wantAssetAddressAddressYesToken address you want to receive
withdrawAmountstringNoAmount to approve (defaults to max uint256)
chainIdChainIdYesChain ID
shareDecimalsnumberNoPre-fetched vault share decimals (avoids redundant RPC call)

Return Type

interface ApproveWithdrawOrderTxData {
  abi: typeof BoringVaultAbi;
  address: `0x${string}`;         // Vault shares (BoringVault) address
  functionName: "approve";
  args: [spender: `0x${string}`, amount: bigint];
}

Examples

import { prepareApproveWithdrawOrderTxData } from "@paxoslabs/amplify-sdk";
import { createWalletClient, createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";

async function approveWithdraw(userAddress: `0x${string}`) {
  const walletClient = createWalletClient({
    account: userAddress,
    chain: mainnet,
    transport: http(),
  });
  const publicClient = createPublicClient({
    chain: mainnet,
    transport: http(),
  });

  const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

  // Approve specific amount
  const txData = await prepareApproveWithdrawOrderTxData({
    yieldType: "CORE",
    wantAssetAddress: USDC,
    withdrawAmount: "100.0",
    chainId: 1,
  });

  const hash = await walletClient.writeContract(txData);
  const receipt = await publicClient.waitForTransactionReceipt({ hash });

  console.log("Approval confirmed:", receipt.transactionHash);
  return hash;
}

Max vs Specific Approval

Max Approval (Default)

When withdrawAmount is not provided, the SDK approves the maximum amount. This is a one-time approval that covers all future withdrawals:
// Max approval - no amount specified
const txData = await prepareApproveWithdrawOrderTxData({
  yieldType: "CORE",
  wantAssetAddress: USDC_ADDRESS,
  chainId: 1,
});

Specific Amount Approval

For tighter security, approve only the amount you intend to withdraw:
// Approve exactly 100 shares
const txData = await prepareApproveWithdrawOrderTxData({
  yieldType: "CORE",
  wantAssetAddress: USDC_ADDRESS,
  withdrawAmount: "100.0",
  chainId: 1,
});

Checking Existing Approval

Before approving, check if approval is already granted:
import {
  isWithdrawalSpendApproved,
  prepareApproveWithdrawOrderTxData,
} from "@paxoslabs/amplify-sdk";

async function ensureApproval(userAddress: `0x${string}`) {
  const USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";

  const approvalInfo = await isWithdrawalSpendApproved({
    yieldType: "CORE",
    wantAssetAddress: USDC,
    recipientAddress: userAddress,
    chainId: 1,
  });

  if (approvalInfo.isApproved) {
    console.log(`Already approved. Allowance: ${approvalInfo.allowance}`);
    return null;
  }

  // Need to approve first
  return prepareApproveWithdrawOrderTxData({
    yieldType: "CORE",
    wantAssetAddress: USDC,
    chainId: 1,
  });
}
Consider using prepareWithdrawalAuthorization instead, which combines the approval check and approval preparation into a single call.

Error Handling

ErrorDescriptionResolution
Vault chain mismatchVault not on requested chainVerify chainId matches vault deployment
BoringVault contract address not configuredMissing vault configCheck vault exists for yieldType/chain
WithdrawQueue contract address not configuredMissing queue configCheck vault configuration
import { prepareApproveWithdrawOrderTxData, APIError } from "@paxoslabs/amplify-sdk";

try {
  const txData = await prepareApproveWithdrawOrderTxData({
    yieldType: "CORE",
    wantAssetAddress: USDC_ADDRESS,
    chainId: 1,
  });
} catch (error) {
  if (error instanceof APIError) {
    console.error("SDK Error:", error.message);
  }
}