@peac/adapter-x402 0.12.0-preview.2 → 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 CHANGED
@@ -1,14 +1,19 @@
1
1
  # @peac/adapter-x402
2
2
 
3
- x402 offer/receipt verification, term-matching, and PEAC record mapping.
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 objects (offers and receipts) and maps
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, acceptIndex);
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(paymentRequired, settlementResponse);
53
- // record.proofs.x402.offer -- raw offer preserved for audit
54
- // record.proofs.x402.receipt -- raw receipt preserved for audit
55
- // record.evidence.txHash -- from signed receipt payload
56
- // record.hints.acceptIndex -- { value: 0, untrusted: true }
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 envelope
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, acceptIndex?, config?)`
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 structure and version.
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(paymentRequired, settlementResponse)`
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, acceptIndex, {
111
- supportedVersions: ['1', '2'],
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). If x402 v2 introduces new required payload fields, update the adapter types and add conformance vectors.
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
  *
@@ -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;AAwBtB;;;;;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"}
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
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AA+BH;;GAEG;AACH,MAAM,iBAAiB,GAAkC;IACvD,oBAAoB,EAAE,GAAG;IACzB,aAAa,EAAE,GAAG;IAClB,yBAAyB,EAAE,GAAG;IAC9B,uBAAuB,EAAE,GAAG;IAC5B,sBAAsB,EAAE,GAAG;IAC3B,yBAAyB,EAAE,GAAG;IAC9B,2BAA2B,EAAE,GAAG;IAChC,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;CACrB,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"}
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
- * x402 Offer/Receipt extension verification, term-matching, and PEAC record mapping.
4
+ * Verification, term-matching, and evidence mapping for the
5
+ * x402 Offer/Receipt extension (compatible with upstream coinbase/x402).
5
6
  *
6
- * NOTE: This adapter targets the x402 Offer/Receipt EXTENSION,
7
- * NOT the baseline x402 header flow. The profile identifier reflects this:
8
- * `peac-x402-offer-receipt/0.1` (extension) vs `peac-x402/0.1` (baseline, reserved).
9
- *
10
- * Key capabilities:
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 { SignatureFormat, OfferPayload, SignedOffer, ReceiptPayload, SignedReceipt, AcceptEntry, X402PaymentRequired, X402SettlementResponse, OfferVerification, ReceiptVerification, VerificationError, VerificationStatus, X402PeacRecord, X402AdapterConfig, MismatchPolicy, } from './types.js';
29
- export { X402_OFFER_RECEIPT_PROFILE, MAX_ACCEPT_ENTRIES, MAX_TOTAL_ACCEPTS_BYTES, MAX_AMOUNT_LENGTH, } from './types.js';
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,YAAY,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,cAAc,GACf,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,0BAA0B,EAC1B,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,GAClB,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,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGzF,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"}
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
- * x402 Offer/Receipt extension verification, term-matching, and PEAC record mapping.
5
+ * Verification, term-matching, and evidence mapping for the
6
+ * x402 Offer/Receipt extension (compatible with upstream coinbase/x402).
6
7
  *
7
- * NOTE: This adapter targets the x402 Offer/Receipt EXTENSION,
8
- * NOT the baseline x402 header flow. The profile identifier reflects this:
9
- * `peac-x402-offer-receipt/0.1` (extension) vs `peac-x402/0.1` (baseline, reserved).
10
- *
11
- * Key capabilities:
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
- // Constants
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;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;;;AAqBH,YAAY;AACZ,uCAKoB;AAJlB,sHAAA,0BAA0B,OAAA;AAC1B,8GAAA,kBAAkB,OAAA;AAClB,mHAAA,uBAAuB,OAAA;AACvB,6GAAA,iBAAiB,OAAA;AAMnB,SAAS;AACT,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAGlB,eAAe;AACf,yCAAyF;AAAhF,wGAAA,WAAW,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAAE,yGAAA,YAAY,OAAA;AAEnE,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"}
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 PaymentRequired + SettlementResponse into a canonical
4
+ * Maps x402 offer/receipt extension data into a canonical
5
5
  * PEAC interaction record (X402PeacRecord).
6
6
  *
7
- * NOTE: This mapper produces records for the x402 Offer/Receipt EXTENSION,
8
- * NOT the baseline x402 header flow. The profile identifier reflects this.
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 { X402PaymentRequired, X402SettlementResponse, X402PeacRecord, OfferVerification } from './types.js';
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
- * Signer identity (if crypto verification was performed)
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
- cryptoSigner?: string;
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
- * IMPORTANT: The resulting record does NOT indicate cryptographic signature
47
- * validity unless you explicitly pass `cryptoVerified: true` in options.
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 offer and accepts
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: X402PaymentRequired, settlementResponse: X402SettlementResponse, options?: ToPeacRecordOptions): X402PeacRecord;
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` (correction item 4)
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;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAIxD,OAAO,KAAK,EACV,mBAAmB,EACnB,sBAAsB,EACtB,cAAc,EAEd,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,eAAe,EAAE,mBAAmB,EACpC,kBAAkB,EAAE,sBAAsB,EAC1C,OAAO,CAAC,EAAE,mBAAmB,GAC5B,cAAc,CAyFhB;AAMD;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAMpF"}
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 PaymentRequired + SettlementResponse into a canonical
5
+ * Maps x402 offer/receipt extension data into a canonical
6
6
  * PEAC interaction record (X402PeacRecord).
7
7
  *
8
- * NOTE: This mapper produces records for the x402 Offer/Receipt EXTENSION,
9
- * NOT the baseline x402 header flow. The profile identifier reflects this.
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
- * IMPORTANT: The resulting record does NOT indicate cryptographic signature
30
- * validity unless you explicitly pass `cryptoVerified: true` in options.
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 offer and accepts
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 offer = paymentRequired.offer;
41
- const receipt = settlementResponse.receipt;
42
- if (!offer?.payload) {
43
- throw new errors_js_1.X402Error('offer_invalid_format', 'PaymentRequired must contain a valid offer with payload');
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
- if (!receipt?.payload) {
46
- throw new errors_js_1.X402Error('receipt_invalid_format', 'SettlementResponse must contain a valid receipt with payload');
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
- const offerPayload = offer.payload;
49
- const receiptPayload = receipt.payload;
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 (first-class, always boolean when present)
58
+ // Derive mismatchDetected from termMatching
53
59
  const termMatching = options?.offerVerification?.termMatching;
54
60
  const mismatchDetected = termMatching?.hintMismatchDetected ?? false;
55
- if (paymentRequired.acceptIndex !== undefined) {
61
+ // acceptIndex is now per-offer
62
+ if (offer.acceptIndex !== undefined) {
56
63
  hints.acceptIndex = {
57
- value: paymentRequired.acceptIndex,
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
- ...(options?.cryptoSigner && { signer: options.cryptoSigner }),
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
- validUntil: offerPayload.validUntil,
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.version && { receiptVersion: receiptPayload.version }),
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` (correction item 4)
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":"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"}
1
+ {"version":3,"file":"map.js","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"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"}