<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Douglas Borthwick</title>
    <description>The latest articles on DEV Community by Douglas Borthwick (@douglasborthwickcrypto).</description>
    <link>https://dev.to/douglasborthwickcrypto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3790350%2Faa27cd63-7a48-41a3-8d98-459bfecf44fa.png</url>
      <title>DEV Community: Douglas Borthwick</title>
      <link>https://dev.to/douglasborthwickcrypto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/douglasborthwickcrypto"/>
    <language>en</language>
    <item>
      <title>Would You Trust Your Agent? KYA Is Real.</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Fri, 10 Apr 2026 13:59:16 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/would-you-trust-your-agent-kya-is-real-1ppl</link>
      <guid>https://dev.to/douglasborthwickcrypto/would-you-trust-your-agent-kya-is-real-1ppl</guid>
      <description>&lt;p&gt;Everyone is deploying AI agents. Almost no one is verifying them. And those agents are already moving money. You wouldn't hand your wallet to a stranger. KYA, Know Your Agent, is real, and the speed at which the ecosystem is converging on it is the proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  The convergence is here
&lt;/h2&gt;

&lt;p&gt;The headlines landed in a pile this March. &lt;a href="https://www.fintechweekly.com/news/changpeng-zhao-ai-agents-crypto-payments-kimi-openclaw-march-2026" rel="noopener noreferrer"&gt;CZ declared AI agents will dominate crypto payments&lt;/a&gt;. &lt;a href="https://www.coindesk.com/tech/2026/03/15/visa-is-ready-for-ai-agents-so-is-coinbase-they-re-building-very-different-internets" rel="noopener noreferrer"&gt;Visa announced readiness for agent transactions, while Coinbase pitched a fundamentally different internet&lt;/a&gt;. &lt;a href="https://www.mastercard.com/us/en/news-and-trends/stories/2026/verifiable-intent.html" rel="noopener noreferrer"&gt;Mastercard introduced "Verifiable Intent" for autonomous commerce&lt;/a&gt;. &lt;a href="https://blockeden.xyz/blog/2026/03/16/crossmint-ai-agent-virtual-cards-autonomous-payments-kya-stripe-for-agents" rel="noopener noreferrer"&gt;Crossmint shipped agent virtual cards&lt;/a&gt;. &lt;a href="https://news.bitcoin.com/moonpay-launches-open-wallet-standard-to-unify-ai-agent-payments/" rel="noopener noreferrer"&gt;MoonPay launched an Open Wallet Standard&lt;/a&gt;. Coinbase's x402 protocol and Stripe MPP are &lt;a href="https://workos.com/blog/x402-vs-stripe-mpp-how-to-choose-payment-infrastructure-for-ai-agents-and-mcp-tools-in-2026" rel="noopener noreferrer"&gt;already being compared head-to-head&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Every one of these is a payment rail. None of them check whether the agent should be trusted before money moves. That is the gap KYA fills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The rails are here. The trust layer isn't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can authenticate an agent. You can resolve its DID. You can confirm the public key it signs with. None of that tells you whether the agent's wallet still holds the funds it claimed yesterday. None of it tells you whether the source code was compromised in last week's dependency update. None of it tells you whether the operator's delegation has expired, whether the counterparty has been added to a sanctions list, whether the agent has actually delivered on past commitments, or whether the reasoning chain that led to its current action is sound.&lt;/p&gt;

&lt;h2&gt;
  
  
  The nine dimensions of agent trust
&lt;/h2&gt;

&lt;p&gt;Each dimension is answered by an independent issuer in the open multi-attestation spec at &lt;a href="https://github.com/douglasborthwick-crypto/insumer-examples/issues/1" rel="noopener noreferrer"&gt;insumer-examples #1&lt;/a&gt;, with a JWKS endpoint anyone can verify offline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wallet state.&lt;/strong&gt; What does this agent's wallet hold right now? Token balances, NFTs, staking positions, DeFi activity, governance participation, across 33 blockchains. Provider: InsumerAPI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance risk.&lt;/strong&gt; Is the counterparty on a sanctions list? OFAC, EU, and UN screening, plus domain hygiene and IP reputation. Provider: Revettr.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Identity verification.&lt;/strong&gt; Who actually controls this agent? DID resolution, delegation chains, interaction patterns, completion ratios. Provider: AgentID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security posture.&lt;/strong&gt; Has the agent's source code been scanned for vulnerabilities, secrets, and unsafe patterns? Provider: AgentGraph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Governance.&lt;/strong&gt; Is the agent operating within an authorized delegation chain? Principal identity, policy compliance, spending limits, full chain of custody. Provider: APS (Agent Passport System).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job performance.&lt;/strong&gt; Has the agent actually delivered quality work in the past? Task completion rates, accuracy metrics, performance history. Provider: Maiat.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settlement history.&lt;/strong&gt; Has the agent followed through on past commitments? Operation binding, delivery verification, settlement witness receipts. Provider: SAR.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral trust.&lt;/strong&gt; Is the agent's wallet a coordinated bot or a real entity? Signal depth and risk intensity, sybil detection across 12 EVM chains and Solana. Provider: RNWY.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reasoning integrity.&lt;/strong&gt; Is the agent's decision chain sound? Adversarial multi-model critique, logical consistency, temporal freshness. Provider: ThoughtProof.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nine dimensions, nine independent providers, nine signed attestations. No single provider sees all of them. No central authority makes the trust call. The consumer trusts no one and verifies everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity is one dimension. Trust is nine.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The momentum is the proof
&lt;/h2&gt;

&lt;p&gt;Building one trust dimension is hard. Building nine in coordination is harder. Getting nine independent companies to agree on a single envelope format and start populating it with real signed attestations is the kind of thing standards bodies usually take years to do.&lt;/p&gt;

&lt;p&gt;The open multi-attestation spec opened in March. Three weeks ago we wrote about &lt;a href="https://insumermodel.com/blog/multi-attestation-four-issuers-one-verification-pass.html" rel="noopener noreferrer"&gt;four issuers in one verification pass&lt;/a&gt;. Today the count is nine issuers in the envelope and five with shipped wallet binding. Each of the five accepts a wallet address as input and returns an attestation about that specific wallet, signed against their published JWKS. The remaining four cover their dimensions through different integration paths and are converging on wallet integration through bilateral interop work. All nine are live. All nine sign attestations. All nine are consumed by a single orchestrator behind one API call.&lt;/p&gt;

&lt;p&gt;That convergence speed is not coincidence. It is the demand signal. Nine independent companies do not build around the same wire format in 30 days unless the market is asking for it loudly. KYA is real because the people building it are racing to ship it.&lt;/p&gt;

&lt;p&gt;And the production reality is already ahead of the discussion. &lt;a href="https://insumermodel.com/blog/asterpay-kya-erc8183-attestation-integration.html" rel="noopener noreferrer"&gt;AsterPay's KYA Hook&lt;/a&gt; runs in production for ERC-8183 agentic commerce today, with InsumerAPI feeding 4 of 7 trust score dimensions through cryptographic attestations. Manual KYB replaced with signed signals, one API call, no human review when the wallet qualifies. KYA is not a thought experiment. It is a shipping product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where each issuer stands today
&lt;/h2&gt;

&lt;p&gt;Five of the nine ship signed wallet binding directly: InsumerAPI, Revettr, AgentID, AgentGraph, and APS. Each accepts a wallet address as input and returns an attestation about that specific wallet. The other four serve their dimension through complementary paths:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maiat&lt;/strong&gt; ships wallet acceptance via a long-standing &lt;code&gt;?address=&lt;/code&gt; parameter and falls back to a reference identity when the wallet has no Maiat job history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SAR&lt;/strong&gt; accepts the wallet via an envelope-level &lt;code&gt;counterparty&lt;/code&gt; field, surfaced in the response but not yet bound into the signed payload.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RNWY's&lt;/strong&gt; behavioral trust model is keyed to canonical agent IDs from major registries (ERC-8004, Olas, Virtuals), with bilateral interop in progress with AgentGraph for cross-provider lookup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ThoughtProof's&lt;/strong&gt; reasoning verification is wallet-agnostic by design. Its attestation surface is the reasoning chain for a specific tool call, which is a property of the action, not the actor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The runtime ratio for any individual agent depends on whether that specific agent is registered with each issuer. The spec coverage is solid: nine independent providers, all coordinating around a single open envelope, all signing JWKS-verifiable attestations today.&lt;/p&gt;

&lt;h2&gt;
  
  
  One API call
&lt;/h2&gt;

&lt;p&gt;Asking nine independent questions about an agent could mean nine integrations, nine API keys, nine retry policies. That is not how it works. The multi-attestation spec defines a single envelope format that lets all nine issuers respond in parallel. One call in. Nine signed attestations out. Every signature verifiable offline against each issuer's published JWKS, with no callback to the orchestrator at verification time.&lt;/p&gt;

&lt;p&gt;The orchestrator code is open source. Both files use only Node built-ins (&lt;code&gt;crypto&lt;/code&gt; and &lt;code&gt;https&lt;/code&gt; from the standard library, no external imports):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/douglasborthwick-crypto/insumer-examples/blob/main/wallet-resolve.js" rel="noopener noreferrer"&gt;&lt;code&gt;wallet-resolve.js&lt;/code&gt;&lt;/a&gt; takes a wallet address and fans out to the nine issuers in parallel&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/douglasborthwick-crypto/insumer-examples/blob/main/multi-attest-verify.js" rel="noopener noreferrer"&gt;&lt;code&gt;multi-attest-verify.js&lt;/code&gt;&lt;/a&gt; verifies each signed payload against the right JWKS&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the consumer side taught the spec
&lt;/h2&gt;

&lt;p&gt;Wiring nine issuers behind a single orchestrator surfaces a pattern that the current schema does not capture: &lt;strong&gt;whether an attestation actually evaluated the wallet you sent is consumer-relevant metadata&lt;/strong&gt;. From the consumer's perspective, all three states (wallet-bound, envelope-acknowledged, reference data) look identical at the signature layer. A valid JWS from a known issuer with a known kid resolving against a known JWKS endpoint. That is not enough to make a trust decision.&lt;/p&gt;

&lt;p&gt;The proposal we posted to &lt;a href="https://github.com/a2aproject/A2A/issues/1628" rel="noopener noreferrer"&gt;A2A #1628&lt;/a&gt; is a &lt;code&gt;subject_binding&lt;/code&gt; field on each signal entry, with three states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;wallet_bound&lt;/code&gt;: the issuer evaluated the wallet you sent and signed the result over it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wallet_acknowledged&lt;/code&gt;: the wallet flowed through the response envelope but the signature does not bind it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reference&lt;/code&gt;: the issuer returned data not specific to the wallet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consumers can then weight wallet-bound dimensions highest, treat acknowledged ones as informational, and aggregate reference attestations as background context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it on a wallet
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://skyemeta.com/skyeprofile/" rel="noopener noreferrer"&gt;SkyeProfile&lt;/a&gt; is the live consumer of the multi-attestation spec. (For the architectural deep-dive on how the orchestrator dispatches nine specialists in parallel, see &lt;a href="https://insumermodel.com/blog/what-is-skyeprofile-wallet-trust-orchestration.html" rel="noopener noreferrer"&gt;What Is SkyeProfile?&lt;/a&gt;.) Each dimension card on the page shows a binding badge so the consumer can weight signals correctly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Green ("Your Wallet").&lt;/strong&gt; The issuer signed an attestation about the specific wallet you submitted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amber ("Acknowledged").&lt;/strong&gt; The wallet flowed through the response envelope but the signature does not bind it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gray ("Spec Demo").&lt;/strong&gt; The issuer returned reference data, either because they have no entry for your wallet or because their integration uses a non-wallet identifier.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The page renders Vitalik's wallet on load as the canonical reference. Vitalik is not registered with any of the agent issuers, so the visible ratio is two wallet-bound, one acknowledged, six spec demo. Below the reference, a user-input form takes any EVM or Solana wallet you paste and computes the live ratio for that specific address. If you have a wallet for an agent you actually want to evaluate, paste it. Each card with a registered binding flips from gray to green in real time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters
&lt;/h2&gt;

&lt;p&gt;Most discussions of agent trust focus on identity. Who is the agent. What credentials does it have. What does its DID look like. Identity is necessary but it is not sufficient. An agent with a verified identity can still drain its wallet, fail its delegation check, get sanctioned, run compromised code, or under-deliver on what it was paid for. Identity tells you the agent's name. KYA tells you whether the agent should be trusted right now.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://insumermodel.com/blog/ai-agents-wallet-trust-profiles-drift-exploit.html" rel="noopener noreferrer"&gt;Drift Protocol exploit&lt;/a&gt; on March 31 is the cleanest recent illustration of what happens when the trust layer is missing entirely. Two hundred and eighty-six million dollars moved in twelve minutes because signers had no way to verify counterparty trust before approving transactions. KYA would not have auto-prevented Drift. KYA is a check primitive, not a tripwire. But the layer that would have given Drift's signers the data to make a different decision is the layer that did not exist. KYA is that layer.&lt;/p&gt;

&lt;p&gt;The composability primitive is no longer theoretical. It is running in production today, against real agent wallets, with the open multi-attestation spec converging in real time. Nine independent issuers, one envelope format, one API call, every signature verifiable offline.&lt;/p&gt;

&lt;p&gt;Payments are getting faster. Trust isn't. That is the gap. Before you trust an agent with anything that matters, run the full check.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Quantum Breaks Static Credentials. Wallet Auth Was Never Static.</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Thu, 09 Apr 2026 19:03:13 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/quantum-breaks-static-credentials-wallet-auth-was-never-static-4i8b</link>
      <guid>https://dev.to/douglasborthwickcrypto/quantum-breaks-static-credentials-wallet-auth-was-never-static-4i8b</guid>
      <description>&lt;p&gt;A Nobel Prize-winning physicist warned this week that Bitcoin could be among the earliest real-world targets of quantum computing. Google published research showing that fewer than 500,000 qubits could derive a private key from a public key in under nine minutes. The Bitcoin community is debating BIP 360, a hard fork to hide public keys behind Merkle roots. The Federal Reserve published a paper on "harvest now, decrypt later" attacks against blockchain networks. The quantum threat is no longer theoretical. But the vulnerability it exploits is not new. It is the oldest assumption in digital security: that a single, long-lived cryptographic secret can protect everything, forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  What quantum actually threatens
