Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,070Paid calls: 1,528Letters: 13Defects: 1,322counted just now
teppi

Server definition

Hash
sha256:b1419232c94c02448ee6d74ba01288c67d0723fe1b3aa7003a49cbb0d27eb942
What it is
What a remote MCP server returned when asked what it offers: 13 tools

The blob, as servednamed by its sha256

{ "instructions": "Vurto Swap — token swaps at the best net price on 9 EVM chains (Ethereum, Optimism, BNB Chain, Gnosis, Polygon, Base, Arbitrum One, Avalanche, Unichain) across Velora, KyberSwap, 1inch, CoW Protocol and the direct pools Uniswap, SushiSwap, PancakeSwap, Aerodrome and QuickSwap, plus `composto`, a two-hop route that crosses two of those pools inside one transaction, and on Solana across Jupiter (router), Raydium, Orca and Meteora.\nONE set of tools, two networks: pick the engine with chainId — an integer for EVM, the string \"solana-mainnet\" for Solana. Everything else is the same vocabulary. Solana addresses are base58 and CASE-SENSITIVE: lowercasing a mint gives a different, non-existent address, and it is the single most common way to break a Solana call.\nSolana differs in exactly four places, and nowhere else. chainId is the string \"solana-mainnet\". There is no approve, so a build has one transaction and never a steps[] array. Signing uses a Solana key, so prepare_signing returns a different signer. And status is asked of the network by signature, not of a stored execution by id.\nALWAYS USE THE LATEST: re-read these tool descriptions each session and fetch the live guide at https://swap.vurto.cc/agent-api.md — never a cached/older copy; if a cached doc disagrees, the live surface wins.\nA quote lives 10-12 seconds. Quoting, thinking for a minute, then building does not work — call swap_build directly when you intend to execute; it quotes and builds in one round trip. Only call swap_quote first if you need to compare routes without committing to one.\nSign steps[] in the order given, with one prepare_signing call for each step. approve is exact, never infinite, by product decision; send it, do not report it as the swap execution, then rebuild before signing the transaction step — call swap_build with quoteId set to the quote.id of the build you just approved, so it rebuilds THAT route. A swap_build without quoteId quotes afresh and may pick another provider whose spender you never approved.\nA CoW ERC-20 order (steps[].type === \"signature\") has no transaction hash — only a uid, from report_execution. A CoW ETH-flow order (selling the chain native asset) DOES send a transaction, but a successful receipt only means the order was registered — the solver fills it later, or never. Call swap_status before telling the user the swap succeeded; do not treat a receipt as proof for either case.\nIf swap_status comes back order_expired_refundable, the funds are stuck in a contract, not lost — call the refund flow pointed to in that response (POST /v1/ethflow/refund) instead of telling the user to give up on them.\nBuilding a liquidity pool or matching a ratio between exactly two legs? Use double_quote/double_build instead of two separate swap_quote/swap_build calls: \"out\" prices one source token split into two destinations, \"in\" prices two source tokens converging on one destination, both legs against the same instant of the market. The two legs are NOT atomic — execute leg A fully (sign, send, report_execution, confirm) before touching leg B, and do not start leg B if leg A failed or was rejected.\nMore than two legs on either side, or a basket where inputs and outputs are matched by value share rather than a fixed amount you already know? Use nn_quote/nn_build (\"N:N\"): N input tokens fund M output tokens in ONE atomic on-chain transaction, backend-allocated by value (waterfall) — unlike double_quote/double_build, the resulting nn_build transaction IS atomic across every leg. report_execution/swap_status do not work for an nn_build transaction (no single quoteId to key off) — confirm it via the transaction receipt directly.\nOn Solana a signature is not proof: the wallet returns it at send time, and until the network confirms it the transaction can still be dropped, or expire past lastValidBlockHeight without ever having existed. Call swap_status with the signature before telling the user it worked.\nInvoices: invoice_create makes a payment request (network, token, amount, receiving wallet) and returns an id like INV-7K3M-Q9XA, a link and a QR. No signature is needed to create or to pay; the invoice history needs a signed-in wallet and lives on the web app only. To pay, call invoice_pay with the payer wallet and the token they hold: same token is a direct transfer, any other token is a swap whose guaranteed minimum covers the requested amount, delivered to the receiver. Sign plan exactly like a swap_build plan (prepare_signing per step; on Solana POST the signed transaction to /v1/svm/execute), then call invoice_report_payment with the hash or signature (for a swap payment also report_execution, as for any swap, so the payer's swap and gain are recorded). The server verifies on-chain what reached the receiver; the invoice turns paid only from that.\nRPC per chain: https://rpc.vurto.cc/<slug> — see the slugs in GET /v1/chains, they are the same for every chain here.\nNever ask for, accept, or repeat a private key in chat, under any circumstance.", "tools": [ { "description": "Builds signable/sendable plans for BOTH legs of a Double Out or Double In swap — two ordinary swap_build calls under the hood, kept together for convenience. Returns { legA, legB }, each a full SwapPlan exactly like swap_build's. The two legs are NOT atomic — there is no combined contract call, each is a transaction (or CoW signature) the wallet sends separately, same as any other swap. Execute leg A fully first (steps, signing, report_execution) and confirm it landed before starting leg B. If leg A fails or is rejected, do NOT execute leg B — proceeding would leave the wallet with only half the ratio the user asked for, which defeats the purpose of a Double swap.", "inputSchema": { "additionalProperties": false, "properties": { "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "legA": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "quoteId": { "description": "Optional: build exactly this route from a prior double_quote.", "type": "string" }, "receiver": { "description": "Optional: deliver the output to this address instead of the signing wallet. Only providers with supportsReceiver true on the resulting quote honor it — others are left out of quotes[] entirely rather than risk sending to the wrong address. supportsReceiver is present on Solana quotes too, so read it instead of assuming. On Solana, selling into native SOL with a separate destination is refused on every provider (receiver_native_sol_unsupported): closing the wrapped-SOL account sends balance and rent to whoever signs. Ask for wSOL instead.", "type": "string" }, "slippageBps": { "description": "Optional, a sane per-pair default applies when omitted.", "type": "integer" }, "tokenIn": { "description": "Contract address (Solana: mint), or symbol (case-insensitive). A symbol matching more than one token on this chain fails with ambiguous_token and every candidate — pick the address you meant and retry. On Solana only VERIFIED tokens resolve by symbol, because there anyone can mint a token using another one's symbol; an unverified token has to be named by its mint.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "type": "object" }, "legB": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "quoteId": { "type": "string" }, "receiver": { "description": "Optional: deliver the output to this address instead of the signing wallet. Only providers with supportsReceiver true on the resulting quote honor it — others are left out of quotes[] entirely rather than risk sending to the wrong address. supportsReceiver is present on Solana quotes too, so read it instead of assuming. On Solana, selling into native SOL with a separate destination is refused on every provider (receiver_native_sol_unsupported): closing the wrapped-SOL account sends balance and rent to whoever signs. Ask for wSOL instead.", "type": "string" }, "slippageBps": { "description": "Optional, a sane per-pair default applies when omitted.", "type": "integer" }, "tokenIn": { "description": "Contract address (Solana: mint), or symbol (case-insensitive). A symbol matching more than one token on this chain fails with ambiguous_token and every candidate — pick the address you meant and retry. On Solana only VERIFIED tokens resolve by symbol, because there anyone can mint a token using another one's symbol; an unverified token has to be named by its mint.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "type": "object" }, "maxSlippageBps": { "description": "Optional ceiling, 0-10000, applied to both legs.", "type": "integer" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "chainId", "wallet", "legA", "legB" ], "type": "object" }, "name": "double_build", "outputSchema": null }, { "description": "Compares ranked routes for TWO swap legs at once — \"Double Out\" (one source token split into two destinations) or \"Double In\" (two source tokens converging on one destination). This exists because building a liquidity pool or matching a target ratio needs both legs priced against the market at the same instant, not one after another with the price moving in between. Each leg is independently quoted (two ordinary swap_quote calls under the hood) — this tool is a convenience that keeps them together, not a combined/atomic route. For mode \"out\": legA.tokenIn must equal legB.tokenIn (the shared source); tokenOut differs. For mode \"in\": legA.tokenOut must equal legB.tokenOut (the shared destination); tokenIn differs. Pass the exact amount each leg should trade — this tool does not compute percentages or splits for you. If the shared token is the chain's native asset, remember gas is paid twice (once per leg's eventual transaction) — do not quote/build a total that leaves nothing for the second leg's gas.", "inputSchema": { "additionalProperties": false, "properties": { "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "legA": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "receiver": { "description": "Optional: deliver the output to this address instead of the signing wallet. Only providers with supportsReceiver true on the resulting quote honor it — others are left out of quotes[] entirely rather than risk sending to the wrong address. supportsReceiver is present on Solana quotes too, so read it instead of assuming. On Solana, selling into native SOL with a separate destination is refused on every provider (receiver_native_sol_unsupported): closing the wrapped-SOL account sends balance and rent to whoever signs. Ask for wSOL instead.", "type": "string" }, "slippageBps": { "description": "Optional, a sane per-pair default applies when omitted.", "type": "integer" }, "tokenIn": { "description": "Contract address (Solana: mint), or symbol (case-insensitive). A symbol matching more than one token on this chain fails with ambiguous_token and every candidate — pick the address you meant and retry. On Solana only VERIFIED tokens resolve by symbol, because there anyone can mint a token using another one's symbol; an unverified token has to be named by its mint.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "tokenIn", "tokenOut" ], "type": "object" }, "legB": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "receiver": { "description": "Optional: deliver the output to this address instead of the signing wallet. Only providers with supportsReceiver true on the resulting quote honor it — others are left out of quotes[] entirely rather than risk sending to the wrong address. supportsReceiver is present on Solana quotes too, so read it instead of assuming. On Solana, selling into native SOL with a separate destination is refused on every provider (receiver_native_sol_unsupported): closing the wrapped-SOL account sends balance and rent to whoever signs. Ask for wSOL instead.", "type": "string" }, "slippageBps": { "description": "Optional, a sane per-pair default applies when omitted.", "type": "integer" }, "tokenIn": { "description": "Contract address (Solana: mint), or symbol (case-insensitive). A symbol matching more than one token on this chain fails with ambiguous_token and every candidate — pick the address you meant and retry. On Solana only VERIFIED tokens resolve by symbol, because there anyone can mint a token using another one's symbol; an unverified token has to be named by its mint.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "tokenIn", "tokenOut" ], "type": "object" }, "mode": { "description": "\"out\": one source, two destinations. \"in\": two sources, one destination.", "enum": [ "out", "in" ], "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "mode", "chainId", "legA", "legB" ], "type": "object" }, "name": "double_quote", "outputSchema": null }, { "description": "Create a payment request: who receives, which token, how much, on which network. Returns invoice.id, invoice.label (INV-XXXX-XXXX, what people copy), invoice.url (share this; it previews with the QR on WhatsApp and Telegram) and invoice.qr (PNG). No signature or API key needed. Only VERIFIED tokens of the network are accepted, by address or symbol — an unverified token is refused because a cloned \"USDC\" with its own pool would let the creator sell a fake at any price. The payer can pay with ANY token on that network.", "inputSchema": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Decimals come from the token list, not from you.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "memo": { "description": "Optional note, up to 80 chars, visible to anyone with the link.", "type": "string" }, "recipient": { "description": "Wallet that receives. EVM 0x address, or base58 on Solana (case-sensitive).", "type": "string" }, "token": { "description": "Token to receive: address/mint or symbol of a verified token on this network.", "type": "string" } }, "required": [ "chainId", "recipient", "token", "amount" ], "type": "object" }, "name": "invoice_create", "outputSchema": null }, { "description": "Read an invoice by id (INV-XXXX-XXXX, with or without dashes): requested amount, token, network, receiver, status (open or paid), the paying transaction once paid, and received (the raw amount measured on-chain so far). Pending payments are re-checked on-chain on every read.", "inputSchema": { "additionalProperties": false, "properties": { "id": { "description": "INV-XXXX-XXXX or the 8-character id.", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "invoice_get", "outputSchema": null }, { "description": "Build the plan to pay an invoice from payer, with the token payer holds (default: the invoice token). Nothing is signed or sent here. method \"transfer\": same token, a direct transfer built from the stored invoice (no fee, no gain; the receiver sees the payer as sender). method \"swap\": another token; amountIn is computed so the GUARANTEED minimum output covers the requested amount, the route is always the one with GAIN when there is one, and the output goes straight to the receiver (the receiver sees the DEX router as sender). Any surplus over the requested amount goes to the receiver. plan has the same shape as a swap_build plan: on EVM sign steps[] in order with prepare_signing (approve steps first, then the transaction); on Solana pass {transaction, executionRef} to prepare_signing and POST the signed transaction to /v1/svm/execute. If simulation.status is approval_required, send the approve and call invoice_pay again. Then call invoice_report_payment with the hash (EVM) or signature (Solana). Errors: price_moved (the minimum fell below the request between quote and build — call again), no_route, native_sol_only (an invoice in SOL can only be paid in SOL), invoice_already_paid.", "inputSchema": { "additionalProperties": false, "properties": { "id": { "description": "INV-XXXX-XXXX or the 8-character id.", "type": "string" }, "payer": { "description": "The wallet that will sign and pay, on the invoice network.", "type": "string" }, "slippageBps": { "description": "Optional, default 50. The guaranteed minimum is computed after it, so a tighter slippage asks the payer for less.", "type": "integer" }, "tokenIn": { "description": "Optional: address/mint or symbol of the token the payer pays with. Omit to pay in the invoice token.", "type": "string" } }, "required": [ "id", "payer" ], "type": "object" }, "name": "invoice_pay", "outputSchema": null }, { "description": "Hand the payment transaction to the server, right after sending it. The server reads the transaction on-chain and measures what reached the receiver in the invoice token; the payer must be the signer and the transaction must be newer than the invoice. Pending until mined; invoice_get re-checks. A hash pays one invoice only (tx_already_used once it confirmed another).", "inputSchema": { "additionalProperties": false, "properties": { "id": { "description": "INV-XXXX-XXXX or the 8-character id.", "type": "string" }, "method": { "description": "From invoice_pay.method.", "enum": [ "transfer", "swap" ], "type": "string" }, "payer": { "description": "The wallet that signed the payment.", "type": "string" }, "txHash": { "description": "EVM transaction hash, or the Solana signature.", "type": "string" } }, "required": [ "id", "payer", "txHash" ], "type": "object" }, "name": "invoice_report_payment", "outputSchema": null }, { "description": "Builds ONE signable/sendable atomic transaction executing every leg of an N:N basket through VurtoSwapRouter. Always re-quotes the whole basket fresh from chainId/inputLegs/outputLegs — there is no quoteId handoff for N:N, pass the same fields used for nn_quote (or skip nn_quote and call this directly). No API key required: pass the wallet that will sign. A machine credential is optional and only raises your limit from the per-IP cap to the credential budget. Returns steps[]: one approve step per DISTINCT input token that still needs allowance, followed by ONE transaction step that executes every leg atomically. The approve target is the VurtoSwapRouter address (steps[].spender / the build's router), NOT each leg's underlying provider — this router pulls every input token itself inside one contract call, so approving providers individually the way swap_build does would approve the wrong address. If simulation.status is approval_required, send the approve step(s) first and call nn_build again for the executable transaction. legs[].routeSwitch, when present on a leg, means the provider the quote picked for THAT leg refused to build (it hit its request limit) and the leg was built with another provider instead: {from, to, reason}. Only that leg changed, the others are untouched, and the replacement is what will be signed: say which provider replaced it before the user signs. IMPORTANT: report_execution and swap_status do NOT support nn_build's transaction step — both key off a single quoteId, and this build has none (it is one transaction covering every leg, not one quote). After sending it, confirm success by checking the transaction receipt directly, not swap_status.", "inputSchema": { "additionalProperties": false, "properties": { "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "inputLegs": { "items": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "tokenIn": { "description": "Contract address, or symbol (case-insensitive).", "type": "string" } }, "required": [ "tokenIn" ], "type": "object" }, "minItems": 1, "type": "array" }, "outputLegs": { "items": { "additionalProperties": false, "properties": { "outputPercent": { "description": "Integer percent (1-100) of the TOTAL basket value this leg receives. Every outputLegs[].outputPercent in the request must sum to exactly 100.", "type": "integer" }, "receiver": { "description": "Optional: deliver this leg's output to a different address than the signing wallet.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" } }, "required": [ "tokenOut", "outputPercent" ], "type": "object" }, "minItems": 1, "type": "array" }, "slippageBps": { "description": "Optional, 5-500, applied to every leg. Default 50.", "type": "integer" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "chainId", "wallet", "inputLegs", "outputLegs" ], "type": "object" }, "name": "nn_build", "outputSchema": null }, { "description": "N:N — quotes a basket where N input tokens fund M output tokens in ONE atomic on-chain transaction. The backend runs a waterfall allocation deciding which input finances which output, then quotes the real tokenIn->tokenOut route for each resulting slice through the same provider fan-out swap_quote uses. NOT decomposable into independent swap_quote/double_quote calls — the allocation itself is the thing being computed, not just N+M separate prices for legs you already know. inputLegs[]: what you sell (tokenIn + amount or amountRaw, each). outputLegs[]: what you want back, as outputPercent — an integer percent of the TOTAL basket value, not a fixed amount, because the actual split depends on the allocation; every outputLegs[].outputPercent in the request must sum to exactly 100. Up to 10 combined input+output legs; the waterfall never produces more than inputLegs.length + outputLegs.length - 1 real on-chain legs. Returns { legs[], failures[] }. Each entry in legs[] is a real quoted tokenIn->tokenOut leg (a NormalizedQuote under .quote, plus amountIn/tokenIn/tokenOut/receiver for that slice) — this is what nn_build will execute, not a rough preview. failures[] lists any slice that found no route; a partial basket is possible and reported, never silently dropped.", "inputSchema": { "additionalProperties": false, "properties": { "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\"). On EVM the multi-swap router must be deployed on the chain or the quote fails with multi_swap_not_supported_on_chain; on Solana there is no router contract, several top-level instructions in one transaction are already all-or-nothing by runtime rule.", "type": [ "integer", "string" ] }, "inputLegs": { "items": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "tokenIn": { "description": "Contract address, or symbol (case-insensitive).", "type": "string" } }, "required": [ "tokenIn" ], "type": "object" }, "minItems": 1, "type": "array" }, "outputLegs": { "items": { "additionalProperties": false, "properties": { "outputPercent": { "description": "Integer percent (1-100) of the TOTAL basket value this leg receives. Every outputLegs[].outputPercent in the request must sum to exactly 100.", "type": "integer" }, "receiver": { "description": "Optional: deliver this leg's output to a different address than the signing wallet.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" } }, "required": [ "tokenOut", "outputPercent" ], "type": "object" }, "minItems": 1, "type": "array" }, "slippageBps": { "description": "Optional, 5-500, applied to every leg. Default 50.", "type": "integer" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "chainId", "inputLegs", "outputLegs" ], "type": "object" }, "name": "nn_quote", "outputSchema": null }, { "description": "Synthesizes the local CLI signer invocation for one step of a swap_build plan. Does not call the Vurto backend — this only assembles the payload. You (the agent) do not need a private key and must never ask for one in chat: signing happens locally on the user's machine. RUN the command yourself as a background task (it blocks until the user approves/rejects/times out, then prints one JSON line and exits) and react to its exit — never ask the user \"did you sign?\". EVM supports \"approve\"/\"transaction\" steps (send tx.to/tx.data on-chain) and \"signature\" steps (sign step.typedData off-chain, EIP-712 — a CoW order; no gas, no transaction, no hash). expected_keys in the response tells you which result field to read: txHash for the first two, signature for the third. Solana has no steps[] and no approve: pass chainId \"solana-mainnet\" and step {transaction: build.transaction, executionRef: build.executionRef}. The response returns a different signer (Solana keys are not EVM keys) with the same shape, and expected_keys is signedTransaction — POST it to /v1/svm/execute, which broadcasts it and returns the signature.", "inputSchema": { "additionalProperties": false, "properties": { "buildId": { "description": "From a prior swap_build/swap_refresh response.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "step": { "description": "EVM: one entry from swap_build's steps[]. Solana: {transaction, executionRef} from the build.", "properties": { "executionRef": { "description": "Solana only: build.executionRef when the build has one. Its absence is meaningful, not an omission: a route we assembled ourselves is broadcast directly, an aggregator order has to go back to the aggregator to land.", "type": "string" }, "humanSummary": { "type": "string" }, "transaction": { "description": "Solana only: build.transaction, base64, verbatim.", "type": "string" }, "tx": { "description": "Required when type is \"approve\" or \"transaction\".", "properties": { "data": { "type": "string" }, "to": { "type": "string" }, "value": { "type": "string" } }, "type": "object" }, "type": { "description": "EVM only.", "enum": [ "approve", "transaction", "signature" ], "type": "string" }, "typedData": { "description": "Required when type is \"signature\" — pass steps[].typedData from swap_build verbatim.", "properties": { "domain": { "type": "object" }, "message": { "type": "object" }, "primaryType": { "type": "string" }, "types": { "type": "object" } }, "type": "object" } }, "type": "object" }, "walletAddress": { "description": "The wallet the plan was built for. The signer refuses to sign if the connected wallet does not match. On Solana this is base58 and CASE-SENSITIVE: lowercasing it produces a different, non-existent address.", "type": "string" } }, "required": [ "buildId", "walletAddress", "chainId", "step" ], "type": "object" }, "name": "prepare_signing", "outputSchema": null }, { "description": "Reports a completed swap, closing the loop. EVM transaction: pass wallet + txHash + quoteId; never report an approve step as an execution. EVM CoW signature: pass wallet + chainId + quoteId + signature; the server reloads the stored build and submits the signed order, returning uid (there is no transaction hash for this path). Solana: pass buildId + signature; the server verifies the fee payer and transaction on the network. No API key required; a machine credential only raises limits.", "inputSchema": { "additionalProperties": false, "properties": { "buildId": { "description": "Solana: buildId returned by swap_build.", "type": "string" }, "chainId": { "description": "EVM CoW: integer chain id. Solana may use \"solana-mainnet\", but buildId + signature are sufficient.", "type": [ "integer", "string" ] }, "quoteId": { "description": "EVM: quote id from the built plan.", "type": "string" }, "signature": { "description": "EVM: EIP-712 CoW signature. Solana: transaction signature.", "type": "string" }, "txHash": { "description": "EVM transaction swap only; do not report approve hashes.", "pattern": "^0x[0-9a-fA-F]{64}$", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "type": "object" }, "name": "report_execution", "outputSchema": null }, { "description": "Build a signable/sendable plan for a swap. This is the tool that does the work — an agent that only knows this tool can execute a swap end to end. Quotes and builds the best route in one call when quoteId is omitted (recommended): a route with GAIN first, re-quoting up to 3 rounds total before accepting one without gain, the same rule as Invoice; pass quoteId from a prior swap_quote to build exactly that route instead. No API key required: pass the wallet that will sign. A machine credential is optional and only raises your limit from the per-IP cap to the credential budget. Four things to hold onto: 1. steps[] are ORDERED and REQUIRED. Skipping an approve step guarantees a revert. 2. If simulation.status is \"approval_required\", sign/send only the approve step(s), do not report them as the swap execution, then call swap_build again with quoteId set to the quote.id of that build (the approved route; without it a fresh quote may pick another provider whose spender you never approved). If it is \"incomplete\", do not sign anything: the transaction was never independently verified. 3. If a step has type \"signature\", there is no transaction and never will be one for that step — what exists afterward is the uid from report_execution, not a hash. 4. If the provider is cowswap and the token sold is the chain's native asset, the transaction only REGISTERS the order — a successful receipt is not a successful swap. Use swap_status, not the receipt, to know what actually happened. 5. routeSwitch, when present, means the route you asked for refused to build (it hit its request limit) and the plan was built with another provider instead: {from, to, reason}. The quote in the plan is the route that will actually be signed. If the user picked that route themselves, say which provider replaced it before they sign.", "inputSchema": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "maxSlippageBps": { "description": "Optional ceiling, 0-10000, enforced on every future refresh of this build — once set it never loosens.", "type": "integer" }, "quoteId": { "description": "Optional: build exactly this route from a prior swap_quote, instead of quoting fresh.", "type": "string" }, "receiver": { "description": "Optional: deliver the output to this address instead of the signing wallet. Only providers with supportsReceiver true on the resulting quote honor it — others are left out of quotes[] entirely rather than risk sending to the wrong address. supportsReceiver is present on Solana quotes too, so read it instead of assuming. On Solana, selling into native SOL with a separate destination is refused on every provider (receiver_native_sol_unsupported): closing the wrapped-SOL account sends balance and rent to whoever signs. Ask for wSOL instead.", "type": "string" }, "slippageBps": { "description": "Optional, a sane per-pair default applies when omitted.", "type": "integer" }, "tokenIn": { "description": "Contract address (Solana: mint), or symbol (case-insensitive). A symbol matching more than one token on this chain fails with ambiguous_token and every candidate — pick the address you meant and retry. On Solana only VERIFIED tokens resolve by symbol, because there anyone can mint a token using another one's symbol; an unverified token has to be named by its mint.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "chainId", "wallet" ], "type": "object" }, "name": "swap_build", "outputSchema": null }, { "description": "Compare ranked routes across providers for a swap, without building or spending anything. Ranked by net value after gas and platform fee, not raw output, with ONE unit price for the output token across every route, so a friendlier price feed can never put a route that delivers fewer tokens on top. Each quote also carries estimatedGas, the gas in units behind the same gasUsd, if you would rather rank against a gas price you read yourself. A quote is only usable by swap_build for about 10-12 seconds — do not hold onto a quoteId and build it later, quote again instead.", "inputSchema": { "additionalProperties": false, "properties": { "amount": { "description": "Human decimal amount, e.g. \"100\". Use this OR amountRaw, not both.", "type": "string" }, "amountRaw": { "description": "Raw integer string in tokenIn's smallest unit.", "type": "string" }, "chainId": { "description": "EVM: integer from GET /v1/chains (1, 10, 56, 100, 137, 8453, 42161, 43114, 130). Solana: string from GET /v1/svm/chains (\"solana-mainnet\").", "type": [ "integer", "string" ] }, "receiver": { "description": "Optional: deliver the output to this address instead of the signing wallet. Only providers with supportsReceiver true on the resulting quote honor it — others are left out of quotes[] entirely rather than risk sending to the wrong address. supportsReceiver is present on Solana quotes too, so read it instead of assuming. On Solana, selling into native SOL with a separate destination is refused on every provider (receiver_native_sol_unsupported): closing the wrapped-SOL account sends balance and rent to whoever signs. Ask for wSOL instead.", "type": "string" }, "slippageBps": { "description": "Optional, a sane per-pair default applies when omitted.", "type": "integer" }, "tokenIn": { "description": "Contract address (Solana: mint), or symbol (case-insensitive). A symbol matching more than one token on this chain fails with ambiguous_token and every candidate — pick the address you meant and retry. On Solana only VERIFIED tokens resolve by symbol, because there anyone can mint a token using another one's symbol; an unverified token has to be named by its mint.", "type": "string" }, "tokenOut": { "description": "Contract address, or symbol.", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [ "chainId", "tokenIn", "tokenOut" ], "type": "object" }, "name": "swap_quote", "outputSchema": null }, { "description": "Re-checks a swap. EVM: pass wallet + executionId (the id from report_execution); for CoW ETH-flow this consults the orderbook and distinguishes order_expired_refundable from order_expired_refunded instead of trusting the registration receipt. Solana: pass signature; answers come directly from the network and may be confirmed, pending, failed or expired.", "inputSchema": { "additionalProperties": false, "properties": { "executionId": { "description": "EVM: the id returned by report_execution.", "type": "string" }, "signature": { "description": "Solana: the transaction signature. Answers come from the network itself: confirmed, pending, failed, or expired (past lastValidBlockHeight the transaction can no longer enter any block).", "type": "string" }, "wallet": { "description": "Wallet that will sign. Required for builds and EVM execution/history calls. On an anonymous EVM quote, pass it to make the returned quoteId executable; without it the quote is indicative.", "type": "string" } }, "required": [], "type": "object" }, "name": "swap_status", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:b1419232c94c02448ee6d74ba01288c67d0723fe1b3aa7003a49cbb0d27eb942 | sha256sum