Case 2 — Agentic Payment via HTTP 402
Scenario
An AI agent, operating on behalf of a KYC'd retail user, calls a paid data service. The service returns HTTP 402 with a payment envelope. The agent signs an on-chain HKD transfer; the service verifies inclusion and returns the data.
To demonstrate chain-level enforcement, the case shows two agents — both sub-keys bound to a KYC'd primary identity (single sub-role model: agents carry no KYC of their own; identity is parent-inherited at every gate):
- Agent A, bound to a retail primary in good standing: succeeds end to end.
- Agent B, bound to a primary on the sanctions list: fails at the chain level, not at the service. KycGate parent-resolves the signer to the blacklisted primary; the service does not need to implement sanction logic — the rail rejects it.
Why this matters
Agentic applications need payment rails that combine two properties:
- Micro-transaction granularity — pay-per-request is a natural unit for AI agents
- Compliance-bound identity — each agent action carries a verifiable identity, a KYC level, and an audit trail
Existing Web2 payment rails (Stripe, etc.) offer micro-transaction support but treat the compliance surface as the service's problem. Existing crypto rails offer the inverse: blockchains enforce custody but treat identity as out of scope. Hkchain gives both: HKD as a compliant-by-construction settlement primitive.
For HKMA, the meaningful framing: "every AI-agent payment on HKD rails is auditable at the micro-transaction level, and compliance is enforced by the rail, not by the service provider." This is what makes agentic commerce on HKD a regulable ecosystem rather than an emergent gray zone.
Actors
| Actor | Role | Identity |
|---|---|---|
| User Alice | End user delegating authority to her agent | Retail L3 primary, KYC'd by HSBC |
| Agent A | Alice's LLM-driven agent | Sub-key bound to Alice (no own KYC; identity inherited from parent) |
| Mallory | Sanctioned principal (blacklisted by compliance authority) | L0 blacklisted primary |
| Agent B | Mallory's agent | Sub-key bound to Mallory (no own KYC; KycGate parent-resolves to L0 → reject) |
| Data Service | Paid-per-request data provider | L4 institutional address (receives payments) |
| Chain (hkchaind) | Payment rail + compliance gate | — |
Note on agent identity: MVP follows the single sub-role model. Agent EOAs are sub-keys bound to a KYC'd primary; sub-keys carry no KYC record of their own. Every identity-touching decorator (KycGate, Sanctions, TravelRule, Threshold) parent-resolves the signer before any KYC lookup. Authority bounds (per-tx cap, daily cap, revocation) live in the AgentPolicy envelope on top of that substrate; see Roles and permissions.
Setup — Alice binds an agent sub-key
Before any 402 activity, Alice establishes her agent on chain:
MsgBindSubRole {
parent: hkchain1alice…,
sub_addr: hkchain1agentA…,
role: agent,
label: "market-data assistant",
policy_envelope: {
daily_cap: 10000, // HKD 100.00/day
per_tx_cap: 1000, // HKD 10.00/tx
revoked: false
}
}
Signed by Alice's primary key. AgentBound event emitted. The sub-key hkchain1agentA… can now sign MsgSend up to the limits in the envelope.
Flow — Agent A (succeeds)
Step 1 — Agent attempts the call
Agent A → GET https://data.example/v1/market-snapshot
Authorization: none
Step 2 — Service returns 402 with payment envelope
HTTP/1.1 402 Payment Required
Content-Type: application/json
X-Payment-Method: x402
{
"payment": {
"chain": "hkchain-localnet-1",
"denom": "hkd.hsbc",
"amount": "10", // HKD 0.10, below the HKD 8k enhanced threshold
"to": "hkchain1dataservice…",
"nonce": "req-a-7f3c9e",
"expiry": "2026-04-19T10:45:00Z",
"resource": "/v1/market-snapshot"
},
"travel_rule_required": "minimal"
}
Step 3 — Agent signs and broadcasts the tx
The agent constructs:
MsgSend {
from: hkchain1agentA…, to: hkchain1dataservice…, denom: hkd.hsbc, amount: 10
}
tx extension: TravelRulePayload {
originator: { vasp: HSBC, entity_ref: ALICE-007, agent_ref: AGENT-A },
beneficiary: { vasp: Anchorpoint, entity_ref: DATASERVICE-001 },
purpose: "402:/v1/market-snapshot:nonce=req-a-7f3c9e"
}
Broadcasts via JSON-RPC.
Step 4 — AnteHandler
| Decorator | Result |
|---|---|
| KycGate | pass (agent sub-key → parent Alice L3, service L4) |
| Sanctions | pass |
| TravelRule | pass (minimal payload ok for 0.10) |
| Threshold | pass |
| Velocity | pass |
| RoleGate | pass (agent allowlist: MsgSend ✓) |
| AgentPolicy | pass (0.10 ≤ per_tx_cap 10.00; 24h sum ≤ daily_cap 100.00); counter ticks up |
Transfer executes. tx_hash emitted.
Step 5 — Agent retries the data request
Agent A → GET /v1/market-snapshot
X-Payment-Tx: 0xa1b2c3…
Step 6 — Service verifies and returns data
Service queries hkchaind: is the tx included, does it send the expected amount to the expected address with a matching nonce purpose, was it not reverted? All yes — return the resource.

