Verify a payment yourself
Check a verdict and a payment from the chain alone, without the Intented API or web app.
Every payment leaves an execute transaction on NEAR. Its arguments carry the exact request, the exact response and NEAR AI's signature, so anyone can check a verdict without trusting the Intented API or web app.
With check-tx
check-tx reads one execute transaction and the wallet's get_config from NEAR's public archival RPC. From execute's own arguments it recomputes the text NEAR AI signed, recovers the signer, checks it against the wallet's allowlist, and prints the model's signed answer, how execute ended and the token transfers it made.
git clone https://github.com/furqaannabi/intented && cd intented/agent && pnpm install
pnpm check-tx intented-wallet.testnet C8P7yHvwT6e6C5LZLgXQ4uXDJwyoCDGX6Y7Vq5uvbtHHsigned text Qwen/Qwen3.8-27B:0d075e0e…c064:32f07d31…6256
signer 0x835ab53d20294ef795906dff21ae4c045336aa26 (on intented-wallet.testnet's allowlist: 0x835ab53d20294ef795906dff21ae4c045336aa26)
verdict ALLOW: The action transfers 0.001 wNEAR to intended-vendor.testnet, which exactly matches the mandate's recipient, token, and amount limit.
execute succeeded
transfer 1000000000000000000000 of wrap.testnet, intented-wallet.testnet → intented-vendor.testnetA refused attack:
pnpm check-tx retest-1105.intented.testnet G9z8XBq486PEMDHD2EDZYQSz7Fxop3M9iNJrDgi5jmPsverdict DENY: The mandate restricts payments to 'intented-vendor.testnet', but the action sends funds to 'intented-attacker.testnet'. …
execute refused: Smart contract panicked: verdict is not ALLOW
transfer noneThe network follows the wallet's name: .near is mainnet. NEAR_RPC_URL overrides the RPC.
By hand
- Open the
executetransaction on nearblocks. Its arguments areproposal_id,req_bytes,resp_bytes(both base64) andsig_65. - Recompute the signed text:
<model_id>:<sha256(req_bytes)>:<sha256(resp_bytes)>, withmodel_idfrom the wallet'sget_configand the hashes as lowercase hex over the decoded bytes. - Recover the signer from
sig_65over that text as an EIP-191 message, for example with ethers'verifyMessage(text, sig_65). - Compare it with
signersinget_config. - Read the verdict inside
resp_bytes:choices[0].message.contentis the JSON{ reason, verdict, action }. - Check the rules:
mandate_hashinget_configis the sha256 of the rules text. Hash the text from the web app's Rules page, or fromGET /api/mandates/{hash}, and compare.
The signer itself
The signer's attestation report, an Intel TDX quote and NVIDIA's GPU attestation, was verified off-chain before the owner allowlisted it. Reports are published in docs/attestations/. The contract doesn't verify the TDX quote itself; see the trust model.