@devlab.group/agent-commerce 1.4.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +168 -183
- package/dist/ap2.d.ts +21 -24
- package/dist/ap2.js +68 -82
- package/dist/ap2.js.map +1 -1
- package/dist/authorization-BpbWGGrf.d.ts +115 -0
- package/dist/{chunk-NWIQLJNU.js → chunk-74BSEXB5.js} +37 -34
- package/dist/chunk-74BSEXB5.js.map +1 -0
- package/dist/chunk-AFI2CEZS.js +10 -0
- package/dist/chunk-AFI2CEZS.js.map +1 -0
- package/dist/chunk-ATTWSFQP.js +680 -0
- package/dist/chunk-ATTWSFQP.js.map +1 -0
- package/dist/{chunk-ZEGFLRGV.js → chunk-IVJC5YLE.js} +63 -26
- package/dist/chunk-IVJC5YLE.js.map +1 -0
- package/dist/{chunk-GF6KHHKL.js → chunk-RAJGPGJG.js} +5 -8
- package/dist/chunk-RAJGPGJG.js.map +1 -0
- package/dist/chunk-V2V2E7HX.js +27 -0
- package/dist/chunk-V2V2E7HX.js.map +1 -0
- package/dist/cli/index.js +812 -573
- package/dist/cli/index.js.map +1 -1
- package/dist/constants-Bkq04FRZ.d.ts +48 -0
- package/dist/guardrails-71XwtXlT.d.ts +31 -0
- package/dist/index.d.ts +245 -265
- package/dist/index.js +1222 -626
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +6 -59
- package/dist/mcp.js +64 -53
- package/dist/mcp.js.map +1 -1
- package/dist/mpp.d.ts +50 -0
- package/dist/mpp.js +353 -0
- package/dist/mpp.js.map +1 -0
- package/dist/protocol-adapter-DTkrXTev.d.ts +238 -0
- package/dist/runtime-CiYbgGpi.d.ts +303 -0
- package/dist/{types-CJtwLu1c.d.ts → types-O6lg3Q5V.d.ts} +17 -23
- package/dist/x402.d.ts +43 -75
- package/dist/x402.js +13 -693
- package/dist/x402.js.map +1 -1
- package/package.json +13 -2
- package/dist/authorization-CPDcpJVa.d.ts +0 -123
- package/dist/chunk-GF6KHHKL.js.map +0 -1
- package/dist/chunk-NWIQLJNU.js.map +0 -1
- package/dist/chunk-ZEGFLRGV.js.map +0 -1
- package/dist/guardrails-Dmwi63KB.d.ts +0 -38
- package/dist/protocol-adapter-Bebmggf_.d.ts +0 -273
- package/dist/runtime-CKq3d_3K.d.ts +0 -340
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<h1 align="center">Agent Commerce Gateway</h1>
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<strong>One backend.
|
|
4
|
+
<strong>One backend. Multiple agent-commerce protocols. Self-hosted and non-custodial.</strong>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
<img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-strict-3178c6">
|
|
11
11
|
<img alt="MCP" src="https://img.shields.io/badge/MCP-supported-6b4fbb">
|
|
12
12
|
<img alt="x402" src="https://img.shields.io/badge/x402-supported-0052ff">
|
|
13
|
+
<img alt="MPP" src="https://img.shields.io/badge/MPP-experimental-f0a30a">
|
|
13
14
|
<img alt="A2A" src="https://img.shields.io/badge/A2A-experimental-f0a30a">
|
|
14
15
|
<img alt="ACP" src="https://img.shields.io/badge/ACP-experimental-f0a30a">
|
|
15
16
|
<img alt="AP2" src="https://img.shields.io/badge/AP2-experimental-f0a30a">
|
|
@@ -17,48 +18,48 @@
|
|
|
17
18
|
|
|
18
19
|
## What it is, in ten seconds
|
|
19
20
|
|
|
20
|
-
You already have an HTTP API. AI agents
|
|
21
|
-
|
|
21
|
+
You already have an HTTP API. Agent Commerce Gateway lets AI agents discover,
|
|
22
|
+
call and pay for it without adding those protocols to your backend.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
wallet - the gateway never holds it, and never holds your keys.
|
|
24
|
+
Run the gateway in your infrastructure and describe each endpoint in YAML, or
|
|
25
|
+
generate draft resource definitions from OpenAPI. Resources can be exposed over
|
|
26
|
+
HTTP, MCP or experimental A2A; dedicated resources can implement experimental
|
|
27
|
+
ACP checkout operations. Paid resources use x402 or experimental MPP and can
|
|
28
|
+
also require an AP2 mandate proving that the buyer approved the purchase. Funds
|
|
29
|
+
go directly to the merchant wallet, and the gateway needs neither the buyer's
|
|
30
|
+
nor the merchant's private key.
|
|
31
31
|
|
|
32
32
|
```text
|
|
33
33
|
Your existing API → Agent Commerce Gateway → AI Agent
|
|
34
|
-
|
|
34
|
+
MCP · A2A · ACP · x402 · MPP · AP2 · receipts · doctor
|
|
35
35
|
```
|
|
36
36
|
|
|
37
37
|
## Demo
|
|
38
38
|
|
|
39
39
|
```text
|
|
40
|
-
[agent]
|
|
41
|
-
[
|
|
42
|
-
[agent]
|
|
43
|
-
|
|
44
|
-
[
|
|
45
|
-
[
|
|
46
|
-
[gateway]
|
|
47
|
-
[
|
|
48
|
-
[
|
|
49
|
-
[gateway]
|
|
50
|
-
|
|
51
|
-
[
|
|
52
|
-
[
|
|
53
|
-
[
|
|
54
|
-
[
|
|
55
|
-
[
|
|
40
|
+
[agent] Agent Commerce Gateway: deterministic buyer demo
|
|
41
|
+
[buyer] balance before 100 MockUSDC
|
|
42
|
+
[agent] merchant balance before 0 MockUSDC
|
|
43
|
+
[gateway] connected to http://localhost:8080/mcp
|
|
44
|
+
[agent] discovered 2 tool(s): weather_basic, market_report
|
|
45
|
+
[agent] paid tool: "market_report", free tool: "weather_basic"
|
|
46
|
+
[gateway] 402 payment required: 0.01 USDC to 0x7099…79C8
|
|
47
|
+
[buyer] challenge checked before signing: pays 10000 units of 0x5fbd…0aa3 to 0x7099…79C8
|
|
48
|
+
[buyer] signed x402 payment proof (LOCAL DEVELOPMENT ONLY - DO NOT FUND)
|
|
49
|
+
[gateway] delivered "market_report"
|
|
50
|
+
[receipt] id=receipt_484b…1eba requestId=mcp_4292…c930 status=settled settlementTx=0x0b19…1c7f
|
|
51
|
+
[buyer] balance after 99.99 MockUSDC (Δ -0.01)
|
|
52
|
+
[agent] merchant balance after 0.01 MockUSDC (Δ 0.01)
|
|
53
|
+
[agent] on-chain balance changes match the expected payment amount
|
|
54
|
+
[gateway] delivered free tool "weather_basic": {"city":"Paris","temperatureC":-4,…}
|
|
55
|
+
[agent] demo complete: free and paid delivery both verified
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
This excerpt of `npm run demo:agent` omits the address lines and shortens long
|
|
59
|
+
values. Balances, IDs and hashes differ from run to run.
|
|
60
|
+
|
|
61
|
+
The dashboard at <http://localhost:5173> polls the gateway's events route and
|
|
62
|
+
shows the same request within a few seconds.
|
|
62
63
|
|
|
63
64
|
## Install
|
|
64
65
|
|
|
@@ -68,21 +69,19 @@ npm install -g @devlab.group/agent-commerce # or install the `agent-commerce` bi
|
|
|
68
69
|
agent-commerce doctor
|
|
69
70
|
```
|
|
70
71
|
|
|
71
|
-
Requires **Node >= 22**.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
Requires **Node >= 22**. The package includes the `agent-commerce` CLI
|
|
73
|
+
(`init`, `validate`, `doctor`, `demo`, `import openapi`, `version`) and a library
|
|
74
|
+
for embedding the gateway.
|
|
75
|
+
The default install excludes optional protocol, payment and authorization
|
|
76
|
+
peers. The OpenAPI parser is a regular dependency because import is part of the
|
|
77
|
+
CLI.
|
|
77
78
|
|
|
78
79
|
```ts
|
|
79
80
|
import { createGateway, loadConfig, receipts } from '@devlab.group/agent-commerce';
|
|
80
81
|
|
|
81
82
|
const config = await loadConfig({ path: 'config.yaml' });
|
|
82
83
|
const store = receipts({ path: './receipts.sqlite' });
|
|
83
|
-
//
|
|
84
|
-
// for the SQLite one this is where a schema written by a newer version is
|
|
85
|
-
// caught, at boot rather than at the first query
|
|
84
|
+
// Initialize before use so an incompatible SQLite schema fails at startup
|
|
86
85
|
await store.init();
|
|
87
86
|
|
|
88
87
|
const gateway = await createGateway({
|
|
@@ -94,21 +93,23 @@ const gateway = await createGateway({
|
|
|
94
93
|
const { url } = await gateway.listen();
|
|
95
94
|
```
|
|
96
95
|
|
|
97
|
-
### Optional peers
|
|
96
|
+
### Optional peers
|
|
98
97
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
the x402 rail brings the whole EVM signing and RPC stack, which a gateway
|
|
102
|
-
serving a free HTTP resource has no business installing.
|
|
98
|
+
Components with extra dependencies use separate subpaths, so a gateway serving
|
|
99
|
+
free HTTP resources does not install MCP, EVM, JOSE or SD-JWT packages.
|
|
103
100
|
|
|
104
101
|
| You want | Install | Import |
|
|
105
102
|
| --------------------------------------- | ---------------------------------- | ------------------------------------------ |
|
|
106
|
-
| gateway, config, receipts, CLI
|
|
103
|
+
| gateway, config, receipts, A2A/ACP, CLI | `@devlab.group/agent-commerce` | `from '@devlab.group/agent-commerce'` |
|
|
107
104
|
| expose resources as MCP tools | `+ @modelcontextprotocol/sdk` | `from '@devlab.group/agent-commerce/mcp'` |
|
|
108
105
|
| accept x402 payments | `+ @x402/core @x402/evm viem` | `from '@devlab.group/agent-commerce/x402'` |
|
|
106
|
+
| accept MPP payments | `+ mppx viem @x402/core @x402/evm` | `from '@devlab.group/agent-commerce/mpp'` |
|
|
109
107
|
| verify AP2 mandates, sign checkout JWTs | `+ jose @sd-jwt/core canonicalize` | `from '@devlab.group/agent-commerce/ap2'` |
|
|
110
108
|
| authenticate to a CDP facilitator | `+ @coinbase/x402` | (no import - loaded on demand) |
|
|
111
109
|
|
|
110
|
+
MPP settles through an x402 facilitator, so its entry also needs the x402
|
|
111
|
+
peers.
|
|
112
|
+
|
|
112
113
|
```bash
|
|
113
114
|
npm install @devlab.group/agent-commerce @modelcontextprotocol/sdk @x402/core @x402/evm viem
|
|
114
115
|
```
|
|
@@ -119,23 +120,17 @@ import { x402 } from '@devlab.group/agent-commerce/x402';
|
|
|
119
120
|
import { ap2 } from '@devlab.group/agent-commerce/ap2';
|
|
120
121
|
```
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
deployment that gates nothing on a mandate should not carry a JOSE stack and an
|
|
125
|
-
SD-JWT parser to serve a resource.
|
|
123
|
+
AP2 peers remain optional because a deployment without mandate-gated resources
|
|
124
|
+
does not need JOSE or SD-JWT support.
|
|
126
125
|
|
|
127
126
|
Peers are pinned exactly: x402's schemas and EIP-712 domains cross this
|
|
128
127
|
boundary, so a version skew is a correctness problem rather than a convenience
|
|
129
|
-
one.
|
|
130
|
-
|
|
131
|
-
rather than starting a gateway that silently serves nothing.
|
|
128
|
+
one. Importing a subpath without its peer fails at load time and names the
|
|
129
|
+
missing package.
|
|
132
130
|
|
|
133
|
-
`@coinbase/x402`
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
high-severity advisories, while the package itself and the other three peers
|
|
137
|
-
audit clean. `auth.type: bearer` covers any facilitator with a static token and
|
|
138
|
-
installs nothing.
|
|
131
|
+
`@coinbase/x402` has no subpath import. It is loaded dynamically only for
|
|
132
|
+
`facilitator.auth.type: cdp` and brings the larger CDP dependency tree. A
|
|
133
|
+
facilitator with a static token can use `auth.type: bearer` without it.
|
|
139
134
|
|
|
140
135
|
## Quickstart
|
|
141
136
|
|
|
@@ -155,15 +150,13 @@ npm run agent-commerce -- doctor --config config-demo.yaml # verify the whole st
|
|
|
155
150
|
npm run demo:agent # watch an agent buy something
|
|
156
151
|
```
|
|
157
152
|
|
|
158
|
-
<sub><b>Linux
|
|
159
|
-
<code>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
Desktop on macOS and Windows translates permissions through its VM and does not
|
|
163
|
-
need this.</sub>
|
|
153
|
+
<sub><b>Linux:</b> if your UID/GID is not 1000, export
|
|
154
|
+
<code>DOCKER_UID=$(id -u) DOCKER_GID=$(id -g)</code> before
|
|
155
|
+
<code>docker compose up</code>. This keeps the generated deployment manifest
|
|
156
|
+
host-writable. Docker Desktop does not need this.</sub>
|
|
164
157
|
|
|
165
|
-
|
|
166
|
-
|
|
158
|
+
The disposable local stack includes Anvil, MockUSDC, a demo merchant API, the
|
|
159
|
+
gateway and a dashboard.
|
|
167
160
|
|
|
168
161
|
To stop and wipe state: `docker compose down -v`.
|
|
169
162
|
|
|
@@ -174,7 +167,7 @@ To stop and wipe state: `docker compose down -v`.
|
|
|
174
167
|
│ AI Agent │
|
|
175
168
|
└───────────────────────────────────────┬──────────────────────────────────────┘
|
|
176
169
|
│ MCP · A2A · ACP · HTTP
|
|
177
|
-
│
|
|
170
|
+
│ payment proof
|
|
178
171
|
│ Agent-Authorization
|
|
179
172
|
┌───────────────────────────────────────▼──────────────────────────────────────┐
|
|
180
173
|
│ Agent Commerce Gateway (yours) │
|
|
@@ -184,7 +177,7 @@ To stop and wipe state: `docker compose down -v`.
|
|
|
184
177
|
│ ┌────────────────────┬──────────────┴──┬────────────────┐ │
|
|
185
178
|
│ ▼ ▼ ▼ ▼ │
|
|
186
179
|
│ AuthorizationProvider PaymentProvider BackendExecutor ReceiptStore │
|
|
187
|
-
│ (ap2)
|
|
180
|
+
│ (ap2) (x402, mpp) (bounded HTTP) (SQLite) │
|
|
188
181
|
└───────────────────────────────────────┬──────────────────────────────────────┘
|
|
189
182
|
│
|
|
190
183
|
┌──────────▼─────────┐
|
|
@@ -192,11 +185,8 @@ To stop and wipe state: `docker compose down -v`.
|
|
|
192
185
|
└────────────────────┘
|
|
193
186
|
```
|
|
194
187
|
|
|
195
|
-
Every protocol adapter
|
|
196
|
-
|
|
197
|
-
adapter has to remember. Money never passes through the box: the buyer pays the
|
|
198
|
-
merchant directly on chain, and the gateway holds neither the funds nor a key.
|
|
199
|
-
Full detail in [docs/architecture.md](docs/architecture.md).
|
|
188
|
+
Every protocol adapter uses one execution pipeline, so payment enforcement does
|
|
189
|
+
not depend on the adapter. See [Architecture](docs/architecture.md).
|
|
200
190
|
|
|
201
191
|
## Configure a resource
|
|
202
192
|
|
|
@@ -217,7 +207,7 @@ resources:
|
|
|
217
207
|
payments: [x402]
|
|
218
208
|
```
|
|
219
209
|
|
|
220
|
-
|
|
210
|
+
The gateway calls your existing backend, which needs no SDK or changes.
|
|
221
211
|
|
|
222
212
|
```bash
|
|
223
213
|
npm run agent-commerce -- init # generate a config interactively
|
|
@@ -231,57 +221,58 @@ Already have an OpenAPI description? Generate the resources from it
|
|
|
231
221
|
agent-commerce import openapi ./openapi.yaml
|
|
232
222
|
```
|
|
233
223
|
|
|
234
|
-
It writes a reviewable `resources:` fragment
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
224
|
+
It writes a reviewable `resources:` fragment with path, query and JSON body
|
|
225
|
+
bindings and supported schemas. The source document never decides price or
|
|
226
|
+
exposure: `pricing` appears only with `--free` and `expose` only with
|
|
227
|
+
`--expose`, and credentials are never imported. See
|
|
228
|
+
[OpenAPI import](docs/openapi-import.md) for the supported subset.
|
|
239
229
|
|
|
240
230
|
See [docs/configuration.md](docs/configuration.md).
|
|
241
231
|
|
|
242
232
|
## Protocol support
|
|
243
233
|
|
|
244
|
-
| Protocol
|
|
245
|
-
|
|
|
246
|
-
| **
|
|
247
|
-
| **
|
|
248
|
-
| **
|
|
249
|
-
| **
|
|
250
|
-
| **
|
|
251
|
-
| **
|
|
252
|
-
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
method
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
list at runtime through `GET /.well-known/agent-commerce` and
|
|
270
|
-
`agent-commerce doctor`, so the claim is checkable rather than marketing.
|
|
234
|
+
| Protocol | Status | Pinned revision |
|
|
235
|
+
| -------- | ------------ | ------------------------------------------------------------------------- |
|
|
236
|
+
| **HTTP** | Supported | native routes |
|
|
237
|
+
| **MCP** | Supported | `@modelcontextprotocol/sdk@1.30.0` |
|
|
238
|
+
| **x402** | Supported | x402 v2 (`@x402/core`, `@x402/evm`), scheme `exact`, EVM |
|
|
239
|
+
| **MPP** | Experimental | `mppx@0.10.1`, `charge` + `evm` + EIP-3009, USDC on Base Sepolia and Base |
|
|
240
|
+
| **A2A** | Experimental | A2A v1.0.0, binding `JSONRPC`, method `SendMessage` |
|
|
241
|
+
| **ACP** | Experimental | ACP `2026-04-17`, REST checkout + discovery |
|
|
242
|
+
| **AP2** | Experimental | AP2 `v0.2.0`, Direct Checkout Mandate verification |
|
|
243
|
+
| UCP | Planned | no implementation |
|
|
244
|
+
|
|
245
|
+
[AP2](docs/ap2.md) is an authorization method, not a transport. It verifies a
|
|
246
|
+
mandate before a paid resource settles; the gateway does not issue the mandate
|
|
247
|
+
or its Checkout Receipt.
|
|
248
|
+
|
|
249
|
+
The experimental entries above ship off by default with documented subsets:
|
|
250
|
+
[A2A](docs/protocols.md#a2a), [ACP](docs/protocols.md#acp),
|
|
251
|
+
[AP2](docs/ap2.md#not-implemented) and [MPP](docs/protocols.md#mpp). Supported
|
|
252
|
+
[MCP](docs/protocols.md#mcp) and [x402](docs/protocols.md#x402) are also scoped.
|
|
253
|
+
ACP exposes only its five checkout operations; merchant `payment_data` is never
|
|
254
|
+
converted into a gateway payment proof.
|
|
255
|
+
|
|
256
|
+
`GET /.well-known/agent-commerce` reports `supportedSpec`, `capabilities` and
|
|
257
|
+
`unsupported` for registered adapters and providers. `agent-commerce doctor`
|
|
258
|
+
prints the `unsupported` lists for A2A, ACP and AP2 when they are enabled.
|
|
271
259
|
|
|
272
260
|
## Payment model
|
|
273
261
|
|
|
274
|
-
- **Non-custodial.**
|
|
275
|
-
|
|
262
|
+
- **Non-custodial.** Buyer payments go directly to the merchant address in
|
|
263
|
+
`payTo` (`recipient` for MPP). The gateway does not require buyer or merchant
|
|
264
|
+
private keys. Local facilitator mode does hold a separate gas-paying signer.
|
|
276
265
|
- **Fail closed.** Missing, malformed, expired, replayed, wrong-amount,
|
|
277
|
-
wrong-recipient, wrong-network and wrong-asset payments
|
|
278
|
-
test.
|
|
266
|
+
wrong-recipient, wrong-network and wrong-asset payments are rejected.
|
|
279
267
|
- **Replay-safe twice over.** EIP-3009 stops a double spend on-chain; the
|
|
280
|
-
gateway additionally reserves a `replayKey` derived from the
|
|
268
|
+
gateway additionally reserves a `replayKey` derived from the authorization
|
|
281
269
|
before it settles anything.
|
|
282
|
-
- **
|
|
270
|
+
- **On-chain settlement in CI.** The end-to-end test asserts the buyer's balance
|
|
283
271
|
falls and the merchant's rises by exactly the price, with a real transaction
|
|
284
272
|
hash in the receipt. A log line saying "payment successful" would not count.
|
|
273
|
+
- **One selected rail per resource.** A resource can name several rails, such as
|
|
274
|
+
`payments: [x402, mpp]`; the first enabled one serves it, and nothing selects
|
|
275
|
+
or falls back between rails per request.
|
|
285
276
|
- **Authorization is separate from payment.** A resource can also require an
|
|
286
277
|
AP2 mandate, verified before settlement and spendable exactly once. It never
|
|
287
278
|
moves money and never unlocks a resource on its own - the payment still has
|
|
@@ -289,50 +280,48 @@ list at runtime through `GET /.well-known/agent-commerce` and
|
|
|
289
280
|
|
|
290
281
|
## Public networks
|
|
291
282
|
|
|
292
|
-
|
|
293
|
-
|
|
283
|
+
Public networks use the same execution pipeline with a remote facilitator.
|
|
284
|
+
Choose the network in config; Base mainnet also requires `allowMainnet: true`.
|
|
294
285
|
|
|
295
286
|
### It has actually settled
|
|
296
287
|
|
|
297
|
-
|
|
298
|
-
|
|
288
|
+
These transactions each moved 0.01 USDC from a buyer to a merchant through a
|
|
289
|
+
remote facilitator:
|
|
299
290
|
|
|
300
|
-
| Network | Transaction |
|
|
301
|
-
| ------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
302
|
-
| Base Sepolia | [`0xea41b234c4…`](https://sepolia.basescan.org/tx/0xea41b234c4645a4d335589ec9753646aa7cccd1b97e9e15823b88bff7b54a247) |
|
|
303
|
-
| Base | [`0x57ec81c2a3…`](https://basescan.org/tx/0x57ec81c2a360d14d59a43cf4e24be09a6bd75cbe6185016372895bda73e42763) |
|
|
291
|
+
| Rail | Network | Transaction |
|
|
292
|
+
| ---- | ------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
293
|
+
| x402 | Base Sepolia | [`0xea41b234c4…`](https://sepolia.basescan.org/tx/0xea41b234c4645a4d335589ec9753646aa7cccd1b97e9e15823b88bff7b54a247) |
|
|
294
|
+
| x402 | Base | [`0x57ec81c2a3…`](https://basescan.org/tx/0x57ec81c2a360d14d59a43cf4e24be09a6bd75cbe6185016372895bda73e42763) |
|
|
295
|
+
| MPP | Base Sepolia | [`0x5d9fcd111b…`](https://sepolia.basescan.org/tx/0x5d9fcd111b615bb8fc9e56d55096f119fc81c3c72c334f813cfaecee402d0ac3) |
|
|
296
|
+
| MPP | Base | [`0xf4255bd7ec…`](https://basescan.org/tx/0xf4255bd7ec46ed06505dedfb5f9537924bd2633816e7952ec6f2b468395b1087) |
|
|
304
297
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
success is not the proof.
|
|
298
|
+
The buyer signed each EIP-3009 authorization without ETH; the remote facilitator
|
|
299
|
+
paid gas and broadcast it. The gateway path received no buyer or merchant key.
|
|
300
|
+
The public-network smoke suites verify balance changes and fetch the transaction
|
|
301
|
+
receipt from the chain instead of trusting the gateway's response.
|
|
310
302
|
|
|
311
|
-
Reproduce with `npm run test:testnet
|
|
312
|
-
|
|
303
|
+
Reproduce with `npm run test:testnet`, which spends test USDC, or
|
|
304
|
+
`npm run test:mainnet`, which spends real USDC. Both run only by hand; see
|
|
305
|
+
[Base mainnet](#base-mainnet).
|
|
313
306
|
|
|
314
307
|
### The facilitator model
|
|
315
308
|
|
|
316
|
-
A **facilitator** verifies the buyer's
|
|
317
|
-
transfer. It is the only component that needs gas
|
|
318
|
-
gateway on a public network.
|
|
309
|
+
A **facilitator** verifies the buyer's authorization and broadcasts the
|
|
310
|
+
transfer. It is the only component that needs gas.
|
|
319
311
|
|
|
320
|
-
| `facilitator.mode` | Who signs
|
|
321
|
-
| ------------------ |
|
|
322
|
-
| `local` | this process, with
|
|
323
|
-
| `remote` | an HTTP facilitator you point at
|
|
312
|
+
| `facilitator.mode` | Who signs | Where it is allowed |
|
|
313
|
+
| ------------------ | -------------------------------------- | ------------------------------------------------------------------ |
|
|
314
|
+
| `local` | this process, with a key you configure | a local Anvil chain; refused on mainnet, fails readiness elsewhere |
|
|
315
|
+
| `remote` | an HTTP facilitator you point at | anywhere |
|
|
324
316
|
|
|
325
|
-
With `remote`, the gateway holds
|
|
326
|
-
EIP-3009
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
nothing. What it can do is see every authorisation you handle, and stop
|
|
330
|
-
answering.
|
|
317
|
+
With `remote`, the gateway holds no facilitator signing key. The buyer signs an
|
|
318
|
+
EIP-3009 authorization without ETH, and the facilitator pays gas. Because the
|
|
319
|
+
authorization fixes the recipient, amount and chain, the facilitator cannot
|
|
320
|
+
redirect the transfer. It can see authorizations and refuse service.
|
|
331
321
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
own - `remote` does not care who operates the endpoint.
|
|
322
|
+
Remote facilitator auth supports `none`, `bearer` and `cdp`. `cdp` loads the
|
|
323
|
+
optional peer `@coinbase/x402`, which signs a fresh JWT per request; bearer auth
|
|
324
|
+
needs no extra peer. Other types are rejected at config load.
|
|
336
325
|
|
|
337
326
|
### Base Sepolia
|
|
338
327
|
|
|
@@ -366,55 +355,51 @@ together, and reported by `doctor`, `health()` and `/.well-known`.
|
|
|
366
355
|
|
|
367
356
|
### Base mainnet
|
|
368
357
|
|
|
369
|
-
|
|
370
|
-
load, and the gateway will not start without them:
|
|
358
|
+
Mainnet moves real funds. Config validation requires:
|
|
371
359
|
|
|
372
|
-
| Required
|
|
373
|
-
|
|
|
374
|
-
| `allowMainnet: true`
|
|
375
|
-
| `facilitator.mode: remote`
|
|
376
|
-
| an HTTPS `facilitator.url`
|
|
377
|
-
| `allowUnauthenticatedFacilitator: true`
|
|
378
|
-
| a non-development `payTo`
|
|
379
|
-
|
|
|
360
|
+
| Required | |
|
|
361
|
+
| -------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
362
|
+
| `allowMainnet: true` | mainnet is never a default |
|
|
363
|
+
| `facilitator.mode: remote` | `local` needs a funded gas key inside this process |
|
|
364
|
+
| an HTTPS `facilitator.url` | |
|
|
365
|
+
| `allowUnauthenticatedFacilitator: true` | required when `facilitator.auth.type` is `none` |
|
|
366
|
+
| a non-development destination (`payTo` or `recipient`) | |
|
|
367
|
+
| Base USDC with `assetName: "USD Coin"` and `assetVersion: "2"` | the buyer signs this EIP-712 domain; `"USDC"` is wrong on Base |
|
|
380
368
|
|
|
381
369
|
Full config in [`examples/base-mainnet/`](examples/base-mainnet/), and
|
|
382
370
|
[`examples/base-mainnet-payai/`](examples/base-mainnet-payai/) for an
|
|
383
|
-
unauthenticated facilitator.
|
|
384
|
-
|
|
371
|
+
unauthenticated facilitator. The mainnet smoke suites cover x402 and MPP and
|
|
372
|
+
spend real USDC when their opt-ins and credentials are present.
|
|
385
373
|
|
|
386
374
|
`agent-commerce validate` reports any of the above before anything starts, and
|
|
387
375
|
`doctor` prints `LIVE MAINNET MODE - REAL FUNDS`.
|
|
388
376
|
|
|
389
|
-
>
|
|
390
|
-
>
|
|
391
|
-
>
|
|
392
|
-
> wallet, and skip themselves without credentials.
|
|
377
|
+
> The public-network suites never run in CI, because a workflow would need a
|
|
378
|
+
> funded buyer key in repository secrets. Run them from the machine that holds
|
|
379
|
+
> the wallet. A test whose required settings are missing skips itself.
|
|
393
380
|
|
|
394
381
|
## Diagnostics
|
|
395
382
|
|
|
396
383
|
```console
|
|
397
384
|
$ npm run agent-commerce -- doctor --config config-demo.yaml
|
|
398
385
|
|
|
399
|
-
PASS Config valid
|
|
386
|
+
PASS Config valid: 2 resource(s), merchant "Demo Data Store" (using local chain manifest .deploy/local.json for X402_ASSET, X402_ASSET_NAME, X402_ASSET_VERSION, X402_ASSET_DECIMALS, MERCHANT_WALLET, X402_FACILITATOR_PRIVATE_KEY)
|
|
400
387
|
PASS Gateway healthy and ready at http://127.0.0.1:8080
|
|
401
388
|
PASS Backend 2/2 backend host(s) reachable
|
|
402
389
|
PASS Protocols http=on mcp=on (/mcp) a2a=off acp=off
|
|
403
390
|
INFO A2A disabled
|
|
404
391
|
INFO ACP disabled
|
|
405
392
|
INFO AP2 disabled
|
|
406
|
-
PASS Payments x402 v2 (scheme=exact) enabled - LOCAL dev chain (eip155:84532, chain id shared with Base Sepolia), destination=0x7099…79C8, facilitator=local
|
|
407
|
-
INFO Payments (MPP)
|
|
408
|
-
PASS Storage sqlite schema
|
|
393
|
+
PASS Payments x402 v2 (scheme=exact) enabled - LOCAL dev chain (eip155:84532, chain id shared with Base Sepolia), destination=0x7099…79C8, facilitator=local (in-process)
|
|
394
|
+
INFO Payments (MPP) MPP not configured
|
|
395
|
+
PASS Storage sqlite schema v2 writable; receipts=2
|
|
409
396
|
PASS Protocol versions reported by gateway /.well-known/agent-commerce
|
|
410
397
|
|
|
411
398
|
Score: 7/7 checks passed
|
|
412
399
|
```
|
|
413
400
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
resolves to, and fails if they disagree - a diagnostic that passes while the
|
|
417
|
-
system is misconfigured is worse than none.
|
|
401
|
+
`doctor` cross-checks the gateway's live settlement configuration against the
|
|
402
|
+
resolved local config and fails if they differ.
|
|
418
403
|
|
|
419
404
|
Exits non-zero if anything fails. `--json` for machines.
|
|
420
405
|
|
|
@@ -426,8 +411,8 @@ reachable by anyone else, know the split:
|
|
|
426
411
|
- **Agent routes** (`/api/resources/:id/invoke`, `/mcp`, the A2A mount) are
|
|
427
412
|
unauthenticated by design - paid resources are protected by payment, not by a
|
|
428
413
|
password. ACP is the exception: its checkout routes require a bearer token.
|
|
429
|
-
- **Operator routes** (`/api/receipts`, `/api/events
|
|
430
|
-
|
|
414
|
+
- **Operator routes** (`/api/receipts`, `/api/events`) are the merchant's
|
|
415
|
+
commerce ledger: payer addresses, amounts, settlement hashes.
|
|
431
416
|
They require `server.adminToken`, and return **404** if none is configured.
|
|
432
417
|
- **Browsers** are governed by `server.allowedOrigins`, an explicit allowlist
|
|
433
418
|
that defaults to empty.
|
|
@@ -452,30 +437,30 @@ See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
|
452
437
|
**Now** - MCP, x402 v2, settlement on the local chain, Base Sepolia and Base
|
|
453
438
|
mainnet, receipts, doctor, deterministic demo, experimental A2A v1.0.0 and ACP
|
|
454
439
|
`2026-04-17` checkout adapters, experimental AP2 v0.2.0 mandate verification,
|
|
455
|
-
and experimental OpenAPI import.
|
|
440
|
+
experimental MPP `charge` payments, and experimental OpenAPI import.
|
|
456
441
|
|
|
457
|
-
**Next** - a `doctor` GitHub Action · UCP ·
|
|
458
|
-
mandates, agent key binding, constraint evaluation) ·
|
|
459
|
-
delegated payment) · Shopify and WooCommerce examples ·
|
|
460
|
-
observability · multi-file and remote OpenAPI sources.
|
|
442
|
+
**Next** - a `doctor` GitHub Action · UCP ·
|
|
443
|
+
autonomous-mode AP2 (open mandates, agent key binding, constraint evaluation) ·
|
|
444
|
+
more of ACP (carts, feed, delegated payment) · Shopify and WooCommerce examples ·
|
|
445
|
+
PostgreSQL · richer observability · multi-file and remote OpenAPI sources.
|
|
461
446
|
|
|
462
|
-
New protocols
|
|
463
|
-
|
|
447
|
+
New protocols need evidence that the adapter model works in real use before
|
|
448
|
+
they are added to a release.
|
|
464
449
|
|
|
465
450
|
## Documentation
|
|
466
451
|
|
|
467
452
|
| | |
|
|
468
453
|
| ---------------------------------------------- | ------------------------------------------- |
|
|
469
454
|
| [Architecture](docs/architecture.md) | how the pieces fit |
|
|
470
|
-
| [Payment flow](docs/payment-flow.md) | the paid round trip
|
|
471
|
-
| [Protocols](docs/protocols.md) |
|
|
455
|
+
| [Payment flow](docs/payment-flow.md) | the paid round trip and failure paths |
|
|
456
|
+
| [Protocols](docs/protocols.md) | supported and unsupported protocol features |
|
|
472
457
|
| [AP2](docs/ap2.md) | mandate verification and the trust model |
|
|
473
458
|
| [Configuration](docs/configuration.md) | `config.yaml` reference |
|
|
474
459
|
| [OpenAPI import](docs/openapi-import.md) | generate resources from an existing API |
|
|
475
460
|
| [Security model](docs/security.md) | trust boundaries, and what we do not defend |
|
|
476
|
-
| [Contracts](docs/contracts.md) | the frozen cross-
|
|
461
|
+
| [Contracts](docs/contracts.md) | the frozen cross-area contract |
|
|
477
462
|
| [Adapter guide](docs/contributing-adapters.md) | add a protocol or a payment rail |
|
|
478
463
|
|
|
479
|
-
##
|
|
464
|
+
## License
|
|
480
465
|
|
|
481
466
|
[Apache-2.0](LICENSE).
|