@vetro-protocol/cli
v1.1.0
Published
CLI to read and operate on Vetro.
Downloads
535
Readme
@vetro-protocol/cli
vetro-cli — a command-line interface that sits on top of the @vetro-protocol/* packages so agents and users can read Vetro state and generate transaction calldata.
Local development
Run it straight from the source, with no build step:
node packages/cli/src/cli.ts swap pegged-token --gateway 0x...To run the bundled bin instead:
pnpm --filter @vetro-protocol/cli bundle # produces _esm/cli.js (the vetro-cli bin)
node packages/cli/_esm/cli.js swap pegged-token --gateway 0x...The @vetro-protocol/* packages are external to that bundle, and inside the monorepo they resolve to workspace source, so this exercises the bundled entrypoint rather than what an npm consumer gets. To check that, pack the tarball and install it in a scratch project.
Configuration
--rpc-url <url> is a global option, accepted anywhere on the command line — before or after the subcommand:
vetro-cli --rpc-url https://my-node.example swap treasury --gateway 0x...
vetro-cli swap treasury --gateway 0x... --rpc-url https://my-node.exampleIt sets the endpoint every read goes to, and therefore the chain the emitted calldata is stamped with. It also accepts the endpoint via env var, so the resolution order is:
--rpc-urlRPC_URLhttps://eth.drpc.org, a public Ethereum mainnet RPC
Only http/https endpoints are accepted; anything else is rejected as a usage error before any request is made.
Supported chains
Vetro is deployed on Ethereum mainnet only, so every command that reads the chain starts by reading the endpoint's eth_chainId and fails if it is anything other than:
| Chain ID | Endpoint |
| -------- | ---------------------------------- |
| 1 | Ethereum mainnet |
| 31337 | local fork (anvil/Hardhat default) |
The check runs before any contract read, so pointing at another network fails fast rather than returning state read off the wrong chain. This restriction is temporary and lifts once Vetro is deployed on more chains.
Output
Successful output is JSON on stdout, so it's directly consumable by an agent.
- Addresses and other strings are emitted as JSON strings; booleans as JSON booleans.
uint256on-chain values are serialized as decimal strings, sincebigintcan't be represented in JSON.- Amounts are in human units on input and in the token's decimals on output.
Failures always exit non-zero, but come in two shapes:
- Runtime errors (RPC failure, contract revert) are JSON on stderr:
{ "error": "..." }. - Usage errors (invalid or missing flags, unknown commands) are written by the CLI parser as plain text on stderr.
Write operations
Write commands touch no keys — they emit a JSON-RPC transaction request and the consumer signs and broadcasts it:
{ "chainId": "0x1", "data": "0x8b6099db…", "to": "0x…gateway", "value": "0x0" }Every numeric field is a hex QUANTITY, so the object can be lifted straight into eth_sendTransaction or an ERC-5792 wallet_sendCalls batch. value is always "0x0".
Token arguments
--token, --from and --to accept either a symbol (case-insensitive, e.g. USDT) or an address. --from is the token the operation spends, so it is whitelisted-only on mint and pegged-only on send-to-queue. --to is the token the operation pays out, so it is pegged on mint and whitelisted-only on preview-redeem and redeem. --token takes either side on swap. On variable-yield it takes the pegged token, or its share token where the command allows it.
Because a token belongs to exactly one gateway, the gateway is inferred from the token and never passed explicitly. For the same reason swap mint --to is optional — the pegged token is whatever that gateway mints.
--amount is in human units of the token the operation spends. Its decimals come from --from or --token when the command takes one. On preview-redeem and redeem the spent token is the pegged token of the gateway inferred from --to, so the decimals come from that pegged token, not from --to. On variable-yield unstake the spent token is the pegged token for --amount and the share token for --shares, whichever of the two --token names. variable-yield instant-withdraw uses the same rule. An amount with more decimals than that token has fails instead of being rounded.
To discover the symbols a gateway takes, run swap whitelisted-tokens --gateway <addr> — a gateway-level read, so it takes the gateway explicitly instead of inferring it from a token.
Commands
This is the list of commands available
gateways — the enabled gateways
| Command | Reads | Returns |
| -------------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| vetro-cli gateways | — | Every enabled gateway. Each entry carries address, peggedToken (the pegged token the gateway mints) and stakingVault (the vault that stakes that pegged token, or null when the gateway has none). address is the --gateway of the gateway-level swap reads. The list is static and covers Ethereum mainnet only. The command makes no RPC call, so it ignores --rpc-url |
swap — whitelisted ↔ pegged token
Write operations
| Command | Encodes | Notes |
| ----------------------------------------------------------------------------------------------------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| vetro-cli swap approve --token <tok> --amount <n> | encodeApproveData | Approves the inferred gateway to spend the token — a whitelisted token to mint, or a pegged token to send-to-queue or to redeem in one step. Prepend it when the allowance is short. --amount 0 resets the allowance. |
| vetro-cli swap cancel-redeem --account <addr> --gateway <addr> | encodeCancelRedeemRequest | Cancels the open redeem request of <addr>. The gateway sends the whole locked amount of the pegged token back to <addr>. Fails when <addr> has no open request. |
| vetro-cli swap mint --from <tok> [--to <tok>] --amount <n> --receiver <addr> [--slippage <percent>] | encodeDeposit | Swap-in. --slippage is a percent off previewDeposit, in [0, 100] with at most one decimal (e.g. 0.5); it defaults to 0, so minPeggedTokenOut is the full previewed amount unless a tolerance is given. Fails when the previewed output is above maxMint, the gateway's remaining mint capacity, or when the treasury has deposits paused for the token (tokenConfig.depositActive is false) — the deposit would revert. <addr> cannot be the zero address. |
| vetro-cli swap send-to-queue --from <tok> --amount <n> | encodeRequestRedeem | Swap-out step 1: locks the pegged token in the gateway and starts the cooldown. The token to redeem into is chosen at step 2, so it is not given here. A second request adds to the open one and restarts the cooldown on the whole locked amount, so queue the full amount at once. Fails when the gateway has the redeem queue disabled — the request would revert, and the redeem is one-step instead. |
| vetro-cli swap redeem --to <tok> --amount <n> --receiver <addr> [--slippage <percent>] | encodeRedeem | Swap-out: step 2 of the Redeem Queue, or the whole redeem when it is one step. --slippage works as on mint. Fails when the payout is 0, above the treasury reserves, or when withdrawals are paused for the token. <addr> cannot be the zero address. |
Read operations
| Command | Reads | Returns |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| vetro-cli swap allowance --token <tok> --account <addr> | allowance | Gateway's spending allowance, in the token's decimals. <tok> may be a whitelisted token (swap-in) or a pegged token (swap-out; the gateway pulls the pegged token at send-to-queue, or at the redeem itself when it is one step) |
| vetro-cli swap cooldown --gateway <addr> | getWithdrawalDelayEnabled, getWithdrawalDelay | Redeem Queue cooldown of the gateway, in seconds. 0 when the delay is disabled — a redeem is then one-step, with no queue. This is the gateway-wide contract value, not a per-account one. |
| vetro-cli swap cooldown-enabled --gateway <addr> | getWithdrawalDelayEnabled | Whether the gateway's Redeem Queue is on. false means a redeem is one-step for every account, and swap send-to-queue fails. |
| vetro-cli swap is-instant-redeem --account <addr> --gateway <addr> | isInstantRedeemWhitelisted | Whether <addr> is whitelisted to skip the gateway's Redeem Queue. true means its redeem is one-step: no send-to-queue, no cooldown. |
| vetro-cli swap max-out --token <tok> | getMaxWithdraw | Treasury reserves for the whitelisted <tok> — its balance plus what its yield vault converts to — in the token's decimals. A liquidity ceiling only. |
| vetro-cli swap mint-fee --token <tok> | getMintFee | Mint fee charged on a deposit of the whitelisted <tok>, in bps |
| vetro-cli swap pegged-token --gateway <addr> | getPeggedToken | Gateway's pegged-token address |
| vetro-cli swap preview-mint --from <tok> --amount <n> | previewDeposit | Pegged token that a deposit of <n> of the whitelisted <tok> would mint, in the pegged token's decimals. A quote only: it does not check maxMint or depositActive, so swap mint can still fail for the same amount. |
| vetro-cli swap preview-redeem --to <tok> --amount <n> | getPeggedToken, decimals, symbol, previewRedeem | Whitelisted <tok> that a redeem of <n> of the gateway's pegged token would pay out, in <tok>'s decimals. A quote only: it does not check withdrawActive or the treasury's reserves (swap max-out), so the redeem can still fail for the same amount. Fails when the redeem would pay out 0, which happens when <n> is below one unit of <tok>. |
| vetro-cli swap price --token <tok> | getTreasury, getPrice | Oracle price of the whitelisted <tok>, read from the treasury of the inferred gateway. Emits latestPrice, the oracle answer for the token, and unitPrice, the price of the gateway's peg unit — latestPrice / unitPrice is the token's value in peg units. |
| vetro-cli swap redeem-fee --token <tok> | getRedeemFee | Redeem fee charged on a redeem into the whitelisted <tok>, in bps |
| vetro-cli swap request --account <addr> --gateway <addr> | getRedeemRequest, getBlock | Open redeem request of <addr> on the gateway: amountLocked (in the pegged token's decimals), claimableAt (unix seconds) and status. The contract does not store status. The CLI derives it from claimableAt and the latest block's timestamp: none (no open request, claimableAt is 0), cooldown, or ready (the redeem can go through). |
| vetro-cli swap token-config --token <tok> | getTreasury, getTokenConfig | Treasury config of the whitelisted <tok>, read from the treasury of the inferred gateway: decimals, depositActive (gates swap mint), oracle, stalePeriod (seconds — a deposit or a redeem reverts once the feed's answer is that old), vault (the yield vault the collateral is routed to) and withdrawActive (gates the redeem) |
| vetro-cli swap treasury --gateway <addr> | getTreasury | Gateway's treasury address |
| vetro-cli swap whitelisted-tokens --gateway <addr> | getTreasury, getWhitelistedTokens, getTokenConfig, symbol, decimals | Every whitelisted token the gateway accepts. Each entry carries address, decimals, depositActive, symbol and withdrawActive |
Swapping in
vetro-cli swap allowance --token USDT --account 0xAgent # "0" → approval needed
vetro-cli swap approve --token USDT --amount 100 # sign + broadcast
vetro-cli swap mint --from USDT --amount 100 --receiver 0xAgent --slippage 0.5Swapping out, step 1
vetro-cli swap allowance --token VUSD --account 0xAgent # "0" → approval needed
vetro-cli swap approve --token VUSD --amount 100 # sign + broadcast
vetro-cli swap send-to-queue --from VUSD --amount 100send-to-queue fails on its own when the queue is off, so no preflight read is needed. To read the cooldown itself, swap cooldown takes --gateway, and the gateway address is the to of any write command's output. swap cooldown is gateway-wide, so it does not tell you whether your address skips the queue: swap is-instant-redeem --account <addr> --gateway <addr> reads that per-account. When it returns true, skip send-to-queue — the redeem is one step.
To follow the cooldown, run swap request --account <addr> --gateway <addr>. Its status changes from cooldown to ready when the request can be redeemed.
Swapping out, step 2
When swap request shows ready, redeem the locked amount:
vetro-cli swap redeem --to USDT --amount 100 --receiver 0xAgent --slippage 0.5Cancelling a redeem
To get the locked pegged token back before you redeem it, cancel the open request:
vetro-cli swap cancel-redeem --account 0xAgent --gateway 0x…gatewayswap request then shows none.
Swapping out in one step
When the queue is off for your address, skip send-to-queue. Approve the pegged token, then redeem:
vetro-cli swap approve --token VUSD --amount 100
vetro-cli swap redeem --to USDT --amount 100 --receiver 0xAgent --slippage 0.5variable-yield — pegged ↔ share token
A pegged token has exactly one staking vault, so the vault is inferred from --token and never passed explicitly. vetro-cli gateways lists the stakingVault of each gateway. Commands that take <pegged> accept only the pegged token, by symbol or address. Commands that take <tok> accept the pegged token or its share token, by symbol or address.
Write operations
| Command | Encodes | Notes |
| --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| vetro-cli variable-yield approve --token <pegged> --amount <n> | encodeApproveData | Generates the calldata that allows the staking vault to spend the pegged token. --amount 0 resets the allowance. |
| vetro-cli variable-yield cancel --token <tok> --request-id <id> | encodeCancelWithdraw | Cancels an exit ticket, in cooldown or ready. The vault stakes its locked pegged token again, at the current share price. Fails when the ticket does not exist. |
| vetro-cli variable-yield claim --token <tok> --request-id <id> --receiver <addr> | encodeClaimWithdraw | Claims a ready exit ticket. The vault pays its locked pegged token to <addr>. Only the ticket owner can claim. Fails when the ticket does not exist or is still in cooldown. <addr> cannot be the zero address. |
| vetro-cli variable-yield claim-all --token <tok> --account <addr> --receiver <addr> | getClaimableRequests, encodeClaimWithdrawBatch | Claims every ready exit ticket of <account> on the vault of <tok> in one transaction. Tickets on other vaults need one call for each vault. The vault pays their locked pegged token to <receiver>. Tickets in cooldown stay open. Only the ticket owner can claim. Fails when <account> has no ready ticket. <receiver> cannot be the zero address. |
| vetro-cli variable-yield instant-withdraw --token <tok> (--amount <n> \| --shares <n>) --account <addr> --receiver <addr> | getCooldownEnabled, getInstantWithdrawWhitelist, encodeWithdraw, encodeRedeem | Withdraws with no cooldown, in one step. The vault burns the shares of <account> and pays the pegged token to <receiver>. Sign with <account>. Fails when <account> cannot withdraw with no cooldown: the vault's cooldown is enabled and <account> is not on its instant-withdraw whitelist. Use unstake then. <receiver> cannot be the zero address. |
| vetro-cli variable-yield stake --token <pegged> --amount <n> --receiver <addr> | encodeDeposit | Stakes <n> of the pegged token. The vault pulls the pegged token from the signer and mints the share token to <addr>. Run approve first when the allowance is short. Fails when the stake would mint 0. <addr> cannot be the zero address. |
| vetro-cli variable-yield unstake --token <tok> (--amount <n> \| --shares <n>) --account <addr> | encodeRequestWithdraw, encodeRequestRedeem | Opens an exit ticket. The shares are burned, and the pegged token goes into cooldown. Fails when the vault's cooldown is disabled: use instant-withdraw then. |
Read operations
| Command | Reads | Returns |
| ----------------------------------------------------------------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| vetro-cli variable-yield allowance --token <pegged> --account <addr> | allowance | Staking vault's spending allowance on the pegged token, in the pegged token's decimals. |
| vetro-cli variable-yield cooldown --token <tok> | getCooldownEnabled, getCooldownDuration | Unstake cooldown of the vault, in seconds. 0 when the cooldown is disabled — unstake then fails, and instant-withdraw withdraws in one step. |
| vetro-cli variable-yield exit-tickets --token <tok> --account <addr> | getPendingRequests, getClaimableRequests | Open exit tickets of <addr>, as [{ assets, claimableAt, requestId, status }], sorted by requestId ascending, which is the order the tickets were opened in. assets is the pegged token locked in the ticket, in the pegged token's decimals. status is cooldown while the cooldown runs, and ready once the ticket can be claimed. claimableAt is the unix timestamp the cooldown ends at, or null once ready. Claimed and cancelled tickets are not listed. [] when <addr> has no open ticket. |
| vetro-cli variable-yield is-instant-withdraw --token <tok> --account <addr> | getCooldownEnabled, getInstantWithdrawWhitelist | Whether <addr> can withdraw with no cooldown (instant-withdraw): true when the vault's cooldown is disabled, or when <addr> is on its instant-withdraw whitelist. |
| vetro-cli variable-yield position --token <tok> --account <addr> | balanceOf | Share token balance of <addr>, in the share token's decimals. Exit tickets are not included: their shares are burned when the cooldown starts. |
| vetro-cli variable-yield preview-stake --token <pegged> --amount <n> | previewDeposit | Share token that a stake of <n> of the pegged token would mint, in the share token's decimals. Fails when the stake would mint 0, which happens when <n> is worth less than one unit of the share token. |
| vetro-cli variable-yield total-assets --token <tok> | totalAssets | Pegged token staked in the vault, in the pegged token's decimals. It includes yield that accrued but was not pulled from the yield distributor yet. It excludes the pegged token locked in exit tickets. |
Staking on variable-yield
vetro-cli variable-yield allowance --token VUSD --account 0xAgent # "0" → approval needed
vetro-cli variable-yield approve --token VUSD --amount 100 # sign + broadcast
vetro-cli variable-yield preview-stake --token VUSD --amount 100 # shares the stake mints, in base units
vetro-cli variable-yield stake --token VUSD --amount 100 --receiver 0xAgent # sign + broadcastSign the stake with the account that holds the pegged token and approved the staking vault. The vault mints the share token to --receiver. After the stake, position --token sVUSD --account 0xAgent shows the new shares. The stake fails when it would mint 0.
Unstaking on variable-yield
Unstake opens an exit ticket. The vault burns the shares, and the pegged token stays in the ticket until the cooldown ends.
vetro-cli variable-yield cooldown --token sVUSD # "0" → the cooldown is disabled: use instant-withdraw
vetro-cli variable-yield position --token sVUSD --account 0xAgent # shares you can unstake, in base units
vetro-cli variable-yield unstake --token sVUSD --shares 100 --account 0xAgent # sign + broadcastGive --shares to unstake an amount of the share token, or --amount to unstake an amount of the pegged token. Do not give both. To unstake the full position, use --shares with the value from position formatted with the token's decimals.
To follow the cooldown, run variable-yield exit-tickets --token sVUSD --account 0xAgent. The status of each ticket changes from cooldown to ready at its claimableAt.
When exit-tickets shows the ticket as ready, claim it by its requestId. The vault pays the locked pegged token to --receiver:
vetro-cli variable-yield claim --token VUSD --request-id 7 --receiver 0xAgent # sign + broadcastOnly the ticket owner can claim. Sign the transaction with the account that opened the ticket. From a different account, the transaction reverts, even though claim printed it. --receiver can be any address except the zero address.
To claim every ready ticket in one transaction, pass the owner instead of a ticket id. The tickets still in cooldown stay open:
vetro-cli variable-yield claim-all --token VUSD --account 0xAgent --receiver 0xAgent # sign + broadcastclaim fails when the ticket does not exist or is still in cooldown. claim-all fails when no ticket is ready. exit-tickets lists what claim-all claims: every ticket with status ready.
To keep the funds staked instead, cancel the ticket by its requestId, in cooldown or ready. The vault stakes the locked pegged token again, at the current share price, and it earns yield again from then on:
vetro-cli variable-yield cancel --token VUSD --request-id 7 # sign + broadcastcancel fails when the ticket does not exist.
Instant withdraw on variable-yield
Some accounts can withdraw with no cooldown: every account when the vault's cooldown is disabled, or an account on the vault's instant-withdraw whitelist. The withdraw is one step, with no exit ticket. The vault burns the shares and pays the pegged token to --receiver in the same transaction:
vetro-cli variable-yield is-instant-withdraw --token VUSD --account 0xAgent # true → instant-withdraw, false → unstake
vetro-cli variable-yield position --token VUSD --account 0xAgent # shares you can withdraw, in base units
vetro-cli variable-yield instant-withdraw --token VUSD --shares 100 --account 0xAgent --receiver 0xAgent # sign + broadcast--amount is in the pegged token, and --shares is in the share token, also when --token names the other token. To withdraw the full position, use --shares with the value from position formatted with the token's decimals. With --amount, yield accrues before the transaction is mined, so some shares stay. Sign the transaction with --account, the owner of the shares. instant-withdraw fails when is-instant-withdraw returns false. Use unstake then.
