Checking the public evidence

Verifiable Agent Commerce

Businesses need to know who authorized an agent’s purchase, what the customer allowed, and whether the payment followed those terms. Dexter connects customer identity, signed authorization and payment enforcement in one verifiable record.

With the customer’s permission, a seller or lender can verify private identity evidence without making that information public.

Identity stays privateWhy?

The public link checks the approval, payments and refusals. The owner’s name needs the original private sharing link and stays hidden until you choose to reveal it.

This demonstration records Claude’s purchases and attempts to pay outside the customer’s authorization. Your browser is checking the evidence.

Dexter ran this controlled demonstration with its own bookstore and copycat sites. These were demonstration orders; no books were delivered.

Industry Context

In October, JPMorgan, Bank of America, Citi and Schwab blocked or restricted outside AI agents from acting in customer accounts.

Six banks, Bank of America among them, have published principles calling for “auditable records to evidence consumer instructions, authentication, intent, and transaction decisions and outcomes.” These are the records of Claude's purchases.

The Customer’s Signed Authorization

The recorded authorization names Claude and Dexter Bookstore. Your browser is checking the customer’s signature and the bookstore’s payment details.

The authorization allowed $3.00 in total, with no more than $1.50 reserved for payment at a time, until Oct 30, 5:00 AM ET.

Signature verification is pending.

View the bookstore’s payment addressD21yDMWuiMZfkoaZj3t67S4hhfBfCgA4hNYuWA5i1esj

This demonstration uses USDC; $1 denotes 1 USDC.

The Purchase Record

  1. Copycat Charge Refused

    The payment program refused a charge to the copycat because the customer had authorized Claude to pay Dexter Bookstore.

    Attempted $1.00

    Transaction details

    Claude’s key and Dexter’s payment key signed the charge. The requested recipient was the copycat’s account. The program returned error 3012 (AccountNotInitialized) and moved no money.

    Inspect the refused transaction

    Checking this evidence…

  2. Claude ordered The Innovator's Dilemma

    Clayton M. Christensen

    Paid $1.00

    Order and payment records

    “Record The Innovator's Dilemma demonstration edition. No text and no shipment.”

    Claude signed the request at 2:35:14 AM ET.

    Checking this evidence…

  3. Claude ordered The Sovereign Individual

    James Dale Davidson & William Rees-Mogg

    $1.00 reserved for this order

    1. Diverted Payout Refused

      Dexter’s payment key attempted to send the reserved money to the copycat. The payment program refused the transfer.

      Attempted $1.00

    2. Paid to Dexter Bookstore

      The record links this reservation to the bookstore payment below. Its evidence is being checked.

      Paid $1.00

    Order and payment records

    Claude signed this order at 2:35:40 AM ET: “Record The Sovereign Individual demonstration edition. No text and no shipment.”

    Dexter’s payment key signed the attempted payout to the copycat’s account. The program returned error 6070 (DebtTransferMismatch) and moved no money.

    Checking this evidence…

  4. Over-Budget Payment Refused

    The program refused a $1.50 request because only $1.00 remained in the customer’s budget.

    Attempted $1.50

    Transaction details

    Claude’s key and Dexter’s payment key both signed the request. The program returned error 6013 (RevolvingCapacityExceeded) and moved no money.

    Inspect the refused transaction

    Checking this evidence…

  5. Payment After Expiry Refused

    The program refused a new $1.00 reservation after the customer’s approval expired at 5:00 AM ET.

    Attempted $1.00

    Transaction details

    Claude’s key and Dexter’s payment key both signed the request. The program returned error 6009 (SessionExpiryInPast) and moved no money.

    Inspect the refused transaction

    Checking this evidence…

The Remaining Budget

Approved total $3.00
$1.00Paid
$1.00Paid
$1.00Unspent
Claude spent $2.00 of the approved $3.00. $1.00 remained unspent when the approval expired.

Inspect the Evidence

