@devlab.group/agent-commerce 2.4.0 → 2.5.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 +115 -15
- package/dist/ap2.d.ts +24 -12
- package/dist/ap2.js +31 -13
- package/dist/ap2.js.map +1 -1
- package/dist/{chunk-AITMDXKW.js → chunk-3OTCFFFT.js} +37 -4
- package/dist/chunk-3OTCFFFT.js.map +1 -0
- package/dist/{chunk-4OEXK3YG.js → chunk-4K7FIBJM.js} +25 -4
- package/dist/chunk-4K7FIBJM.js.map +1 -0
- package/dist/{chunk-WUIAUAA7.js → chunk-FKQK5XZA.js} +652 -68
- package/dist/chunk-FKQK5XZA.js.map +1 -0
- package/dist/chunk-GA3O2A7R.js +92 -0
- package/dist/chunk-GA3O2A7R.js.map +1 -0
- package/dist/{chunk-6WACRJVT.js → chunk-VUCMBGUR.js} +3 -3
- package/dist/{chunk-6WACRJVT.js.map → chunk-VUCMBGUR.js.map} +1 -1
- package/dist/cli/{ap2-QDHPRSTF.js → ap2-YAPLERSC.js} +34 -15
- package/dist/cli/ap2-YAPLERSC.js.map +1 -0
- package/dist/cli/{chunk-G2JEY7MB.js → chunk-2J2IQQ4X.js} +8 -7
- package/dist/cli/chunk-2J2IQQ4X.js.map +1 -0
- package/dist/cli/chunk-2UPPX3FJ.js +311 -0
- package/dist/cli/chunk-2UPPX3FJ.js.map +1 -0
- package/dist/cli/{chunk-WYOGIANL.js → chunk-4H2QLHQI.js} +4 -4
- package/dist/cli/{chunk-WYOGIANL.js.map → chunk-4H2QLHQI.js.map} +1 -1
- package/dist/cli/{chunk-OZ4LAWBK.js → chunk-5R7DM5LM.js} +25 -4
- package/dist/cli/chunk-5R7DM5LM.js.map +1 -0
- package/dist/cli/chunk-663ALDZA.js +92 -0
- package/dist/cli/chunk-663ALDZA.js.map +1 -0
- package/dist/cli/{chunk-QQ3WY5L3.js → chunk-IDY2735M.js} +36 -104
- package/dist/cli/chunk-IDY2735M.js.map +1 -0
- package/dist/cli/chunk-JFVRG2HH.js +107 -0
- package/dist/cli/chunk-JFVRG2HH.js.map +1 -0
- package/dist/cli/chunk-M7NXVRU5.js +8 -0
- package/dist/cli/{chunk-UXB65XCS.js.map → chunk-M7NXVRU5.js.map} +1 -1
- package/dist/cli/chunk-NIU5EMSB.js +119 -0
- package/dist/cli/chunk-NIU5EMSB.js.map +1 -0
- package/dist/cli/{chunk-AZDWFVDW.js → chunk-QA2OPHBF.js} +655 -70
- package/dist/cli/chunk-QA2OPHBF.js.map +1 -0
- package/dist/cli/{chunk-DCMW67JM.js → chunk-QLUCNPRT.js} +404 -161
- package/dist/cli/chunk-QLUCNPRT.js.map +1 -0
- package/dist/cli/chunk-SYQLJXIU.js +105 -0
- package/dist/cli/chunk-SYQLJXIU.js.map +1 -0
- package/dist/cli/{chunk-3MGAJ5FX.js → chunk-VJ4EO4LE.js} +3 -3
- package/dist/cli/{chunk-3MGAJ5FX.js.map → chunk-VJ4EO4LE.js.map} +1 -1
- package/dist/cli/{chunk-PIMFPCNZ.js → chunk-Z34UMZBB.js} +234 -85
- package/dist/cli/chunk-Z34UMZBB.js.map +1 -0
- package/dist/cli/config-BWFMN2ZB.js +12 -0
- package/dist/cli/{config-UI4EDG4L.js.map → config-BWFMN2ZB.js.map} +1 -1
- package/dist/cli/index.js +258 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-26LJMN4N.js → mcp-KZEMXLHR.js} +5 -4
- package/dist/cli/mcp-KZEMXLHR.js.map +1 -0
- package/dist/cli/{near-5AY3HWYF.js → near-U6365VFX.js} +15 -4
- package/dist/cli/near-U6365VFX.js.map +1 -0
- package/dist/cli/payment-providers-SZL36H3Y.js +6 -0
- package/dist/cli/payment-providers-SZL36H3Y.js.map +1 -0
- package/dist/cli/{provider-Z4OJNAYI.js → provider-6TKB5ADJ.js} +30 -16
- package/dist/cli/provider-6TKB5ADJ.js.map +1 -0
- package/dist/cli/receipts-ZGLJWMQG.js +8 -0
- package/dist/cli/receipts-ZGLJWMQG.js.map +1 -0
- package/dist/cli/reconcile-IC22MJD5.js +4 -0
- package/dist/cli/reconcile-IC22MJD5.js.map +1 -0
- package/dist/cli/{run-TEPYJUHG.js → run-ZTYPQI4D.js} +151 -115
- package/dist/cli/run-ZTYPQI4D.js.map +1 -0
- package/dist/cli/svm-KDSPDFJG.js +48 -0
- package/dist/cli/svm-KDSPDFJG.js.map +1 -0
- package/dist/cli/{x402-BMVONZKA.js → x402-WLYBLODI.js} +10 -9
- package/dist/cli/x402-WLYBLODI.js.map +1 -0
- package/dist/index.d.ts +112 -12
- package/dist/index.js +948 -157
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +1 -2
- package/dist/mcp.js +1 -1
- package/dist/mpp.js +24 -11
- package/dist/mpp.js.map +1 -1
- package/dist/{near-D6C42VPE.js → near-FH7HPZV3.js} +15 -4
- package/dist/near-FH7HPZV3.js.map +1 -0
- package/dist/{protocol-adapter-C9odYl6l.d.ts → protocol-adapter-DEXpdp8m.d.ts} +102 -48
- package/dist/{runtime-Cl_BLVZV.d.ts → runtime-Dz2fSO-P.d.ts} +220 -2
- package/dist/svm-KNC3PHMS.js +48 -0
- package/dist/svm-KNC3PHMS.js.map +1 -0
- package/dist/x402.js +5 -5
- package/package.json +1 -1
- package/dist/authorization-DjAecwuW.d.ts +0 -115
- package/dist/chunk-4OEXK3YG.js.map +0 -1
- package/dist/chunk-AITMDXKW.js.map +0 -1
- package/dist/chunk-KA2AX5FH.js +0 -44
- package/dist/chunk-KA2AX5FH.js.map +0 -1
- package/dist/chunk-WUIAUAA7.js.map +0 -1
- package/dist/cli/ap2-QDHPRSTF.js.map +0 -1
- package/dist/cli/chunk-AZDWFVDW.js.map +0 -1
- package/dist/cli/chunk-DCMW67JM.js.map +0 -1
- package/dist/cli/chunk-G2JEY7MB.js.map +0 -1
- package/dist/cli/chunk-OSTCU6ZK.js +0 -44
- package/dist/cli/chunk-OSTCU6ZK.js.map +0 -1
- package/dist/cli/chunk-OZ4LAWBK.js.map +0 -1
- package/dist/cli/chunk-PIMFPCNZ.js.map +0 -1
- package/dist/cli/chunk-QQ3WY5L3.js.map +0 -1
- package/dist/cli/chunk-UXB65XCS.js +0 -8
- package/dist/cli/config-UI4EDG4L.js +0 -11
- package/dist/cli/mcp-26LJMN4N.js.map +0 -1
- package/dist/cli/near-5AY3HWYF.js.map +0 -1
- package/dist/cli/provider-Z4OJNAYI.js.map +0 -1
- package/dist/cli/run-TEPYJUHG.js.map +0 -1
- package/dist/cli/svm-3MMYFPC7.js +0 -33
- package/dist/cli/svm-3MMYFPC7.js.map +0 -1
- package/dist/cli/x402-BMVONZKA.js.map +0 -1
- package/dist/near-D6C42VPE.js.map +0 -1
- package/dist/svm-QEUAUNPQ.js +0 -33
- package/dist/svm-QEUAUNPQ.js.map +0 -1
package/README.md
CHANGED
|
@@ -70,8 +70,8 @@ agent-commerce doctor
|
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
Requires **Node >= 22**. The package includes the `agent-commerce` CLI
|
|
73
|
-
(`init`, `validate`, `start`, `doctor`, `
|
|
74
|
-
a library for embedding the gateway.
|
|
73
|
+
(`init`, `validate`, `start`, `doctor`, `reconcile`, `resolve`, `demo`,
|
|
74
|
+
`import openapi`, `version`) and a library for embedding the gateway.
|
|
75
75
|
The default install excludes optional protocol, payment and authorization
|
|
76
76
|
peers. The OpenAPI parser is a regular dependency because import is part of the
|
|
77
77
|
CLI.
|
|
@@ -84,9 +84,10 @@ agent-commerce start --config config.yaml --env-file .env
|
|
|
84
84
|
Install the optional peers for the features you enable, listed below. Missing
|
|
85
85
|
startup imports stop the gateway with an error naming the package; missing
|
|
86
86
|
Solana, NEAR or CDP peers fail provider health checks or payment requests.
|
|
87
|
-
`start`, `validate` and `
|
|
88
|
-
variables before reading the config. Variables already set in
|
|
89
|
-
take precedence. To embed the gateway in your own process, use
|
|
87
|
+
`start`, `validate`, `doctor`, `reconcile` and `resolve` accept `--env-file <path>` to
|
|
88
|
+
load environment variables before reading the config. Variables already set in
|
|
89
|
+
the environment take precedence. To embed the gateway in your own process, use
|
|
90
|
+
the library:
|
|
90
91
|
|
|
91
92
|
```ts
|
|
92
93
|
import { createGateway, loadConfig, receipts } from '@devlab.group/agent-commerce';
|
|
@@ -309,12 +310,17 @@ prints the `unsupported` lists for A2A, ACP and AP2 when they are enabled.
|
|
|
309
310
|
|
|
310
311
|
### Versioning
|
|
311
312
|
|
|
312
|
-
Minor releases may break experimental configurations, integrations or types
|
|
313
|
-
|
|
314
|
-
`
|
|
315
|
-
|
|
316
|
-
`
|
|
317
|
-
|
|
313
|
+
Minor releases may break experimental configurations, integrations or types:
|
|
314
|
+
MPP, A2A, ACP, AP2, ERC-8409 quotes, `agent-commerce import openapi`, the
|
|
315
|
+
journal's `Transaction` type, `ReceiptStore` journal methods,
|
|
316
|
+
`PaymentProvider.reconcile` and the `/api/transactions` response shape.
|
|
317
|
+
The `transactionId` fields, `receiptCommitted`, and the flags accepted by
|
|
318
|
+
`reconcile` and `resolve` are supported.
|
|
319
|
+
|
|
320
|
+
Experimental runtime adapters and providers identify themselves with
|
|
321
|
+
`status: experimental` in `GET /.well-known/agent-commerce`. Pin experimental
|
|
322
|
+
integrations to an exact version and test upgrades before deployment.
|
|
323
|
+
Since 2.1, some supported x402 behavior and types
|
|
318
324
|
differ from 2.0; see [Upgrading from 2.0 to 2.x](docs/migration-2.1.md).
|
|
319
325
|
|
|
320
326
|
## Payment model
|
|
@@ -461,7 +467,7 @@ INFO ACP disabled
|
|
|
461
467
|
INFO AP2 disabled
|
|
462
468
|
PASS Payments x402 v2 (scheme=exact) enabled - LOCAL dev chain (eip155:31337), destination=0x7099…79C8, facilitator=local (in-process), paymentFlow=authorization
|
|
463
469
|
INFO Payments (MPP) MPP not configured
|
|
464
|
-
PASS Storage sqlite schema
|
|
470
|
+
PASS Storage sqlite schema v4 writable; receipts=2
|
|
465
471
|
PASS Protocol versions reported by gateway /.well-known/agent-commerce
|
|
466
472
|
|
|
467
473
|
Score: 7/7 checks passed
|
|
@@ -474,6 +480,98 @@ failing offers when health is published; reasons appear in gateway debug logs.
|
|
|
474
480
|
|
|
475
481
|
Exits non-zero if anything fails. `--json` for machines.
|
|
476
482
|
|
|
483
|
+
### `agent-commerce reconcile`
|
|
484
|
+
|
|
485
|
+
```bash
|
|
486
|
+
npm run agent-commerce -- reconcile --config config.yaml --dry-run
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
Resolves attempts whose settlement outcome the gateway did not learn:
|
|
490
|
+
`settlement-uncertain` and legacy `failed` attempts, plus `reserved` attempts in
|
|
491
|
+
the journal at least `--min-age` old (default `15m`). The payment provider
|
|
492
|
+
checks chain evidence and returns:
|
|
493
|
+
|
|
494
|
+
- **settled**: a final transfer matches the authorization. The attempt becomes
|
|
495
|
+
`settled` with its transaction ID.
|
|
496
|
+
- **not settled**: final chain state shows the authorization unused after its
|
|
497
|
+
last valid second on EVM or its `maxBlockHeight` on NEAR. The attempt becomes
|
|
498
|
+
`rejected` with reason `not_settled`. Solana reconciliation does not return
|
|
499
|
+
this result: blockhash expiry alone does not prove nonpayment.
|
|
500
|
+
- **unknown**: the evidence is inconclusive. The report includes a reason and,
|
|
501
|
+
when available, a time to try again. The attempt remains unresolved.
|
|
502
|
+
|
|
503
|
+
The command builds payment providers as `start` does without starting a
|
|
504
|
+
listener. It does not call a facilitator, broadcast, refund or retry delivery.
|
|
505
|
+
Each resolution records `--actor` (default: the OS user) and the evidence.
|
|
506
|
+
`--dry-run` checks evidence without recording resolutions; it still opens and
|
|
507
|
+
initializes the receipt database. `--json` prints the report for machines.
|
|
508
|
+
`--limit` caps payment checks and hold updates separately. Journal entries are
|
|
509
|
+
checked by state: `payment-uncertain`, `payment-pending`, then
|
|
510
|
+
`delivery-started`, newest first within each group. Only eligible payment
|
|
511
|
+
attempts are considered. A capped batch of attempts without journal entries
|
|
512
|
+
follows.
|
|
513
|
+
It exits 0 after a completed run, even if attempts remain unresolved, and 1 if
|
|
514
|
+
the run fails to complete.
|
|
515
|
+
|
|
516
|
+
Each family needs its own evidence:
|
|
517
|
+
|
|
518
|
+
- **EVM**: uses the recorded transaction hash or searches logs for a used nonce
|
|
519
|
+
near the attempt's creation time, within its validity bounds. The log search
|
|
520
|
+
covers at most 200,000 blocks. If no match is found and part of the candidate
|
|
521
|
+
range remains unsearched, it returns `unknown` (`search_window_too_wide`).
|
|
522
|
+
- **Solana**: uses the recorded transaction signature or searches a known
|
|
523
|
+
payer's history near the attempt's creation time. Only successful finalized
|
|
524
|
+
transactions count. A search that reaches its page cap returns `unknown`
|
|
525
|
+
(`history_too_long`). Otherwise, a missing match gives `not_expired` while
|
|
526
|
+
the blockhash is valid at `confirmed` commitment, then `blockhash_expired`.
|
|
527
|
+
- **NEAR**: uses the recorded transaction hash and relayer IDs from the
|
|
528
|
+
facilitator's `/supported`. Both are needed to prove `settled`. Without
|
|
529
|
+
them, final access-key state can still prove `not-settled` after expiry;
|
|
530
|
+
other cases remain `unknown`.
|
|
531
|
+
|
|
532
|
+
Coverage is partial: EVM reconciliation (x402 EIP-3009 and Permit2, and MPP)
|
|
533
|
+
is tested on Anvil, Solana on `solana-test-validator` and NEAR on a local
|
|
534
|
+
sandbox. Public-network validation is pending. EVM and NEAR can report
|
|
535
|
+
`not_final` while a referenced transaction awaits finality.
|
|
536
|
+
|
|
537
|
+
With `authorization.ap2` enabled, reconciliation also updates AP2 holds on
|
|
538
|
+
resolved payments: `settled` consumes the mandate; `rejected` releases it.
|
|
539
|
+
It opens the AP2 replay database for these updates without verifying mandates.
|
|
540
|
+
The report's `holds` list (`--json`) covers pending holds whose payments are
|
|
541
|
+
resolved in the database. Dry runs report those holds without writing
|
|
542
|
+
resolutions or hold changes. Both databases are still opened and initialized.
|
|
543
|
+
Later runs can retry holds left pending after earlier payment resolutions,
|
|
544
|
+
including those recorded by `resolve` while AP2 was disabled.
|
|
545
|
+
|
|
546
|
+
### `agent-commerce resolve`
|
|
547
|
+
|
|
548
|
+
```bash
|
|
549
|
+
npm run agent-commerce -- resolve <attemptId> --status settled --reason "transfer seen in explorer" --reference 0x...
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Records an operator's verdict on one unresolved payment attempt, including
|
|
553
|
+
one `reconcile` left `unknown`. Only `reserved`, `settlement-uncertain` and
|
|
554
|
+
legacy `failed` attempts can be resolved, once each:
|
|
555
|
+
|
|
556
|
+
- `--status settled` has no expiry check. `--reference` records an unchecked
|
|
557
|
+
operator claim in the resolution; it does not replace the attempt's recorded
|
|
558
|
+
transaction ID.
|
|
559
|
+
- A `reserved` attempt younger than 15 minutes is refused (`too_recent`),
|
|
560
|
+
because the gateway may still be settling it.
|
|
561
|
+
- `--status rejected` is refused while the recorded expiry is in the future.
|
|
562
|
+
Without a valid recorded expiry, `--confirm-expired` is required. This
|
|
563
|
+
includes Solana and NEAR attempts and those written before the journal.
|
|
564
|
+
|
|
565
|
+
`--actor` is a caller-supplied label and defaults to the OS user. The command
|
|
566
|
+
opens the receipt database directly and works with the gateway running or
|
|
567
|
+
stopped. With AP2 enabled, it attempts the same hold update as `reconcile`.
|
|
568
|
+
If the provider is disabled, its call fails, or the hold's journal write fails,
|
|
569
|
+
the command reports the update as pending with a warning. A later `reconcile`
|
|
570
|
+
run can retry it.
|
|
571
|
+
`POST /api/payment-attempts/:id/resolve` applies the same rules over HTTP;
|
|
572
|
+
the admin token controls access without identifying the operator. Exit 0
|
|
573
|
+
means the resolution was written; 1 means a refusal or error.
|
|
574
|
+
|
|
477
575
|
### `agent-commerce version`
|
|
478
576
|
|
|
479
577
|
```bash
|
|
@@ -493,9 +591,11 @@ reachable by anyone else, know the split:
|
|
|
493
591
|
- **Agent routes** (`/api/resources/:id/invoke`, `/mcp`, the A2A mount) are
|
|
494
592
|
unauthenticated by design - paid resources are protected by payment, not by a
|
|
495
593
|
password. ACP is the exception: its checkout routes require a bearer token.
|
|
496
|
-
- **Operator routes** (`/api/receipts`, `/api/events`, `/api/payment-attempts
|
|
497
|
-
expose the merchant's commerce ledger: payer addresses,
|
|
498
|
-
|
|
594
|
+
- **Operator routes** (`/api/receipts`, `/api/events`, `/api/payment-attempts`,
|
|
595
|
+
`/api/transactions`) expose the merchant's commerce ledger: payer addresses,
|
|
596
|
+
amounts and settlement hashes. `POST /api/payment-attempts/:id/resolve`
|
|
597
|
+
records a resolution. They require `server.adminToken` and return **404** if
|
|
598
|
+
none is configured.
|
|
499
599
|
- **Browsers** are governed by `server.allowedOrigins`, an explicit allowlist
|
|
500
600
|
that defaults to empty.
|
|
501
601
|
- **There is no rate limiting.** A free resource is an unauthenticated proxy to
|
package/dist/ap2.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { E as EnabledAp2Config } from './types-j7MnUXYN.js';
|
|
2
2
|
export { A as AP2_CHECKOUT_MANDATE_VCT, a as AP2_CHECKOUT_PROFILE, b as AP2_DEFAULT_CLOCK_SKEW_SECONDS, c as AP2_MAX_CLOCK_SKEW_SECONDS, d as AP2_SIGNING_ALGORITHM, e as AP2_SPEC_VERSION, f as Ap2AuthorizationConfig, g as Ap2Mode, h as Ap2TrustedIssuer, i as Ap2TrustedKey } from './types-j7MnUXYN.js';
|
|
3
|
-
import { AuthorizationProvider } from './index.js';
|
|
4
|
-
import { Clock, Logger } from './index.js';
|
|
3
|
+
import { AuthorizationProvider, Clock, Logger } from './index.js';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* A private ES256 key: either a private JWK (the pair of the public one in the
|
|
@@ -92,9 +91,9 @@ declare const AP2_REJECTION_REASONS: readonly ["malformed_presentation", "untrus
|
|
|
92
91
|
type Ap2RejectionReason = (typeof AP2_REJECTION_REASONS)[number];
|
|
93
92
|
|
|
94
93
|
/**
|
|
95
|
-
* `released`
|
|
96
|
-
*
|
|
97
|
-
*
|
|
94
|
+
* `released` permits another reservation; other states block reuse.
|
|
95
|
+
* `uncertain` records an unknown settlement outcome and stays blocked until
|
|
96
|
+
* payment resolution is followed by a consume or release update.
|
|
98
97
|
*/
|
|
99
98
|
type Ap2AuthorizationState = 'reserved' | 'consumed' | 'released' | 'uncertain';
|
|
100
99
|
/**
|
|
@@ -118,20 +117,33 @@ interface Ap2ReservationRequest {
|
|
|
118
117
|
type Ap2ReservationResult = {
|
|
119
118
|
readonly kind: 'reserved';
|
|
120
119
|
}
|
|
121
|
-
/** Already reserved, consumed
|
|
120
|
+
/** Already reserved, consumed or uncertain; refuse this reservation */
|
|
122
121
|
| {
|
|
123
122
|
readonly kind: 'replayed';
|
|
124
123
|
readonly state: Ap2AuthorizationState;
|
|
125
124
|
};
|
|
125
|
+
type TransitionResult = boolean | void;
|
|
126
126
|
interface Ap2ReplayStore {
|
|
127
127
|
/** Atomically claim a mandate, or report that something already holds it */
|
|
128
128
|
reserve(request: Ap2ReservationRequest): Ap2ReservationResult;
|
|
129
|
-
/**
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Mark the mandate permanently spent, targeting only the supplied
|
|
131
|
+
* `requestId` when present. Returns true when the matching reservation is
|
|
132
|
+
* consumed, including on a repeated call, and false otherwise.
|
|
133
|
+
*/
|
|
134
|
+
consume(reference: string, requestId?: string): TransitionResult;
|
|
135
|
+
/**
|
|
136
|
+
* Release a reservation for reuse. Returns true if it is released or the
|
|
137
|
+
* supplied `requestId` differs from the current holder; a different holder
|
|
138
|
+
* is left unchanged. Returns false otherwise.
|
|
139
|
+
*/
|
|
140
|
+
release(reference: string, requestId?: string): TransitionResult;
|
|
141
|
+
/**
|
|
142
|
+
* Record an unknown settlement outcome for operator review and block reuse.
|
|
143
|
+
* Returns true when the matching reservation is uncertain, including on a
|
|
144
|
+
* repeated call, and false otherwise.
|
|
145
|
+
*/
|
|
146
|
+
markUncertain(reference: string, requestId?: string): TransitionResult;
|
|
135
147
|
/** Current state, for tests and diagnostics */
|
|
136
148
|
stateOf(reference: string): Ap2AuthorizationState | undefined;
|
|
137
149
|
close(): void;
|
package/dist/ap2.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AP2_CHECKOUT_MANDATE_VCT, AP2_SIGNING_ALGORITHM, AP2_DIGEST_ALGORITHM, AP2_CHECKOUT_PROFILE, AP2_SPEC_VERSION, AP2_KEY_TYPE, AP2_JWK_CURVE, openSqliteDatabase } from './chunk-
|
|
2
|
-
export { AP2_CHECKOUT_MANDATE_VCT, AP2_CHECKOUT_PROFILE, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_MAX_CLOCK_SKEW_SECONDS, AP2_SIGNING_ALGORITHM, AP2_SPEC_VERSION } from './chunk-
|
|
3
|
-
import { systemClock, NOOP_LOGGER, CommerceError, PACKAGE_VERSION } from './chunk-
|
|
1
|
+
import { AP2_CHECKOUT_MANDATE_VCT, AP2_SIGNING_ALGORITHM, AP2_DIGEST_ALGORITHM, AP2_CHECKOUT_PROFILE, AP2_SPEC_VERSION, AP2_KEY_TYPE, AP2_JWK_CURVE, openSqliteDatabase } from './chunk-VUCMBGUR.js';
|
|
2
|
+
export { AP2_CHECKOUT_MANDATE_VCT, AP2_CHECKOUT_PROFILE, AP2_DEFAULT_CLOCK_SKEW_SECONDS, AP2_MAX_CLOCK_SKEW_SECONDS, AP2_SIGNING_ALGORITHM, AP2_SPEC_VERSION } from './chunk-VUCMBGUR.js';
|
|
3
|
+
import { systemClock, NOOP_LOGGER, CommerceError, PACKAGE_VERSION } from './chunk-3OTCFFFT.js';
|
|
4
4
|
import { isRecord } from './chunk-2CJNA7MS.js';
|
|
5
5
|
import { SignJWT, importPKCS8, importJWK, jwtVerify, decodeProtectedHeader, decodeJwt } from 'jose';
|
|
6
6
|
import canonicalize from 'canonicalize';
|
|
@@ -276,7 +276,11 @@ function createAp2ReplayStore(options) {
|
|
|
276
276
|
);
|
|
277
277
|
const transition = db.prepare(
|
|
278
278
|
`UPDATE ap2_authorizations SET state = @state, updated_at = @at
|
|
279
|
-
WHERE reference = @reference AND state
|
|
279
|
+
WHERE reference = @reference AND state IN ('reserved', 'uncertain')
|
|
280
|
+
AND (@request_id IS NULL OR request_id = @request_id)`
|
|
281
|
+
);
|
|
282
|
+
const selectHolder = db.prepare(
|
|
283
|
+
"SELECT state, request_id FROM ap2_authorizations WHERE reference = ?"
|
|
280
284
|
);
|
|
281
285
|
const reserveTx = db.transaction((request) => {
|
|
282
286
|
const at = new Date(now()).toISOString();
|
|
@@ -303,22 +307,32 @@ function createAp2ReplayStore(options) {
|
|
|
303
307
|
});
|
|
304
308
|
return { kind: "reserved" };
|
|
305
309
|
});
|
|
306
|
-
const move = (reference, state) => {
|
|
307
|
-
|
|
310
|
+
const move = (reference, state, requestId) => {
|
|
311
|
+
const { changes } = transition.run({
|
|
312
|
+
reference,
|
|
313
|
+
state,
|
|
314
|
+
request_id: requestId ?? null,
|
|
315
|
+
at: new Date(now()).toISOString()
|
|
316
|
+
});
|
|
317
|
+
if (changes > 0) return true;
|
|
318
|
+
const row = selectHolder.get(reference);
|
|
319
|
+
if (row === void 0) return false;
|
|
320
|
+
if (requestId !== void 0 && row.request_id !== requestId) return state === "released";
|
|
321
|
+
return row.state === state;
|
|
308
322
|
};
|
|
309
323
|
let closed = false;
|
|
310
324
|
return {
|
|
311
325
|
reserve(request) {
|
|
312
326
|
return reserveTx(request);
|
|
313
327
|
},
|
|
314
|
-
consume(reference) {
|
|
315
|
-
move(reference, "consumed");
|
|
328
|
+
consume(reference, requestId) {
|
|
329
|
+
return move(reference, "consumed", requestId);
|
|
316
330
|
},
|
|
317
|
-
release(reference) {
|
|
318
|
-
move(reference, "released");
|
|
331
|
+
release(reference, requestId) {
|
|
332
|
+
return move(reference, "released", requestId);
|
|
319
333
|
},
|
|
320
|
-
markUncertain(reference) {
|
|
321
|
-
move(reference, "uncertain");
|
|
334
|
+
markUncertain(reference, requestId) {
|
|
335
|
+
return move(reference, "uncertain", requestId);
|
|
322
336
|
},
|
|
323
337
|
stateOf(reference) {
|
|
324
338
|
return selectByReference.get(reference)?.state;
|
|
@@ -670,11 +684,15 @@ function createAp2AuthorizationProvider(options) {
|
|
|
670
684
|
};
|
|
671
685
|
}
|
|
672
686
|
const finalize = (action, reservationId, context) => {
|
|
687
|
+
let applied;
|
|
673
688
|
try {
|
|
674
|
-
replay[action](reservationId);
|
|
689
|
+
applied = replay[action](reservationId, context.requestId);
|
|
675
690
|
} catch (cause) {
|
|
676
691
|
throw ap2Unavailable(`replay store could not record ${action}`, { ...context, cause });
|
|
677
692
|
}
|
|
693
|
+
if (applied === false) {
|
|
694
|
+
throw ap2Unavailable(`replay store holds no matching reservation to ${action}`, context);
|
|
695
|
+
}
|
|
678
696
|
};
|
|
679
697
|
return {
|
|
680
698
|
name: "ap2",
|