@peac/adapter-x402 0.10.5

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 ADDED
@@ -0,0 +1,116 @@
1
+ # @peac/adapter-x402
2
+
3
+ x402 offer/receipt verification, term-matching, and PEAC record mapping.
4
+
5
+ ## Overview
6
+
7
+ This package verifies x402 extension objects (offers and receipts) and maps
8
+ them into canonical PEAC interaction records. It implements term-matching
9
+ verification where `acceptIndex` is treated as an untrusted hint and the
10
+ binding comes from matching signed payload fields against accept terms.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pnpm add @peac/adapter-x402
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Verify an offer against accept terms
21
+
22
+ ```typescript
23
+ import { verifyOffer } from '@peac/adapter-x402';
24
+
25
+ const result = verifyOffer(signedOffer, acceptEntries, acceptIndex);
26
+
27
+ if (result.valid) {
28
+ console.log('Matched accept entry:', result.matchedAccept);
29
+ console.log('Used hint:', result.usedHint);
30
+ } else {
31
+ console.log('Verification failed:', result.errors);
32
+ }
33
+ ```
34
+
35
+ ### Select accept entry with term-matching
36
+
37
+ ```typescript
38
+ import { selectAccept } from '@peac/adapter-x402';
39
+
40
+ // With hint (bounds-check + term-match)
41
+ const match = selectAccept(offerPayload, accepts, acceptIndex);
42
+
43
+ // Without hint (scan for unique match)
44
+ const match = selectAccept(offerPayload, accepts);
45
+ ```
46
+
47
+ ### Map to PEAC record
48
+
49
+ ```typescript
50
+ import { toPeacRecord } from '@peac/adapter-x402';
51
+
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
+ ```
58
+
59
+ ## acceptIndex: hint-only semantics
60
+
61
+ In the x402 Offer/Receipt extension, `acceptIndex` is an unsigned envelope
62
+ field outside the signed payload. Verifiers MUST NOT rely on it as a binding
63
+ mechanism.
64
+
65
+ This package treats `acceptIndex` as advisory:
66
+
67
+ - If present: bounds-check, then term-match `accepts[acceptIndex]` against
68
+ the signed payload. Reject on mismatch.
69
+ - If absent: scan all `accepts[]` entries for a unique match. If ambiguous
70
+ (multiple matches), reject.
71
+ - If tampered: does not affect security because the binding comes from
72
+ comparing signed payload fields, not the unsigned index.
73
+
74
+ ## API
75
+
76
+ ### `verifyOffer(offer, accepts, acceptIndex?, config?)`
77
+
78
+ Verify a signed offer against accept terms. Checks structure, expiry,
79
+ version, signature format, and term-matching.
80
+
81
+ ### `verifyReceipt(receipt, config?)`
82
+
83
+ Verify a signed receipt's structure and version.
84
+
85
+ ### `matchAcceptTerms(payload, accept)`
86
+
87
+ Compare offer payload fields against a single accept entry. Returns an
88
+ array of mismatched field names (empty means match).
89
+
90
+ ### `selectAccept(payload, accepts, acceptIndex?)`
91
+
92
+ Select the matching accept entry. Throws `X402Error` on failure.
93
+
94
+ ### `toPeacRecord(paymentRequired, settlementResponse)`
95
+
96
+ Map an x402 payment flow to a PEAC interaction record.
97
+
98
+ ## Error handling
99
+
100
+ All verification functions return structured results with error arrays.
101
+ The `selectAccept` and `toPeacRecord` functions throw `X402Error` with:
102
+
103
+ - `code`: Machine-readable error code (lowercase snake_case)
104
+ - `httpStatus`: Suggested HTTP status code
105
+ - `field`: Optional field that caused the error
106
+ - `details`: Optional structured details
107
+
108
+ ## License
109
+
110
+ Apache-2.0
111
+
112
+ ---
113
+
114
+ PEAC Protocol is an open source project stewarded by Originary and community contributors.
115
+
116
+ [Docs](https://www.peacprotocol.org) | [GitHub](https://github.com/peacprotocol/peac) | [Originary](https://www.originary.xyz)
@@ -0,0 +1,36 @@
1
+ /**
2
+ * x402 adapter error codes and error class
3
+ *
4
+ * Error codes follow PEAC adapter convention: lowercase snake_case.
5
+ * These are adapter-level errors; kernel-level errors use E_* prefix.
6
+ */
7
+ /**
8
+ * x402 adapter error codes
9
+ *
10
+ * Categories:
11
+ * - offer_*: Offer validation/verification errors
12
+ * - receipt_*: Receipt validation/verification errors
13
+ * - accept_*: Accept selection/matching errors
14
+ * - payload_*: Generic payload errors
15
+ * - amount_*: Amount validation errors
16
+ * - network_*: Network validation errors
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';
19
+ /**
20
+ * Custom error class for x402 adapter operations
21
+ *
22
+ * Provides structured error information with code, HTTP status,
23
+ * and optional field/details for debugging.
24
+ */
25
+ export declare class X402Error extends Error {
26
+ readonly code: X402ErrorCode;
27
+ readonly httpStatus: number;
28
+ readonly field?: string;
29
+ readonly details?: Record<string, unknown>;
30
+ constructor(code: X402ErrorCode, message: string, options?: {
31
+ field?: string;
32
+ details?: Record<string, unknown>;
33
+ });
34
+ toJSON(): Record<string, unknown>;
35
+ }
36
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +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"}
package/dist/errors.js ADDED
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ /**
3
+ * x402 adapter error codes and error class
4
+ *
5
+ * Error codes follow PEAC adapter convention: lowercase snake_case.
6
+ * These are adapter-level errors; kernel-level errors use E_* prefix.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.X402Error = void 0;
10
+ /**
11
+ * HTTP status mapping for error codes
12
+ */
13
+ const ERROR_HTTP_STATUS = {
14
+ offer_invalid_format: 400,
15
+ offer_expired: 400,
16
+ offer_version_unsupported: 400,
17
+ offer_signature_invalid: 401,
18
+ receipt_invalid_format: 400,
19
+ receipt_signature_invalid: 401,
20
+ receipt_version_unsupported: 400,
21
+ accept_index_out_of_range: 400,
22
+ accept_no_match: 400,
23
+ accept_ambiguous: 400,
24
+ accept_term_mismatch: 400,
25
+ accept_too_many_entries: 400,
26
+ payload_missing_field: 400,
27
+ payload_tampered: 401,
28
+ amount_invalid: 400,
29
+ network_invalid: 400,
30
+ };
31
+ /**
32
+ * Custom error class for x402 adapter operations
33
+ *
34
+ * Provides structured error information with code, HTTP status,
35
+ * and optional field/details for debugging.
36
+ */
37
+ class X402Error extends Error {
38
+ code;
39
+ httpStatus;
40
+ field;
41
+ details;
42
+ constructor(code, message, options) {
43
+ super(message);
44
+ this.name = 'X402Error';
45
+ this.code = code;
46
+ this.httpStatus = ERROR_HTTP_STATUS[code] ?? 400;
47
+ this.field = options?.field;
48
+ this.details = options?.details;
49
+ }
50
+ toJSON() {
51
+ return {
52
+ name: this.name,
53
+ code: this.code,
54
+ message: this.message,
55
+ httpStatus: this.httpStatus,
56
+ ...(this.field !== undefined && { field: this.field }),
57
+ ...(this.details !== undefined && { details: this.details }),
58
+ };
59
+ }
60
+ }
61
+ exports.X402Error = X402Error;
62
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @peac/adapter-x402
3
+ *
4
+ * x402 Offer/Receipt extension verification, term-matching, and PEAC record mapping.
5
+ *
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.
25
+ *
26
+ * @packageDocumentation
27
+ */
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';
30
+ export type { Result, AdapterError, AdapterErrorCode, JsonObject } from './types.js';
31
+ export { X402Error } from './errors.js';
32
+ export type { X402ErrorCode } from './errors.js';
33
+ export { verifyOffer, verifyReceipt, matchAcceptTerms, selectAccept } from './verify.js';
34
+ export { toPeacRecord } from './map.js';
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +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,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * @peac/adapter-x402
4
+ *
5
+ * x402 Offer/Receipt extension verification, term-matching, and PEAC record mapping.
6
+ *
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.
26
+ *
27
+ * @packageDocumentation
28
+ */
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ 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
32
+ var types_js_1 = require("./types.js");
33
+ Object.defineProperty(exports, "X402_OFFER_RECEIPT_PROFILE", { enumerable: true, get: function () { return types_js_1.X402_OFFER_RECEIPT_PROFILE; } });
34
+ Object.defineProperty(exports, "MAX_ACCEPT_ENTRIES", { enumerable: true, get: function () { return types_js_1.MAX_ACCEPT_ENTRIES; } });
35
+ Object.defineProperty(exports, "MAX_TOTAL_ACCEPTS_BYTES", { enumerable: true, get: function () { return types_js_1.MAX_TOTAL_ACCEPTS_BYTES; } });
36
+ Object.defineProperty(exports, "MAX_AMOUNT_LENGTH", { enumerable: true, get: function () { return types_js_1.MAX_AMOUNT_LENGTH; } });
37
+ // Errors
38
+ var errors_js_1 = require("./errors.js");
39
+ Object.defineProperty(exports, "X402Error", { enumerable: true, get: function () { return errors_js_1.X402Error; } });
40
+ // Verification
41
+ var verify_js_1 = require("./verify.js");
42
+ Object.defineProperty(exports, "verifyOffer", { enumerable: true, get: function () { return verify_js_1.verifyOffer; } });
43
+ Object.defineProperty(exports, "verifyReceipt", { enumerable: true, get: function () { return verify_js_1.verifyReceipt; } });
44
+ Object.defineProperty(exports, "matchAcceptTerms", { enumerable: true, get: function () { return verify_js_1.matchAcceptTerms; } });
45
+ Object.defineProperty(exports, "selectAccept", { enumerable: true, get: function () { return verify_js_1.selectAccept; } });
46
+ // Mapping
47
+ var map_js_1 = require("./map.js");
48
+ Object.defineProperty(exports, "toPeacRecord", { enumerable: true, get: function () { return map_js_1.toPeacRecord; } });
49
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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,mCAAwC;AAA/B,sGAAA,YAAY,OAAA"}
package/dist/map.d.ts ADDED
@@ -0,0 +1,56 @@
1
+ /**
2
+ * x402 to PEAC record mapping
3
+ *
4
+ * Maps x402 PaymentRequired + SettlementResponse into a canonical
5
+ * PEAC interaction record (X402PeacRecord).
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)
15
+ */
16
+ import type { X402PaymentRequired, X402SettlementResponse, X402PeacRecord, OfferVerification } from './types.js';
17
+ /**
18
+ * Options for record mapping
19
+ */
20
+ export interface ToPeacRecordOptions {
21
+ /**
22
+ * Offer verification result (to populate verification hints)
23
+ *
24
+ * The termMatching field in OfferVerification is used to derive
25
+ * hints.acceptIndex.mismatchDetected automatically. This makes
26
+ * mismatch detection first-class without requiring external options.
27
+ */
28
+ offerVerification?: OfferVerification;
29
+ /**
30
+ * Whether cryptographic signature verification was performed
31
+ * Default: false (adapter does NOT perform crypto verification)
32
+ */
33
+ cryptoVerified?: boolean;
34
+ /**
35
+ * Signer identity (if crypto verification was performed)
36
+ */
37
+ cryptoSigner?: string;
38
+ }
39
+ /**
40
+ * Map x402 payment flow to a PEAC interaction record
41
+ *
42
+ * Takes a PaymentRequired (offer side) and SettlementResponse (receipt side)
43
+ * and produces a canonical PEAC record with normalized evidence.
44
+ *
45
+ * IMPORTANT: The resulting record does NOT indicate cryptographic signature
46
+ * validity unless you explicitly pass `cryptoVerified: true` in options.
47
+ * See `hints.verification.cryptographic` in the output.
48
+ *
49
+ * @param paymentRequired - The 402 response with offer and accepts
50
+ * @param settlementResponse - The settlement response with receipt
51
+ * @param options - Optional mapping options
52
+ * @returns Canonical PEAC interaction record
53
+ * @throws X402Error if inputs are structurally invalid
54
+ */
55
+ export declare function toPeacRecord(paymentRequired: X402PaymentRequired, settlementResponse: X402SettlementResponse, options?: ToPeacRecordOptions): X402PeacRecord;
56
+ //# sourceMappingURL=map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.d.ts","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,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"}
package/dist/map.js ADDED
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * x402 to PEAC record mapping
4
+ *
5
+ * Maps x402 PaymentRequired + SettlementResponse into a canonical
6
+ * PEAC interaction record (X402PeacRecord).
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)
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.toPeacRecord = toPeacRecord;
19
+ const errors_js_1 = require("./errors.js");
20
+ const types_js_1 = require("./types.js");
21
+ /**
22
+ * Map x402 payment flow to a PEAC interaction record
23
+ *
24
+ * Takes a PaymentRequired (offer side) and SettlementResponse (receipt side)
25
+ * and produces a canonical PEAC record with normalized evidence.
26
+ *
27
+ * IMPORTANT: The resulting record does NOT indicate cryptographic signature
28
+ * validity unless you explicitly pass `cryptoVerified: true` in options.
29
+ * See `hints.verification.cryptographic` in the output.
30
+ *
31
+ * @param paymentRequired - The 402 response with offer and accepts
32
+ * @param settlementResponse - The settlement response with receipt
33
+ * @param options - Optional mapping options
34
+ * @returns Canonical PEAC interaction record
35
+ * @throws X402Error if inputs are structurally invalid
36
+ */
37
+ function toPeacRecord(paymentRequired, settlementResponse, options) {
38
+ const offer = paymentRequired.offer;
39
+ const receipt = settlementResponse.receipt;
40
+ if (!offer?.payload) {
41
+ throw new errors_js_1.X402Error('offer_invalid_format', 'PaymentRequired must contain a valid offer with payload');
42
+ }
43
+ if (!receipt?.payload) {
44
+ throw new errors_js_1.X402Error('receipt_invalid_format', 'SettlementResponse must contain a valid receipt with payload');
45
+ }
46
+ const offerPayload = offer.payload;
47
+ const receiptPayload = receipt.payload;
48
+ // Build hints (unsigned metadata, explicitly untrusted)
49
+ const hints = {};
50
+ // Derive mismatchDetected from termMatching (first-class, always boolean when present)
51
+ const termMatching = options?.offerVerification?.termMatching;
52
+ const mismatchDetected = termMatching?.hintMismatchDetected ?? false;
53
+ if (paymentRequired.acceptIndex !== undefined) {
54
+ hints.acceptIndex = {
55
+ value: paymentRequired.acceptIndex,
56
+ untrusted: true,
57
+ ...(mismatchDetected && { mismatchDetected: true }),
58
+ };
59
+ }
60
+ const resourceUrl = paymentRequired.resourceUrl ?? settlementResponse.resourceUrl;
61
+ if (resourceUrl) {
62
+ hints.resourceUrl = resourceUrl;
63
+ }
64
+ // Build verification status
65
+ // IMPORTANT: If offerVerification is not provided, we cannot assume terms matched.
66
+ // Callers SHOULD provide offerVerification for a complete record.
67
+ const offerVerification = options?.offerVerification;
68
+ const termMatchingVerified = offerVerification !== undefined;
69
+ const verification = {
70
+ structural: true,
71
+ cryptographic: {
72
+ verified: options?.cryptoVerified ?? false,
73
+ ...(!(options?.cryptoVerified ?? false) && { reason: 'not_checked' }),
74
+ format: offer.format,
75
+ ...(options?.cryptoSigner && { signer: options.cryptoSigner }),
76
+ },
77
+ termMatching: {
78
+ // Safe-by-default: if verification wasn't performed, indicate that clearly
79
+ matched: termMatchingVerified ? offerVerification.valid : false,
80
+ method: offerVerification?.usedHint ? 'hint' : 'scan',
81
+ ...(offerVerification?.matchedIndex !== undefined && {
82
+ matchedIndex: offerVerification.matchedIndex,
83
+ }),
84
+ // Add flag to indicate if term-matching was actually performed
85
+ ...(!termMatchingVerified && { reason: 'not_verified' }),
86
+ },
87
+ };
88
+ hints.verification = verification;
89
+ return {
90
+ version: types_js_1.X402_OFFER_RECEIPT_PROFILE,
91
+ proofs: {
92
+ x402: {
93
+ offer,
94
+ receipt,
95
+ },
96
+ },
97
+ evidence: {
98
+ validUntil: offerPayload.validUntil,
99
+ network: offerPayload.network,
100
+ payee: offerPayload.payTo,
101
+ asset: offerPayload.asset,
102
+ amount: offerPayload.amount,
103
+ txHash: receiptPayload.txHash,
104
+ offerVersion: offerPayload.version,
105
+ ...(receiptPayload.version && { receiptVersion: receiptPayload.version }),
106
+ },
107
+ hints,
108
+ createdAt: new Date().toISOString(),
109
+ };
110
+ }
111
+ //# sourceMappingURL=map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"map.js","sourceRoot":"","sources":["../src/map.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AAmDH,oCA6FC;AA9ID,2CAAwC;AAQxC,yCAAwD;AAyBxD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,YAAY,CAC1B,eAAoC,EACpC,kBAA0C,EAC1C,OAA6B;IAE7B,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC;IACpC,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC;IAE3C,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,qBAAS,CACjB,sBAAsB,EACtB,yDAAyD,CAC1D,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,qBAAS,CACjB,wBAAwB,EACxB,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC;IACnC,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAEvC,wDAAwD;IACxD,MAAM,KAAK,GAA4B,EAAE,CAAC;IAE1C,uFAAuF;IACvF,MAAM,YAAY,GAAG,OAAO,EAAE,iBAAiB,EAAE,YAAY,CAAC;IAC9D,MAAM,gBAAgB,GAAG,YAAY,EAAE,oBAAoB,IAAI,KAAK,CAAC;IAErE,IAAI,eAAe,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9C,KAAK,CAAC,WAAW,GAAG;YAClB,KAAK,EAAE,eAAe,CAAC,WAAW;YAClC,SAAS,EAAE,IAAI;YACf,GAAG,CAAC,gBAAgB,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;SACpD,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,eAAe,CAAC,WAAW,IAAI,kBAAkB,CAAC,WAAW,CAAC;IAClF,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC;IAClC,CAAC;IAED,4BAA4B;IAC5B,mFAAmF;IACnF,kEAAkE;IAClE,MAAM,iBAAiB,GAAG,OAAO,EAAE,iBAAiB,CAAC;IACrD,MAAM,oBAAoB,GAAG,iBAAiB,KAAK,SAAS,CAAC;IAE7D,MAAM,YAAY,GAAuB;QACvC,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE;YACb,QAAQ,EAAE,OAAO,EAAE,cAAc,IAAI,KAAK;YAC1C,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,cAAc,IAAI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;YACrE,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;SAC/D;QACD,YAAY,EAAE;YACZ,2EAA2E;YAC3E,OAAO,EAAE,oBAAoB,CAAC,CAAC,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK;YAC/D,MAAM,EAAE,iBAAiB,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YACrD,GAAG,CAAC,iBAAiB,EAAE,YAAY,KAAK,SAAS,IAAI;gBACnD,YAAY,EAAE,iBAAiB,CAAC,YAAY;aAC7C,CAAC;YACF,+DAA+D;YAC/D,GAAG,CAAC,CAAC,oBAAoB,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;SACzD;KACF,CAAC;IAEF,KAAK,CAAC,YAAY,GAAG,YAAY,CAAC;IAElC,OAAO;QACL,OAAO,EAAE,qCAA0B;QACnC,MAAM,EAAE;YACN,IAAI,EAAE;gBACJ,KAAK;gBACL,OAAO;aACR;SACF;QACD,QAAQ,EAAE;YACR,UAAU,EAAE,YAAY,CAAC,UAAU;YACnC,OAAO,EAAE,YAAY,CAAC,OAAO;YAC7B,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,KAAK,EAAE,YAAY,CAAC,KAAK;YACzB,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,MAAM,EAAE,cAAc,CAAC,MAAM;YAC7B,YAAY,EAAE,YAAY,CAAC,OAAO;YAClC,GAAG,CAAC,cAAc,CAAC,OAAO,IAAI,EAAE,cAAc,EAAE,cAAc,CAAC,OAAO,EAAE,CAAC;SAC1E;QACD,KAAK;QACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;AACJ,CAAC"}