LST / LRT mint · withdraw-request · claim · cancel
GET/v1/actions/vaults/lst
Build calldata for LST / LRT (and Lagoon) actions — mint, withdraw-request, claim, and cancel — via the unified LST dispatchers. The protocol is resolved from the calldata-sdk registry by (chainId, shareToken), or forced with kind= (required for Lagoon — kind=lagoon&mode=sync|async — and any unregistered vault).
Deposits also work through the unified /v1/actions/vaults/deposit — pass the LST share token as
vaultand it routes here automatically (no need to know it's an LST). This endpoint stays as the explicit LST route and is the home for the exit-side actions (request-withdraw/claim/cancel), which the generic deposit endpoint does not cover.
How an integrator knows what to pay with (acceptedInputs)
LSTs are not uniform ERC-4626 vaults — each protocol accepts a different set of pay assets (native ETH, an unwrapped sibling like stETH/eETH, or specific ERC-20s) and some paths require extra slippage/intermediate options. Rather than hard-coding this, fetch the vault data first and let it drive the request:
GET /v1/data/vaults?chainId=…&providers=lst→ each LST carries aproviderMetablock:isMintable—false⇒ no on-chain mint (e.g. cbETH); don't call this endpoint.mintContract— the deposit target.exchangeRate/convertToShares— to compute expected output and aminOut.acceptedInputs[]— the machine-readable accept-set (see below).
- Pick the
acceptedInputsentry whoseassetmatches what the user holds. - Call this endpoint with
action=deposit,payAsset=<that asset>, and the entry'sneeds[]supplied as query params.
acceptedInputs[] entry shape
| field | meaning |
|---|---|
asset | "native" (pay with the chain coin → pass payAsset=0x000…000) or a lowercased ERC-20 address to pass as payAsset. |
symbol | optional UI hint (e.g. stETH). |
mode | direct (single call) · wrap (approve + wrap a base LST the user already holds) · submit-wrap (native → base → wrapped; needs the realised base amount). |
needs | option keys the caller must pass for this path (e.g. ["minMETHAmount"], ["eEthAmount"], ["stEthAmount"]). Absent ⇒ none. |
Example — wstETH advertises three paths:
"acceptedInputs": [
{ "asset": "native", "mode": "direct" },
{ "asset": "0xae7ab9…", "symbol": "stETH", "mode": "wrap" },
{ "asset": "native", "mode": "submit-wrap", "needs": ["stEthAmount"] }
]
- Pay with ETH →
payAsset=0x000…000(one-stepreceive()). - Pay with stETH you already hold →
payAsset=0xae7ab9…(approve + wrap).
Multi-step results
wrap / submit-wrap paths produce multiple ordered transactions. The response's actions.transactions[] is the sequence to execute in order, and actions.permissions[] carries any ERC-20 approvals to run first. Single-step mints return one transaction and (for native) no permissions. Always iterate transactions[]; never assume a single tx.
Slippage / required options
Paths whose needs includes a min-out (minMETHAmount, minRSETHAmountExpected, …) require the caller to compute the floor from the data's exchangeRate and pass it. Native one-step mints (stETH, ETHx, ezETH, ynETH, pufETH, wstETH-receive) need nothing beyond amount.
Actions
deposit— mint.amountrequired;payAsset(default native); path options peracceptedInputs[].needs.request-withdraw— start an exit (queue/cooldown).amountrequired;inputAsset?,outputAsset?,owner?.claim— settle a matured exit. Identifier params:requestIds/hints/amounts(CSV),tokenId,id,shares,assets,controller,user,recipient.cancel— cancel a pending request (same identifier params).
Plain-text reference — GET /v1/actions/vaults/lst
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
chainId | query | string | yes | Chain ID See the ChainId schema for the full set of supported chains. |
action | query | deposit, request-withdraw, claim, cancel | no | Operation to build. |
shareToken | query | string | yes | LST share-token address (the token the user wants to mint / exit). |
operator | query | string | yes | User wallet executing the action (payer). receiver defaults to it. |
receiver | query | string | no | Recipient of the minted shares / claimed assets. Defaults to operator. |
amount | query | string | no | Required for deposit and request-withdraw. Wei, in the payAsset decimals. |
payAsset | query | string | no | deposit: what the user pays. Zero address (or 0xEEEE…) = native; otherwise an ERC-20 from the LST's acceptedInputs[].asset. Defaults to native. |
kind | query | string | no | Protocol override — required for Lagoon (lagoon) and any vault not in the static registry. Otherwise resolved from (chainId, shareToken). |
mode | query | sync, async | no | Lagoon deposit mode. |
minOut | query | integer | no | Generic slippage floor (wei) where the protocol path accepts one. For protocol-specific names see the LST acceptedInputs[].needs. |
referral | query | string | no | Optional referral address (protocols that support it). |
stEthAmount | query | integer | no | wstETH submit-wrap path: the realised stETH amount (read stETH.balanceOf after the submit leg). |
eEthAmount | query | integer | no | weETH submit-wrap path: the realised eETH amount (read after the deposit leg). |
vault | query | string | no | StakeWise per-vault target (and other per-vault protocols). |
poolId | query | string | no | Solv pool selector. |
validatorGroup | query | string | no | StakedCelo (stCELO) deposit: validator group to vote for — a changeStrategy(group) step is prepended (account-wide). Auto-selected when omitted and the caller is on the (reverting) default strategy; zero address forces the default. |
rewardVault | query | string | no | BeraPaw reward-vault target. |
stakingToken | query | string | no | Bearn staking-token target. |
inputAsset | query | string | no | request-withdraw: asset being burned, when the protocol needs it disambiguated. |
outputAsset | query | string | no | request-withdraw / claim: desired exit asset, when the protocol supports a choice. |
owner | query | string | no | request-withdraw: position owner, when not operator. |
requestIds | query | string | no | claim/cancel: CSV of withdrawal-request ids. |
hints | query | string | no | claim/cancel: CSV of finalization hints (Lido). |
amounts | query | string | no | claim/cancel: CSV of per-request amounts. |
tokenId | query | integer | no | claim/cancel: NFT request id. |
id | query | integer | no | claim/cancel: numeric request id. |
shares | query | integer | no | claim: share amount (7540/4626 savings). |
assets | query | integer | no | claim: asset amount. |
controller | query | string | no | claim: 7540 controller, when not receiver. |
user | query | string | no | claim/cancel: position user, when not operator. |
recipient | query | string | no | claim: payout recipient, when supported. |
Response 200
| Field | Type | Description |
|---|---|---|
success | True | |
data | object | Informational data (quotes, simulation results, etc.) |
actions | object | Transaction calldata and approvals. Null for quote-only responses (no account provided). |
actions.transactions | object[] | Pre-trade setup transactions (e.g. e-mode switch, collateral enable). Execute these before the main swap. Empty when no setup is needed. |
actions.transactions[].to | string | Target contract address |
actions.transactions[].data | string | Encoded calldata |
actions.transactions[].value | string | ETH value to send with the transaction |
actions.transactions[].description | string | Human-readable label. For alternatives, this is the aggregator name (e.g. "Paraswap"). For transactions, describes the setup action (e.g. "Switch e-mode to 1"). |
actions.alternatives | object[] | DEX aggregator swap transactions sorted by best output (descending). Each entry's description is the aggregator name. The client should pick one to execute. Present on loop action endpoints. |
actions.alternatives[].to | string | Target contract address |
actions.alternatives[].data | string | Encoded calldata |
actions.alternatives[].value | string | ETH value to send with the transaction |
actions.alternatives[].description | string | Human-readable label. For alternatives, this is the aggregator name (e.g. "Paraswap"). For transactions, describes the setup action (e.g. "Switch e-mode to 1"). |
actions.permissions | object[] | Approval/delegation transactions that must execute before both transactions and alternatives. Includes ERC20 allowances (targeting the composer contract) and lender borrow/withdrawal delegations (targeting the lending protocol contract directly). Filtered against on-chain state so only missing approvals are returned. Null when no approvals are needed. |
actions.permissions[].to | string | Target contract address |
actions.permissions[].data | string | Encoded calldata |
actions.permissions[].value | string | ETH value |
actions.permissions[].description | string | Human-readable description of the approval (e.g. "Approve borrow for AAVE_V3", "Approve ERC20") |
actions.permissions[].spender | string | ERC-20 approve spender (x-chain permissions). Match it against the selected quote's approvalTarget — several bridges can share one spender, so do not match by description. |
Example response
{
"success": true,
"data": {},
"actions": {
"transactions": [
{
"to": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string"
}
],
"alternatives": [
{
"to": "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string"
}
],
"permissions": [
{
"to": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"data": "0x617ba037000000000000000000000000c02aaa39b2",
"value": "0",
"description": "string",
"spender": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
}
]
}
}
Request
Responses
- 200
- 400
- 429
- 500
- 502
Ordered transactions[] (execute in sequence) + ERC-20 permissions[] (execute first). Single-step mints return one transaction.
Validation error
Rate limited. Unauthenticated callers share a per-IP budget; send an x-api-key header to lift it. Retry with exponential backoff.
Unexpected server error. Safe to retry with backoff.
An upstream data source or protocol origin failed (error.code is ORIGIN_FAILED). error.details carries the per-origin status. This is also what a missing or malformed required parameter currently returns, rather than a 400.