@devlab.group/agent-commerce 2.1.0 → 2.2.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.
Files changed (73) hide show
  1. package/README.md +35 -5
  2. package/dist/ap2.js +3 -3
  3. package/dist/{chunk-SY6GUYSQ.js → chunk-7ZMMXZ4G.js} +3 -3
  4. package/dist/{chunk-SY6GUYSQ.js.map → chunk-7ZMMXZ4G.js.map} +1 -1
  5. package/dist/{chunk-UHMYRV3J.js → chunk-HNRDZLSN.js} +7 -5
  6. package/dist/chunk-HNRDZLSN.js.map +1 -0
  7. package/dist/{chunk-LZS5BL3W.js → chunk-IEW7NSP2.js} +23 -5
  8. package/dist/chunk-IEW7NSP2.js.map +1 -0
  9. package/dist/{chunk-IFGRCXME.js → chunk-Y4RE3XYF.js} +3 -3
  10. package/dist/{chunk-IFGRCXME.js.map → chunk-Y4RE3XYF.js.map} +1 -1
  11. package/dist/cli/ap2-MBMQHFX4.js +678 -0
  12. package/dist/cli/ap2-MBMQHFX4.js.map +1 -0
  13. package/dist/cli/chunk-2ZZOGI5I.js +1352 -0
  14. package/dist/cli/chunk-2ZZOGI5I.js.map +1 -0
  15. package/dist/cli/chunk-3EQBCFZY.js +53 -0
  16. package/dist/cli/chunk-3EQBCFZY.js.map +1 -0
  17. package/dist/cli/chunk-3M6U7ILB.js +8 -0
  18. package/dist/cli/chunk-3M6U7ILB.js.map +1 -0
  19. package/dist/cli/chunk-3MGAJ5FX.js +70 -0
  20. package/dist/cli/chunk-3MGAJ5FX.js.map +1 -0
  21. package/dist/cli/chunk-5K4XEAZV.js +113 -0
  22. package/dist/cli/chunk-5K4XEAZV.js.map +1 -0
  23. package/dist/cli/chunk-7JNYFUT3.js +256 -0
  24. package/dist/cli/chunk-7JNYFUT3.js.map +1 -0
  25. package/dist/cli/chunk-AA3FIEAR.js +27 -0
  26. package/dist/cli/chunk-AA3FIEAR.js.map +1 -0
  27. package/dist/cli/chunk-FHCFR2GS.js +17 -0
  28. package/dist/cli/chunk-FHCFR2GS.js.map +1 -0
  29. package/dist/cli/chunk-FRMLWGSS.js +8 -0
  30. package/dist/cli/chunk-FRMLWGSS.js.map +1 -0
  31. package/dist/cli/chunk-KLX2YZDG.js +1400 -0
  32. package/dist/cli/chunk-KLX2YZDG.js.map +1 -0
  33. package/dist/cli/chunk-NSPPEF5M.js +334 -0
  34. package/dist/cli/chunk-NSPPEF5M.js.map +1 -0
  35. package/dist/cli/chunk-OSTCU6ZK.js +44 -0
  36. package/dist/cli/chunk-OSTCU6ZK.js.map +1 -0
  37. package/dist/cli/chunk-QQ3WY5L3.js +271 -0
  38. package/dist/cli/chunk-QQ3WY5L3.js.map +1 -0
  39. package/dist/cli/chunk-RWVPYAKC.js +1742 -0
  40. package/dist/cli/chunk-RWVPYAKC.js.map +1 -0
  41. package/dist/cli/chunk-SPAYKVUP.js +118 -0
  42. package/dist/cli/chunk-SPAYKVUP.js.map +1 -0
  43. package/dist/cli/chunk-SS3QFF5N.js +614 -0
  44. package/dist/cli/chunk-SS3QFF5N.js.map +1 -0
  45. package/dist/cli/chunk-TPC4EJLT.js +11 -0
  46. package/dist/cli/chunk-TPC4EJLT.js.map +1 -0
  47. package/dist/cli/config-4IBGVFSP.js +11 -0
  48. package/dist/cli/config-4IBGVFSP.js.map +1 -0
  49. package/dist/cli/index.js +150 -3627
  50. package/dist/cli/index.js.map +1 -1
  51. package/dist/cli/mcp-CNWQ2MOE.js +559 -0
  52. package/dist/cli/mcp-CNWQ2MOE.js.map +1 -0
  53. package/dist/cli/near-5AY3HWYF.js +58 -0
  54. package/dist/cli/near-5AY3HWYF.js.map +1 -0
  55. package/dist/cli/provider-4BQDH56Y.js +396 -0
  56. package/dist/cli/provider-4BQDH56Y.js.map +1 -0
  57. package/dist/cli/run-5MB2D45X.js +7286 -0
  58. package/dist/cli/run-5MB2D45X.js.map +1 -0
  59. package/dist/cli/svm-3MMYFPC7.js +33 -0
  60. package/dist/cli/svm-3MMYFPC7.js.map +1 -0
  61. package/dist/cli/x402-NKR3WQDQ.js +96 -0
  62. package/dist/cli/x402-NKR3WQDQ.js.map +1 -0
  63. package/dist/index.d.ts +2 -0
  64. package/dist/index.js +48 -5
  65. package/dist/index.js.map +1 -1
  66. package/dist/mcp.js +6 -16
  67. package/dist/mcp.js.map +1 -1
  68. package/dist/mpp.js +3 -3
  69. package/dist/x402.d.ts +5 -0
  70. package/dist/x402.js +4 -4
  71. package/package.json +2 -2
  72. package/dist/chunk-LZS5BL3W.js.map +0 -1
  73. package/dist/chunk-UHMYRV3J.js.map +0 -1