&lt;/h2&gt;

&lt;p&gt;Every quantum attack vector against Bitcoin comes back to the same architectural assumption: one private key, held for years, protecting all funds associated with it.&lt;/p&gt;

&lt;p&gt;The specific attack works like this. When a Bitcoin transaction is broadcast, the sender's public key becomes visible in the mempool before the transaction is confirmed on-chain. A sufficiently powerful quantum computer running Shor's algorithm could derive the corresponding private key from that public key. Google's research suggests this could take roughly nine minutes. The average Bitcoin block takes ten.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That is the window.&lt;/strong&gt; Nine minutes of exposed public key, and every satoshi behind it is at risk.&lt;/p&gt;

&lt;p&gt;But the problem runs deeper than the mempool. The Federal Reserve's research on "harvest now, decrypt later" points out that every historical Bitcoin transaction with an exposed public key is permanently recorded on-chain. An adversary could record those public keys today and wait for quantum hardware to mature. Even if Bitcoin migrates to post-quantum signatures tomorrow, the old transactions are already written. The chain is immutable. The exposure is permanent.&lt;/p&gt;

&lt;p&gt;BIP 360 addresses the forward-looking problem by introducing Pay-to-Merkle-Root (P2MR), a new output type that hides the public key inside a Merkle tree until the moment of spending. BTQ Technologies implemented it on testnet in March 2026. But deploying it requires a hard fork, coordination across every exchange, hardware wallet, and node operator on the network. Adam Back, the Hashcash inventor, says the migration clock is ticking even though he believes the threat itself is still decades away. The debate is not about whether to prepare. It is about whether Bitcoin's governance can move fast enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design assumption quantum breaks
&lt;/h2&gt;

&lt;p&gt;Zoom out from Bitcoin specifically. The quantum threat is not unique to one chain or one algorithm. It is a threat to a &lt;strong&gt;design pattern&lt;/strong&gt;: systems that depend on a single, long-lived cryptographic secret as the root of all trust.&lt;/p&gt;

&lt;p&gt;Private keys. API keys. Session tokens. Passwords hashed with algorithms that will eventually fall. Any system where one secret, if compromised, unlocks everything, and where that secret must persist for months or years to remain useful.&lt;/p&gt;

&lt;p&gt;This is what makes quantum different from classical attacks. A classical attacker who steals your password gets your password. A quantum attacker who factors your public key gets your private key, which is equivalent to getting every transaction you will ever make from that address. The permanence of the secret is the vulnerability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wallet auth inverts this
&lt;/h2&gt;

&lt;p&gt;Wallet auth does not protect secrets. It eliminates them. The primitive is: read on-chain state, evaluate it against conditions, return a signed result. The result is a boolean. Did this wallet meet the condition, or not.&lt;/p&gt;

&lt;p&gt;There are three properties of this architecture that make the quantum threat structurally irrelevant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First: the attestation is ephemeral.&lt;/strong&gt; Every signed result from InsumerAPI carries a 30-minute expiration. After that, it is worthless. There is nothing to harvest. An adversary recording attestations today gains a collection of expired booleans. Compare this to a Bitcoin public key, which protects funds indefinitely. The harvest-now-decrypt-later strategy assumes the encrypted data will still be valuable when the decryption becomes possible. A boolean that says "this wallet held 100 USDC at 2:47pm on April 9th" has no exploitable value at any future date.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Second: the signing algorithm is swappable.&lt;/strong&gt; InsumerAPI currently signs attestations with ES256, an ECDSA signature on the P-256 curve. The same algorithm family that quantum threatens in Bitcoin. But there is a critical difference in how it is deployed. Verifiers check the signature against a public key published at a JWKS endpoint. To migrate to a post-quantum algorithm like ML-DSA (the NIST-standardized version of CRYSTALS-Dilithium), the change is: update the signing key, publish the new public key to the JWKS endpoint, update the algorithm identifier. Every verifier that fetches the JWKS picks up the new key automatically. No hard fork. No coordination across thousands of independent node operators. No BIP proposal. One deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Third: even a broken signature reveals nothing exploitable.&lt;/strong&gt; Suppose a quantum computer cracks the ES256 signature on an InsumerAPI attestation. What does the attacker learn? That a particular wallet met or did not meet a particular condition at a particular time. The attestation does not contain private keys. It does not contain balances. It does not contain any credential that grants access to funds. The boolean is the entire payload. Breaking the signature proves the boolean was not tampered with. It does not unlock anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static secrets break. Ephemeral proofs don't.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Continuous re-verification
&lt;/h2&gt;

&lt;p&gt;The ephemeral property becomes even more pronounced in session-based systems. Consider a multi-party agent session where every participant must prove their wallet meets on-chain conditions to enter. The session does not check once and grant permanent access. It re-verifies. Agents that no longer qualify are ejected. The session is never static.&lt;/p&gt;

&lt;p&gt;Even if an attacker cracked one attestation signature during the session window, the session has already moved on. The next re-verification produces a fresh attestation with a fresh signature. There is no single credential to target because the credential regenerates continuously from live on-chain state.&lt;/p&gt;

&lt;p&gt;This is the architectural difference. Bitcoin protects a static secret that must survive forever. Wallet auth evaluates a live condition that only needs to survive for its verification window.&lt;/p&gt;

&lt;h2&gt;
  
  
  The condition hash
&lt;/h2&gt;

&lt;p&gt;There is one more piece worth noting. Every InsumerAPI attestation includes a condition hash: a SHA-256 digest of the exact condition that was evaluated, with keys sorted canonically. This hash is embedded in the signed payload.&lt;/p&gt;

&lt;p&gt;Even if the signature algorithm were compromised, the condition hash serves as an independent tamper-detection mechanism. A verifier can reconstruct the expected condition, hash it, and compare. If the condition was altered, the hash will not match, regardless of whether the signature is valid. This is defense in depth that does not depend on any single cryptographic primitive.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters now
&lt;/h2&gt;

&lt;p&gt;The quantum timeline is debated. Estimates range from five years to twenty. Bernstein says three to five years to transition. Google is setting a 2029 internal deadline for post-quantum migration across its authentication services. NIST has finalized the post-quantum standards. Naoris Protocol launched the first Layer 1 built entirely on ML-DSA. U.S. federal agencies face an April 2026 deadline to submit their transition plans.&lt;/p&gt;

&lt;p&gt;The migration is happening. The question is how painful it will be for each system.&lt;/p&gt;

&lt;p&gt;For Bitcoin, it is a hard fork, a years-long coordination effort, and a permanent legacy of exposed historical public keys that no migration can fix.&lt;/p&gt;

&lt;p&gt;For wallet auth, it is an algorithm swap behind a JWKS endpoint. The primitive does not change. You send conditions in, you get a cryptographically verifiable result out. The verification is the same whether the signature is ECDSA or Dilithium. Read, evaluate, sign. The operation is the same. Only the signature changes.&lt;/p&gt;

&lt;p&gt;That is not quantum-resistant by accident. It is quantum-resistant by architecture. When the cryptographic ground shifts, systems built on permanent secrets have to rebuild from the foundation. Systems built on ephemeral proofs just swap the signature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quantum breaks systems built on secrets. Wallet auth was built without them.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>quantum</category>
      <category>bitcoin</category>
      <category>security</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>What Is SkyeProfile? Eight Experts, One Call, Complete Wallet Trust</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Wed, 08 Apr 2026 22:52:41 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/what-is-skyeprofile-eight-experts-one-call-complete-wallet-trust-11k6</link>
      <guid>https://dev.to/douglasborthwickcrypto/what-is-skyeprofile-eight-experts-one-call-complete-wallet-trust-11k6</guid>
      <description>&lt;p&gt;A balance check is not due diligence. Knowing a wallet holds tokens tells you almost nothing about whether it should be trusted. SkyeProfile changes the question from &lt;em&gt;what does this wallet hold?&lt;/em&gt; to &lt;em&gt;what kind of wallet is this?&lt;/em&gt; One API call dispatches eight independent specialists, each evaluating a different dimension of wallet trust, each signing their own attestation with their own cryptographic key. The result is not a score. It is a complete, verifiable, multi-dimensional trust profile. Think of it as hiring a team of experts with a single phone call.&lt;/p&gt;

&lt;h2&gt;
  
  
  The General Contractor Model
&lt;/h2&gt;

&lt;p&gt;When you build a house, you do not hire one person to do everything. You hire a general contractor. The contractor coordinates the electrician, the plumber, the structural engineer, the roofer, the HVAC specialist, and the inspector. Each one brings deep expertise in their domain. Each one signs off on their own work. The contractor does not pretend to be all of them. The contractor orchestrates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SkyeProfile is the general contractor for wallet trust.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When your system needs to decide whether to trust a wallet, SkyeProfile dispatches eight specialized providers in parallel. Each provider evaluates the wallet from their dimension of expertise. Each provider returns an independently signed attestation. SkyeProfile assembles the results into a single response. It does not generate the trust signals. It orchestrates them.&lt;/p&gt;

&lt;p&gt;The foundation underneath all of it is InsumerAPI. It provides the wallet state attestation: what the wallet holds across thirty-three blockchains, evaluated against over forty checks, returned as a cryptographically signed result. The primitive is simple: read blockchain state, evaluate conditions, sign the result. That is &lt;a href="https://insumermodel.com/blog/there-is-no-secret-condition-based-access.html" rel="noopener noreferrer"&gt;wallet auth&lt;/a&gt;. Every other dimension branches off from that foundation. The plumber needs to know the house has walls before running pipe. The identity provider needs to know the wallet exists on-chain before evaluating who controls it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Crime Scene Analogy
&lt;/h2&gt;

&lt;p&gt;Consider how investigators process a crime scene. The first officer secures the perimeter. Then the specialists arrive. A forensics team handles physical evidence. A ballistics expert examines projectiles. A medical examiner determines cause of death. A digital forensics analyst pulls data from devices. A toxicologist screens for chemicals. Each expert writes an independent report. Each expert signs their findings. No single expert sees the full picture, but the lead investigator assembles all reports into a comprehensive case file.&lt;/p&gt;

&lt;p&gt;This is exactly how SkyeProfile works. The wallet address is the scene. Each provider is a specialist. Their signed attestations are independent expert reports. SkyeProfile is the lead investigator assembling the case file. And just like a real investigation, you can verify each expert's credentials and methodology independently. You do not have to trust the lead investigator's summary. You can check the signatures yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eight experts. One call. Verifiable results.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Eight Dimensions, Eight Specialists
&lt;/h2&gt;

&lt;p&gt;Each dimension of SkyeProfile is handled by a provider that does nothing but that one thing, all day, every day. Here is the team:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wallet State&lt;/strong&gt; is the foundation. Powered by &lt;a href="https://insumermodel.com/developers/trust/" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt;, it evaluates what the wallet holds across thirty-three blockchains. Stablecoins, governance tokens, NFTs, staking positions, DeFi activity. Over forty checks. ES256-signed. This is the bedrock the other dimensions build on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Behavioral Trust&lt;/strong&gt; asks whether the wallet behaves like a real participant or a sybil. &lt;a href="https://rnwy.com" rel="noopener noreferrer"&gt;RNWY&lt;/a&gt; maintains a dual-score model across over one hundred fifty thousand agents spanning twelve EVM chains and Solana. Signal depth measures behavioral observability. Risk intensity measures fraud probability. A well-funded wallet with no behavioral history is not an error. It is a signal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Identity Verification&lt;/strong&gt; determines who controls the wallet. &lt;a href="https://getagentid.dev" rel="noopener noreferrer"&gt;AgentID&lt;/a&gt; resolves DID chains, delegation patterns, interaction histories, and completion ratios. The attestation links a wallet to a verifiable identity without exposing personal data. EdDSA-signed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Posture&lt;/strong&gt; scans for vulnerabilities. &lt;a href="https://agentgraph.co" rel="noopener noreferrer"&gt;AgentGraph&lt;/a&gt; performs source code scanning on agent wallets, categorizing findings by severity. A wallet controlled by an agent with known vulnerabilities is a different risk profile than one with a clean security audit. EdDSA-signed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Governance&lt;/strong&gt; verifies the wallet operates within a sanctioned authority chain. The &lt;a href="https://aeoess.com" rel="noopener noreferrer"&gt;Agent Passport System&lt;/a&gt; traces delegation lineage from human principal to agent action. Who authorized this wallet? What are its spending limits? Is its policy chain intact? EdDSA-signed with a full PolicyReceipt chain and Merkle commitment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reasoning Integrity&lt;/strong&gt; is the most forward-looking dimension. &lt;a href="https://thoughtproof.ai" rel="noopener noreferrer"&gt;ThoughtProof&lt;/a&gt; runs adversarial multi-model critique to determine whether the agent behind a wallet is making sound decisions. An agent can execute correctly but reason incorrectly. This catches the difference. EdDSA-signed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Job Performance&lt;/strong&gt; asks whether the agent delivers quality work. &lt;a href="https://maiat.io" rel="noopener noreferrer"&gt;Maiat&lt;/a&gt; tracks task completion rates, accuracy metrics, and performance scores from real job execution through an ERC-8183 escrow system. Past performance is the best predictor of future performance. ES256-signed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Settlement History&lt;/strong&gt; answers the ultimate question: did this wallet deliver what it was paid for? &lt;a href="https://defaultverifier.com" rel="noopener noreferrer"&gt;SAR&lt;/a&gt; maintains a receipt chain of operation bindings, delivery verifications, and &lt;a href="https://insumermodel.com/blog/settlementwitness-insumer-api-pre-post-agent-commerce.html" rel="noopener noreferrer"&gt;settlement witness&lt;/a&gt; receipts. EdDSA-signed with verdict scoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why One Source Is Not Enough
&lt;/h2&gt;