Authorization and Outcomes
  1. Identity

    Customer: Name withheld

    The customer's passkey signed a record containing a passport-chip and face-match proof from ZKPassport.Verifier

    Agent: Dexter's signed certificate names Claude.

    Claude held its own key.

  2. Bookstore

    Approval: Before the customer approved Dexter Bookstore, its control of the receiving account was cryptographically verified.

    The customer's passkey signature committed to those verified bookstore details.Signed approval

    Outcome: Both payments went to Dexter Bookstore.

    The recipient matched the bookstore in the customer's signed authorization.

  3. Agent key

    Approval: The customer approved a separate key for Claude.

    The customer signed this approval at 2:27:37 AM with the same passkey.Signed approval

    Outcome: Claude signed both payment requests with that key.

  4. Spending limits

    Approval: The customer allowed Claude to spend up to $3.00 in total and $1.50 at a time, at Dexter Bookstore.

    The bookstore was the only approved seller.Signed approval

    Outcome: Claude's two payments spent $2.00 in total.

    Dexter Bookstore received $1.98, and Dexter received $0.02 in fees (1%).

  5. Time (ET)

    Approval: The customer's approval expired Oct 30, 5:00:00 AM.

    The customer signed it Oct 30, 2:27 AM.Signed approval

    Outcome: Claude completed both payments before expiry.

    The payments finalized between Oct 30, 2:35 AM and 2:36 AM.

  6. Orders

    Dexter Bookstore signed a receipt for each of the two book orders.

    The customer's signed terms cover Claude's key, Dexter Bookstore, the amounts and the expiry. The receipts identify the books.

Payment Enforcement
  • The customer's passkey signature covered Claude's key, the approved seller, the limits and the expiry. The payment program checked that signature before the agent could spend under those terms.

    The approvalThe payment program

  • The program checked the payout recipient against the seller in the signed approval. That restriction also applied to Dexter's payment key: its attempted diversion failed with error 6070. The approved payment included Dexter's 1% fee.

    The refused redirect

  • Before approval, the browser verified the store's signed quote and receiving-account proof against its published domain record. The customer's passkey signature committed to the checked data. The same check refuses copycats V2 and V3 for any buyer and flags V1, V4 and V5 for a buyer who already uses books.dexter.cash.

    The store's domain recordArchived recordThe approval

  • The signed record and public transactions can be checked with the standalone verifier. Its source and the program interface are public.

    Standalone verifierProgram interfacePublished record (JSON)

Accepting Independent Agents

Businesses can accept an agent’s purchase with a record of who authorized it, what they permitted, and where the money went. This demonstration lets a business inspect the signed terms, attempted violations and completed payments together.

For AI agents and other readers without a browser

Claude paid for two book orders at books.dexter.cash with its own key, under one budget a wallet's owner approved with a passkey: up to 3.00 USDC, 1.50 at a time, at one seller address, until Oct 30, 5:00:00 AM ET. Before Approve appeared, his approval screen checked the store's signed quote against dexter.cash's published file, and his passkey signature commits to that check. Solana refused a charge to a copycat's address (error 3012), a payout routed to the copycat's USDC account (error 6070), a 1.50 USDC payment with 1.00 left (error 6013) and a payment after the approval expired (error 6009), though Dexter's own payment key signed each. Every Solana transaction for these payments and refusals is listed.

Read the complete published record (JSON).

If you are reading this HTML without running JavaScript, you are reading this case's published record: the owner's passkey approval, Claude's two payments and the four transactions Solana refused, as Dexter's server read them from finalized Solana transactions, with the seller's receipts and Dexter's certificate for the agent key.

A browser can check the public approval, payments, refusals and seller evidence without the private sharing key. It reads finalized Solana transactions and checks signatures locally. The complete private sharing link also permits identity verification through ZKPassport's verifier on Ethereum. Checks are marked verified only after they succeed. The owner's name stays encrypted to that link's key and is shown only when the reader chooses to reveal it.

Approval and enforcement

  • The customer's passkey signature covered Claude's key, the approved seller, the limits and the expiry. The payment program checked that signature before the agent could spend under those terms.

    The approvalThe payment program

  • The program checked the payout recipient against the seller in the signed approval. That restriction also applied to Dexter's payment key: its attempted diversion failed with error 6070. The approved payment included Dexter's 1% fee.

    The refused redirect

  • Before approval, the browser verified the store's signed quote and receiving-account proof against its published domain record. The customer's passkey signature committed to the checked data. The same check refuses copycats V2 and V3 for any buyer and flags V1, V4 and V5 for a buyer who already uses books.dexter.cash.

    The store's domain recordArchived recordThe approval

  • The signed record and public transactions can be checked with the standalone verifier. Its source and the program interface are public.

    Standalone verifierProgram interfacePublished record (JSON)