@@ -0,0 +1,614 @@
1
+ import { ACP_CHECKOUT_OPERATIONS, ACP_SPEC_VERSION } from './chunk-2ZZOGI5I.js';
2
+ import { openSqliteDatabase } from './chunk-3MGAJ5FX.js';
3
+ import { PACKAGE_VERSION } from './chunk-FRMLWGSS.js';
4
+ import { NOOP_LOGGER, systemClock, toCommerceError, CommerceError } from './chunk-QQ3WY5L3.js';
5
+ import { randomUUID } from 'crypto';
6
+ import { accessSync, constants } from 'fs';
7
+
8
+ // src/storage/receipts/redact.ts
9
+ var SECRET_KEY_PATTERN = /private[-_ ]?key|secret|password|mnemonic|seed[-_ ]?phrase|api[-_ ]?key|authoriz(e|ation)|^auth$|auth[-_]?header|payment[-_ ]?proof|^proof$|x-payment|signature|signed[-_ ]?message|token|bearer|credential|cookie|session|jwt/i;
10
+ var REDACTED = "[REDACTED]";
11
+ function isSecretKey(key) {
12
+ return SECRET_KEY_PATTERN.test(key);
13
+ }
14
+ function redact(value) {
15
+ return redactValue(value);
16
+ }
17
+ function redactValue(value) {
18
+ if (Array.isArray(value)) {
19
+ return value.map(redactValue);
20
+ }
21
+ if (value !== null && typeof value === "object") {
22
+ const out = {};
23
+ for (const [key, inner] of Object.entries(value)) {
24
+ out[key] = isSecretKey(key) ? REDACTED : redactValue(inner);
25
+ }
26
+ return out;
27
+ }
28
+ return value;
29
+ }
30
+
31
+ // src/storage/receipts/rows.ts
32
+ function receiptToRow(receipt) {
33
+ return {
34
+ id: receipt.id,
35
+ request_id: receipt.requestId,
36
+ resource_id: receipt.resourceId,
37
+ payment_json: receipt.payment !== void 0 ? JSON.stringify(redact(receipt.payment)) : null,
38
+ delivered_at: receipt.deliveredAt,
39
+ backend_status: receipt.backendStatus,
40
+ duration_ms: receipt.durationMs ?? null,
41
+ protocol: receipt.protocol ?? null,
42
+ metadata_json: receipt.metadata !== void 0 ? JSON.stringify(redact(receipt.metadata)) : null,
43
+ authorization_json: receipt.authorization !== void 0 ? JSON.stringify(redact(receipt.authorization)) : null
44
+ };
45
+ }
46
+ function rowToReceipt(row) {
47
+ const payment = row.payment_json !== null ? JSON.parse(row.payment_json) : void 0;
48
+ const metadata = row.metadata_json !== null ? JSON.parse(row.metadata_json) : void 0;
49
+ const authorization = row.authorization_json !== null ? JSON.parse(row.authorization_json) : void 0;
50
+ return {
51
+ id: row.id,
52
+ requestId: row.request_id,
53
+ resourceId: row.resource_id,
54
+ deliveredAt: row.delivered_at,
55
+ backendStatus: row.backend_status,
56
+ ...payment !== void 0 ? { payment } : {},
57
+ ...row.duration_ms !== null ? { durationMs: row.duration_ms } : {},
58
+ ...row.protocol !== null ? { protocol: row.protocol } : {},
59
+ ...metadata !== void 0 ? { metadata } : {},
60
+ ...authorization !== void 0 ? { authorization } : {}
61
+ };
62
+ }
63
+ function eventToRow(event) {
64
+ return {
65
+ id: event.id,
66
+ type: event.type,
67
+ request_id: event.requestId,
68
+ resource_id: event.resourceId ?? null,
69
+ at: event.at,
70
+ adapter: event.adapter ?? null,
71
+ payment_provider: event.paymentProvider ?? null,
72
+ duration_ms: event.durationMs ?? null,
73
+ status: event.status ?? null,
74
+ data_json: event.data !== void 0 ? JSON.stringify(redact(event.data)) : null
75
+ };
76
+ }
77
+ function rowToEvent(row) {
78
+ const data = row.data_json !== null ? JSON.parse(row.data_json) : void 0;
79
+ return {
80
+ id: row.id,
81
+ type: row.type,
82
+ requestId: row.request_id,
83
+ at: row.at,
84
+ ...row.resource_id !== null ? { resourceId: row.resource_id } : {},
85
+ ...row.adapter !== null ? { adapter: row.adapter } : {},
86
+ ...row.payment_provider !== null ? { paymentProvider: row.payment_provider } : {},
87
+ ...row.duration_ms !== null ? { durationMs: row.duration_ms } : {},
88
+ ...row.status !== null ? { status: row.status } : {},
89
+ ...data !== void 0 ? { data } : {}
90
+ };
91
+ }
92
+ function rowToPaymentAttempt(row) {
93
+ return {
94
+ id: row.id,
95
+ requestId: row.request_id,
96
+ resourceId: row.resource_id,
97
+ provider: row.provider,
98
+ replayKey: row.replay_key,
99
+ status: row.status,
100
+ amount: row.amount,
101
+ currency: row.currency,
102
+ ...row.payer !== null ? { payer: row.payer } : {},
103
+ ...row.payee !== null ? { payee: row.payee } : {},
104
+ ...row.external_reference !== null ? { externalReference: row.external_reference } : {},
105
+ ...row.rejection_reason !== null ? { rejectionReason: row.rejection_reason } : {},
106
+ createdAt: row.created_at,
107
+ updatedAt: row.updated_at
108
+ };
109
+ }
110
+
111
+ // src/storage/receipts/schema.ts
112
+ var MIGRATIONS = [
113
+ {
114
+ version: 1,
115
+ up(db) {
116
+ db.exec(`
117
+ CREATE TABLE IF NOT EXISTS receipts (
118
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
119
+ id TEXT NOT NULL UNIQUE,
120
+ request_id TEXT NOT NULL,
121
+ resource_id TEXT NOT NULL,
122
+ payment_json TEXT,
123
+ delivered_at TEXT NOT NULL,
124
+ backend_status INTEGER NOT NULL,
125
+ duration_ms INTEGER,
126
+ protocol TEXT,
127
+ metadata_json TEXT
128
+ );
129
+ CREATE INDEX IF NOT EXISTS idx_receipts_request_id ON receipts(request_id);
130
+ CREATE INDEX IF NOT EXISTS idx_receipts_delivered_at ON receipts(delivered_at);
131
+
132
+ CREATE TABLE IF NOT EXISTS events (
133
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
134
+ id TEXT NOT NULL UNIQUE,
135
+ type TEXT NOT NULL,
136
+ request_id TEXT NOT NULL,
137
+ resource_id TEXT,
138
+ at TEXT NOT NULL,
139
+ adapter TEXT,
140
+ payment_provider TEXT,
141
+ duration_ms INTEGER,
142
+ status TEXT,
143
+ data_json TEXT
144
+ );
145
+ CREATE INDEX IF NOT EXISTS idx_events_request_id ON events(request_id);
146
+ CREATE INDEX IF NOT EXISTS idx_events_at ON events(at);
147
+
148
+ CREATE TABLE IF NOT EXISTS payment_attempts (
149
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
150
+ id TEXT NOT NULL UNIQUE,
151
+ request_id TEXT NOT NULL,
152
+ resource_id TEXT NOT NULL,
153
+ provider TEXT NOT NULL,
154
+ replay_key TEXT NOT NULL UNIQUE,
155
+ status TEXT NOT NULL,
156
+ amount TEXT NOT NULL,
157
+ currency TEXT NOT NULL,
158
+ payer TEXT,
159
+ payee TEXT,
160
+ external_reference TEXT,
161
+ rejection_reason TEXT,
162
+ created_at TEXT NOT NULL,
163
+ updated_at TEXT NOT NULL
164
+ );
165
+ CREATE INDEX IF NOT EXISTS idx_payment_attempts_request_id ON payment_attempts(request_id);
166
+ CREATE INDEX IF NOT EXISTS idx_payment_attempts_created_at ON payment_attempts(created_at);
167
+ `);
168
+ }
169
+ },
170
+ {
171
+ version: 2,
172
+ up(db) {
173
+ db.exec(`ALTER TABLE receipts ADD COLUMN authorization_json TEXT;`);
174
+ }
175
+ },
176
+ {
177
+ version: 3,
178
+ up(db) {
179
+ db.exec(`
180
+ CREATE TABLE IF NOT EXISTS payment_attempt_history (
181
+ seq INTEGER PRIMARY KEY AUTOINCREMENT,
182
+ id TEXT NOT NULL,
183
+ request_id TEXT NOT NULL,
184
+ resource_id TEXT NOT NULL,
185
+ provider TEXT NOT NULL,
186
+ replay_key TEXT NOT NULL,
187
+ status TEXT NOT NULL,
188
+ amount TEXT NOT NULL,
189
+ currency TEXT NOT NULL,
190
+ payer TEXT,
191
+ payee TEXT,
192
+ external_reference TEXT,
193
+ rejection_reason TEXT,
194
+ created_at TEXT NOT NULL,
195
+ updated_at TEXT NOT NULL,
196
+ superseded_at TEXT NOT NULL
197
+ );
198
+ CREATE INDEX IF NOT EXISTS idx_payment_attempt_history_replay_key ON payment_attempt_history(replay_key);
199
+ CREATE INDEX IF NOT EXISTS idx_payment_attempt_history_request_id ON payment_attempt_history(request_id);
200
+ `);
201
+ }
202
+ }
203
+ ];
204
+ var SCHEMA_VERSION = MIGRATIONS.at(-1)?.version ?? 0;
205
+ function migrate(db) {
206
+ const current = db.pragma("user_version", { simple: true });
207
+ for (const migration of MIGRATIONS) {
208
+ if (migration.version <= current) continue;
209
+ const apply = db.transaction(() => {
210
+ migration.up(db);
211
+ db.pragma(`user_version = ${migration.version}`);
212
+ });
213
+ apply();
214
+ }
215
+ }
216
+
217
+ // src/storage/receipts/store.ts
218
+ var DEFAULT_LIST_LIMIT = 50;
219
+ var MAX_LIST_LIMIT = 500;
220
+ function clampListLimit(limit) {
221
+ const base = limit !== void 0 && Number.isFinite(limit) ? limit : DEFAULT_LIST_LIMIT;
222
+ return Math.min(Math.max(Math.trunc(base), 1), MAX_LIST_LIMIT);
223
+ }
224
+ var defaultIds = {
225
+ next: (prefix) => prefix !== void 0 ? `${prefix}_${randomUUID()}` : randomUUID()
226
+ };
227
+ function isUniqueConstraintOn(err, column) {
228
+ return err instanceof Error && "code" in err && err.code === "SQLITE_CONSTRAINT_UNIQUE" && err.message.includes(column);
229
+ }
230
+ function createSqliteReceiptStore(options) {
231
+ const logger = options.logger ?? NOOP_LOGGER;
232
+ const clock = options.clock ?? systemClock;
233
+ const ids = options.ids ?? defaultIds;
234
+ const path = options.path;
235
+ const isFileBacked = path !== ":memory:";
236
+ const db = openSqliteDatabase({ path, label: "Receipt database", logger });
237
+ migrate(db);
238
+ const insertReceiptStmt = db.prepare(
239
+ `INSERT INTO receipts (id, request_id, resource_id, payment_json, delivered_at, backend_status, duration_ms, protocol, metadata_json, authorization_json)
240
+ VALUES (@id, @request_id, @resource_id, @payment_json, @delivered_at, @backend_status, @duration_ms, @protocol, @metadata_json, @authorization_json)`
241
+ );
242
+ const getReceiptStmt = db.prepare("SELECT * FROM receipts WHERE id = ?");
243
+ const listReceiptsStmt = db.prepare(
244
+ "SELECT * FROM receipts ORDER BY delivered_at DESC, seq DESC LIMIT ?"
245
+ );
246
+ const listReceiptsByRequestStmt = db.prepare(
247
+ "SELECT * FROM receipts WHERE request_id = ? ORDER BY delivered_at DESC, seq DESC LIMIT ?"
248
+ );
249
+ const countReceiptsStmt = db.prepare(
250
+ "SELECT COUNT(*) AS count FROM receipts"
251
+ );
252
+ const countUndeliveredReceiptsStmt = db.prepare(
253
+ "SELECT COUNT(*) AS count FROM receipts WHERE backend_status NOT BETWEEN 200 AND 299"
254
+ );
255
+ const insertEventStmt = db.prepare(
256
+ `INSERT INTO events (id, type, request_id, resource_id, at, adapter, payment_provider, duration_ms, status, data_json)
257
+ VALUES (@id, @type, @request_id, @resource_id, @at, @adapter, @payment_provider, @duration_ms, @status, @data_json)`
258
+ );
259
+ const listEventsStmt = db.prepare(
260
+ "SELECT * FROM events ORDER BY at DESC, seq DESC LIMIT ?"
261
+ );
262
+ const listEventsByRequestStmt = db.prepare(
263
+ "SELECT * FROM events WHERE request_id = ? ORDER BY at DESC, seq DESC LIMIT ?"
264
+ );
265
+ const insertPaymentAttemptStmt = db.prepare(
266
+ `INSERT INTO payment_attempts (id, request_id, resource_id, provider, replay_key, status, amount, currency, payer, payee, external_reference, rejection_reason, created_at, updated_at)
267
+ VALUES (@id, @request_id, @resource_id, @provider, @replay_key, @status, @amount, @currency, @payer, @payee, @external_reference, @rejection_reason, @created_at, @updated_at)
268
+ RETURNING *`
269
+ );
270
+ const archiveRejectedAttemptStmt = db.prepare(
271
+ `INSERT INTO payment_attempt_history (id, request_id, resource_id, provider, replay_key, status, amount, currency, payer, payee, external_reference, rejection_reason, created_at, updated_at, superseded_at)
272
+ SELECT id, request_id, resource_id, provider, replay_key, status, amount, currency, payer, payee, external_reference, rejection_reason, created_at, updated_at, @created_at
273
+ FROM payment_attempts
274
+ WHERE replay_key = @replay_key AND provider = @provider AND status = 'rejected'`
275
+ );
276
+ const reclaimPaymentAttemptStmt = db.prepare(
277
+ `UPDATE payment_attempts SET id = @id, request_id = @request_id, resource_id = @resource_id,
278
+ status = 'reserved', amount = @amount, currency = @currency,
279
+ payer = @payer, payee = @payee, external_reference = NULL, rejection_reason = NULL,
280
+ created_at = @created_at, updated_at = @updated_at
281
+ WHERE replay_key = @replay_key AND provider = @provider AND status = 'rejected'
282
+ RETURNING *`
283
+ );
284
+ const updatePaymentAttemptStmt = db.prepare(
285
+ `UPDATE payment_attempts SET status = @status,
286
+ external_reference = COALESCE(@external_reference, external_reference),
287
+ rejection_reason = COALESCE(@rejection_reason, rejection_reason),
288
+ updated_at = @updated_at
289
+ WHERE replay_key = @replay_key`
290
+ );
291
+ const listPaymentAttemptsStmt = db.prepare(
292
+ "SELECT * FROM payment_attempts ORDER BY created_at DESC, seq DESC LIMIT ?"
293
+ );
294
+ const listPaymentAttemptsByRequestStmt = db.prepare(
295
+ "SELECT * FROM payment_attempts WHERE request_id = ? ORDER BY created_at DESC, seq DESC LIMIT ?"
296
+ );
297
+ const paymentAttemptStatusStmt = db.prepare(
298
+ "SELECT status FROM payment_attempts WHERE replay_key = ?"
299
+ );
300
+ const reclaimRejectedAttempt = db.transaction(
301
+ (params) => {
302
+ archiveRejectedAttemptStmt.run(params);
303
+ return reclaimPaymentAttemptStmt.get(params);
304
+ }
305
+ );
306
+ let closed = false;
307
+ const descriptor = {
308
+ name: "sqlite-receipt-store",
309
+ kind: "storage",
310
+ implementationVersion: PACKAGE_VERSION,
311
+ supportedSpec: `sqlite-schema-v${SCHEMA_VERSION}`,
312
+ capabilities: ["receipts", "events", "payment-attempts"],
313
+ status: "stable"
314
+ };
315
+ const store = {
316
+ async init() {
317
+ const version = db.pragma("user_version", { simple: true });
318
+ if (version !== SCHEMA_VERSION) {
319
+ throw new CommerceError(
320
+ "STORAGE_ERROR",
321
+ `Receipt store schema version mismatch (found ${version}, expected ${SCHEMA_VERSION})`
322
+ );
323
+ }
324
+ },
325
+ async appendEvent(event) {
326
+ try {
327
+ insertEventStmt.run(eventToRow(event));
328
+ } catch (err) {
329
+ logger.warn(
330
+ {
331
+ err: err instanceof Error ? err.message : String(err),
332
+ eventId: event.id,
333
+ requestId: event.requestId
334
+ },
335
+ "receipt-store: failed to persist commerce event"
336
+ );
337
+ }
338
+ },
339
+ async reservePaymentAttempt(reservation) {
340
+ const now = clock.nowIso();
341
+ const params = {
342
+ id: ids.next("attempt"),
343
+ request_id: reservation.requestId,
344
+ resource_id: reservation.resourceId,
345
+ provider: reservation.provider,
346
+ replay_key: reservation.replayKey,
347
+ amount: reservation.amount,
348
+ currency: reservation.currency,
349
+ payer: reservation.payer ?? null,
350
+ payee: reservation.payee ?? null,
351
+ created_at: now,
352
+ updated_at: now
353
+ };
354
+ let row;
355
+ try {
356
+ row = (reservation.reclaimRejected === true ? reclaimRejectedAttempt.immediate(params) : void 0) ?? // RETURNING on a successful insert always yields the inserted row
357
+ insertPaymentAttemptStmt.get({
358
+ ...params,
359
+ status: "reserved",
360
+ external_reference: null,
361
+ rejection_reason: null
362
+ });
363
+ } catch (err) {
364
+ if (isUniqueConstraintOn(err, "payment_attempts.replay_key")) {
365
+ const existing = paymentAttemptStatusStmt.get(reservation.replayKey);
366
+ throw new CommerceError(
367
+ "PAYMENT_REPLAYED",
368
+ `Payment authorization has already been used (replayKey=${reservation.replayKey})`,
369
+ {
370
+ requestId: reservation.requestId,
371
+ resourceId: reservation.resourceId,
372
+ ...existing !== void 0 ? { details: { attemptStatus: existing.status } } : {}
373
+ }
374
+ );
375
+ }
376
+ throw toCommerceError(err, "STORAGE_ERROR", "Failed to reserve payment attempt");
377
+ }
378
+ return rowToPaymentAttempt(row);
379
+ },
380
+ async updatePaymentAttempt(update) {
381
+ try {
382
+ const result = updatePaymentAttemptStmt.run({
383
+ replay_key: update.replayKey,
384
+ status: update.status,
385
+ external_reference: update.externalReference ?? null,
386
+ rejection_reason: update.rejectionReason ?? null,
387
+ updated_at: clock.nowIso()
388
+ });
389
+ if (result.changes === 0) {
390
+ throw new CommerceError(
391
+ "STORAGE_ERROR",
392
+ `No payment attempt found for replayKey=${update.replayKey}`
393
+ );
394
+ }
395
+ } catch (err) {
396
+ throw toCommerceError(err, "STORAGE_ERROR", "Failed to update payment attempt");
397
+ }
398
+ },
399
+ async saveReceipt(receipt) {
400
+ try {
401
+ insertReceiptStmt.run(receiptToRow(receipt));
402
+ } catch (err) {
403
+ throw toCommerceError(err, "STORAGE_ERROR", "Failed to save receipt");
404
+ }
405
+ },
406
+ async getReceipt(id) {
407
+ const row = getReceiptStmt.get(id);
408
+ return row !== void 0 ? rowToReceipt(row) : void 0;
409
+ },
410
+ async listReceipts(listOptions = {}) {
411
+ const limit = clampListLimit(listOptions.limit);
412
+ const rows = listOptions.requestId !== void 0 ? listReceiptsByRequestStmt.all(listOptions.requestId, limit) : listReceiptsStmt.all(limit);
413
+ return rows.map(rowToReceipt);
414
+ },
415
+ // Exact total, not bounded by the listReceipts clamp (see ReceiptStore.countReceipts)
416
+ async countReceipts() {
417
+ return countReceiptsStmt.get()?.count ?? 0;
418
+ },
419
+ // Exact count of non-2xx receipts (see ReceiptStore.countUndeliveredReceipts)
420
+ async countUndeliveredReceipts() {
421
+ return countUndeliveredReceiptsStmt.get()?.count ?? 0;
422
+ },
423
+ async listEvents(listOptions = {}) {
424
+ const limit = clampListLimit(listOptions.limit);
425
+ const rows = listOptions.requestId !== void 0 ? listEventsByRequestStmt.all(listOptions.requestId, limit) : listEventsStmt.all(limit);
426
+ return rows.map(rowToEvent);
427
+ },
428
+ async listPaymentAttempts(listOptions = {}) {
429
+ const limit = clampListLimit(listOptions.limit);
430
+ const rows = listOptions.requestId !== void 0 ? listPaymentAttemptsByRequestStmt.all(listOptions.requestId, limit) : listPaymentAttemptsStmt.all(limit);
431
+ return rows.map(rowToPaymentAttempt);
432
+ },
433
+ descriptor,
434
+ async health() {
435
+ const startedAt = clock.monotonicMs();
436
+ if (closed) {
437
+ return { status: "fail", detail: "store-unavailable", checkedAt: clock.nowIso() };
438
+ }
439
+ if (isFileBacked) {
440
+ try {
441
+ accessSync(path, constants.W_OK);
442
+ } catch (err) {
443
+ logger.warn(
444
+ { err: err instanceof Error ? err.message : String(err) },
445
+ "receipt-store: health check failed (store not writable)"
446
+ );
447
+ return {
448
+ status: "fail",
449
+ detail: "store-unwritable",
450
+ checkedAt: clock.nowIso(),
451
+ durationMs: clock.monotonicMs() - startedAt
452
+ };
453
+ }
454
+ }
455
+ try {
456
+ const version = db.pragma("user_version", { simple: true });
457
+ if (version !== SCHEMA_VERSION) {
458
+ logger.warn(
459
+ { found: version, expected: SCHEMA_VERSION },
460
+ "receipt-store: health check failed (schema version mismatch)"
461
+ );
462
+ return {
463
+ status: "fail",
464
+ detail: "store-schema-mismatch",
465
+ checkedAt: clock.nowIso(),
466
+ durationMs: clock.monotonicMs() - startedAt
467
+ };
468
+ }
469
+ return {
470
+ status: "pass",
471
+ detail: `sqlite schema v${SCHEMA_VERSION} writable`,
472
+ checkedAt: clock.nowIso(),
473
+ durationMs: clock.monotonicMs() - startedAt
474
+ };
475
+ } catch (err) {
476
+ logger.warn(
477
+ { err: err instanceof Error ? err.message : String(err) },
478
+ "receipt-store: health check failed (store unavailable)"
479
+ );
480
+ return {
481
+ status: "fail",
482
+ detail: "store-unavailable",
483
+ checkedAt: clock.nowIso(),
484
+ durationMs: clock.monotonicMs() - startedAt
485
+ };
486
+ }
487
+ },
488
+ async close() {
489
+ if (!closed) {
490
+ closed = true;
491
+ db.close();
492
+ }
493
+ }
494
+ };
495
+ return store;
496
+ }
497
+
498
+ // src/protocols/a2a/constants.ts
499
+ var A2A_SPEC_VERSION = "1.0.1";
500
+ var A2A_PROTOCOL_VERSION = "1.0";
501
+ var A2A_PROTOCOL_BINDING = "JSONRPC";
502
+ var A2A_AGENT_CARD_PATH = "/.well-known/agent-card.json";
503
+ var A2A_DEFAULT_MOUNT_PATH = "/a2a";
504
+ var A2A_JSON_MEDIA_TYPE = "application/json";
505
+ var A2A_DEFAULT_AGENT_NAME = "agent-commerce";
506
+ var A2A_VERSION_HEADER = "a2a-version";
507
+ var A2A_METHOD_SEND_MESSAGE = "SendMessage";
508
+ var A2A_PUSH_CONFIG_METHODS = [
509
+ "CreateTaskPushNotificationConfig",
510
+ "GetTaskPushNotificationConfig",
511
+ "ListTaskPushNotificationConfigs",
512
+ "DeleteTaskPushNotificationConfig"
513
+ ];
514
+ var A2A_UNSUPPORTED_METHODS = [
515
+ "SendStreamingMessage",
516
+ "GetTask",
517
+ "ListTasks",
518
+ "CancelTask",
519
+ "SubscribeToTask",
520
+ ...A2A_PUSH_CONFIG_METHODS,
521
+ "GetExtendedAgentCard"
522
+ ];
523
+ var A2A_TASK_LOOKUP_METHODS = ["GetTask", "CancelTask"];
524
+ var A2A_TASK_STATE_COMPLETED = "TASK_STATE_COMPLETED";
525
+ var A2A_TASK_STATE_FAILED = "TASK_STATE_FAILED";
526
+ var A2A_TASK_STATE_INPUT_REQUIRED = "TASK_STATE_INPUT_REQUIRED";
527
+ var A2A_EXTENSIONS_HEADER = "a2a-extensions";
528
+
529
+ // src/protocols/a2a/descriptor.ts
530
+ var A2A_CAPABILITIES = [
531
+ "agent-card",
532
+ "jsonrpc",
533
+ "SendMessage",
534
+ // The x402 A2A transport, opt-in per request
535
+ "x402-extension"
536
+ ];
537
+ var A2A_UNSUPPORTED = [
538
+ // Methods, as the protocol names them; the transport refuses the same list
539
+ ...A2A_UNSUPPORTED_METHODS,
540
+ // Transports other than the one binding served
541
+ "HTTP+JSON/REST binding",
542
+ "gRPC binding",
543
+ // Behaviors
544
+ "SSE",
545
+ "long-running task persistence",
546
+ "task resumption other than an x402 extension payment",
547
+ "push notifications",
548
+ "multi-turn conversational continuation",
549
+ "authenticated extended agent cards",
550
+ "A2A authentication schemes",
551
+ "artifact types beyond Agent Commerce outcome data",
552
+ // Pending x402 payments live in process memory
553
+ "x402 extension payments across gateway restarts or instances"
554
+ ];
555
+ function buildDescriptor(implementationVersion) {
556
+ return {
557
+ name: "a2a",
558
+ kind: "protocol",
559
+ implementationVersion,
560
+ supportedSpec: A2A_SPEC_VERSION,
561
+ capabilities: A2A_CAPABILITIES,
562
+ status: "experimental",
563
+ unsupported: A2A_UNSUPPORTED
564
+ };
565
+ }
566
+
567
+ // src/protocols/acp/descriptor.ts
568
+ var ACP_CAPABILITIES = [
569
+ "rest transport",
570
+ "well-known discovery",
571
+ "bearer authentication",
572
+ "API-Version enforcement",
573
+ // Forwarded as received: the gateway verifies neither signature header
574
+ "request header forwarding to the merchant",
575
+ "checkout service",
576
+ ...ACP_CHECKOUT_OPERATIONS
577
+ ];
578
+ var ACP_UNSUPPORTED = [
579
+ // Services this seller does not implement, named as ACP names them. The
580
+ // discovery document advertises `checkout` alone, and these are the reason.
581
+ "carts service",
582
+ "feed service",
583
+ "standalone orders service",
584
+ "delegate_payment",
585
+ "delegate_authentication",
586
+ // Bindings and delivery directions
587
+ "ACP MCP transport binding",
588
+ "webhooks",
589
+ "outbound merchant-to-agent delivery",
590
+ "ACP client role",
591
+ // Request authentication beyond the bearer token
592
+ "Signature header verification",
593
+ "Timestamp replay-window verification",
594
+ // Extensions, versioning and payment handlers
595
+ "discount extension",
596
+ "general ACP extension framework",
597
+ "multiple ACP API versions",
598
+ "seller-backed payment handler integration"
599
+ ];
600
+ function buildDescriptor2(implementationVersion) {
601
+ return {
602
+ name: "acp",
603
+ kind: "protocol",
604
+ implementationVersion,
605
+ supportedSpec: ACP_SPEC_VERSION,
606
+ capabilities: ACP_CAPABILITIES,
607
+ status: "experimental",
608
+ unsupported: ACP_UNSUPPORTED
609
+ };
610
+ }
611
+
612
+ export { A2A_AGENT_CARD_PATH, A2A_DEFAULT_AGENT_NAME, A2A_DEFAULT_MOUNT_PATH, A2A_EXTENSIONS_HEADER, A2A_JSON_MEDIA_TYPE, A2A_METHOD_SEND_MESSAGE, A2A_PROTOCOL_BINDING, A2A_PROTOCOL_VERSION, A2A_PUSH_CONFIG_METHODS, A2A_SPEC_VERSION, A2A_TASK_LOOKUP_METHODS, A2A_TASK_STATE_COMPLETED, A2A_TASK_STATE_FAILED, A2A_TASK_STATE_INPUT_REQUIRED, A2A_UNSUPPORTED, A2A_UNSUPPORTED_METHODS, A2A_VERSION_HEADER, ACP_UNSUPPORTED, buildDescriptor, buildDescriptor2, createSqliteReceiptStore };
613
+ //# sourceMappingURL=chunk-SS3QFF5N.js.map
614
+ //# sourceMappingURL=chunk-SS3QFF5N.js.map