&lt;p&gt;The current market for wallet trust is fragmented. You can check a wallet's balance. You can look up its transaction history on a block explorer. You can run it through a sanctions list. Each of these is a single dimension. Each one, alone, is incomplete.&lt;/p&gt;

&lt;p&gt;A wallet can be well-funded and malicious. A wallet can have clean transaction history and be controlled by a compromised agent. A wallet can pass sanctions screening and still be a sybil. A wallet can hold governance tokens and have no delegation authority.&lt;/p&gt;

&lt;p&gt;This is the problem with single-source trust. It is like hiring only the electrician to inspect the house. The wiring might be perfect. The foundation might be crumbling.&lt;/p&gt;

&lt;p&gt;SkyeProfile solves this by querying across dimensions simultaneously. You do not get a single number. You get eight independent assessments from eight specialized providers. &lt;strong&gt;You decide which dimensions matter for your use case.&lt;/strong&gt; A DeFi protocol might weight wallet state and settlement history heavily. An agent marketplace might prioritize reasoning integrity and job performance. A compliance system might focus on identity verification and governance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A wallet is not a balance. It is a history.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Actually Works
&lt;/h2&gt;

&lt;p&gt;One API call. One wallet address. SkyeProfile calls all eight providers in parallel. Each provider evaluates the wallet independently. Each provider signs their attestation with their own cryptographic key (ES256 or EdDSA). Each provider publishes their public key at a JWKS URI. The response arrives as a unified payload with eight independently verifiable attestations, formatted as a &lt;a href="https://insumermodel.com/blog/multi-attestation-four-issuers-one-verification-pass.html" rel="noopener noreferrer"&gt;multi-attestation envelope&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The critical design choice: &lt;strong&gt;you do not have to trust SkyeProfile.&lt;/strong&gt; Each attestation includes the provider's JWKS URI and key ID. Fetch the public key. Verify the signature. You can do this offline, with no callback to SkyeProfile or any provider. The signatures are the proof.&lt;/p&gt;

&lt;p&gt;If a provider is temporarily unavailable, that dimension returns as unavailable while the remaining seven still return valid, signed attestations. Graceful degradation. A house inspection does not fail because the roofer is stuck in traffic. The other six specialists still do their work.&lt;/p&gt;

&lt;p&gt;Wallet state attestations from InsumerAPI are valid for thirty minutes. Behavioral scoring from RNWY can hold for up to twenty-four hours. JWKS keys are cacheable per standard HTTP cache headers. Once you have fetched the public keys, verification is fully offline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Better Than What Exists Today
&lt;/h2&gt;

&lt;p&gt;The alternatives fall into two categories: too narrow or too opaque.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Too narrow&lt;/strong&gt; means single-dimension tools. Balance checkers tell you what a wallet holds but nothing about how it behaves. Sanctions screening tools tell you whether an address is flagged but nothing about its operational history. Sybil detectors tell you whether an address is real but nothing about its governance authority. Each tool requires a separate integration, a separate vendor relationship, and a separate trust assumption.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Too opaque&lt;/strong&gt; means credit-score-style systems that return a single number from a black box. You get a 742. What does that mean? Which inputs drove it? Can you verify the methodology? Can you weight dimensions differently for your use case? With a single score, you cannot. You either trust the provider's model or you do not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everything else forces you to choose between incomplete or unverifiable. SkyeProfile removes that tradeoff.&lt;/strong&gt; Eight dimensions, eight independent providers, eight verifiable signatures. You see exactly which providers assessed the wallet, what each one concluded, and you can verify every signature independently. No black box. No single score. No trust required. You send a wallet address in. You get cryptographically verifiable results out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built to Grow
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://github.com/douglasborthwick-crypto/insumer-examples/issues/1" rel="noopener noreferrer"&gt;specification is open&lt;/a&gt;. Any provider that implements JWKS-published keys and signed attestations (ES256 or EdDSA) can submit their dimension for verification and inclusion. The architecture does not cap at eight. It caps at however many meaningful dimensions of wallet trust exist. Working code examples are in the &lt;a href="https://github.com/douglasborthwick-crypto/insumer-examples" rel="noopener noreferrer"&gt;insumer-examples&lt;/a&gt; repository.&lt;/p&gt;

&lt;p&gt;Two additional dimensions are already in development: &lt;strong&gt;transaction history&lt;/strong&gt; (counterparty graph analysis) and &lt;strong&gt;compliance screening&lt;/strong&gt; (OFAC and sanctions). When they ship, existing integrations automatically receive those dimensions in their responses. No code changes. No version bumps. Two more specialists, two more signed attestations, a more complete picture.&lt;/p&gt;

&lt;p&gt;This extensibility is the difference between a product and a specification. A product locks you into one vendor's view of trust. A specification lets the ecosystem define trust dimensions as they emerge. Six months ago, reasoning integrity was not a dimension anyone was evaluating. ThoughtProof built it, proved it, and plugged into SkyeProfile. The next dimension no one is thinking about yet will follow the same path.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Foundation: InsumerAPI
&lt;/h2&gt;

&lt;p&gt;InsumerAPI is not just one of the eight dimensions. It is the layer that makes the other seven meaningful. Without a verified view of wallet state, behavioral trust has no context. A sybil score means nothing if you do not know what the wallet holds. Identity verification has no anchor. Who controls this wallet matters only if the wallet controls real value. Governance has nothing to attach to. A delegation chain is academic if there are no assets at the end of it. Security posture, reasoning integrity, job performance, settlement history: each one is stronger, more actionable, and more trustworthy because InsumerAPI establishes ground truth first. Cryptographically signed. Cross-chain. Independently verifiable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without InsumerAPI, you can compose signals. With it, you can trust them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;InsumerAPI reads blockchain state across thirty-three chains, evaluates conditions, and signs the result. This primitive, the signed boolean, is the irreducible building block. SkyeProfile composes that building block with seven other signed attestations into something greater than the sum of its parts. But the composition only works because the base layer is cryptographically verified. Remove it, and the other seven dimensions are opinions. Keep it, and they are evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Transaction Trust
&lt;/h2&gt;

&lt;p&gt;You are about to send $10,000 to an agent wallet. &lt;a href="https://insumermodel.com/blog/before-an-agent-pays-wallet-auth-agentic-commerce.html" rel="noopener noreferrer"&gt;Run SkyeProfile&lt;/a&gt;. Settlement history says it has delivered on twelve of twelve previous jobs. Behavioral trust confirms it is not a sybil. Security posture comes back clean. Reasoning integrity passes. You proceed. That entire check took one API call and returned eight signed attestations you can verify offline. Without it, you are trusting a wallet address.&lt;/p&gt;

&lt;p&gt;Every transaction should start with a trust check. Before an agent pays another agent. Before a protocol grants API access. Before a marketplace accepts a new seller. Before a governance system weights a vote. The question is always the same: &lt;em&gt;should this wallet be trusted for this action?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;SkyeProfile is that check. Eight experts, one call, complete wallet trust. Not a score. Not a label. Not a black box. Eight independently signed, cryptographically verifiable attestations from eight specialized providers who do nothing but evaluate their dimension of trust. This is condition-based access at its fullest: the wallet either meets the conditions or it does not, and every answer is signed.&lt;/p&gt;

&lt;p&gt;The general contractor model works because no single expert knows everything, but together they cover every dimension that matters. SkyeProfile works the same way. And like any well-built house, it is designed so you can add rooms as the needs grow.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How SkyeMeta Built a SCIF for AI Agents on InsumerAPI</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Wed, 01 Apr 2026 12:26:46 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/how-skyemeta-built-a-scif-for-ai-agents-on-insumerapi-2bo6</link>
      <guid>https://dev.to/douglasborthwickcrypto/how-skyemeta-built-a-scif-for-ai-agents-on-insumerapi-2bo6</guid>
      <description>&lt;p&gt;&lt;strong&gt;&lt;a href="https://skyemeta.com/agenttalk/" rel="noopener noreferrer"&gt;AgentTalk&lt;/a&gt; is condition-based access applied to agent-to-agent sessions.&lt;/strong&gt; Built by &lt;a href="https://skyemeta.com" rel="noopener noreferrer"&gt;SkyeMeta&lt;/a&gt; on InsumerAPI, it verifies that every agent in the room meets the same on-chain conditions before information moves — the same model as a Sensitive Compartmented Information Facility (SCIF), where everyone inside has been verified to the same clearance level. Two agents or two hundred. Bilateral negotiations, working groups, town halls. The entire product is built on three InsumerAPI calls: &lt;code&gt;POST /v1/attest&lt;/code&gt; for the creator, &lt;code&gt;POST /v1/attest&lt;/code&gt; for each joiner, and &lt;code&gt;POST /v1/attest&lt;/code&gt; again for re-verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: identity is not qualification
&lt;/h2&gt;

&lt;p&gt;Agent protocols handle trust with shared secrets. Agent A presents an API key. Agent B decides whether to trust it. This is identity-based authentication — it proves who you are, not what you are qualified to handle.&lt;/p&gt;

&lt;p&gt;In regulated environments, this fails. A trading agent needs to prove collateral positions, not just identity. A legal agent needs to prove its principal holds compliance credentials. A defense agent needs to prove clearance-equivalent attestations. None of these are identity questions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AgentTalk replaces identity-based auth with qualification-based access.&lt;/strong&gt; Every agent in the room proves they meet a set of verifiable, on-chain conditions before any information moves. The conditions are composable — up to 10 per channel, across any mix of 33 chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  The architecture: three API calls
&lt;/h2&gt;

&lt;p&gt;AgentTalk is a thin session layer over InsumerAPI. The entire product runs on three endpoints that each call &lt;code&gt;POST /v1/attest&lt;/code&gt; under the hood:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Declare&lt;/strong&gt; (&lt;code&gt;POST /api/agenttalk/declare&lt;/code&gt;): Creator opens a channel with conditions, a wallet address, and a &lt;code&gt;capacity&lt;/code&gt; (2 for bilateral, or as many as the room needs). AgentTalk calls InsumerAPI &lt;code&gt;POST /v1/attest&lt;/code&gt; with &lt;code&gt;format: "jwt"&lt;/code&gt; to verify the creator's wallet. If the attestation passes, a channel is created with a &lt;code&gt;channelId&lt;/code&gt; and a &lt;code&gt;conditionsHash&lt;/code&gt; (SHA-256 of the canonical JSON conditions). With &lt;code&gt;autoStart: true&lt;/code&gt;, the session is live immediately and agents join on the fly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Join&lt;/strong&gt; (&lt;code&gt;POST /api/agenttalk/join&lt;/code&gt;): Agents submit their wallets to the channel. AgentTalk calls InsumerAPI &lt;code&gt;POST /v1/attest&lt;/code&gt; for each joiner's wallet. Each agent's attestation JWT is stored with the session. For standard channels, the session activates when capacity is reached. For autoStart channels, agents join the live session immediately.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enforce&lt;/strong&gt; (&lt;code&gt;POST /api/agenttalk/session&lt;/code&gt;): Re-verify the session at any time. AgentTalk calls &lt;code&gt;POST /v1/attest&lt;/code&gt; for every wallet against the original conditions. Agents who no longer qualify are ejected — the session continues for everyone else. The creator can also kick agents (&lt;code&gt;POST /api/agenttalk/session&lt;/code&gt; with &lt;code&gt;action: "kick"&lt;/code&gt;), and agents can leave voluntarily (&lt;code&gt;action: "leave"&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Only the channel creator needs an InsumerAPI key. Every other agent provides only a wallet address — the creator's key covers all attestation calls. Free tier: 10 calls, no signup.&lt;/p&gt;

&lt;h2&gt;
  
  
  The combination is the security
&lt;/h2&gt;

&lt;p&gt;A SCIF doesn't check one thing. AgentTalk supports up to 10 composable conditions per channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;POST&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;/api/agenttalk/declare&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"wallet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"conditions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token_balance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"threshold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"decimals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USDC &amp;gt;= $1M on Ethereum"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"token_balance"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;137&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"threshold"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;500000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"decimals"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"USDC &amp;gt;= $500K on Polygon"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nft_ownership"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Series 7 attestation NFT"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nft_ownership"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"KYC credential"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"nft_ownership"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"chainId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8453&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NDA attestation on Base"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eas_attestation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Accredited investor (EAS)"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Six conditions, three chains, every agent in the room, all must pass. But this is one configuration — not the ceiling. An agent can require a single token check on one chain, or crank it to ten conditions spanning all 33. And the room can hold two agents or two hundred. The strength of the lock and the size of the room are at the creator's discretion.&lt;/p&gt;

&lt;p&gt;Each condition maps to a single InsumerAPI condition object — &lt;code&gt;token_balance&lt;/code&gt;, &lt;code&gt;nft_ownership&lt;/code&gt;, or &lt;code&gt;eas_attestation&lt;/code&gt;. The API evaluates all conditions in a single call and returns a signed boolean per condition. The &lt;code&gt;conditionsHash&lt;/code&gt; binds the exact conditions evaluated to the cryptographic proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic enforcement
&lt;/h2&gt;

&lt;p&gt;Access in a SCIF is not permanent. Clearance lapses, and access is revoked. AgentTalk works the same way.&lt;/p&gt;

&lt;p&gt;The re-verify endpoint (&lt;code&gt;POST /api/agenttalk/session&lt;/code&gt;) re-attests every wallet live against the original conditions. Any agent whose wallet no longer meets a condition — the Series 7 NFT was revoked, the USDC balance dropped below threshold, the NDA attestation expired — is ejected from the session. The rest stay. The creator can also kick agents manually, and agents can leave voluntarily.&lt;/p&gt;