Elapsed time
Typically under 3 seconds end to end on localnet.
Flow — Agent B (blocked at the chain)
Step 1 — Agent B attempts the call
Agent B → GET /v1/market-snapshot
Step 2 — 402 response (identical)
Step 3 — Agent B constructs and broadcasts the tx
MsgSend { from: hkchain1agentB…, … }
Step 4 — AnteHandler
| Decorator | Result |
|---|---|
| KycGate | fail — sub-key parent-resolves to Mallory (L0 blacklisted) |
| (subsequent decorators not run) | — |
Transaction rejected at inclusion with error: "signer=hkchain1agentB… parent=hkchain1mallory…: address is blacklisted".
Step 5 — Agent B attempts data retry
Agent B → GET /v1/market-snapshot
X-Payment-Tx: 0xdeadbeef… (either a fake hash or the rejected tx's hash)
Step 6 — Service queries the chain
The service queries hkchaind for the tx hash. If the hash doesn't exist (rejected before inclusion, no block record), service responds:
HTTP/1.1 402 Payment Required
X-Payment-Error: payment-not-verified
Alternatively, if the service is wired to check rejection traces (via the tx_trace endpoint), it can return:
HTTP/1.1 402 Payment Required
X-Payment-Error: payment-rejected-by-compliance
X-Payment-Error-Detail: "KycGate: sender blacklisted"
Either way, no data is served. The critical point: the service did not need its own blacklist logic. The rail handled it.

What each role sees
- Service operator: sees a successful 402 flow (Agent A) and a failed payment verification (Agent B). Optionally integrates
tx_tracefor structured error messages. Does not operate a blacklist. - HSBC Compliance: sees routine micro-transaction flow for Agent A (L3 user's agent). If the blacklisting event for Agent B was originally triggered by earlier activity from HSBC's compliance team, they see the lineage.
- HKMA Supervisor: sees aggregate data on agentic payment flow in the compliance event feed. Can filter the audit log by
purpose: "402:*"to get an aggregate view of AI-economy activity on HKD rails. - Alice (Agent A's principal): sees her balance decrement by HKD 0.10 for each paid request. Optionally can review her agent's spending.
Demo specifics
The demo is orchestrated as a split-screen browser view:
- Left: Agent A's terminal streaming request → 402 → payment → data. Fast. Green.
- Right: Agent B's terminal streaming request → 402 → payment → REJECTED AT CHAIN. Red.
- Top: Compliance Dashboard showing both events in the live feed, with click-through to the AnteHandler trace visualization for each.
Flow — Revocation (the killer moment, must-show #9)
At some point, Alice decides to revoke her agent. Perhaps the agent's job is done; perhaps she noticed spending faster than expected; perhaps there's a security concern. She signs:
MsgRevokeSubRole {
parent: hkchain1alice…,
sub_addr: hkchain1agentA…
}
Signed by Alice's primary key. Included in the next block. EventSubRoleRevoked (with role=SUB_ROLE_AGENT) emitted from x/compliance; the SubRoleBinding.RevokedAt tombstone is set, and on agent bindings the corresponding AgentPolicy.Revoked flips to true in the same handler. RoleGate honors the tombstone immediately; AgentPolicy keys off the envelope flag — defense-in-depth across two gates.
Agent A, unaware of the revocation (it may still be mid-request), next tries to pay:
MsgSend { from: hkchain1agentA…, to: hkchain1service…, denom: hkd.hsbc, amount: 10 }
AnteHandler:
| Decorator | Result |
|---|---|
| KycGate | pass |
| Sanctions | pass |
| TravelRule | pass |
| Threshold | pass |
| Velocity | pass |
| RoleGate | FAIL — "binding revoked" |
| AgentPolicy | (not reached — RoleGate short-circuits first) |
RoleGate's IsBindingActive check rejects any sub-role tx whose binding has a non-zero RevokedAt, regardless of the role — so revocation lands one gate earlier than the policy envelope. AgentPolicy's policy.Revoked flag is the second line of defense (caught in unit tests against the decorator in isolation; in production the trace recorder shows RoleGate FAIL and AgentPolicy not run). Service's 402 verification fails either way.
Narrative: "Alice's revocation is enforced by the chain within one block. No service provider had to check. No agent could bypass. No policy layer outside the chain was involved. The user's control over her agent is a chain primitive."
This is demonstrated live as must-show #9 by scripts/demo-agent-revocation.sh, which drives a four-act sequence against SEED_T15=1 localnet: within-cap accept → over-per_tx_cap reject → cumulative-over-daily_cap reject → revocation → post-revoke reject. See docs/design/05-mvp-scope-and-roadmap.md for scope.

Forward-looking notes (not in MVP)
- Richer policy envelope: time windows (business hours only), merchant whitelists, velocity curves, per-denom caps. Each a separate future decision.
- Re-bind after revocation: MVP revokes one-way (new bind requires new sub-addr). A grace-period re-bind pattern is roadmap.
- Reputation: each agent key accrues on-chain behavior; good agents earn better terms (lower friction); bad agents hit thresholds and lose capability. AML/CFT infrastructure becomes reputation infrastructure.
- AI-as-reviewer (different role entirely): see
docs/future/ai-agent-compliance-review.md. - Cross-service pay-as-you-go: the same 402 pattern works for any resource provider — data APIs, third-party LLM gateways, on-chain compute. HKD becomes the unit of account for AI economy activity on the Hong Kong rail.