Skip to main content
The withdrawal authorization system uses discriminated unions to represent the two possible authorization methods. Type guards are provided for TypeScript narrowing.

Import

import {
  WithdrawAuthMethod,
  isWithdrawApprovalAuth,
  isWithdrawAlreadyApprovedAuth,
  type WithdrawAuthorizationResult,
  type WithdrawApprovalAuthorizationResult,
  type WithdrawAlreadyApprovedAuthorizationResult,
} from '@paxoslabs/amplify-sdk'

WithdrawAuthMethod Enum

export const WithdrawAuthMethod = {
  APPROVAL: 'approval',
  ALREADY_APPROVED: 'already_approved',
} as const

export type WithdrawAuthMethod =
  (typeof WithdrawAuthMethod)[keyof typeof WithdrawAuthMethod]
Unlike deposits, withdrawals do not support EIP-2612 permit signatures. Vault share approvals always require an on-chain transaction.

Result Types

WithdrawAuthorizationResult (Discriminated Union)

export type WithdrawAuthorizationResult =
  | WithdrawApprovalAuthorizationResult
  | WithdrawAlreadyApprovedAuthorizationResult

WithdrawApprovalAuthorizationResult

Returned when a vault share approval transaction is needed before submitting the withdrawal order.
interface WithdrawApprovalAuthorizationResult {
  method: 'approval'
  /** Transaction data for vault share approve() call */
  txData: {
    abi: readonly unknown[]
    address: `0x${string}`
    functionName: 'approve'
    args: [`0x${string}`, bigint]
  }
}

WithdrawAlreadyApprovedAuthorizationResult

Returned when the existing vault share allowance is sufficient.
interface WithdrawAlreadyApprovedAuthorizationResult {
  method: 'already_approved'
  /** Current allowance (human-readable) */
  allowance: string
  /** Current allowance as BigInt string */
  allowanceAsBigInt: string
}

Type Guards

Use type guards for TypeScript narrowing:
import {
  prepareWithdrawalAuthorization,
  isWithdrawApprovalAuth,
  isWithdrawAlreadyApprovedAuth,
} from '@paxoslabs/amplify-sdk'

const auth = await prepareWithdrawalAuthorization(params)

if (isWithdrawApprovalAuth(auth)) {
  // TypeScript knows: auth.method === "approval"
  // auth.txData is available with abi, address, functionName, args
  const approvalHash = await walletClient.writeContract(auth.txData)
  await publicClient.waitForTransactionReceipt({ hash: approvalHash })
}

if (isWithdrawAlreadyApprovedAuth(auth)) {
  // TypeScript knows: auth.method === "already_approved"
  // auth.allowance is available
  console.log(`Existing allowance: ${auth.allowance}`)
}

Using Switch Statements

const auth = await prepareWithdrawalAuthorization(params)

switch (auth.method) {
  case 'approval':
    // auth is narrowed to WithdrawApprovalAuthorizationResult
    await writeContract(auth.txData)
    break

  case 'already_approved':
    // auth is narrowed to WithdrawAlreadyApprovedAuthorizationResult
    console.log(`Allowance: ${auth.allowance}`)
    break
}

PrepareWithdrawalAuthorizationParams

interface PrepareWithdrawalAuthorizationParams {
  vaultName: string
  wantAsset: Address
  withdrawAmount: string
  userAddress: Address
  chainId: ChainId
  forceMethod?: 'approval' | 'allowance_check'
}
ParameterTypeRequiredDescription
vaultNamestringYesVault name from getVaultsByConfig()
wantAssetAddressYesToken the user wants to receive
withdrawAmountstringYesAmount as decimal string
userAddressAddressYesUser’s wallet address
chainIdChainIdYesBlockchain network ID
forceMethodstringNoForce "approval" or "allowance_check" (skip auto-detect)