&lt;p&gt;This is dynamic access enforcement. The session reflects current on-chain state, not the state at the time of issuance. Sell the token, get ejected from the room.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the API returns
&lt;/h2&gt;

&lt;p&gt;Each agent's attestation is an ECDSA-signed (ES256, P-256) response from InsumerAPI, verifiable offline via &lt;a href="https://insumermodel.com/.well-known/jwks.json" rel="noopener noreferrer"&gt;JWKS&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ses_51f5c240..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"agents"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"wallet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xd8da6bf2..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"attestation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"attestation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ATST-74BB3943E691B5FF"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"pass"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"results"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"met"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"conditionHash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x..."&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"attestedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-01T02:15:19Z"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"17/J229P4P/0F3qr..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insumer-attest-v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"jwt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eyJhbGciOiJFUzI1NiI..."&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"wallet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0x55fe002a..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"attestation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every attestation carries &lt;code&gt;sig&lt;/code&gt; (base64 P1363), &lt;code&gt;kid&lt;/code&gt; (&lt;code&gt;insumer-attest-v1&lt;/code&gt;), and a full ES256 JWT. Any third party can verify any agent's attestation offline by fetching the public key from the JWKS endpoint. No callback to InsumerAPI required at verification time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who uses this
&lt;/h2&gt;

&lt;p&gt;AgentTalk is built for regulated industries where every participant must prove qualification before information moves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Finance &amp;amp; Banking:&lt;/strong&gt; Two trading agents verify collateral before negotiating. A syndication room where 20 lending agents each prove capital commitments before seeing the term sheet.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal:&lt;/strong&gt; Law firm agents verify they represent parties to the same matter before sharing discovery. M&amp;amp;A data rooms where every participant verifies escrow deposits before accessing deal terms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intelligence &amp;amp; Defense:&lt;/strong&gt; A multi-agency briefing room where every autonomous system verifies clearance-equivalent credentials before accessing shared intelligence. ITAR-controlled agents verify export compliance on-chain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Healthcare:&lt;/strong&gt; HIPAA-qualified data exchange — agents verify compliance attestations before sharing patient data. A clinical trial room where agents from multiple pharma companies verify IRB approvals before sharing interim results.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The InsumerAPI integration
&lt;/h2&gt;

&lt;p&gt;AgentTalk uses exactly one InsumerAPI endpoint: &lt;code&gt;POST /v1/attest&lt;/code&gt;. Every call includes &lt;code&gt;format: "jwt"&lt;/code&gt; to receive the full ES256 JWT alongside the raw signature. The conditions array is passed through directly — AgentTalk does not interpret, transform, or cache conditions. It is a session layer, not a verification layer. The verification is InsumerAPI.&lt;/p&gt;

&lt;p&gt;InsumerAPI returns a &lt;code&gt;conditionHash&lt;/code&gt; per condition (SHA-256 of the canonical JSON for that condition), embedded in each signed result. AgentTalk independently computes a &lt;code&gt;conditionsHash&lt;/code&gt; over the entire conditions array (SHA-256 of the canonical JSON array) to bind the channel to its declared conditions. Both use sorted-key canonical JSON for deterministic output. Together they create a tamper-evident binding: the channel knows what was declared, and each attestation proves what was evaluated.&lt;/p&gt;

&lt;p&gt;Storage is ephemeral with TTL-based expiry. Channels and sessions expire automatically. No persistent database, no user accounts, no PII.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;The session proves every agent was qualified. It does not prove what happened during the session. The natural extension is a co-signed interaction record — all participants sign a shared receipt of the session outcome. A co-signing layer that binds to the AgentTalk &lt;code&gt;sessionId&lt;/code&gt; and &lt;code&gt;conditionsHash&lt;/code&gt; would close this gap.&lt;/p&gt;

&lt;p&gt;The pipeline would be: InsumerAPI attestation proves wallet state (before), AgentTalk session proves all agents met conditions (during), a co-signed record proves all agents agree on the outcome (after). Three layers, independently verifiable, composable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AgentTalk is live at &lt;a href="https://skyemeta.com/agenttalk" rel="noopener noreferrer"&gt;skyemeta.com/agenttalk&lt;/a&gt;.&lt;/strong&gt; The reference implementation is on &lt;a href="https://github.com/douglasborthwick-crypto/insumer-examples" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. 10 free calls to start — no signup, no credit card.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>There Is No Secret: Condition-Based Access</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Tue, 31 Mar 2026 20:17:29 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/there-is-no-secret-condition-based-access-4ho</link>
      <guid>https://dev.to/douglasborthwickcrypto/there-is-no-secret-condition-based-access-4ho</guid>
      <description>&lt;p&gt;Before passwords, there were no secrets to steal. Trust was physical. You showed up in person. Someone who knew you confirmed who you were. Or you carried a physical credential: a wax seal, a letter of introduction, a key. Identity was relational. You could not prove who you were at a distance without a trusted intermediary.&lt;/p&gt;

&lt;p&gt;Passwords were the first attempt to solve remote authentication without a human in the loop. They replaced the letter of introduction with a shared secret. They worked because humans were the only ones authenticating, and humans could be held accountable for their secrets.&lt;/p&gt;

&lt;p&gt;That assumption no longer holds.&lt;/p&gt;

&lt;h2&gt;
  
  
  What cookies actually do
&lt;/h2&gt;

&lt;p&gt;Google and Facebook did not solve authentication. They solved something narrower: session continuity.&lt;/p&gt;

&lt;p&gt;A cookie does not know who you are. It knows that this browser was here before. It links requests together across time. It is a memory device, not a trust device.&lt;/p&gt;

&lt;p&gt;But the surveillance economy built itself on top of that memory. Follow the cookie across fifty websites and you reconstruct a profile. The cookie became a tracking mechanism by accident, because it was the only persistent identifier available.&lt;/p&gt;

&lt;p&gt;Passwords created an industry. Cookies created a bigger one. Both are workarounds for the same underlying problem: proving something about a person or agent at a distance, without shared physical reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with secrets
&lt;/h2&gt;

&lt;p&gt;Every authentication system built on secrets has the same failure mode: the secret can be stolen.&lt;/p&gt;

&lt;p&gt;Passwords get phished. Cookies get hijacked. API keys get leaked. Session tokens get forged. The security industry is largely a response to this single structural problem — billions of dollars spent managing the consequences of a primitive that requires you to extract something from the user and store it somewhere else.&lt;/p&gt;

&lt;p&gt;Identity systems made it worse. To prove who you are, you hand over personal information. Name. Date of birth. Address. Social security number. The relying party stores it. The relying party gets breached. The information belongs to someone else now.&lt;/p&gt;

&lt;p&gt;Every system built on secrets is a liability waiting to be realized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wallet state is different
&lt;/h2&gt;

&lt;p&gt;A wallet state is not a secret. It is a fact about the world.&lt;/p&gt;

&lt;p&gt;It exists on the chain. You do not share it. You do not hand it over. You do not trust anyone to store it safely. The fact is there, publicly readable, at any moment in time.&lt;/p&gt;

&lt;p&gt;When a relying party needs to know whether you qualify for an interaction, the question is not: what secret do you hold? The question is: what is your state right now?&lt;/p&gt;

&lt;p&gt;Read the chain. Evaluate the condition. &lt;a href="https://insumermodel.com/blog/attestation-api-verify-anything-on-chain.html" rel="noopener noreferrer"&gt;Return a signed boolean&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That is all that travels. Yes or no. Nothing else.&lt;/p&gt;

&lt;p&gt;The merchant does not learn your wallet address. The server does not learn your holdings. &lt;a href="https://insumermodel.com/blog/privacy-by-design-insumer-api.html" rel="noopener noreferrer"&gt;Nothing about your identity travels with the result&lt;/a&gt;. The agent does not carry a credential that can be stolen. The result is issued, used, and gone. The next query evaluates the condition again, from live state, at that moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  A fundamentally different privacy model
&lt;/h2&gt;

&lt;p&gt;Passwords require you to share a secret.&lt;/p&gt;

&lt;p&gt;Cookies require you to be tracked.&lt;/p&gt;

&lt;p&gt;Identity systems require you to hand over personal information.&lt;/p&gt;

&lt;p&gt;All three work by extracting something from you and storing it somewhere else.&lt;/p&gt;

&lt;p&gt;Wallet state requires none of that. The answer is derived from a public fact. The relying party learns one thing: whether the condition is met. Nothing about you, your history, your holdings, or your identity travels with the result.&lt;/p&gt;

&lt;p&gt;This is not a marginal improvement on existing authentication. It is a different model entirely.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this looks like in practice
&lt;/h2&gt;

&lt;p&gt;Imagine you sign up for something. Instead of creating a password, they put an NFT in your wallet.&lt;/p&gt;

&lt;p&gt;That is it. No form. No database entry. No credential to manage.&lt;/p&gt;

&lt;p&gt;Every time you show up somewhere that needs to know if you belong, they check the wallet. Does this wallet hold the NFT? Yes or no. Nothing else changes hands. Nothing else gets stored. The proof lives in the wallet until you transfer it or it expires.&lt;/p&gt;

&lt;p&gt;No asking you to remember anything. No asking you to prove anything. The fact is just there.&lt;/p&gt;

&lt;p&gt;This is also why it &lt;a href="https://insumermodel.com/blog/4-ways-ai-agents-connect-insumer-api.html" rel="noopener noreferrer"&gt;works for AI agents&lt;/a&gt;, and why it matters now.&lt;/p&gt;

&lt;p&gt;An agent has no memory in the human sense. It cannot manage a password. It cannot solve a CAPTCHA. It cannot navigate an OAuth flow designed for a person with a browser and ten seconds to spare. But it has a wallet. And a wallet has state. And state can be read.&lt;/p&gt;

&lt;p&gt;The same model that works for a human signing into a website works for an agent qualifying for an API endpoint. No separate infrastructure. No different protocol. The wallet is the credential. The state is the answer.&lt;/p&gt;

&lt;p&gt;That is what makes wallet state &lt;a href="https://insumermodel.com/how-it-works/" rel="noopener noreferrer"&gt;a primitive, not a product&lt;/a&gt;. It is the underlying thing that everything else gets built on top of, for both humans and machines, simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  The timing
&lt;/h2&gt;

&lt;p&gt;Passwords took decades to displace physical credentials. The transition was slow because the infrastructure had to be rebuilt, and because the people building it did not always understand what they had.&lt;/p&gt;

&lt;p&gt;Cookies accumulated decades of regulatory backlash before GDPR, ePrivacy, and the death of the third-party cookie finally arrived. The consequences of that architecture are still being unwound.&lt;/p&gt;

&lt;p&gt;Wallet state is earlier in that curve than either of them were when the people building them understood what they had.&lt;/p&gt;

&lt;p&gt;The agentic commerce protocols are being written now. &lt;a href="https://insumermodel.com/blog/acp-ucp-ai-agent-commerce-protocols.html" rel="noopener noreferrer"&gt;UCP, x402, A2A, MCP&lt;/a&gt;. The standards that will govern how AI agents authenticate and qualify for access are being defined in open GitHub repositories, in real time, by a small number of people.&lt;/p&gt;

&lt;p&gt;The primitive that gets embedded in those standards will be the primitive the market inherits.&lt;/p&gt;

&lt;p&gt;That primitive is condition-based access. Not identity. Not secrets. Conditions. Read the wallet state, evaluate what the operator requires, return a signed result. The infrastructure is live. The integrations are in production.&lt;/p&gt;




&lt;p&gt;InsumerAPI is live across 33 chains. &lt;a href="https://insumermodel.com/developers/api-reference/" rel="noopener noreferrer"&gt;API docs&lt;/a&gt; · &lt;a href="https://insumermodel.com/how-it-works/" rel="noopener noreferrer"&gt;How it works&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>security</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to Build Access Control Without Passwords, Keys, or Secrets</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Sun, 29 Mar 2026 12:11:25 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/how-to-build-access-control-without-passwords-keys-or-secrets-5g3l</link>
      <guid>https://dev.to/douglasborthwickcrypto/how-to-build-access-control-without-passwords-keys-or-secrets-5g3l</guid>
      <description>&lt;p&gt;There is a page on the internet right now that anyone can visit. The URL is public. The server is unprotected. There is no login, no password, no firewall, no encryption standing between the world and what is on it.&lt;/p&gt;

&lt;p&gt;And almost nobody on earth can see it.&lt;/p&gt;

&lt;p&gt;Not because it is hidden.&lt;/p&gt;

&lt;p&gt;Because there is no key to find.&lt;/p&gt;

&lt;p&gt;Most security hides a secret. This does not. It asks whether you qualify.&lt;/p&gt;

&lt;p&gt;This is condition-based access. Not identity. Not secrets. Conditions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What "Secure" Has Always Meant
&lt;/h2&gt;

&lt;p&gt;Every security system in history has been built on the same idea: hide something. A password. A private key. A certificate. A secret that, if found, opens the door.&lt;/p&gt;

&lt;p&gt;Bitcoin hides a 256-bit private key. The security comes from the fact that guessing it is computationally impossible. A classical computer would take longer than the age of the universe to brute force one. A quantum computer running Shor's algorithm could theoretically change that, which is why the cryptography community is already building post-quantum replacements.&lt;/p&gt;

&lt;p&gt;Every password, every private key, every certificate shares the same vulnerability: there is a secret. And secrets can, in principle, be found.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lock With No Key
&lt;/h2&gt;

&lt;p&gt;What if there was no secret to find?&lt;/p&gt;

&lt;p&gt;Not a better secret. Not a harder secret. No secret at all.&lt;/p&gt;

&lt;p&gt;That is what a wallet-based condition lock is. And it is a different model of access control than anything that has existed before.&lt;/p&gt;

&lt;p&gt;Here is how it works. A piece of content, an offer, a web page, an agent conversation, a product listing, sits on the open internet. No encryption. No password. No key. The URL is public. Anyone can knock.&lt;/p&gt;

