Reference implementation of the Intelligent Commerce Protocol (ICP).
ICP is StateSet's open protocol for agent-native commerce: one wire contract that lets any autonomous agent discover merchants, quote baskets, authorize payment, complete checkout, track fulfillment, and handle returns — across currencies, jurisdictions, and payment rails — under a verifiable mandate.
This repository ships:
docs/specification/ICP_SPEC.md— the protocol specification (version2026-04-21).- A standalone Rust handler (this crate) that terminates ICP over HTTP
- gRPC and executes every intent against an embedded StateSet iCommerce engine.
- Compatibility surfaces for the sibling protocols: ACP (OpenAI Agentic Commerce), UCP (Universal Commerce Protocol), MCP (Model Context Protocol), and Google A2A.
Positioning. ACP terminates ChatGPT checkout. UCP provides platform- neutral checkout interop. ICP subsumes both: it is the superset spec that a globally-distributed fleet of agents can target as a single, stable contract — with the engine of record sitting inside the handler process.
| Existing protocol | What it covers | What it leaves out |
|---|---|---|
| ACP (OpenAI, 2025) | ChatGPT Instant Checkout — session create, update, complete + delegated payment vault tokens. | Agent identity, mandates, budgets, negotiation, returns, subscriptions, stablecoin payments, global jurisdictions, peer (A2A) commerce. |
| UCP (StateSet, 2026-01) | Platform-neutral checkout interop with discovery, tokenization, OAuth identity linking, AP2 mandates, order webhooks. | Negotiation, declarative intent model, verifiable receipts, embedded engine, peer-agent payments, first-class global commerce. |
| MCP (Anthropic) | Agent tool surface (stdio JSON-RPC). | Commerce semantics — MCP tools are untyped for the commerce lifecycle. |
| A2A (Google) | Agent-to-agent task protocol. | Commerce semantics. |
ICP is designed to be the protocol an agent speaks when it is doing commerce as a primary intent. It is:
- Agent-first — every request carries an identified agent + a signed mandate. No anonymous writes.
- Intent-based — the API is a small, stable set of verbs
(
intent.quote,intent.buy,intent.return, …) rather than merchant-specific CRUD. - Verifiable — every state-changing response is a compact JWS receipt over the JCS-canonicalized body. Any party can verify offline.
- Global — multi-currency (fiat + stablecoin), multi-jurisdiction tax, cross-border fulfillment as first-class.
- Embedded engine — the handler carries the full iCommerce engine in process. No separate database, no control plane, no network hop between protocol and execution.
- Interoperable — one handler can expose ICP as the native surface and speak ACP, UCP, MCP, and A2A on compatibility paths that route into the same transaction/receipt pipeline.
See the full spec in docs/specification/ICP_SPEC.md.
┌──────────────────────────────────────────────────────┐
│ ICP Handler (Rust) │
│ │
Agents ──┬──▶ │ HTTP /icp/v1/intents ──┐ │
│ │ gRPC icp_handler.v1 │ │
│ │ SSE /icp/v1/events ─┤ ┌──────────────────┐ │
│ │ MCP /mcp ──┼──▶ │ IcpService │ │
│ │ A2A /a2a/v1 ──┘ │ (intent router) │ │
│ │ │ │ │
│ │ Compat: │ ▸ mandate │ │
├──▶ │ ACP /checkout_sessions ───▶ │ ▸ quote │ │
│ │ UCP /api/checkout-… ───▶ │ ▸ authorize │ │
│ │ │ ▸ buy/pay │ │
│ │ │ ▸ return │ │
│ │ │ ▸ track │ │
│ │ └─────────┬────────┘ │
│ │ │ │
│ │ ┌───────▼────────┐ │
│ │ │ stateset- │ │
│ │ │ icommerce │ │
│ │ │ (embedded) │ │
│ │ │ SQLite / PG │ │
│ │ └────────────────┘ │
│ │ │
│ │ Receipts → Ed25519 JWS → /.well-known/icp/jwks.json │
└────┘ │
└──────────────────────────────────────────────────────┘
# 1. Clone the handler
git clone https://github.com/stateset/stateset-icp-handler
# 2. Build
cd stateset-icp-handler
cargo build --release
# 3. Run a local demo (demo API key, relaxed request headers)
ICP_ENABLE_DEMO_KEYS=true \
ICP_REQUIRE_VERSION=false \
ICP_REQUIRE_MANDATE=false \
ICP_REQUIRE_REQUEST_ID=false \
ICP_REQUIRE_IDEMPOTENCY_KEY=false \
cargo run --release
# HTTP → http://0.0.0.0:8082
# gRPC → 0.0.0.0:50052The demo script runs a full agent flow end-to-end:
./demo_test.sh- Agent fetches discovery:
curl -s http://localhost:8082/.well-known/icp | jq - Agent quotes a basket:
curl -s -X POST http://localhost:8082/icp/v1/intents \ -H "Authorization: Bearer icp_demo_key_123" \ -H "ICP-Agent-Id: did:stateset:agent:demo" \ -H "ICP-Version: 2026-04-21" \ -H "ICP-Request-Id: req_demo_quote_1" \ -H "ICP-Idempotency-Key: idem_demo_quote_1" \ -H "ICP-Mandate: <compact-jws-mandate>" \ -H "Content-Type: application/json" \ -d '{ "intent": "intent.quote", "agent_id": "did:stateset:agent:demo", "params": { "items": [ { "sku": "WIDGET-001", "quantity": 2, "unit_price_hint": { "amount_minor": 2999, "currency": "USD" } } ] }, "context": { "currency": "USD", "jurisdiction": "US-CA" } }'
- Agent authorizes + buys against the returned
transaction_id. - Each state-changing response carries a signed receipt in the
ICP-Receiptheader and inline underreceipt.jws.
See docs/getting-started.md for the full
walkthrough including mandate construction.
| Method | Path | Description |
|---|---|---|
GET |
/.well-known/icp |
Discovery document (capabilities, keys, interop). |
GET |
/.well-known/icp/jwks.json |
Receipt signing keys (EdDSA). |
POST |
/icp/v1/intents |
Submit any ICP intent. |
GET |
/icp/v1/transactions/:id |
Retrieve a transaction aggregate. |
GET |
/icp/v1/receipts/:jti |
Retrieve a receipt. |
GET |
/icp/v1/mandates/:jti/usage |
Inspect mandate spend/remaining budget. |
GET |
/icp/v1/events:stream |
Server-Sent Events stream of transaction events. |
GET |
/health, /ready, /metrics |
Ops endpoints. |
gRPC: icp_handler.v1.IcpHandler on :50052, with proto at
proto/icp_handler/v1/icp_handler.proto.
All knobs are environment variables. See
.env.example for the full list.
| Variable | Default | Notes |
|---|---|---|
HOST / PORT |
0.0.0.0 / 8082 |
HTTP bind. |
GRPC_HOST / GRPC_PORT |
0.0.0.0 / 50052 |
gRPC bind. |
ICP_REQUIRE_MANDATE |
true |
Reject writes without a mandate JWS. |
ICP_ENABLE_DEMO_KEYS |
false |
Bundle icp_demo_key_123 on boot. |
COMMERCE_ENABLED |
true |
Open the embedded iCommerce engine. |
COMMERCE_DB_PATH |
./commerce.db |
SQLite path (or postgres://… with --features postgres). |
ICP_A2A_ENABLED |
true |
Advertise A2A compatibility. |
ICP_MCP_ENABLED |
true |
Advertise MCP compatibility. |
ICP_ACP_COMPAT_ENABLED |
true |
Advertise ACP compatibility (path /checkout_sessions). |
ICP_UCP_COMPAT_ENABLED |
true |
Advertise UCP compatibility (path /ucp). |
ICP_SIGNING_KID |
icp-receipt-2026-04 |
JWKS key id advertised for receipts. |
ICP is a superset of ACP and UCP. The mapping is normative:
| ACP / UCP surface | ICP intent |
|---|---|
POST /checkout_sessions |
intent.quote (if items only) → intent.authorize (if buyer + address supplied) |
POST /checkout_sessions/:id/complete |
intent.buy |
POST /checkout_sessions/:id/cancel |
intent.return (canceled-before-fulfillment) |
POST /agentic_commerce/delegate_payment |
intent.buy with PaymentInstrument::DelegatedVault |
POST /api/checkout-sessions (UCP) |
intent.quote + intent.authorize |
POST /api/checkout-sessions/:id/complete (UCP) |
intent.buy |
The compatibility paths are live: ACP at /checkout_sessions/*, UCP at
/checkout-sessions/* + /.well-known/ucp. The spec-level mapping is
documented in docs/interop.md; both routes forward
into the same intent pipeline so receipts, mandate enforcement, and
audit trails are identical across surfaces.
All 17 catalog intents are implemented end-to-end and exercised by the test suite. The handler:
- ✅ Serves
/.well-known/icpwith accurate capability advertisement - ✅ Publishes Ed25519 receipt signing keys at
/.well-known/icp/jwks.json - ✅ Validates mandates (scope, budget, window, merchant) with real
Ed25519 signature verification against
did:keyanddid:webprincipals via the pluggablePrincipalResolvertrait - ✅ Persists buy-flow orders into embedded iCommerce, with the protocol-level state (mandates, receipts, transactions, subscriptions, peer quotes, idempotency cache, webhook outbox) on a separate SQLite database so the two schemas evolve independently
- ✅ Emits signed receipts over JCS-canonicalized responses
- ✅ Streams transaction events via SSE + gRPC
- ✅ Exposes Prometheus metrics on
/metricsand an OpenAPI 3.1 document at/openapi.json(+/docsviewer) - ✅ Enforces tenant-scoped reads across transactions, subscriptions, peer quotes, idempotency, receipts, and ACP/UCP compat sessions
- ✅ Routes compatibility traffic through the same pipeline as native
ICP: ACP
/checkout_sessions/*, UCP/checkout-sessions/*, MCPPOST /mcp(HTTP) and theicp-mcp-stdiobinary for Claude Desktop / Cursor (seedocs/claude-desktop.md) - ✅ Runs an automatic subscription billing scheduler with
weekly/monthly/annual cadences, charge-on-subscribe, dunning that
transitions a subscription to
past_dueafter three consecutive failures, and manualintent.renewrecovery - ✅ Supports A2A peer commerce (
intent.a2a_quote,intent.a2a_pay) with productionexternal_requiredmode that gates settlement on apayment.method=external_authorizationblock carrying the provider, authorization id, and optional instrument hint - ✅ Implements
intent.negotiate(counter-offer + revised quote) andintent.confirm_receipt(buyer-side fulfillment acknowledgement) - ✅ Distributed rate limiting via Redis for both per-tenant and
per-IP pre-auth buckets, with production validation that refuses to
silently fall back to a local limiter when
REDIS_URLis configured - ✅ Durable webhook outbox with exponential backoff, dead-lettering,
SSRF-guarded destination validation, and HMAC-SHA256 signatures
(Stripe-style
t=…,v1=…) — synchronous enqueue so the response body is never returned before the event is committed - ✅ Idempotency cache per ICP §13: replay on byte-equivalent retry,
409
idempotency_conflicton divergent body, with a TTL sweeper - ✅ Conformance harness (
icp-conformancebinary, also published asnpx @stateset/icp-conformance) that validates any handler URL against the spec — see./demo_conformance.sh - ✅ CI on every push/PR:
cargo fmt --check,cargo clippy -D warnings,cargo test,cargo deny check, Docker build, MSRV (1.85) gate - ✅ 348 tests across 36 integration files plus property tests via
proptest — see
tests/
Language clients ship from this repo:
- Rust — this crate
- Python —
clients/python/stateset_icp(published asstateset-icpon PyPI) - Go —
clients/go/stateset-icp-go - TypeScript / npm —
@stateset/icp-conformanceand@stateset/create-icp-commerce
On the roadmap toward v1.0:
- Additional DID resolver methods (
did:stateset:buyer) - Full engine routing for tax, promotions, shipping
- Subscription mid-cycle proration
Recently shipped: subscription free trials (intent.subscribe trial_days)
and cross-instance idempotency (database reservations so multiple replicas
sharing one store can't double-charge). Consult CHANGELOG.md
for the full release history.
Dual-licensed under MIT or Apache-2.0 at your option.