Skip to main content
Withdrawals redeem vault share tokens for the underlying wantAsset through the WithdrawQueue contract. Unlike deposits, there is no inline-permit path in 1.0.0: the share token must have an ERC-20 approve(WithdrawQueue, amount) allowance before submitOrder can pull the shares. Throughout this guide, client refers to a singleton AmplifyClient created on the server — see Project setup for the wiring. All amounts are base-units decimal strings.
Withdrawals have no permit path. For the share token, authorization.detect always returns method: 'approval' or 'already_approved' — never 'permit'. Approve the WithdrawQueue before calling submitOrder.
1

Check the share-token allowance

Call authorization.detect with tokenAddress set to the vault address (the share token is the vault contract). The response tells you whether you need to send an approve transaction or whether sufficient allowance already exists.
Two possible response shapes:
  • auth.method === 'already_approved' — skip to Step 3.
  • auth.method === 'approval' — submit auth.approvalTransaction.encoded to the share-token address (the vault address). The spender baked into the calldata is the WithdrawQueue address.
2

Approve the WithdrawQueue (if needed)

For the approval branch, just forward the returned transaction:
The spender in the approve call is always the WithdrawQueue address, never the vault address. Using the vault address as spender will cause submitOrder to panic with 0x11 when it tries to transferFrom the shares.
3

(Optional) Estimate the fee

client.amplify.withdraw.calculateFee returns the fee the user will pay for a given offer amount. Use it both to render a preview in your UI and to short-circuit submissions that would revert on-chain.
4

Prepare the withdrawal

Required fields:
  • vaultAddress — BoringVault contract address.
  • wantAsset — ERC-20 the user wants to receive on settlement.
  • shareAmount — vault shares to redeem (base-units decimal string).
  • userAddress — wallet submitting the order. Also the default intendedDepositor, receiver, and refundReceiver.
  • chainId — EVM chain ID.
Optional fields:
  • intendedDepositor — on-chain SubmitOrderParams.intendedDepositor. Defaults to userAddress.
  • receiver — address that receives wantAsset on settlement. Defaults to userAddress.
  • refundReceiver — address that receives refunded shares if the order is cancelled. Defaults to userAddress.
  • responseFormat'encoded' (default), 'full', or 'structured'.
5

Submit the transaction

End-to-end example

Listing a user’s withdrawals

client.amplify.withdraw.listRequests supports cursor pagination and an AIP-160-style filter string. Available filter keys: status (PENDING, COMPLETE, PENDING_REFUND, REFUNDED), chainId, wantAssetAddress, vaultAddress, userAddress, receiverAddress, refundReceiverAddress, orderIndex, isSubmittedViaSignature, isForceProcessed, isMarkedForRefund, isMarkedForRefundByUser, didOrderFailTransfer.

Cancelling a pending order

orderIndex comes from a row returned by listRequests. Cancel returns calldata for the WithdrawQueue.cancel (or equivalent) call; submit it the same way as the deposit/withdrawal flows above.

Converting share amounts

Error handling

When surfacing errors to the browser, log err.body and err.rawResponse server-side and return a generic message to the client.

Next steps