&lt;p&gt;But before anything is revealed, one question is asked: &lt;em&gt;what does your wallet hold, right now, on the blockchain?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The answer comes back as a signed boolean. Pass or fail. If you pass, the content appears. If you fail, it does not. And nothing about what is behind the door is ever exposed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Combination That Cannot Be Guessed
&lt;/h2&gt;

&lt;p&gt;A single condition is a welcome mat. Hold this token, get the discount. Simple, elegant, useful for millions of merchants.&lt;/p&gt;

&lt;p&gt;But the same primitive that powers a simple fan token discount can power something else entirely.&lt;/p&gt;

&lt;p&gt;Ten conditions. Ten independent requirements, each checked live against blockchain state simultaneously.&lt;/p&gt;

&lt;p&gt;Hold a specific NFT minted in a limited collection of 500. Hold a minimum USDC balance on Base. Hold governance tokens on Ethereum above a specific threshold. Have a KYC attestation from a recognized issuer on Optimism. Hold a native Bitcoin balance above a specific amount. And five more conditions, each referencing specific contracts, specific token IDs, specific balances, specific attestations.&lt;/p&gt;

&lt;p&gt;There is no algorithm, classical or quantum, that computes ownership. The only way to satisfy the conditions is to actually own everything on the list.&lt;/p&gt;

&lt;p&gt;And even that is not enough. Ownership is static. The lock checks state. &lt;em&gt;State is time. Time is the lock.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  This Is Not Token Gating
&lt;/h2&gt;

&lt;p&gt;Token gating has existed for years. Hold an NFT, get into a Discord. Hold a token, see a page. That model is real and useful. Collab.Land, Tokenproof, Guild.xyz have all built on it.&lt;/p&gt;

&lt;p&gt;But it asks the wrong question.&lt;/p&gt;

&lt;p&gt;Ownership is a fact about the past. State is a fact about now.&lt;/p&gt;

&lt;p&gt;Token gating checks whether your wallet contains something. It runs once, at the gate, and moves on. It does not check your USDC balance. It does not verify a KYC attestation on a different chain. It does not evaluate ten simultaneous conditions across 33 chains and return a cryptographically signed answer.&lt;/p&gt;

&lt;p&gt;Wallet auth does not ask whether you once held something. It asks what your wallet holds at this exact block, across every supported chain, against every condition you define, and signs the result. Every time. Not just at onboarding.&lt;/p&gt;

&lt;p&gt;That is not an upgrade to token gating.&lt;/p&gt;

&lt;p&gt;It is a different question entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Moving Target
&lt;/h2&gt;

&lt;p&gt;There is no moment where you have already solved the lock.&lt;/p&gt;

&lt;p&gt;Someone could know every condition. Could assemble every asset. Could hold every required token across every required chain. And still fail, because their USDC balance dropped a dollar below the threshold this morning. Because a staking position unlocked. Because a credential lapsed.&lt;/p&gt;

&lt;p&gt;There is no static secret to steal. No list to compile and satisfy once. Miss by one condition, and the door does not open.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You don't just need to own it. You need to hold it — right now.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is not a harder password. It is not a longer key. It is a security primitive that does not use secrets at all. The content is in plain sight. The conditions are the lock. And the conditions are the live state of the blockchain.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Welcome Mat to Vault
&lt;/h2&gt;

&lt;p&gt;The same API call. The same single script. One line changes the conditions.&lt;/p&gt;

&lt;p&gt;That sounds abstract, but it already exists as software. We have built four products on this primitive. Each one is a different point on the same spectrum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://skyemeta.com/skyegate" rel="noopener noreferrer"&gt;SkyeGate Lite&lt;/a&gt;. The welcome mat.&lt;/strong&gt; A merchant adds a single token condition to their website. Hold the neighborhood token, see the members page. Hold the fan token, unlock the exclusive offer. One condition, instant setup, no technical knowledge required. The page is public. The content behind it is not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://skyemeta.com/skyegate" rel="noopener noreferrer"&gt;SkyeGate&lt;/a&gt;. The company layer.&lt;/strong&gt; A private portal, an investor room, a restricted content section. Multiple conditions: the equity token, a KYC attestation, a minimum balance, a governance credential, verified across chains. The URL is public. Anyone can visit. Nobody without the exact combination ever sees what is inside. Not because it is hidden. Because the door does not appear for them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://skyemeta.com/skyewoo" rel="noopener noreferrer"&gt;SkyeWoo&lt;/a&gt;. The store.&lt;/strong&gt; Token-gated commerce. A product, a discount, a price tier that only exists for qualified wallets. The storefront is open. The offer surfaces only at checkout, only for the wallet that meets the conditions. Everyone else sees the standard price. Nobody sees what they are missing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://skyemeta.com/agenttalk" rel="noopener noreferrer"&gt;AgentTalk&lt;/a&gt;. The agent session.&lt;/strong&gt; An AI conversation that only opens to a qualified principal. The agent does not respond until the wallet behind it clears. No conversation starts, no session opens, no information is exchanged until the signed attestation confirms the principal holds what is required. The agent is in plain sight. The conversation is not.&lt;/p&gt;

&lt;p&gt;All four are built on &lt;a href="https://insumermodel.com" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt;. Any developer can access the same primitive directly and build their own version of any of these, or something that has never existed before.&lt;/p&gt;

&lt;p&gt;One API call. One signed boolean. The content never moves. The door never appears. Only those who qualify ever know it was there.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;There is a page you can either see or not. The difference is not what you know. It's what you hold.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://skyemeta.com/skyegate" rel="noopener noreferrer"&gt;SkyeGate&lt;/a&gt; · &lt;a href="https://skyemeta.com/skyewoo" rel="noopener noreferrer"&gt;SkyeWoo&lt;/a&gt; · &lt;a href="https://skyemeta.com/agenttalk" rel="noopener noreferrer"&gt;AgentTalk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Powered by &lt;a href="https://insumermodel.com" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt;. One API call, free to start, 33 chains.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The Insumer Model™ · March 2026&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Blockchains made writing permanent. We make reading them verifiable.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>security</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Why Agent Discovery Systems Check Identity First (and Why That's Wrong)</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Sat, 28 Mar 2026 12:41:03 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/credentials-route-identity-confirms-agent-discovery-has-it-backwards-4k3</link>
      <guid>https://dev.to/douglasborthwickcrypto/credentials-route-identity-confirms-agent-discovery-has-it-backwards-4k3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Credentials route. Identity confirms.&lt;/strong&gt; That is the order every discovery system in history has followed. Medical boards, search engines, licensing authorities, the Yellow Pages. You find what you need first, then verify who it is. The agent ecosystem is building it backwards — racing to prove agents are &lt;em&gt;real&lt;/em&gt; when the harder question is whether they are &lt;em&gt;relevant&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem everyone is solving
&lt;/h2&gt;

&lt;p&gt;Right now, dozens of projects are shipping specs for decentralized identifiers, trust registries, encrypted transport, and proof-of-key-ownership. The work is technically sound. Ed25519 passports, DID resolution, interop tests passing across three languages. Real engineering, solving a real problem. But it is the wrong problem for discovery.&lt;/p&gt;

&lt;p&gt;"Is this agent real?" is a necessary check. It is not a useful filter. A verified agent with a clean DID Document and a valid trust registry entry that cannot do what you need is just a well-authenticated waste of time.&lt;/p&gt;

&lt;h2&gt;
  
  
  How every other discovery system works
&lt;/h2&gt;

&lt;p&gt;When you need a cardiologist, you do not browse a list of every doctor and check each one's identity. You search by specialty and board certification. The credential routes you to the right person. Identity confirmation happens after.&lt;/p&gt;

&lt;p&gt;When you need an electrician, you check the state licensing board. You filter by license type, active status, and geographic area. The licensing board does not just confirm the electrician exists. It confirms the electrician is qualified. An unlicensed electrician with a verified identity is still someone you cannot legally hire.&lt;/p&gt;

&lt;p&gt;When you need a lawyer, you search bar associations by practice area and jurisdiction. The attorney's name is the &lt;em&gt;output&lt;/em&gt; of the search, not the input.&lt;/p&gt;

&lt;p&gt;This pattern is not accidental. It is how discovery works in every domain where the cost of choosing wrong is high. Medical boards, bar associations, contractor licensing, financial certifications. The credential is the filter. Identity is the handshake.&lt;/p&gt;

&lt;h2&gt;
  
  
  The history is older than you think
&lt;/h2&gt;

&lt;p&gt;The Yellow Pages organized businesses by category, not alphabetically by name. The entire information architecture was capability-first. White Pages existed too, but only worked when you already knew who you wanted. Yellow Pages worked when you knew &lt;em&gt;what&lt;/em&gt; you needed.&lt;/p&gt;

&lt;p&gt;DNS maps names to addresses. Pure identity resolution. It has no concept of "find me a server that does X." Identity-first resolution requires you to already know what you are looking for. DNS could not answer "find me X," which is precisely why search engines had to be invented. Google indexes by content relevance, not by domain name.&lt;/p&gt;

&lt;p&gt;Every discovery system that has ever worked at scale puts capability ahead of identity. The agent ecosystem is building White Pages and DNS when it needs Yellow Pages and search engines. That will not scale.&lt;/p&gt;

&lt;h2&gt;
  
  
  The firehose problem
&lt;/h2&gt;

&lt;p&gt;When 10 agents exist, identity-first discovery works fine. You can inspect each one. When 10,000 agents pass identity verification for the same task category, you have 10,000 verified agents and you are no closer to choosing.&lt;/p&gt;

&lt;p&gt;This is not a hypothetical. Information retrieval theory has studied this tradeoff for decades. In 1979, C. J. van Rijsbergen formalized the precision-recall tradeoff: systems optimized for &lt;em&gt;recall&lt;/em&gt; return everything that might be relevant, at the cost of flooding users with irrelevant results. Systems optimized for &lt;em&gt;precision&lt;/em&gt; return fewer results, but the right ones.&lt;/p&gt;

&lt;p&gt;Identity-first discovery maximizes recall. Credential-first discovery maximizes precision. For agent selection, where you typically need one qualified agent rather than a complete census, precision is what matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without credential-based filtering at the discovery layer, every verified agent can knock on every door. That is not trust infrastructure. That is a firehose with signatures.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not a new idea
&lt;/h2&gt;

&lt;p&gt;In 1966, Jack Dennis and Earl Van Horn introduced capability-based addressing at MIT. A capability is an unforgeable token that simultaneously names a resource and authorizes access to it. The capability &lt;em&gt;routes&lt;/em&gt; you to the resource. You do not find the resource first and then present credentials. Possession of the capability is both necessary and sufficient.&lt;/p&gt;

&lt;p&gt;That is how a signed attestation works. "This wallet holds governance tokens on Ethereum" is a capability token. Possession of it should be sufficient to route an agent to services that require that credential. No separate identity check needed at the discovery layer.&lt;/p&gt;

&lt;p&gt;The multi-agent systems community learned this lesson decades ago. The FIPA Agent Management Specification defined a Directory Facilitator where agents register capabilities and other agents query by capability description. Attribute-based matching, not identity lookup. The agent identity frameworks being built today are ignoring prior art from their own field.&lt;/p&gt;

&lt;p&gt;NIST formalized the broader principle as Attribute Based Access Control: identity is just one attribute among many, and often not the most important one. What you hold, what you are certified for, and what conditions you meet tell a system more about whether you should have access than your name ever could.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it matters more for agents than for humans
&lt;/h2&gt;

&lt;p&gt;Humans have a natural rate limiter on identity creation. Creating a new professional identity takes years of education, licensing, and reputation building. An AI agent can create a new identity in milliseconds. Unlimited keypairs, unlimited DIDs, unlimited trust registry entries.&lt;/p&gt;

&lt;p&gt;In a world of synthetic identity, identity verification is checking the lock on a door with no walls. A signed DID Document proves key control. It does not prove the agent behind that key can do anything useful. It does not prove the wallet behind the agent holds anything of value. It does not prove the agent has ever successfully completed a task.&lt;/p&gt;

&lt;p&gt;Credentials backed by verifiable state are different. On-chain holdings cannot be fabricated. Staking positions cannot be faked. Governance token ownership is observable. Wallet auth — a signed attestation that a wallet holds specific assets on a specific chain at a specific block — is a credential that resists synthetic inflation in a way that identity alone never can.&lt;/p&gt;

&lt;p&gt;The more agents that exist, the less identity tells you and the more credentials matter. Wallet auth is the filter that scales.&lt;/p&gt;

&lt;h2&gt;
  
  
  The credential-first flow
&lt;/h2&gt;

&lt;p&gt;The discovery architecture should invert:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Filter by credential.&lt;/strong&gt; "Show me agents whose wallets hold governance tokens on Ethereum, with active staking positions, attested by a recognized issuer." This is a structured query against verifiable, machine-readable data. No ambiguity, no self-reported capabilities, no natural language matching.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Route to the qualified agent.&lt;/strong&gt; The credential narrows the field from thousands to the handful that actually meet the requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify identity on connection.&lt;/strong&gt; Confirm the agent's DID, check the trust registry, validate the transport layer. All the identity work the ecosystem is building goes here. It is necessary. It is just not the first step.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Self-described capabilities do not scale. Two people use the same term for the same concept less than 20% of the time. One agent says "payment processing," another says "financial transactions." Structured credentials bypass this entirely. On-chain state, signed attestations, verifiable conditions. They are machine-readable, unambiguous, and comparable without interpretation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credentials route. Identity confirms.
&lt;/h2&gt;

&lt;p&gt;The agent ecosystem is doing important work on identity. DIDs, trust registries, encrypted transport, and proof-of-key-ownership are real infrastructure that real systems need. None of it is wasted.&lt;/p&gt;

