@peac/adapter-x402 0.12.0 → 0.12.1
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 +46 -19
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -0
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +14 -23
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -22
- package/dist/index.js.map +1 -1
- package/dist/map.d.ts +29 -23
- package/dist/map.d.ts.map +1 -1
- package/dist/map.js +57 -36
- package/dist/map.js.map +1 -1
- package/dist/normalize.d.ts +97 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +75 -0
- package/dist/normalize.js.map +1 -0
- package/dist/raw.d.ts +246 -0
- package/dist/raw.d.ts.map +1 -0
- package/dist/raw.js +246 -0
- package/dist/raw.js.map +1 -0
- package/dist/types.d.ts +292 -144
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +18 -16
- package/dist/types.js.map +1 -1
- package/dist/verify.d.ts +50 -41
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +380 -344
- package/dist/verify.js.map +1 -1
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
# @peac/adapter-x402
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Verification, term-matching, and evidence mapping for the x402
|
|
4
|
+
Offer/Receipt extension (compatible with upstream coinbase/x402).
|
|
4
5
|
|
|
5
6
|
## Overview
|
|
6
7
|
|
|
7
|
-
This package verifies x402 extension
|
|
8
|
+
This package verifies x402 extension artifacts (offers and receipts) and maps
|
|
8
9
|
them into canonical PEAC interaction records. It implements term-matching
|
|
9
10
|
verification where `acceptIndex` is treated as an untrusted hint and the
|
|
10
11
|
binding comes from matching signed payload fields against accept terms.
|
|
11
12
|
|
|
13
|
+
Compatible with upstream x402 Offer/Receipt extension wire shapes. Defaults
|
|
14
|
+
match upstream behavior; stricter verification is available via opt-in
|
|
15
|
+
configuration.
|
|
16
|
+
|
|
12
17
|
## Install
|
|
13
18
|
|
|
14
19
|
```bash
|
|
@@ -22,7 +27,7 @@ pnpm add @peac/adapter-x402
|
|
|
22
27
|
```typescript
|
|
23
28
|
import { verifyOffer } from '@peac/adapter-x402';
|
|
24
29
|
|
|
25
|
-
const result = verifyOffer(signedOffer, acceptEntries
|
|
30
|
+
const result = verifyOffer(signedOffer, acceptEntries);
|
|
26
31
|
|
|
27
32
|
if (result.valid) {
|
|
28
33
|
console.log('Matched accept entry:', result.matchedAccept);
|
|
@@ -37,8 +42,8 @@ if (result.valid) {
|
|
|
37
42
|
```typescript
|
|
38
43
|
import { selectAccept } from '@peac/adapter-x402';
|
|
39
44
|
|
|
40
|
-
// With hint (bounds-check + term-match)
|
|
41
|
-
const match = selectAccept(offerPayload, accepts, acceptIndex);
|
|
45
|
+
// With hint (bounds-check + term-match via offer.acceptIndex)
|
|
46
|
+
const match = selectAccept(offerPayload, accepts, offer.acceptIndex);
|
|
42
47
|
|
|
43
48
|
// Without hint (scan for unique match)
|
|
44
49
|
const match = selectAccept(offerPayload, accepts);
|
|
@@ -49,16 +54,32 @@ const match = selectAccept(offerPayload, accepts);
|
|
|
49
54
|
```typescript
|
|
50
55
|
import { toPeacRecord } from '@peac/adapter-x402';
|
|
51
56
|
|
|
52
|
-
const record = toPeacRecord(
|
|
53
|
-
// record.proofs.x402.offer
|
|
54
|
-
// record.proofs.x402.receipt
|
|
55
|
-
// record.evidence.
|
|
56
|
-
// record.
|
|
57
|
+
const record = toPeacRecord(challenge, settlementResponse);
|
|
58
|
+
// record.proofs.x402.offer -- raw offer preserved for audit
|
|
59
|
+
// record.proofs.x402.receipt -- raw receipt preserved for audit
|
|
60
|
+
// record.evidence.resourceUrl -- from signed offer payload
|
|
61
|
+
// record.evidence.payer -- from signed receipt payload
|
|
62
|
+
// record.evidence.transaction -- optional, from receipt (privacy-minimal)
|
|
63
|
+
// record.hints.acceptIndex -- { value: 0, untrusted: true }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Extract from upstream wire format
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { extractExtensionInfo, extractReceiptFromHeaders } from '@peac/adapter-x402';
|
|
70
|
+
|
|
71
|
+
// Extract offers from upstream 402 response body
|
|
72
|
+
const info = extractExtensionInfo(responseBody);
|
|
73
|
+
// info.offers: RawSignedOffer[]
|
|
74
|
+
// info.receipt?: RawSignedReceipt
|
|
75
|
+
|
|
76
|
+
// Extract receipt from settlement response headers
|
|
77
|
+
const receipt = extractReceiptFromHeaders(responseHeaders);
|
|
57
78
|
```
|
|
58
79
|
|
|
59
80
|
## acceptIndex: hint-only semantics
|
|
60
81
|
|
|
61
|
-
In the x402 Offer/Receipt extension, `acceptIndex` is an unsigned
|
|
82
|
+
In the x402 Offer/Receipt extension, `acceptIndex` is an unsigned per-offer
|
|
62
83
|
field outside the signed payload. Verifiers MUST NOT rely on it as a binding
|
|
63
84
|
mechanism.
|
|
64
85
|
|
|
@@ -73,25 +94,31 @@ This package treats `acceptIndex` as advisory:
|
|
|
73
94
|
|
|
74
95
|
## API
|
|
75
96
|
|
|
76
|
-
### `verifyOffer(offer, accepts,
|
|
97
|
+
### `verifyOffer(offer, accepts, config?)`
|
|
77
98
|
|
|
78
99
|
Verify a signed offer against accept terms. Checks structure, expiry,
|
|
79
100
|
version, signature format, and term-matching.
|
|
80
101
|
|
|
81
102
|
### `verifyReceipt(receipt, config?)`
|
|
82
103
|
|
|
83
|
-
Verify a signed receipt's
|
|
104
|
+
Verify a signed receipt's required fields, version, payer format, and
|
|
105
|
+
issuedAt recency.
|
|
106
|
+
|
|
107
|
+
### `verifyOfferReceiptConsistency(offerPayload, receiptPayload, config?, options?)`
|
|
108
|
+
|
|
109
|
+
Verify consistency between an offer and a receipt (resourceUrl, network,
|
|
110
|
+
issuedAt freshness, optional payer candidate matching).
|
|
84
111
|
|
|
85
|
-
### `matchAcceptTerms(payload, accept)`
|
|
112
|
+
### `matchAcceptTerms(payload, accept, addressComparator?)`
|
|
86
113
|
|
|
87
114
|
Compare offer payload fields against a single accept entry. Returns an
|
|
88
115
|
array of mismatched field names (empty means match).
|
|
89
116
|
|
|
90
|
-
### `selectAccept(payload, accepts, acceptIndex?)`
|
|
117
|
+
### `selectAccept(payload, accepts, acceptIndex?, addressComparator?)`
|
|
91
118
|
|
|
92
119
|
Select the matching accept entry. Throws `X402Error` on failure.
|
|
93
120
|
|
|
94
|
-
### `toPeacRecord(
|
|
121
|
+
### `toPeacRecord(challenge, settlementResponse, options?)`
|
|
95
122
|
|
|
96
123
|
Map an x402 payment flow to a PEAC interaction record.
|
|
97
124
|
|
|
@@ -107,12 +134,12 @@ This adapter supports x402 **Offer/Receipt extension version 1** (default).
|
|
|
107
134
|
The version is configurable per call:
|
|
108
135
|
|
|
109
136
|
```typescript
|
|
110
|
-
const result = verifyOffer(offer, accepts,
|
|
111
|
-
supportedVersions: [
|
|
137
|
+
const result = verifyOffer(offer, accepts, {
|
|
138
|
+
supportedVersions: [1, 2],
|
|
112
139
|
});
|
|
113
140
|
```
|
|
114
141
|
|
|
115
|
-
The adapter defines its own x402 types (no external x402 npm dependencies).
|
|
142
|
+
The adapter defines its own x402 types (no external x402 npm dependencies).
|
|
116
143
|
|
|
117
144
|
## Error handling
|
|
118
145
|
|
package/dist/errors.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* - amount_*: Amount validation errors
|
|
16
16
|
* - network_*: Network validation errors
|
|
17
17
|
*/
|
|
18
|
-
export type X402ErrorCode = 'offer_invalid_format' | 'offer_expired' | 'offer_version_unsupported' | 'offer_signature_invalid' | 'receipt_invalid_format' | 'receipt_signature_invalid' | 'receipt_version_unsupported' | 'accept_index_out_of_range' | 'accept_no_match' | 'accept_ambiguous' | 'accept_term_mismatch' | 'accept_too_many_entries' | 'payload_missing_field' | 'payload_tampered' | 'amount_invalid' | 'network_invalid';
|
|
18
|
+
export type X402ErrorCode = 'offer_invalid_format' | 'offer_expired' | 'offer_version_unsupported' | 'offer_signature_invalid' | 'offer_no_expiry' | 'receipt_invalid_format' | 'receipt_signature_invalid' | 'receipt_version_unsupported' | 'receipt_resource_mismatch' | 'receipt_network_mismatch' | 'receipt_issuedAt_stale' | 'receipt_payer_invalid' | 'receipt_payer_not_in_candidates' | 'accept_index_out_of_range' | 'accept_no_match' | 'accept_ambiguous' | 'accept_term_mismatch' | 'accept_too_many_entries' | 'payload_missing_field' | 'payload_tampered' | 'amount_invalid' | 'network_invalid' | 'jws_too_large' | 'jws_malformed' | 'jws_padded_base64url' | 'jws_payload_not_object';
|
|
19
19
|
/**
|
|
20
20
|
* Custom error class for x402 adapter operations
|
|
21
21
|
*
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,eAAe,GACf,2BAA2B,GAC3B,yBAAyB,GACzB,wBAAwB,GACxB,2BAA2B,GAC3B,6BAA6B,GAC7B,2BAA2B,GAC3B,iBAAiB,GACjB,kBAAkB,GAClB,sBAAsB,GACtB,yBAAyB,GACzB,uBAAuB,GACvB,kBAAkB,GAClB,gBAAgB,GAChB,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,eAAe,GACf,2BAA2B,GAC3B,yBAAyB,GACzB,iBAAiB,GACjB,wBAAwB,GACxB,2BAA2B,GAC3B,6BAA6B,GAC7B,2BAA2B,GAC3B,0BAA0B,GAC1B,wBAAwB,GACxB,uBAAuB,GACvB,iCAAiC,GACjC,2BAA2B,GAC3B,iBAAiB,GACjB,kBAAkB,GAClB,sBAAsB,GACtB,yBAAyB,GACzB,uBAAuB,GACvB,kBAAkB,GAClB,gBAAgB,GAChB,iBAAiB,GACjB,eAAe,GACf,eAAe,GACf,sBAAsB,GACtB,wBAAwB,CAAC;AAkC7B;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAGzC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;IAUjE,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAUlC"}
|
package/dist/errors.js
CHANGED
|
@@ -15,9 +15,15 @@ const ERROR_HTTP_STATUS = {
|
|
|
15
15
|
offer_expired: 400,
|
|
16
16
|
offer_version_unsupported: 400,
|
|
17
17
|
offer_signature_invalid: 401,
|
|
18
|
+
offer_no_expiry: 400,
|
|
18
19
|
receipt_invalid_format: 400,
|
|
19
20
|
receipt_signature_invalid: 401,
|
|
20
21
|
receipt_version_unsupported: 400,
|
|
22
|
+
receipt_resource_mismatch: 400,
|
|
23
|
+
receipt_network_mismatch: 400,
|
|
24
|
+
receipt_issuedAt_stale: 400,
|
|
25
|
+
receipt_payer_invalid: 400,
|
|
26
|
+
receipt_payer_not_in_candidates: 400,
|
|
21
27
|
accept_index_out_of_range: 400,
|
|
22
28
|
accept_no_match: 400,
|
|
23
29
|
accept_ambiguous: 400,
|
|
@@ -27,6 +33,10 @@ const ERROR_HTTP_STATUS = {
|
|
|
27
33
|
payload_tampered: 401,
|
|
28
34
|
amount_invalid: 400,
|
|
29
35
|
network_invalid: 400,
|
|
36
|
+
jws_too_large: 400,
|
|
37
|
+
jws_malformed: 400,
|
|
38
|
+
jws_padded_base64url: 400,
|
|
39
|
+
jws_payload_not_object: 400,
|
|
30
40
|
};
|
|
31
41
|
/**
|
|
32
42
|
* Custom error class for x402 adapter operations
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAyCH;;GAEG;AACH,MAAM,iBAAiB,GAAkC;IACvD,oBAAoB,EAAE,GAAG;IACzB,aAAa,EAAE,GAAG;IAClB,yBAAyB,EAAE,GAAG;IAC9B,uBAAuB,EAAE,GAAG;IAC5B,eAAe,EAAE,GAAG;IACpB,sBAAsB,EAAE,GAAG;IAC3B,yBAAyB,EAAE,GAAG;IAC9B,2BAA2B,EAAE,GAAG;IAChC,yBAAyB,EAAE,GAAG;IAC9B,wBAAwB,EAAE,GAAG;IAC7B,sBAAsB,EAAE,GAAG;IAC3B,qBAAqB,EAAE,GAAG;IAC1B,+BAA+B,EAAE,GAAG;IACpC,yBAAyB,EAAE,GAAG;IAC9B,eAAe,EAAE,GAAG;IACpB,gBAAgB,EAAE,GAAG;IACrB,oBAAoB,EAAE,GAAG;IACzB,uBAAuB,EAAE,GAAG;IAC5B,qBAAqB,EAAE,GAAG;IAC1B,gBAAgB,EAAE,GAAG;IACrB,cAAc,EAAE,GAAG;IACnB,eAAe,EAAE,GAAG;IACpB,aAAa,EAAE,GAAG;IAClB,aAAa,EAAE,GAAG;IAClB,oBAAoB,EAAE,GAAG;IACzB,sBAAsB,EAAE,GAAG;CAC5B,CAAC;AAEF;;;;;GAKG;AACH,MAAa,SAAU,SAAQ,KAAK;IACzB,IAAI,CAAgB;IACpB,UAAU,CAAS;IACnB,KAAK,CAAU;IACf,OAAO,CAA2B;IAE3C,YACE,IAAmB,EACnB,OAAe,EACf,OAA+D;QAE/D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAC;IAClC,CAAC;IAED,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YACtD,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;SAC7D,CAAC;IACJ,CAAC;CACF;AA7BD,8BA6BC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,36 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @peac/adapter-x402
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* Verification, term-matching, and evidence mapping for the
|
|
5
|
+
* x402 Offer/Receipt extension (compatible with upstream coinbase/x402).
|
|
5
6
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - Structural validation of x402 offers and receipts
|
|
12
|
-
* - Term-matching: verify signed payload against accept entries
|
|
13
|
-
* - Accept selection with acceptIndex as untrusted hint
|
|
14
|
-
* - Mapping to canonical PEAC interaction records
|
|
15
|
-
* - DoS protection: limits on accepts array size
|
|
16
|
-
* - Amount/network validation: CAIP-2 format, integer strings
|
|
17
|
-
*
|
|
18
|
-
* IMPORTANT: This package does NOT perform cryptographic signature verification
|
|
19
|
-
* (EIP-712 recovery, JWS validation). That is the caller's responsibility.
|
|
20
|
-
* `valid: true` does NOT imply cryptographic signature validity unless
|
|
21
|
-
* a CryptoVerifier is supplied and `verification.cryptographic.verified` is true.
|
|
22
|
-
*
|
|
23
|
-
* The focus is on term-matching and record mapping -- the verification
|
|
24
|
-
* layer that makes unsigned acceptIndex irrelevant for security.
|
|
7
|
+
* Architecture:
|
|
8
|
+
* - Layer A (raw.ts): Exact upstream wire types and extraction
|
|
9
|
+
* - Layer B (normalize.ts): Semantic normalization (EIP-712 placeholders)
|
|
10
|
+
* - Layer C (map.ts): PEAC evidence mapping
|
|
11
|
+
* - Verification (verify.ts): Layered verification API
|
|
25
12
|
*
|
|
26
13
|
* @packageDocumentation
|
|
27
14
|
*/
|
|
28
|
-
export type {
|
|
29
|
-
export {
|
|
15
|
+
export type { RawOfferPayload, RawReceiptPayload, RawJWSSignedOffer, RawEIP712SignedOffer, RawSignedOffer, RawJWSSignedReceipt, RawEIP712SignedReceipt, RawSignedReceipt, RawX402ExtensionInfo, ParsedCompactJWS, } from './raw.js';
|
|
16
|
+
export { OFFER_RECEIPT, MAX_COMPACT_JWS_BYTES, X402_RECEIPT_HEADERS, parseCompactJWS, extractOfferPayload, extractReceiptPayload, extractExtensionInfo, extractReceiptFromHeaders, } from './raw.js';
|
|
17
|
+
export type { NormalizedOfferPayload, NormalizedReceiptPayload } from './normalize.js';
|
|
18
|
+
export { normalizeOfferPayload, normalizeReceiptPayload } from './normalize.js';
|
|
19
|
+
export type { SignatureFormat, OfferPayload, SignedOffer, ReceiptPayload, SignedReceipt, AcceptEntry, X402OfferReceiptChallenge, X402SettlementResponse, WireVerification, OfferVerification, ReceiptVerification, ConsistencyVerification, ConsistencyOptions, VerificationError, VerificationStatus, X402PeacRecord, X402AdapterConfig, MismatchPolicy, AddressComparator, CryptoResult, CryptoVerifier, EIP712Domain, SignerAuthorizer, AuthorizationContext, AuthorizationResult, } from './types.js';
|
|
20
|
+
export { X402_OFFER_RECEIPT_PROFILE, MAX_ACCEPT_ENTRIES, MAX_TOTAL_ACCEPTS_BYTES, MAX_AMOUNT_LENGTH, defaultAddressComparator, } from './types.js';
|
|
30
21
|
export type { Result, AdapterError, AdapterErrorCode, JsonObject } from './types.js';
|
|
31
22
|
export { X402Error } from './errors.js';
|
|
32
23
|
export type { X402ErrorCode } from './errors.js';
|
|
33
|
-
export { verifyOffer, verifyReceipt, matchAcceptTerms, selectAccept } from './verify.js';
|
|
24
|
+
export { verifyOffer, verifyReceipt, verifyOfferWire, verifyReceiptWire, verifyOfferReceiptConsistency, matchAcceptTerms, selectAccept, } from './verify.js';
|
|
34
25
|
export { toPeacRecord, toPeacCarrier } from './map.js';
|
|
35
26
|
export type { X402HeaderMap, X402ResponseLike, X402ExtractResult, X402ExtractAsyncResult, } from './carrier.js';
|
|
36
27
|
export { X402_CARRIER_LIMITS, fromOfferResponse, fromOfferResponseAsync, fromSettlementResponse, fromSettlementResponseAsync, X402CarrierAdapter, } from './carrier.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,mBAAmB,EACnB,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAElB,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,EACf,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,UAAU,CAAC;AAGlB,YAAY,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAEvF,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAGhF,YAAY,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,WAAW,EACX,yBAAyB,EACzB,sBAAsB,EACtB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGrF,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,6BAA6B,EAC7B,gBAAgB,EAChB,YAAY,GACb,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGvD,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,38 +2,38 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @peac/adapter-x402
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Verification, term-matching, and evidence mapping for the
|
|
6
|
+
* x402 Offer/Receipt extension (compatible with upstream coinbase/x402).
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* - Structural validation of x402 offers and receipts
|
|
13
|
-
* - Term-matching: verify signed payload against accept entries
|
|
14
|
-
* - Accept selection with acceptIndex as untrusted hint
|
|
15
|
-
* - Mapping to canonical PEAC interaction records
|
|
16
|
-
* - DoS protection: limits on accepts array size
|
|
17
|
-
* - Amount/network validation: CAIP-2 format, integer strings
|
|
18
|
-
*
|
|
19
|
-
* IMPORTANT: This package does NOT perform cryptographic signature verification
|
|
20
|
-
* (EIP-712 recovery, JWS validation). That is the caller's responsibility.
|
|
21
|
-
* `valid: true` does NOT imply cryptographic signature validity unless
|
|
22
|
-
* a CryptoVerifier is supplied and `verification.cryptographic.verified` is true.
|
|
23
|
-
*
|
|
24
|
-
* The focus is on term-matching and record mapping -- the verification
|
|
25
|
-
* layer that makes unsigned acceptIndex irrelevant for security.
|
|
8
|
+
* Architecture:
|
|
9
|
+
* - Layer A (raw.ts): Exact upstream wire types and extraction
|
|
10
|
+
* - Layer B (normalize.ts): Semantic normalization (EIP-712 placeholders)
|
|
11
|
+
* - Layer C (map.ts): PEAC evidence mapping
|
|
12
|
+
* - Verification (verify.ts): Layered verification API
|
|
26
13
|
*
|
|
27
14
|
* @packageDocumentation
|
|
28
15
|
*/
|
|
29
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.mapX402ToChallengeType = exports.X402CarrierAdapter = exports.fromSettlementResponseAsync = exports.fromSettlementResponse = exports.fromOfferResponseAsync = exports.fromOfferResponse = exports.X402_CARRIER_LIMITS = exports.toPeacCarrier = exports.toPeacRecord = exports.selectAccept = exports.matchAcceptTerms = exports.verifyReceipt = exports.verifyOffer = exports.X402Error = exports.MAX_AMOUNT_LENGTH = exports.MAX_TOTAL_ACCEPTS_BYTES = exports.MAX_ACCEPT_ENTRIES = exports.X402_OFFER_RECEIPT_PROFILE = void 0;
|
|
31
|
-
|
|
17
|
+
exports.mapX402ToChallengeType = exports.X402CarrierAdapter = exports.fromSettlementResponseAsync = exports.fromSettlementResponse = exports.fromOfferResponseAsync = exports.fromOfferResponse = exports.X402_CARRIER_LIMITS = exports.toPeacCarrier = exports.toPeacRecord = exports.selectAccept = exports.matchAcceptTerms = exports.verifyOfferReceiptConsistency = exports.verifyReceiptWire = exports.verifyOfferWire = exports.verifyReceipt = exports.verifyOffer = exports.X402Error = exports.defaultAddressComparator = exports.MAX_AMOUNT_LENGTH = exports.MAX_TOTAL_ACCEPTS_BYTES = exports.MAX_ACCEPT_ENTRIES = exports.X402_OFFER_RECEIPT_PROFILE = exports.normalizeReceiptPayload = exports.normalizeOfferPayload = exports.extractReceiptFromHeaders = exports.extractExtensionInfo = exports.extractReceiptPayload = exports.extractOfferPayload = exports.parseCompactJWS = exports.X402_RECEIPT_HEADERS = exports.MAX_COMPACT_JWS_BYTES = exports.OFFER_RECEIPT = void 0;
|
|
18
|
+
var raw_js_1 = require("./raw.js");
|
|
19
|
+
Object.defineProperty(exports, "OFFER_RECEIPT", { enumerable: true, get: function () { return raw_js_1.OFFER_RECEIPT; } });
|
|
20
|
+
Object.defineProperty(exports, "MAX_COMPACT_JWS_BYTES", { enumerable: true, get: function () { return raw_js_1.MAX_COMPACT_JWS_BYTES; } });
|
|
21
|
+
Object.defineProperty(exports, "X402_RECEIPT_HEADERS", { enumerable: true, get: function () { return raw_js_1.X402_RECEIPT_HEADERS; } });
|
|
22
|
+
Object.defineProperty(exports, "parseCompactJWS", { enumerable: true, get: function () { return raw_js_1.parseCompactJWS; } });
|
|
23
|
+
Object.defineProperty(exports, "extractOfferPayload", { enumerable: true, get: function () { return raw_js_1.extractOfferPayload; } });
|
|
24
|
+
Object.defineProperty(exports, "extractReceiptPayload", { enumerable: true, get: function () { return raw_js_1.extractReceiptPayload; } });
|
|
25
|
+
Object.defineProperty(exports, "extractExtensionInfo", { enumerable: true, get: function () { return raw_js_1.extractExtensionInfo; } });
|
|
26
|
+
Object.defineProperty(exports, "extractReceiptFromHeaders", { enumerable: true, get: function () { return raw_js_1.extractReceiptFromHeaders; } });
|
|
27
|
+
var normalize_js_1 = require("./normalize.js");
|
|
28
|
+
Object.defineProperty(exports, "normalizeOfferPayload", { enumerable: true, get: function () { return normalize_js_1.normalizeOfferPayload; } });
|
|
29
|
+
Object.defineProperty(exports, "normalizeReceiptPayload", { enumerable: true, get: function () { return normalize_js_1.normalizeReceiptPayload; } });
|
|
30
|
+
// Constants and functions from types
|
|
32
31
|
var types_js_1 = require("./types.js");
|
|
33
32
|
Object.defineProperty(exports, "X402_OFFER_RECEIPT_PROFILE", { enumerable: true, get: function () { return types_js_1.X402_OFFER_RECEIPT_PROFILE; } });
|
|
34
33
|
Object.defineProperty(exports, "MAX_ACCEPT_ENTRIES", { enumerable: true, get: function () { return types_js_1.MAX_ACCEPT_ENTRIES; } });
|
|
35
34
|
Object.defineProperty(exports, "MAX_TOTAL_ACCEPTS_BYTES", { enumerable: true, get: function () { return types_js_1.MAX_TOTAL_ACCEPTS_BYTES; } });
|
|
36
35
|
Object.defineProperty(exports, "MAX_AMOUNT_LENGTH", { enumerable: true, get: function () { return types_js_1.MAX_AMOUNT_LENGTH; } });
|
|
36
|
+
Object.defineProperty(exports, "defaultAddressComparator", { enumerable: true, get: function () { return types_js_1.defaultAddressComparator; } });
|
|
37
37
|
// Errors
|
|
38
38
|
var errors_js_1 = require("./errors.js");
|
|
39
39
|
Object.defineProperty(exports, "X402Error", { enumerable: true, get: function () { return errors_js_1.X402Error; } });
|
|
@@ -41,6 +41,9 @@ Object.defineProperty(exports, "X402Error", { enumerable: true, get: function ()
|
|
|
41
41
|
var verify_js_1 = require("./verify.js");
|
|
42
42
|
Object.defineProperty(exports, "verifyOffer", { enumerable: true, get: function () { return verify_js_1.verifyOffer; } });
|
|
43
43
|
Object.defineProperty(exports, "verifyReceipt", { enumerable: true, get: function () { return verify_js_1.verifyReceipt; } });
|
|
44
|
+
Object.defineProperty(exports, "verifyOfferWire", { enumerable: true, get: function () { return verify_js_1.verifyOfferWire; } });
|
|
45
|
+
Object.defineProperty(exports, "verifyReceiptWire", { enumerable: true, get: function () { return verify_js_1.verifyReceiptWire; } });
|
|
46
|
+
Object.defineProperty(exports, "verifyOfferReceiptConsistency", { enumerable: true, get: function () { return verify_js_1.verifyOfferReceiptConsistency; } });
|
|
44
47
|
Object.defineProperty(exports, "matchAcceptTerms", { enumerable: true, get: function () { return verify_js_1.matchAcceptTerms; } });
|
|
45
48
|
Object.defineProperty(exports, "selectAccept", { enumerable: true, get: function () { return verify_js_1.selectAccept; } });
|
|
46
49
|
// Mapping
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;GAaG;;;AAgBH,mCASkB;AARhB,uGAAA,aAAa,OAAA;AACb,+GAAA,qBAAqB,OAAA;AACrB,8GAAA,oBAAoB,OAAA;AACpB,yGAAA,eAAe,OAAA;AACf,6GAAA,mBAAmB,OAAA;AACnB,+GAAA,qBAAqB,OAAA;AACrB,8GAAA,oBAAoB,OAAA;AACpB,mHAAA,yBAAyB,OAAA;AAM3B,+CAAgF;AAAvE,qHAAA,qBAAqB,OAAA;AAAE,uHAAA,uBAAuB,OAAA;AA+BvD,qCAAqC;AACrC,uCAMoB;AALlB,sHAAA,0BAA0B,OAAA;AAC1B,8GAAA,kBAAkB,OAAA;AAClB,mHAAA,uBAAuB,OAAA;AACvB,6GAAA,iBAAiB,OAAA;AACjB,oHAAA,wBAAwB,OAAA;AAM1B,SAAS;AACT,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAGlB,eAAe;AACf,yCAQqB;AAPnB,wGAAA,WAAW,OAAA;AACX,0GAAA,aAAa,OAAA;AACb,4GAAA,eAAe,OAAA;AACf,8GAAA,iBAAiB,OAAA;AACjB,0HAAA,6BAA6B,OAAA;AAC7B,6GAAA,gBAAgB,OAAA;AAChB,yGAAA,YAAY,OAAA;AAGd,UAAU;AACV,mCAAuD;AAA9C,sGAAA,YAAY,OAAA;AAAE,uGAAA,aAAa,OAAA;AAUpC,2CAOsB;AANpB,iHAAA,mBAAmB,OAAA;AACnB,+GAAA,iBAAiB,OAAA;AACjB,oHAAA,sBAAsB,OAAA;AACtB,oHAAA,sBAAsB,OAAA;AACtB,yHAAA,2BAA2B,OAAA;AAC3B,gHAAA,kBAAkB,OAAA;AAKpB,+CAAwD;AAA/C,sHAAA,sBAAsB,OAAA"}
|
package/dist/map.d.ts
CHANGED
|
@@ -1,41 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* x402 to PEAC record mapping
|
|
2
|
+
* x402 to PEAC record mapping (Layer C)
|
|
3
3
|
*
|
|
4
|
-
* Maps x402
|
|
4
|
+
* Maps x402 offer/receipt extension data into a canonical
|
|
5
5
|
* PEAC interaction record (X402PeacRecord).
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* The record preserves:
|
|
11
|
-
* - Raw proofs (offer + receipt) for audit/dispute
|
|
12
|
-
* - Normalized evidence fields from signed payloads
|
|
13
|
-
* - Unsigned hints (acceptIndex) explicitly marked as untrusted
|
|
14
|
-
* - Verification status metadata (structural, cryptographic, termMatching)
|
|
7
|
+
* Uses normalized payloads (Layer B output) for evidence fields.
|
|
8
|
+
* Raw upstream artifacts are preserved as-is in proofs.
|
|
15
9
|
*/
|
|
16
10
|
import type { PeacEvidenceCarrier } from '@peac/kernel';
|
|
17
|
-
import type {
|
|
11
|
+
import type { X402OfferReceiptChallenge, X402SettlementResponse, X402PeacRecord, OfferVerification, ConsistencyVerification, CryptoResult, AuthorizationResult } from './types.js';
|
|
18
12
|
/**
|
|
19
13
|
* Options for record mapping
|
|
20
14
|
*/
|
|
21
15
|
export interface ToPeacRecordOptions {
|
|
22
16
|
/**
|
|
23
17
|
* Offer verification result (to populate verification hints)
|
|
24
|
-
*
|
|
25
|
-
* The termMatching field in OfferVerification is used to derive
|
|
26
|
-
* hints.acceptIndex.mismatchDetected automatically. This makes
|
|
27
|
-
* mismatch detection first-class without requiring external options.
|
|
28
18
|
*/
|
|
29
19
|
offerVerification?: OfferVerification;
|
|
20
|
+
/**
|
|
21
|
+
* Consistency verification result
|
|
22
|
+
*/
|
|
23
|
+
consistencyVerification?: ConsistencyVerification;
|
|
30
24
|
/**
|
|
31
25
|
* Whether cryptographic signature verification was performed
|
|
32
26
|
* Default: false (adapter does NOT perform crypto verification)
|
|
33
27
|
*/
|
|
34
28
|
cryptoVerified?: boolean;
|
|
35
29
|
/**
|
|
36
|
-
*
|
|
30
|
+
* Crypto verification result (if crypto verification was performed)
|
|
31
|
+
*/
|
|
32
|
+
cryptoResult?: CryptoResult;
|
|
33
|
+
/**
|
|
34
|
+
* Signer authorization result (if authorization was performed)
|
|
35
|
+
*/
|
|
36
|
+
authorizationResult?: AuthorizationResult;
|
|
37
|
+
/**
|
|
38
|
+
* Index of the offer within the offers array to use for mapping
|
|
39
|
+
* Default: 0 (first offer)
|
|
40
|
+
*/
|
|
41
|
+
offerIndex?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Maximum compact JWS byte length for payload extraction
|
|
37
44
|
*/
|
|
38
|
-
|
|
45
|
+
maxCompactJwsBytes?: number;
|
|
39
46
|
}
|
|
40
47
|
/**
|
|
41
48
|
* Map x402 payment flow to a PEAC interaction record
|
|
@@ -43,21 +50,20 @@ export interface ToPeacRecordOptions {
|
|
|
43
50
|
* Takes a PaymentRequired (offer side) and SettlementResponse (receipt side)
|
|
44
51
|
* and produces a canonical PEAC record with normalized evidence.
|
|
45
52
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
* See `hints.verification.cryptographic` in the output.
|
|
53
|
+
* Uses Layer B (normalized) payloads for evidence; stores exact raw
|
|
54
|
+
* artifacts in proofs (proof preservation discipline).
|
|
49
55
|
*
|
|
50
|
-
* @param paymentRequired - The 402 response with
|
|
56
|
+
* @param paymentRequired - The 402 response with offers and accepts
|
|
51
57
|
* @param settlementResponse - The settlement response with receipt
|
|
52
58
|
* @param options - Optional mapping options
|
|
53
59
|
* @returns Canonical PEAC interaction record
|
|
54
60
|
* @throws X402Error if inputs are structurally invalid
|
|
55
61
|
*/
|
|
56
|
-
export declare function toPeacRecord(paymentRequired:
|
|
62
|
+
export declare function toPeacRecord(paymentRequired: X402OfferReceiptChallenge, settlementResponse: X402SettlementResponse, options?: ToPeacRecordOptions): X402PeacRecord;
|
|
57
63
|
/**
|
|
58
64
|
* Convert an x402 PEAC record to a PeacEvidenceCarrier.
|
|
59
65
|
*
|
|
60
|
-
* Uses the shared `computeReceiptRef()` from `@peac/schema`
|
|
66
|
+
* Uses the shared `computeReceiptRef()` from `@peac/schema`
|
|
61
67
|
* to produce a canonical, content-addressed receipt_ref from the JWS.
|
|
62
68
|
*
|
|
63
69
|
* @param receiptJws - Compact JWS of the PEAC receipt
|
package/dist/map.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAOxD,OAAO,KAAK,EACV,yBAAyB,EACzB,sBAAsB,EACtB,cAAc,EAEd,iBAAiB,EACjB,uBAAuB,EACvB,YAAY,EACZ,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;OAEG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;IAClD;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B;;OAEG;IACH,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,eAAe,EAAE,yBAAyB,EAC1C,kBAAkB,EAAE,sBAAsB,EAC1C,OAAO,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CA2HhB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAMpF"}
|
package/dist/map.js
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* x402 to PEAC record mapping
|
|
3
|
+
* x402 to PEAC record mapping (Layer C)
|
|
4
4
|
*
|
|
5
|
-
* Maps x402
|
|
5
|
+
* Maps x402 offer/receipt extension data into a canonical
|
|
6
6
|
* PEAC interaction record (X402PeacRecord).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* The record preserves:
|
|
12
|
-
* - Raw proofs (offer + receipt) for audit/dispute
|
|
13
|
-
* - Normalized evidence fields from signed payloads
|
|
14
|
-
* - Unsigned hints (acceptIndex) explicitly marked as untrusted
|
|
15
|
-
* - Verification status metadata (structural, cryptographic, termMatching)
|
|
8
|
+
* Uses normalized payloads (Layer B output) for evidence fields.
|
|
9
|
+
* Raw upstream artifacts are preserved as-is in proofs.
|
|
16
10
|
*/
|
|
17
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
12
|
exports.toPeacRecord = toPeacRecord;
|
|
19
13
|
exports.toPeacCarrier = toPeacCarrier;
|
|
20
14
|
const schema_1 = require("@peac/schema");
|
|
21
15
|
const errors_js_1 = require("./errors.js");
|
|
16
|
+
const raw_js_1 = require("./raw.js");
|
|
17
|
+
const normalize_js_1 = require("./normalize.js");
|
|
22
18
|
const types_js_1 = require("./types.js");
|
|
23
19
|
/**
|
|
24
20
|
* Map x402 payment flow to a PEAC interaction record
|
|
@@ -26,35 +22,46 @@ const types_js_1 = require("./types.js");
|
|
|
26
22
|
* Takes a PaymentRequired (offer side) and SettlementResponse (receipt side)
|
|
27
23
|
* and produces a canonical PEAC record with normalized evidence.
|
|
28
24
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* See `hints.verification.cryptographic` in the output.
|
|
25
|
+
* Uses Layer B (normalized) payloads for evidence; stores exact raw
|
|
26
|
+
* artifacts in proofs (proof preservation discipline).
|
|
32
27
|
*
|
|
33
|
-
* @param paymentRequired - The 402 response with
|
|
28
|
+
* @param paymentRequired - The 402 response with offers and accepts
|
|
34
29
|
* @param settlementResponse - The settlement response with receipt
|
|
35
30
|
* @param options - Optional mapping options
|
|
36
31
|
* @returns Canonical PEAC interaction record
|
|
37
32
|
* @throws X402Error if inputs are structurally invalid
|
|
38
33
|
*/
|
|
39
34
|
function toPeacRecord(paymentRequired, settlementResponse, options) {
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
35
|
+
const offerIndex = options?.offerIndex ?? 0;
|
|
36
|
+
const maxJwsBytes = options?.maxCompactJwsBytes;
|
|
37
|
+
// Validate offers array
|
|
38
|
+
if (!paymentRequired.offers ||
|
|
39
|
+
!Array.isArray(paymentRequired.offers) ||
|
|
40
|
+
paymentRequired.offers.length === 0) {
|
|
41
|
+
throw new errors_js_1.X402Error('offer_invalid_format', 'PaymentRequired must contain a non-empty offers array');
|
|
42
|
+
}
|
|
43
|
+
if (offerIndex < 0 || offerIndex >= paymentRequired.offers.length) {
|
|
44
|
+
throw new errors_js_1.X402Error('offer_invalid_format', `offerIndex ${offerIndex} is out of range [0, ${paymentRequired.offers.length - 1}]`);
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
const offer = paymentRequired.offers[offerIndex];
|
|
47
|
+
const receipt = settlementResponse.receipt;
|
|
48
|
+
if (!receipt) {
|
|
49
|
+
throw new errors_js_1.X402Error('receipt_invalid_format', 'SettlementResponse must contain a valid receipt');
|
|
47
50
|
}
|
|
48
|
-
|
|
49
|
-
const
|
|
51
|
+
// Extract and normalize payloads (Layer A -> Layer B)
|
|
52
|
+
const rawOfferPayload = (0, raw_js_1.extractOfferPayload)(offer, maxJwsBytes);
|
|
53
|
+
const rawReceiptPayload = (0, raw_js_1.extractReceiptPayload)(receipt, maxJwsBytes);
|
|
54
|
+
const offerPayload = (0, normalize_js_1.normalizeOfferPayload)(rawOfferPayload);
|
|
55
|
+
const receiptPayload = (0, normalize_js_1.normalizeReceiptPayload)(rawReceiptPayload);
|
|
50
56
|
// Build hints (unsigned metadata, explicitly untrusted)
|
|
51
57
|
const hints = {};
|
|
52
|
-
// Derive mismatchDetected from termMatching
|
|
58
|
+
// Derive mismatchDetected from termMatching
|
|
53
59
|
const termMatching = options?.offerVerification?.termMatching;
|
|
54
60
|
const mismatchDetected = termMatching?.hintMismatchDetected ?? false;
|
|
55
|
-
|
|
61
|
+
// acceptIndex is now per-offer
|
|
62
|
+
if (offer.acceptIndex !== undefined) {
|
|
56
63
|
hints.acceptIndex = {
|
|
57
|
-
value:
|
|
64
|
+
value: offer.acceptIndex,
|
|
58
65
|
untrusted: true,
|
|
59
66
|
...(mismatchDetected && { mismatchDetected: true }),
|
|
60
67
|
};
|
|
@@ -64,47 +71,61 @@ function toPeacRecord(paymentRequired, settlementResponse, options) {
|
|
|
64
71
|
hints.resourceUrl = resourceUrl;
|
|
65
72
|
}
|
|
66
73
|
// Build verification status
|
|
67
|
-
// IMPORTANT: If offerVerification is not provided, we cannot assume terms matched.
|
|
68
|
-
// Callers SHOULD provide offerVerification for a complete record.
|
|
69
74
|
const offerVerification = options?.offerVerification;
|
|
70
75
|
const termMatchingVerified = offerVerification !== undefined;
|
|
76
|
+
const cryptoResult = options?.cryptoResult;
|
|
77
|
+
const authResult = options?.authorizationResult;
|
|
71
78
|
const verification = {
|
|
72
79
|
structural: true,
|
|
73
80
|
cryptographic: {
|
|
74
81
|
verified: options?.cryptoVerified ?? false,
|
|
75
82
|
...(!(options?.cryptoVerified ?? false) && { reason: 'not_checked' }),
|
|
76
83
|
format: offer.format,
|
|
77
|
-
...(
|
|
84
|
+
...(cryptoResult?.signer && { signer: cryptoResult.signer }),
|
|
78
85
|
},
|
|
79
86
|
termMatching: {
|
|
80
|
-
// Safe-by-default: if verification wasn't performed, indicate that clearly
|
|
81
87
|
matched: termMatchingVerified ? offerVerification.valid : false,
|
|
82
88
|
method: offerVerification?.usedHint ? 'hint' : 'scan',
|
|
83
89
|
...(offerVerification?.matchedIndex !== undefined && {
|
|
84
90
|
matchedIndex: offerVerification.matchedIndex,
|
|
85
91
|
}),
|
|
86
|
-
// Add flag to indicate if term-matching was actually performed
|
|
87
92
|
...(!termMatchingVerified && { reason: 'not_verified' }),
|
|
88
93
|
},
|
|
94
|
+
...(options?.consistencyVerification && {
|
|
95
|
+
consistency: {
|
|
96
|
+
checked: true,
|
|
97
|
+
valid: options.consistencyVerification.valid,
|
|
98
|
+
},
|
|
99
|
+
}),
|
|
100
|
+
...(authResult && {
|
|
101
|
+
signerAuthorization: {
|
|
102
|
+
checked: true,
|
|
103
|
+
authorized: authResult.authorized,
|
|
104
|
+
...(authResult.method && { method: authResult.method }),
|
|
105
|
+
},
|
|
106
|
+
}),
|
|
89
107
|
};
|
|
90
108
|
hints.verification = verification;
|
|
91
109
|
return {
|
|
92
110
|
version: types_js_1.X402_OFFER_RECEIPT_PROFILE,
|
|
93
111
|
proofs: {
|
|
94
112
|
x402: {
|
|
95
|
-
offer,
|
|
96
|
-
receipt,
|
|
113
|
+
offer, // exact raw artifact, never mutated
|
|
114
|
+
receipt, // exact raw artifact, never mutated
|
|
97
115
|
},
|
|
98
116
|
},
|
|
99
117
|
evidence: {
|
|
100
|
-
|
|
118
|
+
resourceUrl: offerPayload.resourceUrl,
|
|
119
|
+
...(offerPayload.validUntil !== undefined && { validUntil: offerPayload.validUntil }),
|
|
101
120
|
network: offerPayload.network,
|
|
102
121
|
payee: offerPayload.payTo,
|
|
103
122
|
asset: offerPayload.asset,
|
|
104
123
|
amount: offerPayload.amount,
|
|
105
|
-
txHash: receiptPayload.txHash,
|
|
106
124
|
offerVersion: offerPayload.version,
|
|
107
|
-
...(receiptPayload.
|
|
125
|
+
...(receiptPayload.payer && { payer: receiptPayload.payer }),
|
|
126
|
+
...(receiptPayload.issuedAt && { issuedAt: receiptPayload.issuedAt }),
|
|
127
|
+
...(receiptPayload.transaction && { transaction: receiptPayload.transaction }),
|
|
128
|
+
...(receiptPayload.version !== undefined && { receiptVersion: receiptPayload.version }),
|
|
108
129
|
},
|
|
109
130
|
hints,
|
|
110
131
|
createdAt: new Date().toISOString(),
|
|
@@ -116,7 +137,7 @@ function toPeacRecord(paymentRequired, settlementResponse, options) {
|
|
|
116
137
|
/**
|
|
117
138
|
* Convert an x402 PEAC record to a PeacEvidenceCarrier.
|
|
118
139
|
*
|
|
119
|
-
* Uses the shared `computeReceiptRef()` from `@peac/schema`
|
|
140
|
+
* Uses the shared `computeReceiptRef()` from `@peac/schema`
|
|
120
141
|
* to produce a canonical, content-addressed receipt_ref from the JWS.
|
|
121
142
|
*
|
|
122
143
|
* @param receiptJws - Compact JWS of the PEAC receipt
|
package/dist/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"map.js","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"map.js","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"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"}
|