{"name":"check_transaction_intent","title":"Does it do what I meant?","category":"transactions","useWhen":"Use right before signing a transfer your agent built from an instruction like \"send 5 USDC to X\". Confirms the transaction moves exactly that token, amount and recipient and nothing else, catching hallucinated amounts, wrong decimals and injected instructions.","benefit":{"kind":"accuracy","text":"Asked to send 5 USDC, an agent can build a transaction for 50 (a decimals slip) or to a hallucinated address. This returns MISMATCH and names the exact field."},"description":"Compares a transaction against the stated intent field by field (asset, amount in exact base units, recipient, sender), flags every instruction that is not part of the transfer, and checks the simulated balance changes so funds moved any other way are caught.","price":"$0.02","priceText":"25 free calls a day, then $0.02 USDC per call (x402)","http":{"method":"POST","path":"/api/tools/check_transaction_intent","body":"JSON object with the inputs below"},"mcp":{"method":"tools/call","name":"check_transaction_intent"},"inputs":[{"name":"transaction","type":"string (base64)","required":true,"description":"The unsigned (or signed) transaction, serialized and base64-encoded. Legacy and v0 transactions with lookup tables are supported. Signatures are not checked.","howToGet":"From your wallet SDK before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or the swap transaction returned by an aggregator API."},{"name":"intent.token","type":"string (\"SOL\" or mint)","required":true,"description":"What should be sent.","howToGet":"Use \"SOL\" for native SOL, otherwise the mint from resolve_token."},{"name":"intent.amount","type":"string (decimal)","required":true,"description":"How much should be sent, in human units, e.g. \"5\" for 5 USDC.","howToGet":"The amount the user asked for, as a string."},{"name":"intent.recipient","type":"string (wallet address)","required":true,"description":"The wallet that should receive it (the person, not their token account).","howToGet":"The address the user gave. Do not take it from the transaction itself."},{"name":"intent.sender","type":"string (wallet address)","required":false,"description":"The wallet that should pay. Defaults to the transaction's fee payer.","howToGet":"Your agent's wallet address."},{"name":"intent.action","type":"\"transfer\"","required":false,"description":"The kind of intent. Only transfers are supported today.","howToGet":"Leave out, or pass \"transfer\"."},{"name":"network","type":"\"mainnet-beta\" | \"devnet\"","required":false,"description":"Solana cluster to read. Defaults to \"mainnet-beta\" (real funds).","howToGet":"Leave it out for mainnet. Use \"devnet\" only for test wallets and test transactions."}],"outputs":[{"field":"verdict","type":"\"MATCH\" | \"MISMATCH\"","meaning":"MATCH: the transaction does exactly what the intent says. MISMATCH: at least one field check failed; do not sign.","howComputed":"MATCH only when every fieldChecks entry is ok and unexpectedEffects is empty."},{"field":"explanation","type":"string","meaning":"Plain-language result, naming the first mismatch.","howComputed":"Built from the failed checks."},{"field":"expected.assetMint / amountBaseUnits / decimals","type":"string | number","meaning":"The intent converted to exact on-chain terms.","howComputed":"SOL uses 9 decimals; tokens use the mint's on-chain decimals; amount converted with exact integer math."},{"field":"fieldChecks[].field","type":"\"asset\" | \"amount\" | \"recipient\" | \"sender\" | \"simulation\"","meaning":"What was compared.","howComputed":"Fixed list."},{"field":"fieldChecks[].expected / actual","type":"string","meaning":"The intended value and what the transaction actually does.","howComputed":"actual comes from the decoded transfer instruction; for tokens the recipient is the owner of the destination token account (read on chain, or from an ATA-create instruction in the same transaction)."},{"field":"fieldChecks[].ok","type":"boolean","meaning":"Whether they match.","howComputed":"Exact equality (amounts compared in base units)."},{"field":"transfers[]","type":"object[]","meaning":"Every transfer found in the transaction with from wallet, to wallet, asset and exact amount.","howComputed":"Decoded System and Token transfer instructions; token account owners resolved on chain."},{"field":"unexpectedEffects[]","type":"string[]","meaning":"Anything the intent did not ask for: extra transfers, approvals, authority changes, account closures, calls to other programs, or the sender losing more than the transfer explains.","howComputed":"Every instruction except the matched transfer, Compute Budget, Memo and creating the recipient's token account is listed (approvals and authority changes with the details preflight_transaction gives). Then the simulation's balance changes for the sender are compared with the amount, plus fees and the recipient's account deposit for SOL; any larger loss is listed."}],"notes":["Creating the recipient's token account (about 0.002 SOL deposit) is allowed and not flagged, since token transfers to new holders need it.","Any other instruction gives MISMATCH, even a harmless one, because a transfer should not need it. Read unexpectedEffects before overriding."],"inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"transaction":{"type":"string","minLength":20},"intent":{"type":"object","properties":{"action":{"default":"transfer","type":"string","const":"transfer"},"token":{"type":"string"},"amount":{"type":"string"},"recipient":{"type":"string"},"sender":{"type":"string"}},"required":["token","amount","recipient"]},"network":{"default":"mainnet-beta","type":"string","enum":["mainnet-beta","devnet"]}},"required":["transaction","intent"]}}