Skip to main content

client.withdraw.getCalldata(params)

Returns server-built withdrawal execution payloads. The server resolves the Safe and user context from the accountId, selects source chains, and returns an ordered payload set for the integrator to execute.
const result = await client.withdraw.getCalldata({
  accountId: account.accountId,
  destinationChainId: 8453,
  amount: "1000000000000000000",
  // isMaxWithdraw: true,
});

for (const payload of result.payloads) {
  for (const step of payload.steps) {
    switch (step.kind) {
      case "liquidityReset":
        // submit step.data as delegatecall to step.to
        break;
      case "approve":
      case "withdraw":
      case "approveReset":
        // submit step.data to step.to as a regular call
        break;
      case "bridge":
        // submit step.data to step.to with step.value as ETH value
        break;
    }
  }
}

WithdrawChainPayload

Each WithdrawChainPayload contains:
FieldTypeDescription
chainIdnumberSource chain for this payload
vaultAddressstringERC-4626 vault being exited
amountstringAmount allocated from this chain
timeEstimatenumberEstimated settlement time in seconds. 0 when same chain
feesQuoteFees | nullBridge fee breakdown. null when no bridge needed
stepsWithdrawStep[]Ordered steps: liquidityReset, approve, withdraw, approveReset, bridge
Each WithdrawStep is a discriminated union on kind:
KindSubmit asExtra fields
liquidityResetdelegatecall from the SafedelegateCall: true
approveregular call-
withdrawregular call-
approveResetregular call-
bridgeregular call with ETH valuevalue, chainId, timeEstimate, fees
Important behavior:
  • amount is an integer string in underlying token units
  • isMaxWithdraw: true redeems all shares across chains
  • a 409 response means a rebalance flow plan is already active
  • for max withdraws, bridge payloads may be omitted because the exact post-settlement amount is not known up front

Next steps

Last modified on March 20, 2026