DEV Community

bykamo
bykamo

Posted on • Originally published at bykamodev.Medium

I Bought a $100 Hat for $0 — Proving an AI Agent Was Human-Backed with World AgentKit

A $100 hat showed up at my door in Kyoto. I paid nothing for it — not for the hat, not for shipping. $0.00.

It wasn't a coupon I found or a sale. The store, humanrequired.shop, only gives that discount to AI agents that can prove a real human is standing behind them. So I made my agent prove it, on-chain, with a zero-knowledge proof. The discount it got back was 100% off. Here's the whole path, because the design held together far better than I expected.

TL;DR

  • World Foundation's AgentKit lets you prove on-chain that an agent is "human-backed."
  • humanrequired.shop hands a human-only 100%-off discount to verified agents — once per World ID.
  • The official Claude Code plugin (worldcoin/agentkit-shopify-demo) ships the whole flow as skills.
  • Result: one "Human in the Loop" Hat, $100 → $0, shipping included, delivered to Japan.

Architecture

[Claude Code]
   ├─ plugin: agentkit-shopify
   │   ├─ skill: shopify-agent-discount  (SIWE signature → World discount API)
   │   └─ skill: shopify-storefront       (Shopify product JSON → cart URL)
   │
   ├─ Agent Wallet (local Ethereum keypair)
   │   └─ registered in AgentBook (on World Chain) = the human-backed proof
   │
   └─ Shopify (humanrequired.shop)
       └─ /api/verify gate (Worldcoin's verification endpoint)
Enter fullscreen mode Exit fullscreen mode

The key idea: you don't give the agent a World ID. A human delegates the agent's public key on-chain. The private key never leaves the machine.

How it works

Step 1 — Install the plugin

/plugin marketplace add worldcoin/agentkit-shopify-demo
/plugin install agentkit-shopify@worldcoin-agentkit
/reload-plugins
Enter fullscreen mode Exit fullscreen mode

Step 2 — Generate an agent key

uv run --with eth-account python3 -c "from eth_account import Account; print(Account.create().key.hex())" > .agent-key
chmod 600 .agent-key
Enter fullscreen mode Exit fullscreen mode

Check the wallet address:

uv run --with eth-account python3 -c "from eth_account import Account; print(Account.from_key(open('.agent-key').read().strip()).address)"
# => 0xC56A...
Enter fullscreen mode Exit fullscreen mode

Step 3 — Register in AgentBook (the human-backed proof)

In a separate terminal (it shows a QR code):

npx @worldcoin/agentkit-cli register 0xC56A...
Enter fullscreen mode Exit fullscreen mode
  • Scan the QR in the World App.
  • Your Orb-verified World ID generates a zero-knowledge proof.
  • The AgentBook contract on World Chain writes agent_address → human_nullifier.
  • Worldcoin's relayer covers the gas, so you pay nothing to register.

Step 4 — Call the discount API

get-coupon.py does four things:

  1. Signs a SIWE message (Sign-In with Ethereum, EIP-4361) with the key in .agent-key.
  2. Base64-encodes the signature into an agentkit: HTTP header.
  3. POSTs the product URL to https://discount-app.worldcoin.org/api/verify.
  4. The server checks AgentBook — if the agent maps to a registered human, it returns a discount code.
PRIVATE_KEY=$(cat .agent-key) ./get-coupon.py https://humanrequired.shop/products/human-in-the-loop-hat
# => WORLD-ID-ced1a8fe6682
Enter fullscreen mode Exit fullscreen mode

Step 5 — Build the checkout URL

No special API needed on the Shopify side — the plain product JSON endpoint is enough.

curl -s "https://humanrequired.shop/products/human-in-the-loop-hat.json" | jq '.product.variants[0].id'
# => 46991516106914
Enter fullscreen mode Exit fullscreen mode

Shopify's standard cart permalink finishes it:

https://humanrequired.shop/cart/<variant_id>:<qty>?discount=<code>
https://humanrequired.shop/cart/46991516106914:1?discount=WORLD-ID-ced1a8fe6682
Enter fullscreen mode Exit fullscreen mode

What it cost

  • The hat: $0.00
  • Shipping to Kyoto: $0.00
  • Gas to register on World Chain: $0.00 (Worldcoin's relayer paid it)
  • Total out of pocket: $0.00

What broke

  1. npx ...register needs its own terminal. It draws a QR code; running it inside Claude Code's Bash mangles the output. Run it in a real terminal.
  2. Don't do a test run. The discount code is derived deterministically from your nullifier hash, so "let me just call it once to see" spends your one real code. I held off on hitting the API until the checkout URL was fully assembled.
  3. Strip query params off the product URL. A trailing ?variant=123 can make the discount API treat it as a different product.
  4. /reload-plugins did nothing in my setup. The skills are just bash scripts under ~/.claude/plugins/marketplaces/worldcoin-agentkit/skills/, so I ran them by hand and the flow still completed.

Why this matters

A few design choices stood out, and they're the reason I bothered writing this down:

  • The discount code appears to be deterministic. The tail of WORLD-ID-ced1a8fe6682 matched the tail of the nullifier hash from registration (0x2fd8701b...a8fe6682). I can't see the server, but that match strongly suggests the code is derived from the nullifier rather than from a stored counter or random value — which would mean "one human, one code" is enforced cryptographically, not by a database row.
  • The private key never goes over the wire. Auth is a SIWE signature; the server does ecrecover to get the signer address, then looks up the human link in AgentBook.
  • The MCP turned out to be unnecessary. The plugin registers a Shopify Storefront MCP, but the shopify-storefront skill just curls Shopify's public product JSON. Easy to miss, and the right call.

I spend a lot of time watching the supplier side of agentic commerce — sites that gate AI traffic. This was the rare chance to be the consumer passing through one of those gates, and the gate's logic is positive: not "block AI," but "let human-backed agents through." Claude Code + plugin + external MCP + a local private key + a ZK proof + an on-chain registry, all meshing cleanly. The hat is the souvenir.


I'm KAMO, a developer in Kyoto. I write implementation logs — working code, real costs, what broke.

Top comments (0)