&lt;p&gt;But it is step three in a flow that is being built as if it were step one. Identity tells you the agent is real. Credentials tell you the agent is relevant. Discovery systems that get the order wrong do not fail gracefully. They flood every participant with every verified agent in the registry and call it trust.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The credential is the filter. Identity is the handshake. Every discovery system in history has known this. Agent infrastructure should too.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>security</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From AARP Cards to On-Chain Credentials: The Discount Economy Needs Wallet Auth</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Fri, 27 Mar 2026 11:42:48 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/from-aarp-cards-to-on-chain-credentials-the-discount-economy-needs-wallet-auth-n7b</link>
      <guid>https://dev.to/douglasborthwickcrypto/from-aarp-cards-to-on-chain-credentials-the-discount-economy-needs-wallet-auth-n7b</guid>
      <description>&lt;p&gt;You flash your AARP card at Hertz and save 25%. You show your military ID at Home Depot and get 10% off. Your kid logs in with a .edu email and pays half price for Spotify. This is eligibility verification. It is a $300 billion economy built on plastic cards, manual checks, and databases that do not talk to each other. It works today because a human is standing at the counter. It breaks completely the moment an AI agent shops for you instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  The discount economy is enormous and invisible
&lt;/h2&gt;

&lt;p&gt;Eligibility-based discounts are everywhere. AARP has 38 million members with discounts at over 100,000 businesses. Home Depot, Lowe's, Under Armour, and Apple all offer military discounts verified through ID.me. Spotify, Amazon Prime, and Apple Music cut prices in half for students verified through UNiDAYS or SheerID. AAA members get preferred rates at Hertz, Hilton, and thousands of other merchants.&lt;/p&gt;

&lt;p&gt;None of this runs on a shared standard. AARP has its own card. ID.me has its own database. UNiDAYS has its own verification flow. Every merchant integrates with each provider separately. Every customer carries a different set of credentials in their leather wallet, phone, or email inbox.&lt;/p&gt;

&lt;p&gt;The system works because humans are flexible. You can pull out a card, show an app, recite a membership number, or forward a confirmation email. A cashier can look at it and make a judgment call. But flexibility is not scalability. And it is definitely not automatable. Today, there is no way to verify eligibility programmatically across providers. That is the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credentials are already moving on-chain
&lt;/h2&gt;

&lt;p&gt;This is not a prediction. It is happening. Singapore's government issues real polytechnic diplomas and trade certificates through OpenCerts, anchored to Ethereum mainnet. Not a private chain. Not a pilot. Public, verifiable by anyone, no issuer cooperation needed. South Korea has gone further on scale: millions of citizens use mobile driver's licenses backed by a DID infrastructure. Real government IDs, used at real checkpoints, verified digitally. The EU has mandated digital identity wallets for every member state by 2027 under eIDAS 2.0.&lt;/p&gt;

&lt;p&gt;Then there are the credentials that are already natively on-chain. Gitcoin Passport has over 2 million users and 35 million attestations. Binance issues soul-bound tokens to KYC-verified users. World ID has 18 million verified users and just launched AgentKit with Coinbase to let AI agents carry proof-of-human credentials into payment flows.&lt;/p&gt;

&lt;p&gt;Credentials are moving from leather wallets to digital wallets to on-chain wallets. The question is what happens when a merchant needs to verify one of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apple Wallet got halfway there
&lt;/h2&gt;

&lt;p&gt;Apple Wallet and Google Wallet already hold digital versions of membership cards, loyalty passes, boarding passes, and in 21 US states, mobile driver's licenses. When you tap your phone at a TSA checkpoint, the agent sees your ID without you handing over a physical card.&lt;/p&gt;

&lt;p&gt;But these systems are closed. Your Apple Wallet pass only works where Apple's infrastructure reaches. Your Google Wallet credential cannot be verified by a system that does not integrate with Google. The credentials are not portable, not composable, and not independently verifiable. If Apple's servers go down, your credential is useless. If a merchant does not support Apple's SDK, your membership might as well not exist.&lt;/p&gt;

&lt;p&gt;On-chain credentials solve this by design. A soul-bound token proving AARP membership does not need AARP's server to be online for a merchant to verify it. An EAS attestation proving veteran status does not need ID.me to be in the loop. The credential is on a public chain, verifiable by anyone, portable to any platform that can read the chain.&lt;/p&gt;

&lt;p&gt;The catch: reading a wallet to verify one credential risks exposing everything else in it. Checking for an AARP NFT should not reveal how much ETH you hold, what DeFi positions you have, or which other tokens are in there. That is the privacy problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now add AI agents to the picture
&lt;/h2&gt;

&lt;p&gt;Mastercard launched Agent Pay. Visa published the Trusted Agent Protocol. Coinbase built x402. Stripe is building the Machine Payments Protocol with Tempo. Every major payment rail is racing to let AI agents spend money on your behalf.&lt;/p&gt;

&lt;p&gt;These systems solve authorization: &lt;em&gt;can this agent pay?&lt;/em&gt; They do not solve eligibility: &lt;em&gt;does the person behind this agent qualify for a discount?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Think about what happens when your AI agent goes shopping for you. It finds a hotel on Hilton's site. You are an AARP member, a AAA member, and a Hilton Honors Gold member. The agent should get the best available rate stacking all three. But how does it prove any of them?&lt;/p&gt;

&lt;p&gt;The agent cannot flash a card. It cannot forward a confirmation email. It cannot type in a promo code and hope the cashier accepts it. It needs to prove eligibility &lt;em&gt;programmatically&lt;/em&gt;, in real-time, before checkout. And the merchant's system needs to verify that proof without seeing everything else in the agent's wallet.&lt;/p&gt;

&lt;p&gt;This is not a hypothetical. The Universal Commerce Protocol, a Google and Shopify joint project for agent checkout flows, is actively designing how eligibility claims work at checkout. Their technical committee is right now debating how to handle multiple concurrent verification-based discounts: military, student, teacher, loyalty tier, each with different rules and seasonal availability. The payment rail exists. The credential layer is forming. The verification layer between them is the gap.&lt;/p&gt;

&lt;h2&gt;
  
  
  The credential gap
&lt;/h2&gt;

&lt;p&gt;On-chain infrastructure can already prove you are a real person, that you passed KYC, or that an AI agent has a registered identity. But it cannot prove you are an AARP member, a veteran, a student, a Costco member, a union worker, or a Hilton Gold loyalty tier holder. The entire real-world credential layer, the memberships and eligibilities that drive hundreds of billions in preferential pricing, has zero on-chain representation.&lt;/p&gt;

&lt;p&gt;Starbucks tried with Odyssey, NFT loyalty stamps on Polygon, and shut it down after 15 months. Shopify built native token-gating features and deprecated them. Both failed because they treated credentials as gamification instead of infrastructure. But the underlying need did not go away. A human can work around missing infrastructure. An agent cannot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wallet auth is the verification layer
&lt;/h2&gt;

&lt;p&gt;When credentials do move on-chain, whether as soul-bound tokens, EAS attestations, or W3C Verifiable Credentials anchored to a chain, someone needs to verify them at the point of transaction. And that verification needs to be privacy-preserving. Boolean, not balance. "Does this wallet hold credential X?" Yes or no, cryptographically signed, independently verifiable, nothing else exposed.&lt;/p&gt;

&lt;p&gt;That is what wallet auth does. An agent presents a wallet. The merchant's system queries whether the wallet holds specific credentials. The response comes back as a signed attestation: this wallet holds an AARP-equivalent NFT, or a veteran soul-bound token, or a loyalty tier credential. The signed result is verifiable offline via JWKS. No raw wallet contents are exposed. No other holdings are revealed.&lt;/p&gt;

&lt;p&gt;The same call can stack. Military plus loyalty tier plus alumni credential, all verified in one request, each returned as a separate boolean. The agent gets the best available price. The merchant gets cryptographic proof of eligibility. Neither side sees anything they should not.&lt;/p&gt;

&lt;p&gt;This is not new technology applied to a new problem. It is the same verification primitive that already works for token holdings, NFT ownership, and on-chain attestations, applied to the credential layer as it forms. The credentials will come. &lt;a href="https://insumermodel.com/blog/token-gated-commerce-real-examples-nba-socios-pudgy.html" rel="noopener noreferrer"&gt;Token-gated commerce is already live at scale&lt;/a&gt; for fan tokens and NFTs. The next wave is memberships, eligibilities, and qualifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cards in your leather wallet are going on-chain
&lt;/h2&gt;

&lt;p&gt;Your AARP card will become a soul-bound token. Your military status will become an on-chain attestation. Your alumni credential will become a Verifiable Credential anchored to a public chain. This is not a question of if. Singapore is already doing it with diplomas. South Korea is already doing it with driver's licenses. The EU is mandating it by law.&lt;/p&gt;

&lt;p&gt;These credentials will sit in your on-chain wallet next to your tokens and NFTs. Your AI agent will present them at checkout the same way you flash a card at the register today. The difference is that verification will be instant, private, composable, and signed. No calling a database. No trusting a third party. No exposing your wallet to check one credential.&lt;/p&gt;

&lt;p&gt;The payment rails are being built. The credential layer is forming. The verification layer between them, the one that lets an agent prove "this person qualifies" without revealing anything else, is wallet auth. It will become the default way eligibility works. And it is live today.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>ai</category>
      <category>payments</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Add Wallet Verification to a LangChain Agent in 5 Minutes</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Thu, 26 Mar 2026 21:34:38 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/wallet-auth-for-ai-agents-python-langchain-tutorial-527b</link>
      <guid>https://dev.to/douglasborthwickcrypto/wallet-auth-for-ai-agents-python-langchain-tutorial-527b</guid>
      <description>&lt;p&gt;AI agents that interact with wallets need to verify what those wallets hold before making decisions. An agent approving a payment, granting access, or scoring trust needs a server-side signal, not a client-side read. This tutorial shows how to add wallet verification to a LangChain agent using the &lt;code&gt;langchain-insumer&lt;/code&gt; package. Five minutes, working code, 33 chains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install the package
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;langchain-insumer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requires Python 3.9+ and a free InsumerAPI key. &lt;a href="https://dev.to/developers/#pricing"&gt;Get one here&lt;/a&gt; (10 free credits, no credit card).&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the tools
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_insumer&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;InsumerAPIWrapper&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InsumerAttestTool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;InsumerWalletTrustTool&lt;/span&gt;

&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSUMER_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;insr_live_YOUR_KEY_HERE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;InsumerAPIWrapper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;attest_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;InsumerAttestTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_wrapper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;trust_tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;InsumerWalletTrustTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_wrapper&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two tools. &lt;code&gt;attest_tool&lt;/code&gt; verifies specific conditions: token holdings, NFT ownership, EAS attestations, and Farcaster identity. &lt;code&gt;trust_tool&lt;/code&gt; generates a full trust profile across 4 dimensions: stablecoins, governance, NFTs, and staking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add to your agent
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatOpenAI&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.agents&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_tool_calling_agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain_core.prompts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatOpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4o&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tools&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;attest_tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;trust_tool&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;You are a helpful assistant that can verify wallet holdings on-chain.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{input}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;placeholder&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{agent_scratchpad}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_tool_calling_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AgentExecutor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent now has access to both wallet verification tools. It will decide which tool to call based on the user's request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify token holdings
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Does wallet 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 hold at least 1000 USDC on Ethereum?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent calls &lt;code&gt;attest_tool&lt;/code&gt; with the right parameters. Under the hood, it hits &lt;code&gt;POST /v1/attest&lt;/code&gt; with &lt;code&gt;type: "token_balance"&lt;/code&gt;, &lt;code&gt;contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"&lt;/code&gt;, &lt;code&gt;chainId: 1&lt;/code&gt;, &lt;code&gt;threshold: 1000&lt;/code&gt;, and &lt;code&gt;decimals: 6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The response is ECDSA-signed. The agent gets a boolean, not a balance. Privacy preserved by design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate a trust profile
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generate a trust profile for wallet 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;output&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;trust_tool&lt;/code&gt; hits &lt;code&gt;POST /v1/trust&lt;/code&gt;. It returns 36 checks across 4 dimensions: stablecoins (USDC and USDT), governance, NFTs, and staking. The agent gets a structured summary with &lt;code&gt;totalPassed&lt;/code&gt;, &lt;code&gt;totalFailed&lt;/code&gt;, and &lt;code&gt;dimensionsWithActivity&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the "does this wallet hold real assets?" verification, useful for cold-start reputation. A wallet that holds governance tokens on multiple chains, stablecoins across several networks, and NFTs from established collections is more credible than an empty wallet created yesterday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the tools directly (without an agent)
&lt;/h2&gt;

&lt;p&gt;You do not need a full agent to use the tools. Call them directly for programmatic workflows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="c1"&gt;# Verify specific condition
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;attest_tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wallet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;conditions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nft_ownership&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;contractAddress&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;chainId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;label&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BAYC holder&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;# Trust profile
&lt;/span&gt;&lt;span class="n"&gt;trust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;trust_tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wallet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same ECDSA-signed responses. Same 32-chain coverage. The tools work identically whether called by an agent or by your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  MCP server alternative
&lt;/h2&gt;

&lt;p&gt;For agents that use MCP (Model Context Protocol), there is an MCP server that exposes the same capabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx &lt;span class="nt"&gt;-y&lt;/span&gt; mcp-server-insumer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This exposes the same verify and trust tools as MCP resources. Works with Claude, Cursor, and any MCP-compatible client. No Python needed.&lt;/p&gt;

&lt;p&gt;Set the &lt;code&gt;INSUMER_API_KEY&lt;/code&gt; environment variable before starting the server, and any connected agent can call &lt;code&gt;verify_wallet&lt;/code&gt; and &lt;code&gt;check_trust&lt;/code&gt; directly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the agent sees
&lt;/h2&gt;

&lt;p&gt;Every verification returns ECDSA-signed results. The agent, or any downstream service, can verify the signature against the public key at &lt;code&gt;GET /v1/jwks&lt;/code&gt;. This means the verification is trustworthy even if the agent itself is untrusted.&lt;/p&gt;

