Skip to main content
Glama

Read the transaction you are about to sign

inspect_payment
Read-onlyIdempotent

Call this with the CALLDATA you are about to sign, before you sign it. Every other check here asks whether an address is worth dealing with; this asks whether the transaction is the one you think it is, and the two catch different losses. No amount of reputation makes the recipient in the bytes match the recipient on your screen, and a spotless counterparty record says nothing about an UNLIMITED APPROVAL granted to it, which is not a payment at all but a standing permission that outlives the transaction. It reads three calls — transferWithAuthorization, approve, transfer — and REFUSES to guess at any other: decoding unknown calldata without the ABI means guessing where each argument begins, and a confident wrong answer about where money goes is worse than none. Amounts are atomic units, never dollars, because the token owns its decimals. Free, needs no key, stores nothing.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
toNoThe contract being called, where you know it. On an ERC-20 payment this IS the token: the calldata carries a recipient and an amount and never the asset, so without `to` there is nothing to compare the endpoint’s quoted asset against.
dataNoThe calldata, 0x-prefixed. Without it nothing about the transaction is read, and the answer says so rather than passing.
expectNoWhat you believe you are doing. Anything you leave out is not compared, and is reported as not compared rather than as agreeing.
resourceNoThe http(s) URL of the endpoint you are paying, where there is one. Send it and the answer also compares the bytes with the amount and the payee that endpoint demanded in its own 402 — the check that catches a transaction which is exactly what you meant and is not what the seller asked for.
refreshQuoteNoKnock on `resource` NOW instead of comparing against a stored reading, and set what comes back against the reading it replaced. `againstEndpoint.refreshed.quoteStillMatches` is true, false, or null where the two cannot be compared, with `verdict` as match/changed/unknown and `differs` naming which of amount, asset, network or payee moved. A CHANGED PAYEE is the substitution this whole check exists to catch. Only for an endpoint already in the x402 catalogue we read — we do not fetch a URL because a request named it — and at most one live handshake a minute per resource, shared by every caller. A match is what the endpoint said a moment ago, not a promise about the next moment.
maxQuoteAgeSecondsNoHow old a quote you are willing to act on, in seconds. YOURS, not ours: four hours is alarming for a market quote and irrelevant for a tariff unchanged since March, so a threshold published here would be a number we invented wearing the clothes of a measurement. The answer comes back as `againstEndpoint.standing.freshness` — `within-your-limit` or `older-than-your-limit` — with `freshEnough` as the boolean and your limit echoed back. Without it the answer says `no-limit-given` rather than grading the age.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
callNoWhat the bytes actually are, or null where it is not a call this decodes.
limitsNoWhat decoding a payment establishes. It reads what the transaction SAYS it will do; it does not simulate it and cannot tell you the recipient is honest.
spenderNoWho would be allowed to move your tokens later. Only an approve() has one, and an approve() has nothing else.
verdictYes`read` means every comparison you asked for agreed. `mismatch` means at least one did not. `undecodable` means the call is not one this reads and NOTHING was checked — it is not a pass.
findingsYesOne per check, each carrying whether it ran: observation, mismatch, or unknown.
selectorNoThe four-byte function selector the calldata begins with, where we could read one. Null means the payload is not a call we can decode, which is not evidence that it is bad.
recipientNoWho RECEIVES the money. Null on an approve(), which pays nobody: branch on this rather than on the prose.
amountAtomicNoAtomic units, as a decimal string. The token owns its decimals and this does not apply them.
actualTransferNoWhether tokens move in THIS transaction. False for an approval, where the amount is a ceiling on what somebody else may take later rather than a sum leaving now.
againstEndpointNoSENT `resource`? THEN THIS COMPARES THE BYTES WITH WHAT THE ENDPOINT ITSELF IS DEMANDING, which is the one thing `expect` cannot catch: bytes that are exactly what you meant and are not what the seller is asking for. `amount` is `exact-match`, `below-quote`, `above-quote` or `unknown`, in BASE UNITS with no scaling and only where the token the call is made against is the token the quote prices in. **`below-quote` is the expensive one**: the call is refused and the tokens have left. `payee` is `matches`, `differs` or `unknown` against the address the 402 named, and it reads the approved SPENDER on an approval, which pays nobody. `asked: false` means we have never probed that endpoint, which is our gap and not evidence about it. `verdict` above is UNCHANGED by any of this — that is the manifest against YOUR expectation, and the two questions are kept apart on purpose.
unlimitedAllowanceNoTrue where this grants permission to move every token of this kind you will ever hold.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedInput schema / properties / maxQuoteAgeSeconds
      Added value: +{
      +  "description": "How old a quote you are willing to act on, in seconds. YOURS, not ours: four hours is alarming for a market quote and irrelevant for a tariff unchanged since March, so a threshold published here would be a number we invented wearing the clothes of a measurement. The answer comes back as `againstEndpoint.standing.freshness` — `within-your-limit` or `older-than-your-limit` — with `freshEnough` as the boolean and your limit echoed back. Without it the answer says `no-limit-given` rather than grading the age.",
      +  "type": "number"
      +}
    • addedInput schema / properties / refreshQuote
      Added value: +{
      +  "description": "Knock on `resource` NOW instead of comparing against a stored reading, and set what comes back against the reading it replaced. `againstEndpoint.refreshed.quoteStillMatches` is true, false, or null where the two cannot be compared, with `verdict` as match/changed/unknown and `differs` naming which of amount, asset, network or payee moved. A CHANGED PAYEE is the substitution this whole check exists to catch. Only for an endpoint already in the x402 catalogue we read — we do not fetch a URL because a request named it — and at most one live handshake a minute per resource, shared by every caller. A match is what the endpoint said a moment ago, not a promise about the next moment.",
      +  "type": "boolean"
      +}
  2. Changed3 schema fields changed
    • addedInput schema / properties / resource
      Added value: +{
      +  "description": "The http(s) URL of the endpoint you are paying, where there is one. Send it and the answer also compares the bytes with the amount and the payee that endpoint demanded in its own 402 — the check that catches a transaction which is exactly what you meant and is not what the seller asked for.",
      +  "type": "string"
      +}
    • changedInput schema / properties / to / description
      Previous value: -"The contract being called, where you know it."New value: +"The contract being called, where you know it. On an ERC-20 payment this IS the token: the calldata carries a recipient and an amount and never the asset, so without `to` there is nothing to compare the endpoint’s quoted asset against."
    • addedOutput schema / properties / againstEndpoint
      Added value: +{
      +  "description": "SENT `resource`? THEN THIS COMPARES THE BYTES WITH WHAT THE ENDPOINT ITSELF IS DEMANDING, which is the one thing `expect` cannot catch: bytes that are exactly what you meant and are not what the seller is asking for. `amount` is `exact-match`, `below-quote`, `above-quote` or `unknown`, in BASE UNITS with no scaling and only where the token the call is made against is the token the quote prices in. **`below-quote` is the expensive one**: the call is refused and the tokens have left. `payee` is `matches`, `differs` or `unknown` against the address the 402 named, and it reads the approved SPENDER on an approval, which pays nobody. `asked: false` means we have never probed that endpoint, which is our gap and not evidence about it. `verdict` above is UNCHANGED by any of this — that is the manifest against YOUR expectation, and the two questions are kept apart on purpose.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  3. Changed3 schema fields changed
    • addedOutput schema / properties / actualTransfer
      Added value: +{
      +  "description": "Whether tokens move in THIS transaction. False for an approval, where the amount is a ceiling on what somebody else may take later rather than a sum leaving now.",
      +  "type": "boolean"
      +}
    • changedOutput schema / properties / recipient / description
      Previous value: -"Who the bytes pay, read from the payload rather than from a label."New value: +"Who RECEIVES the money. Null on an approve(), which pays nobody: branch on this rather than on the prose."
    • addedOutput schema / properties / spender
      Added value: +{
      +  "description": "Who would be allowed to move your tokens later. Only an approve() has one, and an approve() has nothing else.",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
  4. Changed2 schema fields changed
    • addedOutput schema / properties / limits / description
      Added value: +"What decoding a payment establishes. It reads what the transaction SAYS it will do; it does not simulate it and cannot tell you the recipient is honest."
    • addedOutput schema / properties / selector / description
      Added value: +"The four-byte function selector the calldata begins with, where we could read one. Null means the payload is not a call we can decode, which is not evidence that it is bad."
  5. Added

TDQS

Score is being calculated.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources