# TxGuard Deterministic Base transaction and x402 payment preflight for agents, paid per call. TxGuard tells an agent what a Base transaction actually does before it signs one. It decodes calldata against verified ABIs, resolves every known proxy pattern including the legacy slot Base USDC really uses, unwraps multicall wrappers recursively, classifies allowances against the token's own supply rather than a list of sentinel values, and runs the full x402 authorization check table against the quote a payment claims to satisfy. There is no model anywhere in it. When a four-byte selector matches more than one signature it returns unknown and hands back every candidate, because a confident decode of an ambiguous selector is how a preflight API becomes dangerous. ## Payment - Protocol: x402 V2, scheme `exact`, network `eip155:8453` (Base mainnet) - Asset: USDC `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` - No accounts, no API keys, no subscriptions. - Failed calls are not charged. Only a successful, usable result settles. - Payment authorization window: 60s ## Endpoints ### `POST /v1/tx/preflight` — $0.01 per successful call Explain and preflight an unsigned Base transaction, EIP-712 typed data, or an EIP-3009 x402 payment authorization before you sign it. Decodes intent against verified ABIs, resolves proxies, classifies approvals, and checks a payment authorization against the quote it claims to pay: recipient, amount, asset, chain, freshness, and nonce replay. Returns unknown rather than guessing when a selector is ambiguous. Not a guarantee that a transaction is safe or profitable. Unpaid request returns HTTP 402 with the challenge in the `PAYMENT-REQUIRED` header: ```bash curl -i -sS -X POST https://txguard.schemasure.com/v1/tx/preflight \ -H 'content-type: application/json' \ -d '{"unsigned_tx":{"from":"0x9F2C5E4A8db1C3a7E6B0d4f8C1E2a5b7D9C0e3F4","to":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","value":"0","data":"0xa9059cbb0000000000000000000000005d3e1a9b7c2f4e8a0b6d3c5f9e1a7b4d2c8f0a6e0000000000000000000000000000000000000000000000000000000000002710"},"expected_quote":{"scheme":"exact","network":"eip155:8453","amount":"10000","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","payTo":"0x1a2B3c4D5E6F7a8B9c0D1e2F3A4b5C6d7E8F9a0b","maxTimeoutSeconds":60,"extra":{"name":"USD Coin","version":"2"}}}' ``` Example successful response: ```json { "ok": true, "verdict": "block", "confidence": 1, "risk_codes": [ "RECIPIENT_MISMATCH", "RPC_UNAVAILABLE" ], "evidence": [ { "code": "RECIPIENT_MISMATCH", "severity": "critical", "detail": "Pays 0x5D3e1a9b7c2f4E8A0b6d3c5F9E1A7b4D2C8f0a6E, but the quote names 0x1a2B3c4D5E6F7a8B9c0D1e2F3A4b5C6d7E8F9a0b. Signing this pays someone other than the party you are buying from.", "source": "quote-comparison", "data": { "field": "payTo", "expected": "0x1a2B3c4D5E6F7a8B9c0D1e2F3A4b5C6d7E8F9a0b", "actual": "0x5D3e1a9b7c2f4E8A0b6d3c5F9E1A7b4D2C8f0a6E" } }, { "code": "RPC_UNAVAILABLE", "severity": "medium", "detail": "No Base RPC endpoint is configured, so chain-dependent fields are unknown rather than assumed. See result.unresolved.", "source": "rpc" } ], "result": { "input_shape": "unsigned_tx", "chain": "eip155:8453", "intent": { "kind": "erc20_transfer", "summary": "Transfer 10000 base units of token 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 to 0x5D3e1a9b7c2f4E8A0b6d3c5F9E1A7b4D2C8f0a6E.", "decode_source": "bundled-abi", "selector": "0xa9059cbb", "signature": "transfer(address,uint256)", "function_name": "transfer", "standard": "erc20", "target": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "value_wei": "0", "args": [ { "name": "to", "type": "address", "value": "0x5D3e1a9b7c2f4E8A0b6d3c5F9E1A7b4D2C8f0a6E" }, { "name": "amount", "type": "uint256", "value": "10000" } ], "calls": [], "depth": 0, "truncated": false }, "expected_transfers": [ { "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "asset_kind": "erc20", "from": "0x9f2C5E4a8DB1C3A7e6b0d4f8C1e2A5b7d9c0E3f4", "to": "0x5D3e1a9b7c2f4E8A0b6d3c5F9E1A7b4D2C8f0a6E", "amount": "10000", "token_id": null, "source": "decode" } ], "approvals": [], "permit_scope": null, "spender": { "address": null, "is_contract": null, "detail": "this transaction grants no allowance, so it has no spender" }, "proxy": { "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "kind": "unknown", "implementation": null, "admin": null, "beacon": null, "upgradeable": null, "slots_probed": [], "detail": "no RPC endpoint is configured, so no slot could be read" }, "authorization_checks": [], "quote_comparison": { "present": true, "matches": false, "fields": [ { "field": "payTo", "expected": "0x1a2B3c4D5E6F7a8B9c0D1e2F3A4b5C6d7E8F9a0b", "actual": "0x5D3e1a9b7c2f4E8A0b6d3c5F9E1A7b4D2C8f0a6E", "matches": false }, { "field": "amount", "expected": "10000", "actual": "10000", "matches": true }, { "field": "asset", "expected": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "actual": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "matches": true }, { "field": "chainId", "expected": "8453", "actual": null, "matches": null }, { "field": "extra.name", "expected": "USD Coin", "actual": null, "matches": null }, { "field": "extra.version", "expected": "2", "actual": null, "matches": null } ], "detail": "2 of 3 comparable fields match" }, "simulation": { "requested": false, "status": "not_requested", "asset_changes": [], "gas_used": null, "block_number": null, "detail": "simulation was not requested; send simulate: true to run one" }, "candidate_signatures": [], "denylist_hits": [], "unresolved": [ "proxy status of 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 is unknown: no RPC endpoint is configured, so no slot could be read" ], "rpc": { "configured": false, "reachable": null, "endpoints": [] } }, "policy_version": "2026-08-03", "request_hash": "sha256:6d5c717eb5eede165dada2645ad0944430ff492739cf58d0c2dad2b812f0ddb4", "data_versions": { "denylist": "2026-08-03.1", "abi_packs": "2026-08-03.1", "signature_index": "2026-08-03.1", "policy": "2026-08-03", "chain": "eip155:8453" }, "warnings": [] } ``` ## Result contract Every response is the shared portfolio envelope: `ok`, `verdict`, `confidence`, `risk_codes`, `evidence`, `result`, `policy_version`, `request_hash`, `data_versions`, `warnings`. `verdict: "unknown"` is a real answer, not a failure. It means the service could not determine the result and says why in `evidence`. It is never silently reported as a safe or clean outcome. ## Service level - Target P50: 500 ms - Target P95: 2000 ms ## Data handling - Caller content is processed transiently and never retained. - No training on customer content. - No subprocessors see caller content. ## Machine-readable surfaces - https://txguard.schemasure.com/openapi.json - https://txguard.schemasure.com/.well-known/x402.json - https://txguard.schemasure.com/.well-known/pricing.json - https://txguard.schemasure.com/.well-known/benchmarks.json - https://txguard.schemasure.com/.well-known/data-handling.json - https://txguard.schemasure.com/apis.json - https://txguard.schemasure.com/SKILL.md