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

// First discover the vault
const [vault] = await getVaultsByConfig({
  yieldType: 'CORE',
  chainId: 1,
})

const txData = await prepareApproveWithdrawOrderTxData({
  vaultName: vault.name,
  wantAssetAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
  withdrawAmount: '100.0',
  chainId: 1,
})

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

Parameters

ParameterTypeRequiredDescription
vaultNamestringYesVault name from AmplifyVault.name (e.g. from getVaultsByConfig())
wantAssetAddressAddressYesToken address you want to receive
withdrawAmountstringNoAmount to approve (defaults to max uint256)
chainIdnumberYesChain 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 {
  getVaultsByConfig,
  prepareApproveWithdrawOrderTxData,
  YieldType,
} 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";

  const [vault] = await getVaultsByConfig({
    yieldType: YieldType.CORE,
    chainId: 1,
  });

  // Approve specific amount
  const txData = await prepareApproveWithdrawOrderTxData({
    vaultName: vault.name,
    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:
const [vault] = await getVaultsByConfig({ yieldType: 'CORE', chainId: 1 })

// Max approval - no amount specified
const txData = await prepareApproveWithdrawOrderTxData({
  vaultName: vault.name,
  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({
  vaultName: vault.name,
  wantAssetAddress: USDC_ADDRESS,
  withdrawAmount: '100.0',
  chainId: 1,
})

Checking Existing Approval

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

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

  const [vault] = await getVaultsByConfig({ yieldType: 'CORE', chainId: 1 })

  const approvalInfo = await isWithdrawalSpendApproved({
    vaultName: vault.name,
    wantAssetAddress: USDC,
    recipientAddress: userAddress,
    chainId: 1,
  })

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

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

Error Handling

ErrorDescriptionResolution
Vault not foundNo vault matches vaultNameVerify vault name via getVaultsByConfig()
Vault chain mismatchVault not on requested chainVerify chainId matches vault deployment
BoringVault contract address not configuredMissing vault configCheck vault configuration
WithdrawQueue contract address not configuredMissing queue configCheck vault configuration