What the program enforces

  • Only the approved agent key, basJdwTFFhkpUSRD41f96KnPmkVJqZuUPtYGB649kEF, can sign payments under this approval.
  • Only the approved seller address, D21yDMWuiMZfkoaZj3t67S4hhfBfCgA4hNYuWA5i1esj, can be paid, apart from Dexter's fee to its fee account, TabsikY2gKPbtLyg5WLExwpDjc4sdfnkQSBu5JZmqsG, which received each payment's 1% fee.
  • No payment above 1.50 USDC, and no more than 3.00 USDC in total.
  • No payment can be reserved after Oct 30, 5:00:00 AM ET (program error 6009, SessionExpiryInPast).
  • No payment to an address the owner had not approved: a charge to the copycat's address, carrying Claude's signature and Dexter's, failed with error 3012, AccountNotInitialized, because no permission existed for that address.
  • A reserved payment pays only the store's account named in the locked payment, apart from Dexter's fee (1% on these payments): routing it to the copycat's USDC account, with Dexter's payment key signing, failed with error 6070, DebtTransferMismatch. The same reservation then paid the store: purchase 2, The Sovereign Individual, at 2:36:53 AM ET; that payment is listed with its purchase below.
  • Today a Dexter key can upgrade the vault program; that authority is temporary, and Dexter's plan moves it to a two-of-three multisig with one signer outside Dexter and a time delay longer than the payment settlement window, and then removes the upgrade authority entirely once the program is final.
  • These limits bind every signer, Dexter's own payment key included: the refused payment below carries Claude's signed request and Dexter's signature, and the program refused it with error 6013, RevolvingCapacityExceeded. No money moved.

The seller check