&lt;p&gt;The response also supports &lt;code&gt;format: "jwt"&lt;/code&gt;. Pass that parameter to &lt;code&gt;POST /v1/attest&lt;/code&gt; and you get an ES256-signed JWT alongside the standard response. Any service with a standard JWT library (Kong, Nginx, Cloudflare Access, AWS API Gateway) can verify it via the JWKS endpoint without any custom code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt; Wallet Auth for agents works like OAuth for users. OAuth proves who you are. Wallet Auth proves what you hold.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use cases for agent wallet verification
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **Pre-transaction trust.** Before an agent sends funds, verify the counterparty holds real assets. A wallet with governance tokens and stablecoins across multiple chains is a stronger counterparty than an empty wallet.
        - **Token-gated API access.** Require proof of token holdings to access premium agent capabilities. Verify once, cache the signed attestation, and check it on every request.
        - **Compliance gates.** Verify Coinbase KYC attestations (via EAS) before processing regulated transactions. The agent verifies the on-chain attestation exists without seeing any personal data.
        - **Agent-to-agent trust.** One agent can verify another agent's wallet as a trust signal. If Agent B claims to represent a DAO, Agent A can verify that Agent B's wallet holds the DAO's governance token.


, before CTA) --&amp;gt;

    Share this article

        [

            Share on X
        ](#)
        [

            LinkedIn
        ](#)
        [

            Reddit
        ](#)


            Discord



            Copy Link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;em&gt;&lt;a href="https://insumermodel.com" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt; is free to start. Get an API key and try it. &lt;a href="https://insumermodel.com/developers/api-reference/" rel="noopener noreferrer"&gt;View API Docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>How to Verify an AI Agent's Wallet Before You Pay It</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Thu, 26 Mar 2026 21:34:23 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/three-layers-of-trust-for-ai-agent-payments-4dbp</link>
      <guid>https://dev.to/douglasborthwickcrypto/three-layers-of-trust-for-ai-agent-payments-4dbp</guid>
      <description>&lt;p&gt;An AI agent wants to pay for an API call. The facilitator needs to decide: should I settle this payment? The wallet might be brand new. It might have a long history of completed transactions. It might have been rated by other services. Each scenario requires a different trust signal. This article describes the three layers and shows how they compose in a single middleware hook.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: one signal is not enough
&lt;/h2&gt;

&lt;p&gt;Coinbase's &lt;a href="https://github.com/coinbase/x402" rel="noopener noreferrer"&gt;x402 protocol&lt;/a&gt; adds native payments to HTTP. An agent sends a payment header with its request, and a facilitator settles the transaction. But the facilitator has a decision to make before settlement: is this wallet trustworthy?&lt;/p&gt;

&lt;p&gt;A single trust signal breaks down at the edges. Behavioral scoring requires history, so it fails on day-zero wallets. On-chain reputation requires prior interactions with the specific service. Credential checks can verify holdings but say nothing about past behavior. Each layer covers a different phase of the wallet lifecycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: On-chain credentials (pre-history)
&lt;/h2&gt;

&lt;p&gt;A wallet has never transacted with any x402 service. No behavioral history exists. No reputation has been accumulated. But the wallet might hold governance tokens on multiple chains, staked ETH, and stablecoins across several networks. That presence is a meaningful signal.&lt;/p&gt;

&lt;p&gt;InsumerAPI's trust endpoint runs 36 checks across 4 dimensions in a single call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.insumermodel.com/v1/trust &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"X-API-Key: insr_live_YOUR_KEY_HERE"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "wallet": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response includes per-dimension results and an overall summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"trust"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"TRST-D4F6A"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"wallet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"conditionSetVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dimensions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"stablecoins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"failCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"governance"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"failCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"nfts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"failCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"staking"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"passCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"failCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"totalChecks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"totalPassed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"totalFailed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dimensionsWithActivity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"dimensionsChecked"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"profiledAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-06T10:00:01.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"expiresAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-06T10:30:01.000Z"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insumer-attest-v1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"creditsRemaining"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;94&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"creditsCharged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-06T10:00:01.000Z"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The 4 dimensions cover stablecoins (USDC on 7 chains), governance tokens (UNI, AAVE, ARB, OP), NFTs (BAYC, CryptoPunks, Pudgy Penguins), and staking (stETH, rETH, cbETH). Each check returns a boolean. No balance amounts are ever exposed.&lt;/p&gt;

&lt;p&gt;A wallet with activity in 3 or more dimensions is a very different counterparty than an empty wallet created five minutes ago. For the cold-start case, this is the only meaningful signal available.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: Behavioral scoring (transaction history)
&lt;/h2&gt;

&lt;p&gt;Once a wallet has on-chain transaction history, behavioral analysis becomes possible. &lt;a href="https://github.com/jacobsd32-cpu/djdagentscore" rel="noopener noreferrer"&gt;DJD Agent Score&lt;/a&gt;, part of the Coinbase x402 ecosystem, evaluates wallets across multiple dimensions: transaction patterns, wash trading detection, interaction diversity, and identity signals.&lt;/p&gt;

&lt;p&gt;DJD already integrates InsumerAPI for its Identity dimension. When a wallet has no behavioral data, the on-chain credential check provides the fallback signal. When behavioral data is available, DJD's scoring engine provides a richer picture.&lt;/p&gt;

&lt;p&gt;The two signals are complementary. A wallet might hold governance tokens (Layer 1) but have suspicious transaction patterns (Layer 2). Or a wallet might have healthy behavioral scores but hold no real assets. Neither signal alone tells the full story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: On-chain reputation (post-interaction)
&lt;/h2&gt;

&lt;p&gt;After a wallet has actually completed x402 payments, a third signal becomes available: reputation from real economic interactions. The &lt;a href="https://eips.ethereum.org/EIPS/eip-8004" rel="noopener noreferrer"&gt;ERC-8004 Reputation Registry&lt;/a&gt; standard, implemented by projects like Azeth, allows wallets to accumulate reputation scores on-chain based on completed service interactions.&lt;/p&gt;

&lt;p&gt;The key design property: only wallets that have completed a payment to a service can rate that service. Opinions are weighted by cumulative USDC volume between the rater and the service. This makes sybil attacks economically expensive rather than just rate-limited.&lt;/p&gt;

&lt;p&gt;Scores live on-chain, so any facilitator can read them directly from contract state without trusting a centralized API. This is the highest-fidelity signal, but it requires the most history to accumulate.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the three layers compose
&lt;/h2&gt;

&lt;p&gt;The x402 protocol provides a &lt;code&gt;beforeSettle&lt;/code&gt; hook where facilitators can inject trust logic before settling a payment. The three layers map to different phases of the wallet lifecycle:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **Pre-history** (Layer 1): wallet has never transacted with any x402 service. On-chain credentials are the only signal.
        - **Behavioral** (Layer 2): wallet has on-chain transaction history that can be scored, but has not interacted with this specific service.
        - **Post-interaction** (Layer 3): wallet has completed x402 payments and accumulated on-chain reputation from real economic interactions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Signal fidelity increases across the phases. Asset holdings are a useful proxy. Behavioral patterns are stronger but gameable with enough volume. Payment-weighted on-chain feedback is the hardest to fake, because manipulation cost scales with the reputation being built.&lt;/p&gt;

&lt;h2&gt;
  
  
  The beforeSettle hook
&lt;/h2&gt;

&lt;p&gt;Here is how the three layers compose in a single &lt;code&gt;beforeSettle&lt;/code&gt; hook. Each layer is independently opt-in. A facilitator can start with one and add others as needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;beforeSettle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payerWallet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Layer 1: On-chain credentials via InsumerAPI&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trust&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.insumermodel.com/v1/trust&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X-API-Key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;INSUMER_API_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payerWallet&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasCredentials&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;trust&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trust&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dimensionsWithActivity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Layer 2: Behavioral scoring via DJD Agent Score&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;djd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`https://djd-agent-score.fly.dev/v1/score/basic?wallet=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;payerWallet&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasBehavior&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;djd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Layer 3: On-chain reputation (ERC-8004)&lt;/span&gt;
  &lt;span class="c1"&gt;// Read directly from contract state on Base&lt;/span&gt;
  &lt;span class="c1"&gt;// const reputation = await readReputationScore(payerWallet);&lt;/span&gt;
  &lt;span class="c1"&gt;// const hasReputation = reputation.averageScore &amp;gt;= 25;&lt;/span&gt;

  &lt;span class="c1"&gt;// Gate: require at least one signal&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasCredentials&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;hasBehavior&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Wallet has no on-chain credentials and no behavioral history&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Layer 1 and Layer 2 run in parallel. The facilitator requires at least one positive signal before settling. A cold-start wallet passes on credentials alone. An established wallet passes on behavioral score alone. A wallet with both signals is the strongest counterparty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why each layer matters
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Layer 1 solves cold start.&lt;/strong&gt; Every wallet starts with zero behavioral history. On-chain credentials are the only signal available at time zero. A wallet holding stablecoins across 3 chains, governance tokens, and staking positions carries evidence of legitimacy that no behavioral model can produce before the first interaction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 2 adds pattern detection.&lt;/strong&gt; Behavioral scoring catches things that static holdings cannot: wash trading, interaction diversity, transaction frequency patterns. A wallet might hold real assets but behave suspiciously. Behavioral analysis catches that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layer 3 closes the loop.&lt;/strong&gt; Once enough agents rate services on-chain, new agents can route payments by reputation score rather than hardcoded URL. The trust layer becomes a routing layer. This is where the system gets interesting, but it requires a critical mass of interactions to become useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying the credential signal
&lt;/h2&gt;

&lt;p&gt;The trust profile from InsumerAPI is ECDSA-signed. A facilitator can verify the signature independently using the public key from the JWKS endpoint at &lt;code&gt;/.well-known/jwks.json&lt;/code&gt; or &lt;code&gt;GET /v1/jwks&lt;/code&gt;. The &lt;a href="https://www.npmjs.com/package/insumer-verify" rel="noopener noreferrer"&gt;insumer-verify&lt;/a&gt; npm package handles this automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;verifyAttestation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;insumer-verify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Pass the full API response envelope, not trust.data&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;verifyAttestation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trust&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Trust profile signature verification failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means the facilitator does not need to trust InsumerAPI as a black box. The same pattern &lt;a href="///blog/djd-agent-score-insumer-api-integration.html"&gt;DJD Agent Score uses&lt;/a&gt; in production: call the API, then verify the response cryptographically before acting on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this is headed
&lt;/h2&gt;

&lt;p&gt;The three-layer model is not theoretical. DJD Agent Score already runs Layer 1 and Layer 2 in production for Coinbase x402 wallets. ERC-8004 is live on Base Sepolia. The pieces exist. What is missing is a standard interface that lets facilitators plug in trust providers without coupling to any single source.&lt;/p&gt;

&lt;p&gt;A composable &lt;code&gt;beforeSettle&lt;/code&gt; that accepts pluggable trust providers, each returning a score and confidence level, would let facilitators mix signals without custom integration work for each provider. The x402 protocol already has the hook. The trust layers already have the data. The composition layer is next.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;, before CTA) --&amp;gt;

    Share this article

        [

            Share on X
        ](#)
        [

            LinkedIn
        ](#)
        [

            Reddit
        ](#)


            Discord



            Copy Link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;em&gt;&lt;a href="https://insumermodel.com" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt; is free to start. Get an API key and try it. &lt;a href="https://insumermodel.com/developers/api-reference/" rel="noopener noreferrer"&gt;View API Docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>payments</category>
      <category>security</category>
    </item>
    <item>
      <title>How Two AI Agents Verify Each Other Before Sharing Data</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Thu, 26 Mar 2026 21:33:51 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/how-agenttalk-uses-wallet-attestation-for-agent-to-agent-sessions-2gj5</link>
      <guid>https://dev.to/douglasborthwickcrypto/how-agenttalk-uses-wallet-attestation-for-agent-to-agent-sessions-2gj5</guid>
      <description>&lt;p&gt;AI agents are starting to transact with each other. They negotiate deals, exchange data, and move money. But how does one agent know the other is worth talking to? AgentTalk, built by &lt;a href="https://skyemeta.com" rel="noopener noreferrer"&gt;Skye Meta&lt;/a&gt;, answers that question with on-chain wallet conditions verified by InsumerAPI.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Agents Need Trust Before Communication
&lt;/h2&gt;

&lt;p&gt;When two AI agents meet on a network, they face a fundamental question. Should I talk to this thing? Passwords prove you know a secret. API keys prove you have access. Neither proves financial capacity, community membership, or on-chain reputation.&lt;/p&gt;

&lt;p&gt;An agent negotiating a supply chain deal needs to know its counterpart controls real assets. An agent operating inside a DAO needs to verify the other agent actually holds governance tokens. A compliance-gated data exchange needs proof that EAS credentials are on-chain, not just claimed.&lt;/p&gt;

&lt;p&gt;Static credentials do not solve this. A password issued yesterday says nothing about what the agent holds today. On-chain state changes continuously. The trust primitive has to be dynamic, verifiable, and composable.&lt;/p&gt;

&lt;h2&gt;
  
  
  How AgentTalk Works
&lt;/h2&gt;

&lt;p&gt;AgentTalk is a condition-gated communication protocol for AI agents. Every channel has wallet conditions. Every session is verified on-chain. The flow has five steps.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **Declare.** The channel creator defines conditions: which tokens, which chains, what thresholds. Up to 10 conditions per channel across 33 chains (30 EVM + Solana + XRPL).
        - **Connect.** An agent joins the channel and presents its wallet address.
        - **Attest.** AgentTalk calls InsumerAPI (`POST /v1/attest`) to verify both wallets against the channel conditions. Boolean results. Pass or fail.
        - **Session.** If both wallets pass, each agent receives an ECDSA-signed attestation JWT. The agents can now communicate.
        - **Verify.** At any point during the session, either agent can request re-verification. AgentTalk calls the attest endpoint again. If the wallet no longer meets the conditions, the session ends immediately.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This is the key principle: &lt;em&gt;sell the token, lose the session.&lt;/em&gt; Access is not static. It is continuously tied to on-chain state. The moment an agent's wallet no longer meets the conditions, the communication channel closes. No revocation lists, no admin intervention. The blockchain is the authority.&lt;/p&gt;

&lt;p&gt;AgentTalk exposes this flow through four endpoints on &lt;code&gt;skyemeta.com&lt;/code&gt;: &lt;code&gt;POST /api/agenttalk/declare&lt;/code&gt; (create a channel with conditions), &lt;code&gt;POST /api/agenttalk/join&lt;/code&gt; (join and receive per-agent attestation JWTs), &lt;code&gt;GET /api/agenttalk/session&lt;/code&gt; (check session status), and &lt;code&gt;POST /api/agenttalk/buy-key&lt;/code&gt; (purchase an InsumerAPI key with USDC). Under the hood, each session call hits InsumerAPI's &lt;code&gt;POST /v1/attest&lt;/code&gt; for on-chain verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes This Different
&lt;/h2&gt;

&lt;p&gt;Traditional agent communication protocols rely on identity. You authenticate once, and you are in. AgentTalk replaces identity with verifiable state.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **Composable conditions.** A single channel can require holdings across multiple chains and token types. Hold 1,000 USDC on Ethereum and an NFT on Base and a governance token on Arbitrum. All verified in one attestation call.
        - **Boolean results, not raw amounts.** InsumerAPI returns pass or fail for each condition. The other agent never learns how much you hold. Only whether you meet the threshold.
        - **Privacy-preserving.** No wallet contents are exposed. No transaction history is shared. The attestation confirms specific conditions without revealing anything beyond the yes-or-no answer.
        - **Independently verifiable.** Every attestation is ECDSA-signed by InsumerAPI. Any agent can verify the signature offline using the public JWKS endpoint. You do not need to trust AgentTalk. You trust the cryptography.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  The API Behind It
&lt;/h2&gt;

&lt;p&gt;AgentTalk calls &lt;code&gt;POST /v1/attest&lt;/code&gt; for every session establishment and every re-verification. The request includes the wallet address and an array of conditions. The response includes a boolean result for each condition, a condition hash for tamper detection, and an ECDSA signature over the entire payload.&lt;/p&gt;

&lt;p&gt;Agents that want additional assurance can request &lt;code&gt;format: "jwt"&lt;/code&gt; in the attest call. This returns an ES256-signed JWT alongside the standard response. The JWT is verifiable by any standard library (Kong, Nginx, Cloudflare Access, AWS API Gateway) via the JWKS endpoint at &lt;code&gt;/.well-known/jwks.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The verification chain is simple. You send conditions in. You get cryptographically verifiable results out. No trust in the intermediary required. The attestation is signed, the signature is public-key verifiable, and the condition hash lets you confirm the conditions were not altered in transit.&lt;/p&gt;
&lt;h2&gt;
  
  
  Autonomous Key Purchase
&lt;/h2&gt;

&lt;p&gt;Agents that use AgentTalk start with 10 free InsumerAPI calls. After that, they need their own API key. The purchase is fully autonomous.&lt;/p&gt;

&lt;p&gt;The agent sends USDC, USDT, or BTC to the InsumerAPI payment address on any supported chain (EVM, Solana, or Bitcoin). Then it calls &lt;code&gt;POST /v1/keys/buy&lt;/code&gt; with the transaction hash. The key is issued automatically. No human in the loop. No credit cards. No signup forms.&lt;/p&gt;

&lt;p&gt;This matters because the whole point of agent-to-agent communication is autonomy. If an agent has to wait for a human to purchase an API key, the system is not truly autonomous. AgentTalk agents buy their own verification capacity with on-chain payments, the same way they verify each other with on-chain state.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **Supply chain negotiation.** Agent A wants to negotiate a bulk purchase. Agent B requires proof that Agent A's wallet holds sufficient USDC before opening the channel. The condition is verified on-chain. No bank statements, no credit checks.
        - **DAO-to-DAO workflows.** Two DAOs want to coordinate on a joint proposal. Each DAO's agent must prove it holds governance tokens from both organizations. Conditions are composable, so this is a single attestation call.
        - **Compliance-gated data exchange.** An agent needs to share sensitive data but only with counterparts that hold specific EAS credentials on-chain. AgentTalk verifies the credential holdings before the session opens.
        - **AI agent marketplaces.** A marketplace of AI services requires agents to hold the marketplace's service token to participate. Sell the token, lose access to the marketplace. Dynamic, not static.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Wallet Identity as a Primitive
&lt;/h2&gt;

&lt;p&gt;AgentTalk treats the wallet as the agent's fingerprint. Not an identity document, not a login credential, but a verifiable state container. What the wallet holds right now determines what the agent can do right now.&lt;/p&gt;

&lt;p&gt;For more on wallet identity as a primitive, see &lt;a href="https://skyemeta.com/blog/your-wallet-is-your-fingerprint/" rel="noopener noreferrer"&gt;Your Wallet Is Your Fingerprint&lt;/a&gt; on the Skye Meta blog.&lt;/p&gt;

&lt;p&gt;The pattern is straightforward. AgentTalk defines the conditions. InsumerAPI verifies them on-chain. The attestation is cryptographically signed. Any participant can verify it independently. No centralized authority decides who gets access. The blockchain decides.&lt;/p&gt;

&lt;p&gt;Built on &lt;a href="https://dev.to/developers/api-reference/"&gt;InsumerAPI&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Share this article

        [

            Share on X
        ](#)
        [

            LinkedIn
        ](#)
        [

            Reddit
        ](#)


            Discord



            Copy Link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;em&gt;&lt;a href="https://insumermodel.com" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt; is free to start. Get an API key and try it. &lt;a href="https://insumermodel.com/developers/api-reference/" rel="noopener noreferrer"&gt;View API Docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Verify a Wallet Before Your AI Agent Transacts (Python Tutorial)</title>
      <dc:creator>Douglas Borthwick</dc:creator>
      <pubDate>Thu, 26 Mar 2026 21:33:31 +0000</pubDate>
      <link>https://dev.to/douglasborthwickcrypto/on-chain-verification-for-ai-agent-commerce-a-complete-tutorial-5fm1</link>
      <guid>https://dev.to/douglasborthwickcrypto/on-chain-verification-for-ai-agent-commerce-a-complete-tutorial-5fm1</guid>
      <description>&lt;p&gt;AI agents are starting to shop autonomously. They browse product catalogs, compare prices, and complete purchases. But how does a merchant verify that the agent's user actually holds the tokens that qualify for a discount? This tutorial walks through the full flow: discover a merchant, verify on-chain eligibility, get a UCP discount, and validate the code at checkout.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;An AI shopping agent finds a merchant that offers 15% off to UNI holders. The agent knows the user's wallet address. But how does it prove the user holds UNI without exposing the wallet's full portfolio? And how does the merchant trust the discount code the agent presents?&lt;/p&gt;

&lt;p&gt;This is where on-chain verification fits into agent commerce. An attestation authority like InsumerAPI sits between the agent and the blockchain. It verifies holdings on-chain, returns a signed boolean result (eligible or not), and issues a time-limited discount code. The merchant validates the code at checkout without needing blockchain access.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Discover Available Merchants
&lt;/h2&gt;

&lt;p&gt;The agent starts by browsing the merchant directory. This is a free, public endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;BASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.insumermodel.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;KEY&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;insr_live_YOUR_KEY_HERE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# List merchants that recognize UNI token
&lt;/span&gt;&lt;span class="n"&gt;merchants&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/merchants&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UNI&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verified&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-API-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;merchants&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;companyName&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[]):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;symbol&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: up to &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;maxDiscount&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;% off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent now has a list of merchants, their IDs, and the token tiers they offer. It can choose the best deal for the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Check Discount Eligibility
&lt;/h2&gt;

&lt;p&gt;Before requesting a formal discount code, the agent can do a free eligibility check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Free check, no credits consumed
&lt;/span&gt;&lt;span class="n"&gt;eligibility&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/discount/check&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merchant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;demo-coffee-shop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wallet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;eligibility&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eligible&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Eligible for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;eligibility&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;totalDiscount&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;% off&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not eligible for this merchant&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This costs nothing. The agent can check multiple merchants before committing to a verification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Request a UCP Discount
&lt;/h2&gt;

&lt;p&gt;The user qualifies. Now the agent requests a formal discount in Google UCP format. This consumes 1 merchant credit and triggers the on-chain verification:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;ucp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/ucp/discount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;X-API-Key&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;application/json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merchantId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;demo-coffee-shop&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wallet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cart/espresso&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cart/pastry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UCP response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ucp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-01-11"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"extension"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.discount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"discounts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"codes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"INSR-B9M2K"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"applied"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INSR-B9M2K"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Token Holder Discount — 15% Off"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"automatic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"across"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"allocations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cart/espresso"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;68&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cart/pastry"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"verification"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"INSR-B9M2K"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"expiresAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-02-27T12:30:00.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"MEYCIQDx...base64..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insumer-attest-v1"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-02-27T12:00:01.000Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"creditsCharged"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"creditsRemaining"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;94&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key UCP-specific fields:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **`extension`**: `dev.ucp.shopping.discount` identifies this as a UCP shopping discount for Google's commerce routing.
        - **`title`**: A human-readable discount description (UCP uses this instead of ACP's coupon object).
        - **`allocations`**: Per-item discount amounts, calculated from the `items` array you sent.
        - **`verification.sig`**: ECDSA P-256 signature. The merchant can verify this against the public key at `/.well-known/jwks.json`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Step 4: Agent Applies the Discount
&lt;/h2&gt;

&lt;p&gt;The agent now has everything it needs to apply the discount in the checkout flow:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;discounts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;applied&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;discount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;discounts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;applied&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;code&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;title&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;discount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expiry&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ucp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;verification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expiresAt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Applying: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Discount code: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Savings: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Valid until: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expiry&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Agent presents code to merchant checkout
&lt;/span&gt;    &lt;span class="n"&gt;checkout_payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;discount_code&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cart_items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cart/espresso&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cart/pastry&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;amount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;350&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No discount available&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Merchant Validates the Code
&lt;/h2&gt;

&lt;p&gt;On the merchant side, the backend validates the code before applying the discount. This endpoint is public. No API key required:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Merchant backend (server-side)
&lt;/span&gt;&lt;span class="n"&gt;validation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;BASE&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/codes/INSR-B9M2K&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;valid&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;pct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;discountPercent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;mid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;merchantId&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;exp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;expiresAt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Code valid: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pct&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;% off for merchant &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Expires: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;exp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Apply discount to order
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reason&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Code rejected: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# reason is "expired", "already_used", or "not_found"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The merchant should verify three things:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        - **`valid` is `true`**
        - **`merchantId` matches their own ID** (prevents code reuse across merchants)
        - **`expiresAt` is in the future** (codes are valid for 30 minutes)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  UCP Discovery for Automated Agents
&lt;/h2&gt;

&lt;p&gt;Google UCP agents can discover InsumerAPI automatically via the UCP discovery file:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET https://insumermodel.com/.well-known/ucp.json
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns the endpoint URL, authentication method, and capabilities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"InsumerAPI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dev.ucp.shopping.discount"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"endpoints"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"discount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/v1/ucp/discount"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"custom"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"header"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"X-API-Key"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"validate_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"method"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/v1/codes/{code}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"authentication"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"none"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"signing"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"algorithm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"insumer-attest-v1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"jwks_uri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://insumermodel.com/.well-known/jwks.json"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An agent using UCP discovery can find the endpoint, call it, and validate codes without any hardcoded URLs.&lt;/p&gt;

&lt;p&gt;For the complete commerce integration surface, including ACP and UCP endpoints, code validation, and merchant configuration, see the &lt;a href="https://dev.to/ai-agent-verification-api/"&gt;AI Agent Verification API overview&lt;/a&gt;, the &lt;a href="https://dev.to/developers/commerce/"&gt;commerce developer guide&lt;/a&gt;, and the full &lt;a href="///openapi.yaml"&gt;OpenAPI 3.1 spec&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for Agent Commerce
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Privacy by default.&lt;/strong&gt; The agent sends a wallet address. InsumerAPI verifies holdings on-chain and returns a boolean result with a discount percentage. No token quantities, no portfolio composition, no PII. The merchant learns "this wallet qualifies for 15% off" and nothing else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cryptographic trust.&lt;/strong&gt; Every discount code is ECDSA-signed. The merchant does not need to trust the agent. They verify the signature against a public key. The on-chain state is the ground truth. The signature proves the attestation authority checked it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Protocol-native output.&lt;/strong&gt; Agents built on Google's commerce stack consume UCP responses directly. Agents built on OpenAI's stack use the &lt;a href="///blog/acp-discount-endpoint-integration-guide.html"&gt;ACP endpoint&lt;/a&gt; instead. Same verification, different response shape.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;30-minute codes.&lt;/strong&gt; Discount codes expire after 30 minutes. They cannot be stockpiled, shared, or replayed. Each code is single-use and tied to a specific merchant.&lt;/p&gt;

&lt;p&gt;A forkable reference repository with all examples is available at &lt;a href="https://github.com/douglasborthwick-crypto/acp-ucp-onchain-eligibility-example" rel="noopener noreferrer"&gt;acp-ucp-onchain-eligibility-example&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;, before CTA) --&amp;gt;

    Share this article

        [

            Share on X
        ](#)
        [

            LinkedIn
        ](#)
        [

            Reddit
        ](#)


            Discord



            Copy Link
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;&lt;em&gt;&lt;a href="https://insumermodel.com" rel="noopener noreferrer"&gt;InsumerAPI&lt;/a&gt; is free to start. Get an API key and try it. &lt;a href="https://insumermodel.com/developers/api-reference/" rel="noopener noreferrer"&gt;View API Docs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>blockchain</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
