@atlasauth/pca-acp 0.0.0-stage → 0.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.
- package/LICENSE +21 -0
- package/README.md +64 -2
- package/dist/index.d.ts +369 -0
- package/dist/index.js +478 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Atlas Authorization
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,65 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @atlasauth/pca-acp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Agentic Commerce Protocol (ACP) and x402 adapter for Proof-Carrying Authority (PCA). It mints an ACP-style delegated one-time payment token (a JWS bound to session, merchant, amount, currency and expiry) from a PCActn, and provides an x402 (HTTP 402) facilitator hook that only settles when the token and its backing proof verify.
|
|
4
|
+
|
|
5
|
+
The PCActn's capability caveats gate issuance: minting is refused (`AcpAuthorityError`) if the requested amount, currency, merchant, category or human-present modality exceeds what the proof authorizes, or if the token would outlive the proof. The token carries the proof by reference (its digest), never its contents. For the AP2 Intent/Cart/Payment chain see `@atlasauth/pca-ap2`.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm i @atlasauth/pca-acp
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Depends on `@atlasauth/pca` and `jose` (installed transitively).
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import {
|
|
19
|
+
spendCapCaveat, merchantAllowCaveat,
|
|
20
|
+
mintDelegatedPaymentToken, verifyDelegatedPaymentToken,
|
|
21
|
+
x402Challenge, x402Settle, acpX402Verifier,
|
|
22
|
+
} from '@atlasauth/pca-acp';
|
|
23
|
+
|
|
24
|
+
// `grant` carries payment caveats, e.g. mintRoot({ ..., caveats: [spendCapCaveat(500, 'USD'),
|
|
25
|
+
// merchantAllowCaveat(['acme'])] }); `pcActn` is a PCActn built from it with @atlasauth/pca.
|
|
26
|
+
|
|
27
|
+
const token = await mintDelegatedPaymentToken(pcActn, {
|
|
28
|
+
amount: 100, currency: 'USD', merchant: 'acme', session: 'sess-1',
|
|
29
|
+
expiresAt: Date.now() + 10 * 60_000,
|
|
30
|
+
paymentMethod: { type: 'shared_payment_token', token: 'spt_abc' },
|
|
31
|
+
signingKey: privateKey, // jose KeyLike, Uint8Array or JWK; default alg EdDSA
|
|
32
|
+
});
|
|
33
|
+
// minting 900 against the 500 cap throws AcpAuthorityError
|
|
34
|
+
|
|
35
|
+
// Settlement: check the token binding and re-verify the backing proof.
|
|
36
|
+
await verifyDelegatedPaymentToken(token, {
|
|
37
|
+
expectedMerchant: 'acme', amount: 100, verifyKey: publicKey,
|
|
38
|
+
pcActn, grant, audience: 'my-rs', // optional full proof re-verification
|
|
39
|
+
}); // { ok: true, claims, pcaResult }
|
|
40
|
+
|
|
41
|
+
// x402: answer with a 402 challenge, then gate settlement on the proof-bound token.
|
|
42
|
+
const challenge = x402Challenge('/api/report', { amount: 100, currency: 'USDC', payTo: '0xabc' });
|
|
43
|
+
const result = await x402Settle({ token, merchant: 'acme', amount: 100 }, {
|
|
44
|
+
verify: acpX402Verifier({ verifyKey: publicKey, pcActn, grant, audience: 'my-rs' }),
|
|
45
|
+
settle: async (payload, claims) => ({ charged: claims.amount }), // your facilitator call
|
|
46
|
+
}); // { settled: true, status: 200, receipt } or { settled: false, status: 402, reason }
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Pass `expectedMerchant` and `amount` to `acpX402Verifier` from your own order data when you can; by default it reads them from the client's payload.
|
|
50
|
+
|
|
51
|
+
## API
|
|
52
|
+
|
|
53
|
+
- Caveats: `spendCapCaveat`, `merchantAllowCaveat`, `merchantCategoryCaveat`, `humanPresentCaveat`, `extractPaymentAuthority`, `checkPaymentAuthority`, `AcpAuthorityError`.
|
|
54
|
+
- Tokens: `mintDelegatedPaymentToken`, `verifyDelegatedPaymentToken`.
|
|
55
|
+
- x402: `x402Challenge`, `x402Settle`, `acpX402Verifier`.
|
|
56
|
+
|
|
57
|
+
## Status
|
|
58
|
+
|
|
59
|
+
Experimental. ACP and x402 are young protocols: the token and `accepts` field names are structural and should be validated against the current Stripe/OpenAI ACP and Coinbase x402 specs before production use. The x402 helpers perform no network I/O; verification and settlement are injected. Single use of a token (`jti`) is not tracked here, so the resource server must record used ids. The cryptography is unaudited.
|
|
60
|
+
|
|
61
|
+
Source and issues: https://github.com/Atlas-Authorization/pca
|
|
62
|
+
|
|
63
|
+
## License
|
|
64
|
+
|
|
65
|
+
MIT - see LICENSE
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @atlasauth/pca-acp — Agentic Commerce Protocol (ACP) + x402 for PCA.
|
|
3
|
+
*
|
|
4
|
+
* ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
5
|
+
* │ PCA GOVERNS. ACP mints the delegated one-time payment token. x402 (HTTP 402) is the pay rail. │
|
|
6
|
+
* │ "Every payment mandate is a verifiable proof-carrying action." │
|
|
7
|
+
* └──────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
8
|
+
*
|
|
9
|
+
* ACP (the Agentic Commerce Protocol, OpenAI + Stripe, 2025) lets an agent complete a purchase inside a
|
|
10
|
+
* chat/agent surface. Its payment leg is the Delegated / Shared Payment Token: a one-time, scope-bound
|
|
11
|
+
* token the buyer's agent hands the merchant to pull a bounded amount for ONE checkout
|
|
12
|
+
* (session + merchant + amount + expiry). x402 (Coinbase's HTTP 402 "Payment Required" flow) is the
|
|
13
|
+
* other net-new rail: a resource server answers `402` with a payment challenge, the client pays, and
|
|
14
|
+
* the server settles.
|
|
15
|
+
*
|
|
16
|
+
* This module makes BOTH of those proof-carrying. A delegated payment token is minted FROM a PCActn and
|
|
17
|
+
* carries that proof's authority by reference (its digest); the PCA proof's capability caveats — the
|
|
18
|
+
* spend cap, the merchant/category allowlist, the human-present requirement — GATE issuance: a token is
|
|
19
|
+
* refused at mint when the requested amount / currency / merchant / category / modality exceeds what the
|
|
20
|
+
* proof authorizes. At settlement the token's session/merchant/amount/expiry binding is re-checked and
|
|
21
|
+
* the bound PCActn can be re-verified, failing closed on over-amount, wrong-merchant, expiry, or a proof
|
|
22
|
+
* that no longer matches.
|
|
23
|
+
*
|
|
24
|
+
* This is ACP + x402, NOT AP2. The AP2 Intent→Cart→Payment VDC chain is `@atlasauth/pca-ap2`; this
|
|
25
|
+
* package reuses that mandate vocabulary (MonetaryAmount / merchants / categories / human_present /
|
|
26
|
+
* PaymentMethod) for consistency but is a distinct, wire-compatible adapter, not a re-implementation.
|
|
27
|
+
*
|
|
28
|
+
* ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
29
|
+
* HONEST CAVEAT — VERIFY BEFORE PRODUCTION WIRE USE
|
|
30
|
+
* ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
31
|
+
* ACP and x402 are young and moving. The exact JSON field names of the Stripe Shared Payment Token and
|
|
32
|
+
* the Coinbase x402 `accepts` requirement object should be validated against their current specs before
|
|
33
|
+
* production. The AUTHORITY model here (mint-time caveat gating + settlement-time PCActn binding) is the
|
|
34
|
+
* stable, load-bearing contribution; the wire envelopes are structural and injectable.
|
|
35
|
+
*/
|
|
36
|
+
import { type Capability, type Caveat, type PCActn, type VerifyResult } from '@atlasauth/pca';
|
|
37
|
+
import { type JWK, type KeyLike } from 'jose';
|
|
38
|
+
/** The ACP delegated-payment-token shape this module emits (version pinned into the claims). */
|
|
39
|
+
export declare const ACP_DELEGATED_TOKEN_VERSION: 1;
|
|
40
|
+
/** The `typ` claim carried in a delegated payment token (identifies the envelope to a verifier). */
|
|
41
|
+
export declare const ACP_DELEGATED_TOKEN_TYPE: "acp-delegated-payment";
|
|
42
|
+
/** ISO-4217 currency + decimal value (use minor units in production to avoid float drift). */
|
|
43
|
+
export interface MonetaryAmount {
|
|
44
|
+
currency: string;
|
|
45
|
+
value: number;
|
|
46
|
+
}
|
|
47
|
+
/** The payment instrument a delegated token authorizes. Mirrors the AP2 `PaymentMethod` shape. */
|
|
48
|
+
export interface PaymentMethod {
|
|
49
|
+
/** e.g. `card`, `shared_payment_token`, `x402`, `crypto`. */
|
|
50
|
+
type: string;
|
|
51
|
+
display?: string;
|
|
52
|
+
/** Opaque token (e.g. a Stripe Shared Payment Token id); never a raw PAN. */
|
|
53
|
+
token?: string;
|
|
54
|
+
}
|
|
55
|
+
/** `{ type: 'max_amount', max, currency? }` — per-transaction spend ceiling (optionally currency-bound). */
|
|
56
|
+
export declare const SPEND_CAP_CAVEAT: "max_amount";
|
|
57
|
+
/** `{ type: 'merchant_allow', merchants: [...] }` — allowlisted merchant ids (absent ⇒ any merchant). */
|
|
58
|
+
export declare const MERCHANT_ALLOW_CAVEAT: "merchant_allow";
|
|
59
|
+
/** `{ type: 'merchant_category', categories: [...] }` — allowlisted MCC categories (absent ⇒ any). */
|
|
60
|
+
export declare const MERCHANT_CATEGORY_CAVEAT: "merchant_category";
|
|
61
|
+
/** `{ type: 'human_present', required: boolean }` — require a human-present modality for the charge. */
|
|
62
|
+
export declare const HUMAN_PRESENT_CAVEAT: "human_present";
|
|
63
|
+
export interface SpendCapCaveat extends Caveat {
|
|
64
|
+
type: typeof SPEND_CAP_CAVEAT;
|
|
65
|
+
max: number;
|
|
66
|
+
currency?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface MerchantAllowCaveat extends Caveat {
|
|
69
|
+
type: typeof MERCHANT_ALLOW_CAVEAT;
|
|
70
|
+
merchants: string[];
|
|
71
|
+
}
|
|
72
|
+
export interface MerchantCategoryCaveat extends Caveat {
|
|
73
|
+
type: typeof MERCHANT_CATEGORY_CAVEAT;
|
|
74
|
+
categories: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface HumanPresentCaveat extends Caveat {
|
|
77
|
+
type: typeof HUMAN_PRESENT_CAVEAT;
|
|
78
|
+
required: boolean;
|
|
79
|
+
}
|
|
80
|
+
/** Build a per-transaction spend-cap caveat `{ type: 'max_amount', max, currency? }`. */
|
|
81
|
+
export declare function spendCapCaveat(max: number, currency?: string): SpendCapCaveat;
|
|
82
|
+
/** Build a merchant-allowlist caveat `{ type: 'merchant_allow', merchants }`. */
|
|
83
|
+
export declare function merchantAllowCaveat(merchants: string[]): MerchantAllowCaveat;
|
|
84
|
+
/** Build a merchant-category (MCC) allowlist caveat `{ type: 'merchant_category', categories }`. */
|
|
85
|
+
export declare function merchantCategoryCaveat(categories: string[]): MerchantCategoryCaveat;
|
|
86
|
+
/** Build a human-present requirement caveat `{ type: 'human_present', required }`. */
|
|
87
|
+
export declare function humanPresentCaveat(required?: boolean): HumanPresentCaveat;
|
|
88
|
+
/** Thrown when a delegated payment token cannot be minted because the request exceeds the proof's authority. */
|
|
89
|
+
export declare class AcpAuthorityError extends Error {
|
|
90
|
+
constructor(message: string);
|
|
91
|
+
}
|
|
92
|
+
/** The conjunction of all payment caveats on a proof's leaf capability. */
|
|
93
|
+
export interface PaymentAuthority {
|
|
94
|
+
/** Tightest per-transaction spend cap, or undefined when unconstrained. */
|
|
95
|
+
maxAmount?: number;
|
|
96
|
+
/** Currency the spend cap is denominated in, or undefined when the cap is currency-agnostic. */
|
|
97
|
+
currency?: string;
|
|
98
|
+
/** Allowlisted merchant ids (intersection of every allowlist caveat), or `null` for "any merchant". */
|
|
99
|
+
merchants: string[] | null;
|
|
100
|
+
/** Allowlisted MCC categories (intersection), or `null` for "any category". */
|
|
101
|
+
categories: string[] | null;
|
|
102
|
+
/** True when any caveat requires the charge to be human-present. */
|
|
103
|
+
humanPresentRequired: boolean;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Collapse a leaf capability's cumulative caveat list into its effective payment authority. Payment
|
|
107
|
+
* caveats combine conjunctively (tightest cap, intersected allowlists, sticky human-present); a malformed
|
|
108
|
+
* PAYMENT caveat throws (fail closed); any non-payment caveat type is ignored. The order of caveats does
|
|
109
|
+
* not matter — the result is the same conjunction either way.
|
|
110
|
+
*/
|
|
111
|
+
export declare function extractPaymentAuthority(caveats: readonly Caveat[]): PaymentAuthority;
|
|
112
|
+
/** A concrete purchase request, checked against a {@link PaymentAuthority}. */
|
|
113
|
+
export interface PaymentRequest {
|
|
114
|
+
amount: number;
|
|
115
|
+
currency: string;
|
|
116
|
+
merchant: string;
|
|
117
|
+
/** The merchant's MCC category, when known (required only if the proof constrains categories). */
|
|
118
|
+
category?: string;
|
|
119
|
+
/** Whether a human is present/attesting for this charge (the ACP modality signal). */
|
|
120
|
+
humanPresent?: boolean;
|
|
121
|
+
}
|
|
122
|
+
/** The outcome of checking a purchase request against a proof's payment authority. */
|
|
123
|
+
export interface AuthorityCheck {
|
|
124
|
+
ok: boolean;
|
|
125
|
+
reason?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Check a concrete purchase request against the payment authority a PCActn carries. Pure and fail-closed:
|
|
129
|
+
* an over-cap amount, a currency the cap forbids, a merchant / category outside the allowlist, or a
|
|
130
|
+
* missing human-present signal the proof demands all return `{ ok: false }`.
|
|
131
|
+
*/
|
|
132
|
+
export declare function checkPaymentAuthority(authority: PaymentAuthority, request: PaymentRequest): AuthorityCheck;
|
|
133
|
+
/** How a delegated payment token points back at the PCActn that authorized it (authority by reference). */
|
|
134
|
+
export interface PcaAuthorityRef {
|
|
135
|
+
/** `pcactnDigest()` of the authorizing proof — the binding a verifier re-checks against the proof. */
|
|
136
|
+
digest: string;
|
|
137
|
+
/** The proof's audience (resource server / Atlas instance id). */
|
|
138
|
+
aud: string;
|
|
139
|
+
/** The proof's grant id. */
|
|
140
|
+
grant_ref: string;
|
|
141
|
+
/** The acting leaf capability holder (b64u public key). */
|
|
142
|
+
leaf_holder: string;
|
|
143
|
+
verb: string;
|
|
144
|
+
resource: string;
|
|
145
|
+
params_digest: string;
|
|
146
|
+
}
|
|
147
|
+
/** A key usable to sign/verify a delegated payment token. A plain JWK is imported; other forms pass through. */
|
|
148
|
+
export type TokenKey = KeyLike | Uint8Array | JWK;
|
|
149
|
+
/** The claims a delegated payment token carries (the JWS payload). One-time, scope-bound, proof-referenced. */
|
|
150
|
+
export interface DelegatedPaymentClaims {
|
|
151
|
+
typ: typeof ACP_DELEGATED_TOKEN_TYPE;
|
|
152
|
+
ver: typeof ACP_DELEGATED_TOKEN_VERSION;
|
|
153
|
+
/** One-time id (a resource server tracks it to enforce single-use). */
|
|
154
|
+
jti: string;
|
|
155
|
+
/** The ACP checkout session this token is bound to. */
|
|
156
|
+
session: string;
|
|
157
|
+
/** The merchant this token may pay. */
|
|
158
|
+
merchant: string;
|
|
159
|
+
/** The maximum amount this token authorizes (minor-unit-safe decimal). */
|
|
160
|
+
amount: number;
|
|
161
|
+
currency: string;
|
|
162
|
+
/** Issued-at (epoch ms). */
|
|
163
|
+
iat: number;
|
|
164
|
+
/** Expiry (epoch ms). */
|
|
165
|
+
exp: number;
|
|
166
|
+
paymentMethod: PaymentMethod;
|
|
167
|
+
/** The ACP human-present modality signal for this charge. */
|
|
168
|
+
humanPresent: boolean;
|
|
169
|
+
/** The merchant category, when supplied at mint. */
|
|
170
|
+
category?: string;
|
|
171
|
+
/** Optional issuer id of the minting party (agent platform / facilitator). */
|
|
172
|
+
iss?: string;
|
|
173
|
+
/** The PCA authority this token carries by reference. */
|
|
174
|
+
pca: PcaAuthorityRef;
|
|
175
|
+
}
|
|
176
|
+
/** Options for {@link mintDelegatedPaymentToken}. */
|
|
177
|
+
export interface MintOptions {
|
|
178
|
+
/** The amount to authorize (the token's ceiling for this one checkout). */
|
|
179
|
+
amount: number;
|
|
180
|
+
currency: string;
|
|
181
|
+
/** The merchant the token may pay. */
|
|
182
|
+
merchant: string;
|
|
183
|
+
/** The ACP checkout session id the token is bound to. */
|
|
184
|
+
session: string;
|
|
185
|
+
/** Token expiry (epoch ms). Must be in the future and not outlive the authorizing proof's `exp`. */
|
|
186
|
+
expiresAt: number;
|
|
187
|
+
paymentMethod: PaymentMethod;
|
|
188
|
+
/** The JWS signing key (the minting party's key). Required to produce the token. */
|
|
189
|
+
signingKey: TokenKey;
|
|
190
|
+
/** JWS algorithm (default `'EdDSA'`). */
|
|
191
|
+
alg?: string;
|
|
192
|
+
/** Merchant category (MCC), required only when the proof constrains categories. */
|
|
193
|
+
category?: string;
|
|
194
|
+
/** The human-present modality to stamp; also satisfies a `human_present` caveat when `true`. */
|
|
195
|
+
humanPresent?: boolean;
|
|
196
|
+
/** Issuer id to stamp into the claims. */
|
|
197
|
+
issuer?: string;
|
|
198
|
+
/** JWS `kid` header (set it when verifiers resolve the key from a JWKS). */
|
|
199
|
+
kid?: string;
|
|
200
|
+
/** Explicit one-time id. Default: a deterministic digest of the binding + proof digest. */
|
|
201
|
+
jti?: string;
|
|
202
|
+
/** Issued-at clock (epoch ms). Default `Date.now()`. */
|
|
203
|
+
now?: number;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Mint a one-time ACP delegated payment token (a JWS) FROM a PCActn. The token is bound to
|
|
207
|
+
* session + merchant + amount + currency + expiry and carries the proof's authority BY REFERENCE
|
|
208
|
+
* (`pca.digest`). The PCActn's capability caveats gate issuance: the request is checked against the
|
|
209
|
+
* proof's {@link PaymentAuthority} and the mint is REFUSED (throws {@link AcpAuthorityError}) when the
|
|
210
|
+
* amount / currency / merchant / category / modality exceeds it, or when the requested expiry is in the
|
|
211
|
+
* past or would outlive the proof. The token never re-exposes the proof's contents — only the digest.
|
|
212
|
+
*/
|
|
213
|
+
export declare function mintDelegatedPaymentToken(pcActn: PCActn, opts: MintOptions): Promise<string>;
|
|
214
|
+
/** Options for {@link verifyDelegatedPaymentToken}. */
|
|
215
|
+
export interface VerifyTokenOptions {
|
|
216
|
+
/** The expected merchant the token must authorize. */
|
|
217
|
+
expectedMerchant: string;
|
|
218
|
+
/** The amount the caller intends to settle. Fails closed when it exceeds the token's authorized amount. */
|
|
219
|
+
amount: number;
|
|
220
|
+
/** The JWS verification key. */
|
|
221
|
+
verifyKey: TokenKey;
|
|
222
|
+
/** JWS algorithm (default `'EdDSA'`). */
|
|
223
|
+
alg?: string;
|
|
224
|
+
/** Verification clock (epoch ms). Default `Date.now()`. */
|
|
225
|
+
now?: number;
|
|
226
|
+
/** The session the token must be bound to, when the caller wants it checked. */
|
|
227
|
+
expectedSession?: string;
|
|
228
|
+
/** Expected settlement currency, when the caller wants it checked. */
|
|
229
|
+
expectedCurrency?: string;
|
|
230
|
+
/**
|
|
231
|
+
* The authorizing PCActn. When supplied, its `pcactnDigest()` must equal the token's `pca.digest`
|
|
232
|
+
* (proof-binding). When `grant` is ALSO supplied, the proof is additionally re-verified end-to-end.
|
|
233
|
+
*/
|
|
234
|
+
pcActn?: PCActn;
|
|
235
|
+
/** The grant to re-verify `pcActn` against (enables a full `verifyPCActnCore` pass). */
|
|
236
|
+
grant?: Capability;
|
|
237
|
+
/** This verifier's audience for the full `verifyPCActnCore` pass (see the core's fail-closed rule). */
|
|
238
|
+
audience?: string | null;
|
|
239
|
+
}
|
|
240
|
+
/** The outcome of verifying a delegated payment token. */
|
|
241
|
+
export interface TokenVerification {
|
|
242
|
+
ok: boolean;
|
|
243
|
+
reason?: string;
|
|
244
|
+
/** The verified claims (present only on success, or when the JWS verified but a binding check failed). */
|
|
245
|
+
claims?: DelegatedPaymentClaims;
|
|
246
|
+
/** The full PCActn verify result, when a re-verify was requested. */
|
|
247
|
+
pcaResult?: VerifyResult;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Verify a delegated payment token at settlement. Checks the JWS signature, then the token binding:
|
|
251
|
+
* merchant must equal `expectedMerchant`, the amount being settled must not exceed the token's authorized
|
|
252
|
+
* amount, the token must not be expired, and (when asked) the session / currency must match. When a
|
|
253
|
+
* `pcActn` is supplied its digest must equal the token's `pca.digest`; with a `grant` it is re-verified
|
|
254
|
+
* end-to-end. Fails CLOSED on every mismatch.
|
|
255
|
+
*/
|
|
256
|
+
export declare function verifyDelegatedPaymentToken(token: string, opts: VerifyTokenOptions): Promise<TokenVerification>;
|
|
257
|
+
/** A single x402 payment requirement (the server's `accepts` entry). Structural; check against the x402 spec. */
|
|
258
|
+
export interface X402Requirement {
|
|
259
|
+
scheme: string;
|
|
260
|
+
network: string;
|
|
261
|
+
maxAmountRequired: string;
|
|
262
|
+
resource: string;
|
|
263
|
+
description: string;
|
|
264
|
+
payTo: string;
|
|
265
|
+
asset: string;
|
|
266
|
+
mimeType: string;
|
|
267
|
+
}
|
|
268
|
+
/** The HTTP 402 challenge a resource server returns to demand payment. */
|
|
269
|
+
export interface X402Challenge {
|
|
270
|
+
status: 402;
|
|
271
|
+
headers: Record<string, string>;
|
|
272
|
+
body: {
|
|
273
|
+
x402Version: 1;
|
|
274
|
+
accepts: X402Requirement[];
|
|
275
|
+
error?: string;
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
/** Options for {@link x402Challenge}. */
|
|
279
|
+
export interface X402ChallengeOptions {
|
|
280
|
+
amount: number;
|
|
281
|
+
currency?: string;
|
|
282
|
+
/** The settlement network (e.g. an x402 chain id). Default `base-sepolia`. */
|
|
283
|
+
network?: string;
|
|
284
|
+
/** Payee address / account. */
|
|
285
|
+
payTo?: string;
|
|
286
|
+
description?: string;
|
|
287
|
+
/** Payment scheme. Default `exact`. */
|
|
288
|
+
scheme?: string;
|
|
289
|
+
mimeType?: string;
|
|
290
|
+
/** An error reason to surface alongside the challenge (e.g. on a rejected prior attempt). */
|
|
291
|
+
error?: string;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Build the HTTP 402 `Payment Required` challenge for a protected resource — the server's `accepts`
|
|
295
|
+
* payment requirement plus the `402` status. Structural only; no network. (Field names follow the
|
|
296
|
+
* public x402 shape and should be validated against the x402 spec before production.)
|
|
297
|
+
*/
|
|
298
|
+
export declare function x402Challenge(resource: string, opts: X402ChallengeOptions): X402Challenge;
|
|
299
|
+
/** The client's x402 payment payload (the decoded `X-PAYMENT`). Carries the delegated payment token. */
|
|
300
|
+
export interface X402PaymentPayload {
|
|
301
|
+
x402Version?: number;
|
|
302
|
+
scheme?: string;
|
|
303
|
+
network?: string;
|
|
304
|
+
/** The ACP delegated payment token (a JWS) proving proof-carrying authority for this charge. */
|
|
305
|
+
token: string;
|
|
306
|
+
/** The merchant the client is paying (checked against the token). */
|
|
307
|
+
merchant?: string;
|
|
308
|
+
/** The amount the client intends to settle (checked against the token). */
|
|
309
|
+
amount?: number;
|
|
310
|
+
resource?: string;
|
|
311
|
+
[k: string]: unknown;
|
|
312
|
+
}
|
|
313
|
+
/** The outcome an injected x402 verifier returns. */
|
|
314
|
+
export interface X402VerifyResult {
|
|
315
|
+
ok: boolean;
|
|
316
|
+
reason?: string;
|
|
317
|
+
/** The verified token claims, when the payment verified. */
|
|
318
|
+
claims?: DelegatedPaymentClaims;
|
|
319
|
+
}
|
|
320
|
+
/** An injectable function that verifies an x402 payment payload (fed a verified PCActn-bound token). */
|
|
321
|
+
export type X402Verify = (payload: X402PaymentPayload) => X402VerifyResult | Promise<X402VerifyResult>;
|
|
322
|
+
/** An injectable settlement step run once payment is verified (e.g. a facilitator call). No network here. */
|
|
323
|
+
export type X402Settler = (payload: X402PaymentPayload, claims: DelegatedPaymentClaims) => unknown | Promise<unknown>;
|
|
324
|
+
/** Options for {@link x402Settle} — the injected verify (required) and optional settlement step. */
|
|
325
|
+
export interface X402SettleOptions {
|
|
326
|
+
verify: X402Verify;
|
|
327
|
+
/** Optional settlement step run only after `verify` passes; its return value becomes the `receipt`. */
|
|
328
|
+
settle?: X402Settler;
|
|
329
|
+
}
|
|
330
|
+
/** The outcome of an x402 settlement attempt. */
|
|
331
|
+
export interface X402SettleResult {
|
|
332
|
+
settled: boolean;
|
|
333
|
+
status: number;
|
|
334
|
+
reason?: string;
|
|
335
|
+
claims?: DelegatedPaymentClaims;
|
|
336
|
+
receipt?: unknown;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Gate an x402 settlement on a verified, PCActn-bound payment. Runs the injected `verify` over the
|
|
340
|
+
* client's payment payload; on failure it REFUSES with a fresh `402` (fail closed), on success it
|
|
341
|
+
* optionally runs the injected `settle` step and returns the receipt. The verify/settle steps are
|
|
342
|
+
* injectable so this composes with {@link verifyDelegatedPaymentToken} (see {@link acpX402Verifier})
|
|
343
|
+
* without this module performing any network itself.
|
|
344
|
+
*/
|
|
345
|
+
export declare function x402Settle(payload: X402PaymentPayload, opts: X402SettleOptions): Promise<X402SettleResult>;
|
|
346
|
+
/** Options for {@link acpX402Verifier}. */
|
|
347
|
+
export interface AcpX402VerifierOptions {
|
|
348
|
+
/** The JWS verification key for the delegated payment token. */
|
|
349
|
+
verifyKey: TokenKey;
|
|
350
|
+
alg?: string;
|
|
351
|
+
now?: number;
|
|
352
|
+
/** Override the expected merchant (default: the payload's `merchant`). */
|
|
353
|
+
expectedMerchant?: string;
|
|
354
|
+
/** Override the settlement amount (default: the payload's `amount`). */
|
|
355
|
+
amount?: number;
|
|
356
|
+
expectedSession?: string;
|
|
357
|
+
expectedCurrency?: string;
|
|
358
|
+
/** The authorizing proof to re-check the token against (digest, and end-to-end with `grant`). */
|
|
359
|
+
pcActn?: PCActn;
|
|
360
|
+
grant?: Capability;
|
|
361
|
+
audience?: string | null;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Adapt {@link verifyDelegatedPaymentToken} into an {@link X402Verify} for {@link x402Settle}: it reads
|
|
365
|
+
* the delegated payment token (and, by default, the merchant + amount the client claims) from the x402
|
|
366
|
+
* payload and verifies the token's binding + bound proof. This is the glue that makes the
|
|
367
|
+
* 402 → pay-with-proof → settle flow proof-carrying end to end.
|
|
368
|
+
*/
|
|
369
|
+
export declare function acpX402Verifier(opts: AcpX402VerifierOptions): X402Verify;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,478 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @atlasauth/pca-acp — Agentic Commerce Protocol (ACP) + x402 for PCA.
|
|
4
|
+
*
|
|
5
|
+
* ┌──────────────────────────────────────────────────────────────────────────────────────────────┐
|
|
6
|
+
* │ PCA GOVERNS. ACP mints the delegated one-time payment token. x402 (HTTP 402) is the pay rail. │
|
|
7
|
+
* │ "Every payment mandate is a verifiable proof-carrying action." │
|
|
8
|
+
* └──────────────────────────────────────────────────────────────────────────────────────────────┘
|
|
9
|
+
*
|
|
10
|
+
* ACP (the Agentic Commerce Protocol, OpenAI + Stripe, 2025) lets an agent complete a purchase inside a
|
|
11
|
+
* chat/agent surface. Its payment leg is the Delegated / Shared Payment Token: a one-time, scope-bound
|
|
12
|
+
* token the buyer's agent hands the merchant to pull a bounded amount for ONE checkout
|
|
13
|
+
* (session + merchant + amount + expiry). x402 (Coinbase's HTTP 402 "Payment Required" flow) is the
|
|
14
|
+
* other net-new rail: a resource server answers `402` with a payment challenge, the client pays, and
|
|
15
|
+
* the server settles.
|
|
16
|
+
*
|
|
17
|
+
* This module makes BOTH of those proof-carrying. A delegated payment token is minted FROM a PCActn and
|
|
18
|
+
* carries that proof's authority by reference (its digest); the PCA proof's capability caveats — the
|
|
19
|
+
* spend cap, the merchant/category allowlist, the human-present requirement — GATE issuance: a token is
|
|
20
|
+
* refused at mint when the requested amount / currency / merchant / category / modality exceeds what the
|
|
21
|
+
* proof authorizes. At settlement the token's session/merchant/amount/expiry binding is re-checked and
|
|
22
|
+
* the bound PCActn can be re-verified, failing closed on over-amount, wrong-merchant, expiry, or a proof
|
|
23
|
+
* that no longer matches.
|
|
24
|
+
*
|
|
25
|
+
* This is ACP + x402, NOT AP2. The AP2 Intent→Cart→Payment VDC chain is `@atlasauth/pca-ap2`; this
|
|
26
|
+
* package reuses that mandate vocabulary (MonetaryAmount / merchants / categories / human_present /
|
|
27
|
+
* PaymentMethod) for consistency but is a distinct, wire-compatible adapter, not a re-implementation.
|
|
28
|
+
*
|
|
29
|
+
* ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
30
|
+
* HONEST CAVEAT — VERIFY BEFORE PRODUCTION WIRE USE
|
|
31
|
+
* ────────────────────────────────────────────────────────────────────────────────────────────────
|
|
32
|
+
* ACP and x402 are young and moving. The exact JSON field names of the Stripe Shared Payment Token and
|
|
33
|
+
* the Coinbase x402 `accepts` requirement object should be validated against their current specs before
|
|
34
|
+
* production. The AUTHORITY model here (mint-time caveat gating + settlement-time PCActn binding) is the
|
|
35
|
+
* stable, load-bearing contribution; the wire envelopes are structural and injectable.
|
|
36
|
+
*/
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.AcpAuthorityError = exports.HUMAN_PRESENT_CAVEAT = exports.MERCHANT_CATEGORY_CAVEAT = exports.MERCHANT_ALLOW_CAVEAT = exports.SPEND_CAP_CAVEAT = exports.ACP_DELEGATED_TOKEN_TYPE = exports.ACP_DELEGATED_TOKEN_VERSION = void 0;
|
|
39
|
+
exports.spendCapCaveat = spendCapCaveat;
|
|
40
|
+
exports.merchantAllowCaveat = merchantAllowCaveat;
|
|
41
|
+
exports.merchantCategoryCaveat = merchantCategoryCaveat;
|
|
42
|
+
exports.humanPresentCaveat = humanPresentCaveat;
|
|
43
|
+
exports.extractPaymentAuthority = extractPaymentAuthority;
|
|
44
|
+
exports.checkPaymentAuthority = checkPaymentAuthority;
|
|
45
|
+
exports.mintDelegatedPaymentToken = mintDelegatedPaymentToken;
|
|
46
|
+
exports.verifyDelegatedPaymentToken = verifyDelegatedPaymentToken;
|
|
47
|
+
exports.x402Challenge = x402Challenge;
|
|
48
|
+
exports.x402Settle = x402Settle;
|
|
49
|
+
exports.acpX402Verifier = acpX402Verifier;
|
|
50
|
+
const pca_1 = require("@atlasauth/pca");
|
|
51
|
+
const jose_1 = require("jose");
|
|
52
|
+
// ===================================================================================================
|
|
53
|
+
// Version + token type
|
|
54
|
+
// ===================================================================================================
|
|
55
|
+
/** The ACP delegated-payment-token shape this module emits (version pinned into the claims). */
|
|
56
|
+
exports.ACP_DELEGATED_TOKEN_VERSION = 1;
|
|
57
|
+
/** The `typ` claim carried in a delegated payment token (identifies the envelope to a verifier). */
|
|
58
|
+
exports.ACP_DELEGATED_TOKEN_TYPE = 'acp-delegated-payment';
|
|
59
|
+
// ===================================================================================================
|
|
60
|
+
// Payment caveat vocabulary (what the PCA proof's capability chain carries to bound a purchase)
|
|
61
|
+
// ===================================================================================================
|
|
62
|
+
//
|
|
63
|
+
// The PCA capability chain is attenuating and append-only (see @atlasauth/pca `capability.ts`): a child
|
|
64
|
+
// hop can only ADD caveats, never drop or widen one. The leaf hop therefore carries the full cumulative
|
|
65
|
+
// caveat list, and these payment caveats COMBINE CONJUNCTIVELY (the tightest spend cap wins; merchant /
|
|
66
|
+
// category allowlists INTERSECT; any `human_present` requirement sticks). A malformed PAYMENT caveat
|
|
67
|
+
// fails closed; caveats of any other type (ttl, scope, …) are ignored here.
|
|
68
|
+
/** `{ type: 'max_amount', max, currency? }` — per-transaction spend ceiling (optionally currency-bound). */
|
|
69
|
+
exports.SPEND_CAP_CAVEAT = 'max_amount';
|
|
70
|
+
/** `{ type: 'merchant_allow', merchants: [...] }` — allowlisted merchant ids (absent ⇒ any merchant). */
|
|
71
|
+
exports.MERCHANT_ALLOW_CAVEAT = 'merchant_allow';
|
|
72
|
+
/** `{ type: 'merchant_category', categories: [...] }` — allowlisted MCC categories (absent ⇒ any). */
|
|
73
|
+
exports.MERCHANT_CATEGORY_CAVEAT = 'merchant_category';
|
|
74
|
+
/** `{ type: 'human_present', required: boolean }` — require a human-present modality for the charge. */
|
|
75
|
+
exports.HUMAN_PRESENT_CAVEAT = 'human_present';
|
|
76
|
+
/** Build a per-transaction spend-cap caveat `{ type: 'max_amount', max, currency? }`. */
|
|
77
|
+
function spendCapCaveat(max, currency) {
|
|
78
|
+
return currency !== undefined ? { type: exports.SPEND_CAP_CAVEAT, max, currency } : { type: exports.SPEND_CAP_CAVEAT, max };
|
|
79
|
+
}
|
|
80
|
+
/** Build a merchant-allowlist caveat `{ type: 'merchant_allow', merchants }`. */
|
|
81
|
+
function merchantAllowCaveat(merchants) {
|
|
82
|
+
return { type: exports.MERCHANT_ALLOW_CAVEAT, merchants: [...merchants] };
|
|
83
|
+
}
|
|
84
|
+
/** Build a merchant-category (MCC) allowlist caveat `{ type: 'merchant_category', categories }`. */
|
|
85
|
+
function merchantCategoryCaveat(categories) {
|
|
86
|
+
return { type: exports.MERCHANT_CATEGORY_CAVEAT, categories: [...categories] };
|
|
87
|
+
}
|
|
88
|
+
/** Build a human-present requirement caveat `{ type: 'human_present', required }`. */
|
|
89
|
+
function humanPresentCaveat(required = true) {
|
|
90
|
+
return { type: exports.HUMAN_PRESENT_CAVEAT, required };
|
|
91
|
+
}
|
|
92
|
+
// ===================================================================================================
|
|
93
|
+
// Errors
|
|
94
|
+
// ===================================================================================================
|
|
95
|
+
/** Thrown when a delegated payment token cannot be minted because the request exceeds the proof's authority. */
|
|
96
|
+
class AcpAuthorityError extends Error {
|
|
97
|
+
constructor(message) {
|
|
98
|
+
super(message);
|
|
99
|
+
this.name = 'AcpAuthorityError';
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.AcpAuthorityError = AcpAuthorityError;
|
|
103
|
+
function asStringArray(v, label) {
|
|
104
|
+
if (!Array.isArray(v) || !v.every((x) => typeof x === 'string')) {
|
|
105
|
+
throw new AcpAuthorityError(`malformed ${label} caveat: expected a string[] (fail closed)`);
|
|
106
|
+
}
|
|
107
|
+
return v;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Collapse a leaf capability's cumulative caveat list into its effective payment authority. Payment
|
|
111
|
+
* caveats combine conjunctively (tightest cap, intersected allowlists, sticky human-present); a malformed
|
|
112
|
+
* PAYMENT caveat throws (fail closed); any non-payment caveat type is ignored. The order of caveats does
|
|
113
|
+
* not matter — the result is the same conjunction either way.
|
|
114
|
+
*/
|
|
115
|
+
function extractPaymentAuthority(caveats) {
|
|
116
|
+
let maxAmount;
|
|
117
|
+
let currency;
|
|
118
|
+
let merchants = null;
|
|
119
|
+
let categories = null;
|
|
120
|
+
let humanPresentRequired = false;
|
|
121
|
+
for (const c of caveats) {
|
|
122
|
+
switch (c.type) {
|
|
123
|
+
case exports.SPEND_CAP_CAVEAT: {
|
|
124
|
+
const max = c.max;
|
|
125
|
+
if (typeof max !== 'number' || !Number.isFinite(max) || max < 0) {
|
|
126
|
+
throw new AcpAuthorityError('malformed max_amount caveat: max must be a finite number >= 0 (fail closed)');
|
|
127
|
+
}
|
|
128
|
+
maxAmount = maxAmount === undefined ? max : Math.min(maxAmount, max);
|
|
129
|
+
const cur = c.currency;
|
|
130
|
+
if (cur !== undefined) {
|
|
131
|
+
if (typeof cur !== 'string' || cur.length === 0) {
|
|
132
|
+
throw new AcpAuthorityError('malformed max_amount caveat: currency must be a non-empty string (fail closed)');
|
|
133
|
+
}
|
|
134
|
+
if (currency !== undefined && currency !== cur) {
|
|
135
|
+
throw new AcpAuthorityError(`conflicting spend-cap currencies "${currency}" vs "${cur}" (fail closed)`);
|
|
136
|
+
}
|
|
137
|
+
currency = cur;
|
|
138
|
+
}
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
case exports.MERCHANT_ALLOW_CAVEAT: {
|
|
142
|
+
const list = asStringArray(c.merchants, 'merchant_allow');
|
|
143
|
+
merchants = merchants === null ? [...new Set(list)] : merchants.filter((m) => list.includes(m));
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case exports.MERCHANT_CATEGORY_CAVEAT: {
|
|
147
|
+
const list = asStringArray(c.categories, 'merchant_category');
|
|
148
|
+
categories = categories === null ? [...new Set(list)] : categories.filter((m) => list.includes(m));
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case exports.HUMAN_PRESENT_CAVEAT: {
|
|
152
|
+
const req = c.required;
|
|
153
|
+
if (typeof req !== 'boolean') {
|
|
154
|
+
throw new AcpAuthorityError('malformed human_present caveat: required must be a boolean (fail closed)');
|
|
155
|
+
}
|
|
156
|
+
humanPresentRequired = humanPresentRequired || req;
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
default:
|
|
160
|
+
break; // non-payment caveat (ttl, scope, resource, …) — not this adapter's concern
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
...(maxAmount !== undefined ? { maxAmount } : {}),
|
|
165
|
+
...(currency !== undefined ? { currency } : {}),
|
|
166
|
+
merchants,
|
|
167
|
+
categories,
|
|
168
|
+
humanPresentRequired,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/** The leaf (acting) capability of a proof's chain. */
|
|
172
|
+
function leafCapability(pcActn) {
|
|
173
|
+
const chain = pcActn.cap_chain;
|
|
174
|
+
if (!Array.isArray(chain) || chain.length === 0) {
|
|
175
|
+
throw new AcpAuthorityError('PCActn carries no capability chain (fail closed)');
|
|
176
|
+
}
|
|
177
|
+
const leaf = chain[chain.length - 1];
|
|
178
|
+
if (leaf === undefined)
|
|
179
|
+
throw new AcpAuthorityError('PCActn capability chain has no leaf (fail closed)');
|
|
180
|
+
return leaf;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Check a concrete purchase request against the payment authority a PCActn carries. Pure and fail-closed:
|
|
184
|
+
* an over-cap amount, a currency the cap forbids, a merchant / category outside the allowlist, or a
|
|
185
|
+
* missing human-present signal the proof demands all return `{ ok: false }`.
|
|
186
|
+
*/
|
|
187
|
+
function checkPaymentAuthority(authority, request) {
|
|
188
|
+
if (typeof request.amount !== 'number' || !Number.isFinite(request.amount) || request.amount <= 0) {
|
|
189
|
+
return { ok: false, reason: 'amount must be a finite number > 0' };
|
|
190
|
+
}
|
|
191
|
+
if (typeof request.currency !== 'string' || request.currency.length === 0) {
|
|
192
|
+
return { ok: false, reason: 'currency must be a non-empty string' };
|
|
193
|
+
}
|
|
194
|
+
if (typeof request.merchant !== 'string' || request.merchant.length === 0) {
|
|
195
|
+
return { ok: false, reason: 'merchant must be a non-empty string' };
|
|
196
|
+
}
|
|
197
|
+
if (authority.currency !== undefined && authority.currency !== request.currency) {
|
|
198
|
+
return { ok: false, reason: `currency "${request.currency}" is not the authorized currency "${authority.currency}"` };
|
|
199
|
+
}
|
|
200
|
+
if (authority.maxAmount !== undefined && request.amount > authority.maxAmount) {
|
|
201
|
+
return { ok: false, reason: `amount ${request.amount} exceeds the authorized spend cap ${authority.maxAmount}` };
|
|
202
|
+
}
|
|
203
|
+
if (authority.merchants !== null && !authority.merchants.includes(request.merchant)) {
|
|
204
|
+
return { ok: false, reason: `merchant "${request.merchant}" is not in the authorized allowlist` };
|
|
205
|
+
}
|
|
206
|
+
if (authority.categories !== null) {
|
|
207
|
+
if (request.category === undefined) {
|
|
208
|
+
return { ok: false, reason: 'the proof constrains merchant categories but no category was supplied' };
|
|
209
|
+
}
|
|
210
|
+
if (!authority.categories.includes(request.category)) {
|
|
211
|
+
return { ok: false, reason: `category "${request.category}" is not in the authorized allowlist` };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (authority.humanPresentRequired && request.humanPresent !== true) {
|
|
215
|
+
return { ok: false, reason: 'the proof requires a human-present charge but humanPresent was not asserted' };
|
|
216
|
+
}
|
|
217
|
+
return { ok: true };
|
|
218
|
+
}
|
|
219
|
+
function authorityRef(pcActn) {
|
|
220
|
+
const leaf = leafCapability(pcActn);
|
|
221
|
+
return {
|
|
222
|
+
digest: (0, pca_1.pcactnDigest)(pcActn),
|
|
223
|
+
aud: pcActn.aud,
|
|
224
|
+
grant_ref: pcActn.grant_ref,
|
|
225
|
+
leaf_holder: leaf.holder,
|
|
226
|
+
verb: pcActn.action.verb,
|
|
227
|
+
resource: pcActn.action.resource,
|
|
228
|
+
params_digest: pcActn.action.params_digest,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function isJwk(k) {
|
|
232
|
+
return typeof k === 'object' && k !== null && !(k instanceof Uint8Array) && 'kty' in k;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Mint a one-time ACP delegated payment token (a JWS) FROM a PCActn. The token is bound to
|
|
236
|
+
* session + merchant + amount + currency + expiry and carries the proof's authority BY REFERENCE
|
|
237
|
+
* (`pca.digest`). The PCActn's capability caveats gate issuance: the request is checked against the
|
|
238
|
+
* proof's {@link PaymentAuthority} and the mint is REFUSED (throws {@link AcpAuthorityError}) when the
|
|
239
|
+
* amount / currency / merchant / category / modality exceeds it, or when the requested expiry is in the
|
|
240
|
+
* past or would outlive the proof. The token never re-exposes the proof's contents — only the digest.
|
|
241
|
+
*/
|
|
242
|
+
async function mintDelegatedPaymentToken(pcActn, opts) {
|
|
243
|
+
const now = Number.isFinite(opts.now) ? opts.now : Date.now();
|
|
244
|
+
// 1. Gate issuance on the proof's authority (fail closed on an over-authority request).
|
|
245
|
+
const authority = extractPaymentAuthority(leafCapability(pcActn).caveats);
|
|
246
|
+
const check = checkPaymentAuthority(authority, {
|
|
247
|
+
amount: opts.amount,
|
|
248
|
+
currency: opts.currency,
|
|
249
|
+
merchant: opts.merchant,
|
|
250
|
+
...(opts.category !== undefined ? { category: opts.category } : {}),
|
|
251
|
+
...(opts.humanPresent !== undefined ? { humanPresent: opts.humanPresent } : {}),
|
|
252
|
+
});
|
|
253
|
+
if (!check.ok)
|
|
254
|
+
throw new AcpAuthorityError(`refused: ${check.reason ?? 'request exceeds the proof authority'}`);
|
|
255
|
+
// 2. Expiry binding: the token must expire in the future and never outlive the proof that authorized it.
|
|
256
|
+
if (!Number.isFinite(opts.expiresAt))
|
|
257
|
+
throw new AcpAuthorityError('refused: expiresAt must be a finite epoch-ms timestamp');
|
|
258
|
+
if (opts.expiresAt <= now)
|
|
259
|
+
throw new AcpAuthorityError('refused: expiresAt is not in the future');
|
|
260
|
+
if (opts.expiresAt > pcActn.exp) {
|
|
261
|
+
throw new AcpAuthorityError(`refused: token expiry ${opts.expiresAt} would outlive the proof's exp ${pcActn.exp}`);
|
|
262
|
+
}
|
|
263
|
+
if (!opts.session)
|
|
264
|
+
throw new AcpAuthorityError('refused: a session id is required');
|
|
265
|
+
const pca = authorityRef(pcActn);
|
|
266
|
+
const jti = opts.jti ??
|
|
267
|
+
(0, pca_1.pcactnDigest)({
|
|
268
|
+
...pcActn,
|
|
269
|
+
// Derive a stable one-time id from the proof digest + the token binding (not a real PCActn; just a hash seed).
|
|
270
|
+
nonce: `acp:${opts.session}:${opts.merchant}:${opts.amount}:${opts.currency}:${opts.expiresAt}:${pca.digest}`,
|
|
271
|
+
});
|
|
272
|
+
const claims = {
|
|
273
|
+
typ: exports.ACP_DELEGATED_TOKEN_TYPE,
|
|
274
|
+
ver: exports.ACP_DELEGATED_TOKEN_VERSION,
|
|
275
|
+
jti,
|
|
276
|
+
session: opts.session,
|
|
277
|
+
merchant: opts.merchant,
|
|
278
|
+
amount: opts.amount,
|
|
279
|
+
currency: opts.currency,
|
|
280
|
+
iat: now,
|
|
281
|
+
exp: opts.expiresAt,
|
|
282
|
+
paymentMethod: { ...opts.paymentMethod },
|
|
283
|
+
humanPresent: opts.humanPresent === true,
|
|
284
|
+
...(opts.category !== undefined ? { category: opts.category } : {}),
|
|
285
|
+
...(opts.issuer !== undefined ? { iss: opts.issuer } : {}),
|
|
286
|
+
pca,
|
|
287
|
+
};
|
|
288
|
+
const alg = opts.alg ?? 'EdDSA';
|
|
289
|
+
const key = isJwk(opts.signingKey) ? await (0, jose_1.importJWK)(opts.signingKey, alg) : opts.signingKey;
|
|
290
|
+
const protectedHeader = {
|
|
291
|
+
alg,
|
|
292
|
+
typ: exports.ACP_DELEGATED_TOKEN_TYPE,
|
|
293
|
+
...(opts.kid !== undefined ? { kid: opts.kid } : {}),
|
|
294
|
+
};
|
|
295
|
+
return new jose_1.CompactSign((0, pca_1.utf8)(JSON.stringify(claims))).setProtectedHeader(protectedHeader).sign(key);
|
|
296
|
+
}
|
|
297
|
+
function isPaymentMethod(v) {
|
|
298
|
+
return v !== null && typeof v === 'object' && typeof v.type === 'string';
|
|
299
|
+
}
|
|
300
|
+
function parseClaims(bytes) {
|
|
301
|
+
let parsed;
|
|
302
|
+
try {
|
|
303
|
+
parsed = JSON.parse(new TextDecoder().decode(bytes));
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed))
|
|
309
|
+
return null;
|
|
310
|
+
const c = parsed;
|
|
311
|
+
if (c.typ !== exports.ACP_DELEGATED_TOKEN_TYPE || c.ver !== exports.ACP_DELEGATED_TOKEN_VERSION)
|
|
312
|
+
return null;
|
|
313
|
+
if (typeof c.jti !== 'string' ||
|
|
314
|
+
typeof c.session !== 'string' ||
|
|
315
|
+
typeof c.merchant !== 'string' ||
|
|
316
|
+
typeof c.amount !== 'number' ||
|
|
317
|
+
typeof c.currency !== 'string' ||
|
|
318
|
+
typeof c.iat !== 'number' ||
|
|
319
|
+
typeof c.exp !== 'number' ||
|
|
320
|
+
typeof c.humanPresent !== 'boolean' ||
|
|
321
|
+
!isPaymentMethod(c.paymentMethod)) {
|
|
322
|
+
return null;
|
|
323
|
+
}
|
|
324
|
+
const pcaRaw = c.pca;
|
|
325
|
+
if (pcaRaw === null || typeof pcaRaw !== 'object' || Array.isArray(pcaRaw))
|
|
326
|
+
return null;
|
|
327
|
+
const p = pcaRaw;
|
|
328
|
+
if (typeof p.digest !== 'string' ||
|
|
329
|
+
typeof p.aud !== 'string' ||
|
|
330
|
+
typeof p.grant_ref !== 'string' ||
|
|
331
|
+
typeof p.leaf_holder !== 'string' ||
|
|
332
|
+
typeof p.verb !== 'string' ||
|
|
333
|
+
typeof p.resource !== 'string' ||
|
|
334
|
+
typeof p.params_digest !== 'string') {
|
|
335
|
+
return null;
|
|
336
|
+
}
|
|
337
|
+
// Shape validated field-by-field above; assemble the typed view.
|
|
338
|
+
return parsed;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Verify a delegated payment token at settlement. Checks the JWS signature, then the token binding:
|
|
342
|
+
* merchant must equal `expectedMerchant`, the amount being settled must not exceed the token's authorized
|
|
343
|
+
* amount, the token must not be expired, and (when asked) the session / currency must match. When a
|
|
344
|
+
* `pcActn` is supplied its digest must equal the token's `pca.digest`; with a `grant` it is re-verified
|
|
345
|
+
* end-to-end. Fails CLOSED on every mismatch.
|
|
346
|
+
*/
|
|
347
|
+
async function verifyDelegatedPaymentToken(token, opts) {
|
|
348
|
+
const alg = opts.alg ?? 'EdDSA';
|
|
349
|
+
const now = Number.isFinite(opts.now) ? opts.now : Date.now();
|
|
350
|
+
// 1. JWS signature.
|
|
351
|
+
let claims;
|
|
352
|
+
try {
|
|
353
|
+
const key = isJwk(opts.verifyKey) ? await (0, jose_1.importJWK)(opts.verifyKey, alg) : opts.verifyKey;
|
|
354
|
+
const { payload } = await (0, jose_1.compactVerify)(token, key, { algorithms: [alg] });
|
|
355
|
+
claims = parseClaims(payload);
|
|
356
|
+
}
|
|
357
|
+
catch (e) {
|
|
358
|
+
return { ok: false, reason: `token signature did not verify: ${e.message}` };
|
|
359
|
+
}
|
|
360
|
+
if (claims === null)
|
|
361
|
+
return { ok: false, reason: 'token payload is not a well-formed delegated payment token' };
|
|
362
|
+
// 2. Binding checks (fail closed).
|
|
363
|
+
if (claims.merchant !== opts.expectedMerchant) {
|
|
364
|
+
return { ok: false, reason: `token merchant "${claims.merchant}" does not match expected "${opts.expectedMerchant}"`, claims };
|
|
365
|
+
}
|
|
366
|
+
if (typeof opts.amount !== 'number' || !Number.isFinite(opts.amount) || opts.amount <= 0) {
|
|
367
|
+
return { ok: false, reason: 'settlement amount must be a finite number > 0', claims };
|
|
368
|
+
}
|
|
369
|
+
if (opts.amount > claims.amount) {
|
|
370
|
+
return { ok: false, reason: `settlement amount ${opts.amount} exceeds the token's authorized amount ${claims.amount}`, claims };
|
|
371
|
+
}
|
|
372
|
+
if (now > claims.exp) {
|
|
373
|
+
return { ok: false, reason: 'the delegated payment token has expired', claims };
|
|
374
|
+
}
|
|
375
|
+
if (opts.expectedSession !== undefined && claims.session !== opts.expectedSession) {
|
|
376
|
+
return { ok: false, reason: `token session "${claims.session}" does not match expected "${opts.expectedSession}"`, claims };
|
|
377
|
+
}
|
|
378
|
+
if (opts.expectedCurrency !== undefined && claims.currency !== opts.expectedCurrency) {
|
|
379
|
+
return { ok: false, reason: `token currency "${claims.currency}" does not match expected "${opts.expectedCurrency}"`, claims };
|
|
380
|
+
}
|
|
381
|
+
// 3. Proof binding (optional): the token's digest must match the supplied PCActn.
|
|
382
|
+
if (opts.pcActn !== undefined) {
|
|
383
|
+
if ((0, pca_1.pcactnDigest)(opts.pcActn) !== claims.pca.digest) {
|
|
384
|
+
return { ok: false, reason: 'pcactn_digest mismatch: the supplied proof is not the one that minted this token', claims };
|
|
385
|
+
}
|
|
386
|
+
if (opts.grant !== undefined) {
|
|
387
|
+
const pcaResult = await (0, pca_1.verifyPCActnCore)(opts.pcActn, {
|
|
388
|
+
grant: opts.grant,
|
|
389
|
+
nowEpoch: now,
|
|
390
|
+
audience: opts.audience,
|
|
391
|
+
});
|
|
392
|
+
if (!pcaResult.allow) {
|
|
393
|
+
return { ok: false, reason: `bound proof failed to verify: ${pcaResult.reason ?? 'denied'}`, claims, pcaResult };
|
|
394
|
+
}
|
|
395
|
+
return { ok: true, claims, pcaResult };
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return { ok: true, claims };
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Build the HTTP 402 `Payment Required` challenge for a protected resource — the server's `accepts`
|
|
402
|
+
* payment requirement plus the `402` status. Structural only; no network. (Field names follow the
|
|
403
|
+
* public x402 shape and should be validated against the x402 spec before production.)
|
|
404
|
+
*/
|
|
405
|
+
function x402Challenge(resource, opts) {
|
|
406
|
+
const requirement = {
|
|
407
|
+
scheme: opts.scheme ?? 'exact',
|
|
408
|
+
network: opts.network ?? 'base-sepolia',
|
|
409
|
+
maxAmountRequired: String(opts.amount),
|
|
410
|
+
resource,
|
|
411
|
+
description: opts.description ?? `Payment required for ${resource}`,
|
|
412
|
+
payTo: opts.payTo ?? '',
|
|
413
|
+
asset: opts.currency ?? '',
|
|
414
|
+
mimeType: opts.mimeType ?? 'application/json',
|
|
415
|
+
};
|
|
416
|
+
return {
|
|
417
|
+
status: 402,
|
|
418
|
+
headers: { 'Content-Type': 'application/json' },
|
|
419
|
+
body: {
|
|
420
|
+
x402Version: 1,
|
|
421
|
+
accepts: [requirement],
|
|
422
|
+
...(opts.error !== undefined ? { error: opts.error } : {}),
|
|
423
|
+
},
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Gate an x402 settlement on a verified, PCActn-bound payment. Runs the injected `verify` over the
|
|
428
|
+
* client's payment payload; on failure it REFUSES with a fresh `402` (fail closed), on success it
|
|
429
|
+
* optionally runs the injected `settle` step and returns the receipt. The verify/settle steps are
|
|
430
|
+
* injectable so this composes with {@link verifyDelegatedPaymentToken} (see {@link acpX402Verifier})
|
|
431
|
+
* without this module performing any network itself.
|
|
432
|
+
*/
|
|
433
|
+
async function x402Settle(payload, opts) {
|
|
434
|
+
if (payload === null || typeof payload !== 'object' || typeof payload.token !== 'string') {
|
|
435
|
+
return { settled: false, status: 402, reason: 'x402 payment payload is missing a token' };
|
|
436
|
+
}
|
|
437
|
+
const v = await opts.verify(payload);
|
|
438
|
+
if (!v.ok) {
|
|
439
|
+
return { settled: false, status: 402, reason: v.reason ?? 'payment verification failed', ...(v.claims ? { claims: v.claims } : {}) };
|
|
440
|
+
}
|
|
441
|
+
if (v.claims === undefined) {
|
|
442
|
+
return { settled: false, status: 402, reason: 'verifier admitted the payment but returned no claims (fail closed)' };
|
|
443
|
+
}
|
|
444
|
+
const receipt = opts.settle ? await opts.settle(payload, v.claims) : undefined;
|
|
445
|
+
return { settled: true, status: 200, claims: v.claims, ...(receipt !== undefined ? { receipt } : {}) };
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Adapt {@link verifyDelegatedPaymentToken} into an {@link X402Verify} for {@link x402Settle}: it reads
|
|
449
|
+
* the delegated payment token (and, by default, the merchant + amount the client claims) from the x402
|
|
450
|
+
* payload and verifies the token's binding + bound proof. This is the glue that makes the
|
|
451
|
+
* 402 → pay-with-proof → settle flow proof-carrying end to end.
|
|
452
|
+
*/
|
|
453
|
+
function acpX402Verifier(opts) {
|
|
454
|
+
return async (payload) => {
|
|
455
|
+
const merchant = opts.expectedMerchant ?? payload.merchant;
|
|
456
|
+
if (typeof merchant !== 'string' || merchant.length === 0) {
|
|
457
|
+
return { ok: false, reason: 'x402 payload has no merchant to check the token against' };
|
|
458
|
+
}
|
|
459
|
+
const amount = opts.amount ?? payload.amount;
|
|
460
|
+
if (typeof amount !== 'number') {
|
|
461
|
+
return { ok: false, reason: 'x402 payload has no amount to check the token against' };
|
|
462
|
+
}
|
|
463
|
+
const res = await verifyDelegatedPaymentToken(payload.token, {
|
|
464
|
+
expectedMerchant: merchant,
|
|
465
|
+
amount,
|
|
466
|
+
verifyKey: opts.verifyKey,
|
|
467
|
+
...(opts.alg !== undefined ? { alg: opts.alg } : {}),
|
|
468
|
+
...(opts.now !== undefined ? { now: opts.now } : {}),
|
|
469
|
+
...(opts.expectedSession !== undefined ? { expectedSession: opts.expectedSession } : {}),
|
|
470
|
+
...(opts.expectedCurrency !== undefined ? { expectedCurrency: opts.expectedCurrency } : {}),
|
|
471
|
+
...(opts.pcActn !== undefined ? { pcActn: opts.pcActn } : {}),
|
|
472
|
+
...(opts.grant !== undefined ? { grant: opts.grant } : {}),
|
|
473
|
+
...(opts.audience !== undefined ? { audience: opts.audience } : {}),
|
|
474
|
+
});
|
|
475
|
+
return { ok: res.ok, ...(res.reason !== undefined ? { reason: res.reason } : {}), ...(res.claims ? { claims: res.claims } : {}) };
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlasauth/pca-acp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Agentic Commerce (ACP) + x402 adapter for PCA: mint an ACP delegated one-time payment token (bound to session+merchant+amount+expiry) AS a PCA proof, and an x402/HTTP-402 facilitator hook that gates settlement on a verified PCActn.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"agentic commerce",
|
|
7
|
+
"x402",
|
|
8
|
+
"payments",
|
|
9
|
+
"http 402",
|
|
10
|
+
"agent authorization",
|
|
11
|
+
"proof-carrying authority",
|
|
12
|
+
"pca",
|
|
13
|
+
"ai agents"
|
|
14
|
+
],
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"homepage": "https://github.com/Atlas-Authorization/pca#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/Atlas-Authorization/pca/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/Atlas-Authorization/pca.git",
|
|
23
|
+
"directory": "packages/pca-acp"
|
|
24
|
+
},
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./package.json": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"jose": "^5.9.6",
|
|
36
|
+
"@atlasauth/pca": "0.2.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"typescript": "^5.6.3",
|
|
40
|
+
"vitest": "^2.1.4"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist",
|
|
44
|
+
"README.md",
|
|
45
|
+
"LICENSE"
|
|
46
|
+
],
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=20"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsc -p tsconfig.build.json",
|
|
55
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
56
|
+
"test": "vitest run"
|
|
57
|
+
}
|
|
6
58
|
}
|