The store's quote key and receiving address are published on its own website, in https://dexter.cash/.well-known/did.json. Before Approve appeared, the owner's approval screen fetched that file, checked the store's signed quote for The Innovator's Dilemma against it (the key did:web:dexter.cash#books-quote-1 is listed, the quote names this seller address, and the address carries its own signature proving control), and recorded what it checked. The last 32 bytes of the 200-byte challenge his passkey signed in the approval transaction, from offset 168, are a salted fingerprint of that record: 745db66d64da3918a0a3cae8d6d3d693cc3084aaefb429461da050d7b4c04adf. sellerBindingNonce in @dexterai/x402/seller computes it as SHA-256 over the text DEXTER_SELLER_BINDING_V1, then the 32 bytes of the record's own SHA-256 (9ad25a29d13b991086fd59eb439a90e8eec631f9a8025f6ed0dc2cabc32380ed), then the 32 bytes of the salt (VQ33k9lDCRkeNXJvpzgBaECmZNH0ziTaeQKFoBavLM4 in base64url). The published JSON carries that check record as seller.binding (base64url; the hash is of its decoded bytes) and the salt as seller.salt. Solana stores the fingerprint; it does not check the store at payment. The check uses no Dexter registry, signature or permission for the store's key or addresses. Which store he already uses comes only from his own approvals, and the copycat reruns below use this approval of books.dexter.cash. An Internet Archive copy of the file, captured Oct 29, 10:55:33 PM ET: https://web.archive.org/web/20261030025533id_/https://dexter.cash/.well-known/did.json.

Copycats, each saved with the exact files the check fetched, rerun by a browser at their recorded times:

  • V1, copycat address FRLf4qg2xEHRWXv1DrujbqxqUXzxsgAs6tcPkTUZRHH2: "Dexter Bookstore" at dexter-bookstore.pages.dev, signed by its own site. Flagged with a notice naming books.dexter.cash, for a buyer who already uses the store (R4 lookalike_name).
  • V2, copycat address FRLf4qg2xEHRWXv1DrujbqxqUXzxsgAs6tcPkTUZRHH2: Claims books.dexter.cash and signs with a key dexter.cash's file does not list. Refused for any buyer (R1 kid_not_listed).
  • V3, copycat address FRLf4qg2xEHRWXv1DrujbqxqUXzxsgAs6tcPkTUZRHH2: The store's real quote, with another payout address. Refused for any buyer (R2 payto_mismatch).
  • V4, copycat address FRLf4qg2xEHRWXv1DrujbqxqUXzxsgAs6tcPkTUZRHH2: No signature; its request named "Dexter Bookstore". Flagged with a notice naming books.dexter.cash, for a buyer who already uses the store (R4 lookalike_name).
  • V5, copycat address FRLf4qg2xEHRWXv1DrujbqxqUXzxsgAs6tcPkTUZRHH2: Claims books.dexter.cash, no signature, another payout address. Flagged with a notice naming books.dexter.cash, for a buyer who already uses the store (R5 unsigned_known_host).

Claude's key never had permission to pay the copycat's address: every transaction for that address's permission account up to Claude's attempt failed. At first contact, a buyer with no history sees the copycat's true web address and “First payment to this website”, with Approve available.

The store and every copycat are Dexter's, in a demonstration by Dexter's founder.

What a browser checks

  1. The owner's passkey signed the approval. Solana's secp256r1 program checks the passkey signature in the approval transaction, and the browser reads its terms: the agent key, the seller address, the 3.00 USDC total, 1.50 USDC at a time and the expiry.
  2. With the private sharing link: the same passkey signed the owner's identity record: a zero-knowledge proof of his passport chip with a strict face match through ZKPassport, checked with ZKPassport's verifier on Ethereum using chain state at the identity anchor.
  3. Each of the two payments: Dexter's reservation, the agent key's Ed25519 signature on the payment voucher, the lock, the USDC transfer to the seller with Dexter's 1% fee, and the bookstore's receipt for that order.
  4. Each budget or expiry refusal: the failed transaction, the program's error, Claude's signed request inside it, and the capacity left at that slot.
  5. The seller check: the record's fingerprint recomputed and compared with the bytes in the approval's passkey challenge, the saved store file's hash, the quote's signature under the listed key, the listed address and its control signature, each book receipt signed by the store's key, each copycat rerun, the copycat address history, and both refused redirects.
  6. Dexter's signed certificate for the agent key (ES256, keys at https://api.dexter.cash/.well-known/jwks.json), which names Claude and records how its key was held. The custody record is Dexter's attestation. Claude ran on a server Dexter operates.
  7. Altered copies of this record fail the same checks: another seller address, another agent key and an amount above the limit. Historical checks use the original finalized transactions; replay simulation is not run, and no transaction is sent.

Transactions on Solana mainnet

Program Hg3wRaydFtJhYrdvYrKECacpJYDsC9Px7yKmpncj2fhc. Any full-history Solana RPC node returns each transaction with getTransaction; explorers such as Solscan open them in a browser.

  • The owner's passkey signs his identity record 5gUnH9ittvEny4BzhQZb3nbBze4sWwG5Soff7whHgAJGeKKtZWQT1PCytFXHM59YKLnwEQ1yn1RvanUdP7JtnF8T
  • The owner's passkey approves the agent key and the budget, Oct 30, 2:27:37 AM ET 2vWcs5iPRHqoTHBrtKiSWjriYUWf7DHpWZPUPYbZFCem3WhhBkW9weBA9JvSg9h1ZNWjM7dPSReFQHcKe1xj9P6F
  • Purchase 1: The Innovator's Dilemma, Clayton M. Christensen, 1.00 USDC (0.99 to the seller, 0.01 fee). A demonstration order. Claude's reason: “Record The Innovator's Dilemma demonstration edition. No text and no shipment.”
    • Dexter's reservation 47TPLbQ8F1QGppaNpVks2gv1uYG8H5jY9qFy8g5ScvzQ1fSxQSn7nuTZnhjASsCeSKrsd7bxDtQRLZ8Aj9VmzT6H
    • Claude's signature, checked on Solana, Oct 30, 2:35:14 AM ET 4n8NojSQM9vEuvpSPdPtfoUq2KvAQaxdPdwGKUaRNj5dr8gXmX7s1rMhxgGvUw6j6q786iQF6RZRbwL4WLd8X1Yg
    • The payment, Oct 30, 2:35:26 AM ET 2hJBKx3GqFHPEsjGQNBNjTAdLd2S121KSNxzccVupjfGxywbFscozePwVY6SPwe95JgicywY6LzNwhJwrY5tJV7d
    • The bookstore's receipt bookstore:8efd0ed283d062f8946a0c9b183621333a4d19ced00db9d1b97162d90b872ffd
  • Purchase 2: The Sovereign Individual, James Dale Davidson & William Rees-Mogg, 1.00 USDC (0.99 to the seller, 0.01 fee). A demonstration order. Claude's reason: “Record The Sovereign Individual demonstration edition. No text and no shipment.”
    • Dexter's reservation 52HpZsfuaac9vaxsey6qrnAutxxS3cddFGyiaHsw3DieEaRNJ9xmDBYRCKwuXGCE5u8838pA8jLZ4ki2vLk8Pg7u
    • Claude's signature, checked on Solana, Oct 30, 2:35:40 AM ET 2dYig3jWweXNTA517WhTbTZZKfCandALMWQ94FrJ3TmThLm2mQ8nxrHCzV4g7qLqfvho8K6edfEeCfiFWwdCLAtJ
    • The payment, Oct 30, 2:36:53 AM ET QNb41FGAxugzUWaWiKjj8vsouA2sLngHVftaXuycR4JmBxMg5CetYmUGVwmymuo7hCF3P3h8DkSmKXJkg96eN8h
    • The bookstore's receipt bookstore:e8a68de617f74b324a51ce874356c37f8f00b32c056574cc275584da1cce36d2
  • Refused: a 1.00 USDC charge to the copycat's address, error 3012 AccountNotInitialized, Oct 30, 2:32:06 AM ET 4GAMqg1P86Vj9VCkHvrrsVegzkwKxiWC2GojAN9z4mQjiKn3eFuCmihPf12t3xobVJPeLVc9WwqRx5J8D4KHbe7e Program log: AnchorError caused by account: session. Error Code: AccountNotInitialized. Error Number: 3012. Error Message: The program expected this account to be already initialized.
  • Refused: a reserved 1.00 USDC routed to the copycat's USDC account, error 6070 DebtTransferMismatch, Oct 30, 2:35:53 AM ET 4MMw5EVLvGK6yQBrGUWRJxNH4LudxFkZRcKdkayUUxxpjzLMPHnE8Z9QjBD6U8niYuNn5yxjR99Q9XHPn5DLFxXg Program log: AnchorError thrown in programs/dexter-vault/src/instructions/settle_locked_voucher.rs:207. Error Code: DebtTransferMismatch. Error Number: 6070. Error Message: Debt-transfer amounts do not reconcile.
  • Refused: 1.50 USDC with 1.00 left, error 6013 RevolvingCapacityExceeded, Oct 30, 2:37:09 AM ET 4g3gekW1RySoGHvPWY1jAvgRku3QV8qPzLeg9roau3M9kBpHwvc67hs1EuSuXyyVveF6RjYP4sFmv6qXjva84krK Program log: AnchorError thrown in programs/dexter-vault/src/instructions/settle_voucher.rs:108. Error Code: RevolvingCapacityExceeded. Error Number: 6013. Error Message: Opening this tab would exceed the session's revolving capacity.
  • Refused: 1.00 USDC after the approval expired, error 6009 SessionExpiryInPast, Oct 30, 5:01:07 AM ET 54mYrWvYsMqvDz5GMh2rPrQNZcBfyF3gbANPCUgRdpegdAi7R6PQRnR3MEA1RgdrYTiQKCFJe4yJxDuZ8yipKdqz Program log: AnchorError thrown in programs/dexter-vault/src/instructions/settle_voucher.rs:95. Error Code: SessionExpiryInPast. Error Number: 6009. Error Message: Session expiry must be in the future.

Addresses

  • Owner's wallet 3NWeBKnPPxAZZYqytNVgb29gqNDmaRdGMQuD5LrQR9Ke
  • Owner's vault H6YGwccDRcjtaRFgCfaa5tWxFC1fkMjQWJRtCmXnMuJr
  • Claude's key basJdwTFFhkpUSRD41f96KnPmkVJqZuUPtYGB649kEF
  • Seller, books.dexter.cash D21yDMWuiMZfkoaZj3t67S4hhfBfCgA4hNYuWA5i1esj
  • The approval's session account 4ULzdi6RAknd7xhfpwHJyBLTZXkQ1SH8P37YAhLvb7Vs
  • USDC mint EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

The record

The published record as JSON: https://api.dexter.cash/api/public/mandate-cases/b0ee0521-898e-828b-9c14-265bfb59216c/published. The owner published it, and it stays public until he revokes it.

Owner-approved payments on Solana
Customer-Approved Agent Payments | Dexter