@peac/rails-x402 0.9.18

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,23 @@
1
+ # @peac/rails-x402
2
+
3
+ x402 payment rail adapter for PEAC protocol
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @peac/rails-x402
9
+ ```
10
+
11
+ ## Documentation
12
+
13
+ See [peacprotocol.org](https://peacprotocol.org) for full documentation.
14
+
15
+ ## License
16
+
17
+ Apache-2.0
18
+
19
+ ---
20
+
21
+ PEAC Protocol is an open source project stewarded by Originary and community contributors.
22
+
23
+ [Originary](https://www.originary.xyz) | [Docs](https://peacprotocol.org) | [GitHub](https://github.com/peacprotocol/peac)
@@ -0,0 +1,46 @@
1
+ /**
2
+ * x402 protocol constants and types
3
+ *
4
+ * Supports both x402 v1 (legacy X-PAYMENT-* headers) and v2 (Payment-* headers).
5
+ * Default behavior is auto-detection with v1 fallback.
6
+ */
7
+ /**
8
+ * x402 protocol dialect
9
+ *
10
+ * - 'v1': Legacy X-PAYMENT-* headers (pre-Dec 2025)
11
+ * - 'v2': New Payment-* headers (Dec 2025+)
12
+ * - 'auto': Auto-detect from response headers (default)
13
+ */
14
+ export type X402Dialect = 'v1' | 'v2' | 'auto';
15
+ /**
16
+ * x402 v1 header names (legacy, pre-Dec 2025)
17
+ */
18
+ export declare const X402_HEADERS_V1: {
19
+ readonly paymentRequired: "X-PAYMENT";
20
+ readonly paymentResponse: "X-PAYMENT-RESPONSE";
21
+ };
22
+ /**
23
+ * x402 v2 header names (Dec 2025+)
24
+ */
25
+ export declare const X402_HEADERS_V2: {
26
+ readonly paymentRequired: "Payment-Required";
27
+ readonly paymentSignature: "Payment-Signature";
28
+ readonly paymentResponse: "Payment-Response";
29
+ };
30
+ /**
31
+ * CAIP-2 network registry
32
+ *
33
+ * Maps canonical CAIP-2 identifiers to human-readable labels and environment.
34
+ * Used for validation/logging only - network IDs are passed through unchanged.
35
+ *
36
+ * Reference: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md
37
+ */
38
+ export declare const CAIP2_REGISTRY: Record<string, {
39
+ label: string;
40
+ env: 'mainnet' | 'testnet';
41
+ }>;
42
+ /**
43
+ * Default network for v1 x402 (Lightning)
44
+ */
45
+ export declare const X402_V1_DEFAULT_NETWORK = "lightning";
46
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,eAAe;;;CAGlB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,CAWxF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB,cAAc,CAAC"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * x402 protocol constants and types
4
+ *
5
+ * Supports both x402 v1 (legacy X-PAYMENT-* headers) and v2 (Payment-* headers).
6
+ * Default behavior is auto-detection with v1 fallback.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.X402_V1_DEFAULT_NETWORK = exports.CAIP2_REGISTRY = exports.X402_HEADERS_V2 = exports.X402_HEADERS_V1 = void 0;
10
+ /**
11
+ * x402 v1 header names (legacy, pre-Dec 2025)
12
+ */
13
+ exports.X402_HEADERS_V1 = {
14
+ paymentRequired: 'X-PAYMENT',
15
+ paymentResponse: 'X-PAYMENT-RESPONSE',
16
+ };
17
+ /**
18
+ * x402 v2 header names (Dec 2025+)
19
+ */
20
+ exports.X402_HEADERS_V2 = {
21
+ paymentRequired: 'Payment-Required',
22
+ paymentSignature: 'Payment-Signature',
23
+ paymentResponse: 'Payment-Response',
24
+ };
25
+ /**
26
+ * CAIP-2 network registry
27
+ *
28
+ * Maps canonical CAIP-2 identifiers to human-readable labels and environment.
29
+ * Used for validation/logging only - network IDs are passed through unchanged.
30
+ *
31
+ * Reference: https://github.com/ChainAgnostic/CAIPs/blob/master/CAIPs/caip-2.md
32
+ */
33
+ exports.CAIP2_REGISTRY = {
34
+ // EVM chains
35
+ 'eip155:8453': { label: 'Base', env: 'mainnet' },
36
+ 'eip155:84532': { label: 'Base Sepolia', env: 'testnet' },
37
+ 'eip155:43114': { label: 'Avalanche', env: 'mainnet' },
38
+ 'eip155:43113': { label: 'Avalanche Fuji', env: 'testnet' },
39
+ // Solana
40
+ 'solana:mainnet': { label: 'Solana', env: 'mainnet' },
41
+ 'solana:devnet': { label: 'Solana Devnet', env: 'testnet' },
42
+ // Lightning (v1 default)
43
+ lightning: { label: 'Lightning', env: 'mainnet' },
44
+ };
45
+ /**
46
+ * Default network for v1 x402 (Lightning)
47
+ */
48
+ exports.X402_V1_DEFAULT_NETWORK = 'lightning';
49
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAWH;;GAEG;AACU,QAAA,eAAe,GAAG;IAC7B,eAAe,EAAE,WAAW;IAC5B,eAAe,EAAE,oBAAoB;CAC7B,CAAC;AAEX;;GAEG;AACU,QAAA,eAAe,GAAG;IAC7B,eAAe,EAAE,kBAAkB;IACnC,gBAAgB,EAAE,mBAAmB;IACrC,eAAe,EAAE,kBAAkB;CAC3B,CAAC;AAEX;;;;;;;GAOG;AACU,QAAA,cAAc,GAAkE;IAC3F,aAAa;IACb,aAAa,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE;IAChD,cAAc,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,SAAS,EAAE;IACzD,cAAc,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE;IACtD,cAAc,EAAE,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,SAAS,EAAE;IAC3D,SAAS;IACT,gBAAgB,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE;IACrD,eAAe,EAAE,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,EAAE,SAAS,EAAE;IAC3D,yBAAyB;IACzB,SAAS,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE;CAClD,CAAC;AAEF;;GAEG;AACU,QAAA,uBAAuB,GAAG,WAAW,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * x402 helper functions
3
+ *
4
+ * Detection, normalization, and logging utilities for x402 v1/v2 support.
5
+ */
6
+ import { type X402Dialect, X402_HEADERS_V1, X402_HEADERS_V2 } from './constants';
7
+ import type { X402Invoice } from './types';
8
+ /**
9
+ * Log warning for unknown CAIP-2 network (once per network per process)
10
+ *
11
+ * Message is calm and informative. Does not throw.
12
+ */
13
+ export declare function logUnknownNetworkWarning(networkId: string): void;
14
+ /**
15
+ * Detect x402 dialect from HTTP response headers
16
+ *
17
+ * Priority: v2 headers first (case-insensitive), then v1 fallback.
18
+ *
19
+ * Detection rules:
20
+ * 1. If any v2 header present (Payment-Required, Payment-Signature, Payment-Response) -> v2
21
+ * 2. If only v1 headers present (X-PAYMENT-*) -> v1
22
+ * 3. If no headers provided -> v1 (safe default)
23
+ *
24
+ * @param headers - HTTP response headers (optional)
25
+ * @returns Detected dialect ('v1' or 'v2')
26
+ */
27
+ export declare function detectDialect(headers?: Record<string, string>): 'v1' | 'v2';
28
+ /**
29
+ * Resolve dialect for invoice processing (no headers available)
30
+ *
31
+ * Heuristics:
32
+ * 1. If explicit dialect is specified (not 'auto') -> use it
33
+ * 2. If invoice.network is a CAIP-2 string (contains ':') -> v2
34
+ * 3. If invoice.payTo is present -> v2
35
+ * 4. Otherwise -> v1
36
+ *
37
+ * @param invoice - x402 invoice
38
+ * @param explicitDialect - Explicit dialect from config
39
+ * @returns Resolved dialect ('v1' or 'v2')
40
+ */
41
+ export declare function resolveDialectFromInvoice(invoice: X402Invoice, explicitDialect: X402Dialect): 'v1' | 'v2';
42
+ /**
43
+ * Normalize network ID (returns canonical ID, not label)
44
+ *
45
+ * Behavior:
46
+ * - Missing input -> "lightning" (v1 default)
47
+ * - Known CAIP-2 -> return as-is
48
+ * - Unknown -> log warning, return as-is (no throw)
49
+ *
50
+ * Key rule: NO lossy mapping. The canonical ID is always preserved.
51
+ *
52
+ * @param caip2 - CAIP-2 network identifier (optional)
53
+ * @returns Canonical network ID
54
+ */
55
+ export declare function normalizeNetworkId(caip2: string | undefined): string;
56
+ /**
57
+ * Get human-readable label for network (for evidence.network_label)
58
+ *
59
+ * @param caip2 - CAIP-2 network identifier
60
+ * @returns Human-readable label, or undefined for unknown networks
61
+ */
62
+ export declare function getNetworkLabel(caip2: string): string | undefined;
63
+ /**
64
+ * Get header names for a specific dialect
65
+ *
66
+ * @param dialect - 'v1' or 'v2'
67
+ * @returns Header name mapping
68
+ */
69
+ export declare function getHeaders(dialect: 'v1' | 'v2'): typeof X402_HEADERS_V1 | typeof X402_HEADERS_V2;
70
+ /**
71
+ * Check if a network ID indicates testnet environment
72
+ *
73
+ * @param networkId - CAIP-2 network identifier
74
+ * @returns true if testnet, false otherwise
75
+ */
76
+ export declare function isTestnet(networkId: string): boolean;
77
+ /**
78
+ * Clear warned networks set (for testing)
79
+ */
80
+ export declare function _resetWarnedNetworks(): void;
81
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,KAAK,WAAW,EAChB,eAAe,EACf,eAAe,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAO3C;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAKhE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,IAAI,CAiB3E;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,WAAW,GAC3B,IAAI,GAAG,IAAI,CAUb;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQpE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjE;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI,GAAG,OAAO,eAAe,GAAG,OAAO,eAAe,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ /**
3
+ * x402 helper functions
4
+ *
5
+ * Detection, normalization, and logging utilities for x402 v1/v2 support.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.logUnknownNetworkWarning = logUnknownNetworkWarning;
9
+ exports.detectDialect = detectDialect;
10
+ exports.resolveDialectFromInvoice = resolveDialectFromInvoice;
11
+ exports.normalizeNetworkId = normalizeNetworkId;
12
+ exports.getNetworkLabel = getNetworkLabel;
13
+ exports.getHeaders = getHeaders;
14
+ exports.isTestnet = isTestnet;
15
+ exports._resetWarnedNetworks = _resetWarnedNetworks;
16
+ const constants_1 = require("./constants");
17
+ /**
18
+ * Track warned networks to avoid log spam (one warning per network per process)
19
+ */
20
+ const warnedNetworks = new Set();
21
+ /**
22
+ * Log warning for unknown CAIP-2 network (once per network per process)
23
+ *
24
+ * Message is calm and informative. Does not throw.
25
+ */
26
+ function logUnknownNetworkWarning(networkId) {
27
+ if (warnedNetworks.has(networkId))
28
+ return;
29
+ warnedNetworks.add(networkId);
30
+ console.warn(`[peac:x402] Unknown CAIP-2 network "${networkId}", passing through as-is.`);
31
+ }
32
+ /**
33
+ * Detect x402 dialect from HTTP response headers
34
+ *
35
+ * Priority: v2 headers first (case-insensitive), then v1 fallback.
36
+ *
37
+ * Detection rules:
38
+ * 1. If any v2 header present (Payment-Required, Payment-Signature, Payment-Response) -> v2
39
+ * 2. If only v1 headers present (X-PAYMENT-*) -> v1
40
+ * 3. If no headers provided -> v1 (safe default)
41
+ *
42
+ * @param headers - HTTP response headers (optional)
43
+ * @returns Detected dialect ('v1' or 'v2')
44
+ */
45
+ function detectDialect(headers) {
46
+ if (!headers)
47
+ return 'v1';
48
+ const lowerHeaders = Object.keys(headers).map((k) => k.toLowerCase());
49
+ // Check for v2 headers first
50
+ const v2Headers = [
51
+ constants_1.X402_HEADERS_V2.paymentRequired.toLowerCase(),
52
+ constants_1.X402_HEADERS_V2.paymentSignature.toLowerCase(),
53
+ constants_1.X402_HEADERS_V2.paymentResponse.toLowerCase(),
54
+ ];
55
+ if (v2Headers.some((h) => lowerHeaders.includes(h))) {
56
+ return 'v2';
57
+ }
58
+ return 'v1';
59
+ }
60
+ /**
61
+ * Resolve dialect for invoice processing (no headers available)
62
+ *
63
+ * Heuristics:
64
+ * 1. If explicit dialect is specified (not 'auto') -> use it
65
+ * 2. If invoice.network is a CAIP-2 string (contains ':') -> v2
66
+ * 3. If invoice.payTo is present -> v2
67
+ * 4. Otherwise -> v1
68
+ *
69
+ * @param invoice - x402 invoice
70
+ * @param explicitDialect - Explicit dialect from config
71
+ * @returns Resolved dialect ('v1' or 'v2')
72
+ */
73
+ function resolveDialectFromInvoice(invoice, explicitDialect) {
74
+ if (explicitDialect !== 'auto') {
75
+ return explicitDialect;
76
+ }
77
+ // v2 indicators
78
+ if (invoice.network && invoice.network.includes(':'))
79
+ return 'v2';
80
+ if (invoice.payTo)
81
+ return 'v2';
82
+ return 'v1';
83
+ }
84
+ /**
85
+ * Normalize network ID (returns canonical ID, not label)
86
+ *
87
+ * Behavior:
88
+ * - Missing input -> "lightning" (v1 default)
89
+ * - Known CAIP-2 -> return as-is
90
+ * - Unknown -> log warning, return as-is (no throw)
91
+ *
92
+ * Key rule: NO lossy mapping. The canonical ID is always preserved.
93
+ *
94
+ * @param caip2 - CAIP-2 network identifier (optional)
95
+ * @returns Canonical network ID
96
+ */
97
+ function normalizeNetworkId(caip2) {
98
+ if (!caip2)
99
+ return constants_1.X402_V1_DEFAULT_NETWORK;
100
+ if (!(caip2 in constants_1.CAIP2_REGISTRY)) {
101
+ logUnknownNetworkWarning(caip2);
102
+ }
103
+ return caip2; // Always return the canonical ID unchanged
104
+ }
105
+ /**
106
+ * Get human-readable label for network (for evidence.network_label)
107
+ *
108
+ * @param caip2 - CAIP-2 network identifier
109
+ * @returns Human-readable label, or undefined for unknown networks
110
+ */
111
+ function getNetworkLabel(caip2) {
112
+ return constants_1.CAIP2_REGISTRY[caip2]?.label;
113
+ }
114
+ /**
115
+ * Get header names for a specific dialect
116
+ *
117
+ * @param dialect - 'v1' or 'v2'
118
+ * @returns Header name mapping
119
+ */
120
+ function getHeaders(dialect) {
121
+ return dialect === 'v2' ? constants_1.X402_HEADERS_V2 : constants_1.X402_HEADERS_V1;
122
+ }
123
+ /**
124
+ * Check if a network ID indicates testnet environment
125
+ *
126
+ * @param networkId - CAIP-2 network identifier
127
+ * @returns true if testnet, false otherwise
128
+ */
129
+ function isTestnet(networkId) {
130
+ return constants_1.CAIP2_REGISTRY[networkId]?.env === 'testnet';
131
+ }
132
+ /**
133
+ * Clear warned networks set (for testing)
134
+ */
135
+ function _resetWarnedNetworks() {
136
+ warnedNetworks.clear();
137
+ }
138
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;AAqBH,4DAKC;AAeD,sCAiBC;AAeD,8DAaC;AAeD,gDAQC;AAQD,0CAEC;AAQD,gCAEC;AAQD,8BAEC;AAKD,oDAEC;AAhJD,2CAMqB;AAGrB;;GAEG;AACH,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;AAEzC;;;;GAIG;AACH,SAAgB,wBAAwB,CAAC,SAAiB;IACxD,IAAI,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC;QAAE,OAAO;IAC1C,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAE9B,OAAO,CAAC,IAAI,CAAC,uCAAuC,SAAS,2BAA2B,CAAC,CAAC;AAC5F,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,aAAa,CAAC,OAAgC;IAC5D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE1B,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IAEtE,6BAA6B;IAC7B,MAAM,SAAS,GAAG;QAChB,2BAAe,CAAC,eAAe,CAAC,WAAW,EAAE;QAC7C,2BAAe,CAAC,gBAAgB,CAAC,WAAW,EAAE;QAC9C,2BAAe,CAAC,eAAe,CAAC,WAAW,EAAE;KAC9C,CAAC;IAEF,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,yBAAyB,CACvC,OAAoB,EACpB,eAA4B;IAE5B,IAAI,eAAe,KAAK,MAAM,EAAE,CAAC;QAC/B,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,gBAAgB;IAChB,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClE,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAE/B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,SAAgB,kBAAkB,CAAC,KAAyB;IAC1D,IAAI,CAAC,KAAK;QAAE,OAAO,mCAAuB,CAAC;IAE3C,IAAI,CAAC,CAAC,KAAK,IAAI,0BAAc,CAAC,EAAE,CAAC;QAC/B,wBAAwB,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,OAAO,KAAK,CAAC,CAAC,2CAA2C;AAC3D,CAAC;AAED;;;;;GAKG;AACH,SAAgB,eAAe,CAAC,KAAa;IAC3C,OAAO,0BAAc,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,UAAU,CAAC,OAAoB;IAC7C,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,2BAAe,CAAC,CAAC,CAAC,2BAAe,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,SAAiB;IACzC,OAAO,0BAAc,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,SAAS,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB;IAClC,cAAc,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * x402 payment rail adapter
3
+ *
4
+ * Normalizes x402 invoices/settlements to PEAC PaymentEvidence.
5
+ * Supports both v1 (legacy X-PAYMENT-* headers) and v2 (Payment-* headers).
6
+ *
7
+ * Default behavior is auto-detection with v1 fallback for backwards compatibility.
8
+ */
9
+ import type { PaymentEvidence } from '@peac/schema';
10
+ export * from './constants';
11
+ export * from './types';
12
+ export * from './helpers';
13
+ import type { X402Dialect } from './constants';
14
+ import type { X402Invoice, X402Settlement, X402WebhookEvent } from './types';
15
+ /**
16
+ * Normalize x402 invoice to PEAC PaymentEvidence
17
+ *
18
+ * Supports both v1 and v2 x402 formats. Default is auto-detection.
19
+ *
20
+ * @param invoice - x402 invoice object
21
+ * @param env - Environment ('live' or 'test')
22
+ * @param dialect - x402 dialect ('v1', 'v2', or 'auto')
23
+ * @returns Normalized PaymentEvidence
24
+ */
25
+ export declare function fromInvoice(invoice: X402Invoice, env?: 'live' | 'test', dialect?: X402Dialect): PaymentEvidence;
26
+ /**
27
+ * Normalize x402 settlement to PEAC PaymentEvidence
28
+ *
29
+ * @param settlement - x402 settlement object
30
+ * @param env - Environment ('live' or 'test')
31
+ * @param dialect - x402 dialect ('v1', 'v2', or 'auto')
32
+ * @returns Normalized PaymentEvidence
33
+ */
34
+ export declare function fromSettlement(settlement: X402Settlement, env?: 'live' | 'test', dialect?: X402Dialect): PaymentEvidence;
35
+ /**
36
+ * Normalize x402 webhook event to PEAC PaymentEvidence
37
+ *
38
+ * Supports:
39
+ * - invoice.paid
40
+ * - settlement.completed
41
+ *
42
+ * Dialect is auto-detected from headers if provided.
43
+ *
44
+ * @param event - x402 webhook event
45
+ * @param env - Environment ('live' or 'test')
46
+ * @param headers - HTTP response headers (optional, for dialect detection)
47
+ * @returns Normalized PaymentEvidence
48
+ */
49
+ export declare function fromWebhookEvent(event: X402WebhookEvent, env?: 'live' | 'test', headers?: Record<string, string>): PaymentEvidence;
50
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,cAAc,CAAC;AAGlE,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAE1B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAgB,MAAM,SAAS,CAAC;AA2F3F;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EACpB,GAAG,GAAE,MAAM,GAAG,MAAe,EAC7B,OAAO,GAAE,WAAoB,GAC5B,eAAe,CA+EjB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,cAAc,EAC1B,GAAG,GAAE,MAAM,GAAG,MAAe,EAC7B,OAAO,GAAE,WAAoB,GAC5B,eAAe,CAqDjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,gBAAgB,EACvB,GAAG,GAAE,MAAM,GAAG,MAAe,EAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,eAAe,CAgBjB"}
package/dist/index.js ADDED
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ /**
3
+ * x402 payment rail adapter
4
+ *
5
+ * Normalizes x402 invoices/settlements to PEAC PaymentEvidence.
6
+ * Supports both v1 (legacy X-PAYMENT-* headers) and v2 (Payment-* headers).
7
+ *
8
+ * Default behavior is auto-detection with v1 fallback for backwards compatibility.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
22
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.fromInvoice = fromInvoice;
26
+ exports.fromSettlement = fromSettlement;
27
+ exports.fromWebhookEvent = fromWebhookEvent;
28
+ // Re-export types and constants for consumers
29
+ __exportStar(require("./constants"), exports);
30
+ __exportStar(require("./types"), exports);
31
+ __exportStar(require("./helpers"), exports);
32
+ const helpers_1 = require("./helpers");
33
+ /**
34
+ * Build aggregator and splits from x402 invoice metadata
35
+ *
36
+ * Mapping rules:
37
+ * - aggregator: Set when invoice has platform/aggregator in metadata
38
+ * - Pattern: "x402:{serviceName}" (e.g., "x402:load", "x402:tollbit")
39
+ * - splits: Mapped from explicit split data, or single merchant split if aggregator known
40
+ * - If no split data and no aggregator -> undefined
41
+ *
42
+ * @param invoice - x402 invoice
43
+ * @param resolvedDialect - Resolved dialect
44
+ * @returns Object with optional aggregator and splits
45
+ */
46
+ function buildAggregatorAndSplits(invoice, resolvedDialect) {
47
+ // Only attempt aggregator/splits for v2 (v1 has no such concept)
48
+ if (resolvedDialect === 'v1') {
49
+ return {};
50
+ }
51
+ let aggregator;
52
+ let splits;
53
+ // Detect aggregator from invoice metadata or known patterns
54
+ const meta = invoice.metadata;
55
+ if (meta?.aggregator && typeof meta.aggregator === 'string') {
56
+ aggregator = `x402:${meta.aggregator}`;
57
+ }
58
+ else if (meta?.platform && typeof meta.platform === 'string') {
59
+ aggregator = `x402:${meta.platform}`;
60
+ }
61
+ // Build splits if we have explicit split data
62
+ if (meta?.splits && Array.isArray(meta.splits)) {
63
+ const rawSplits = meta.splits;
64
+ splits = rawSplits
65
+ .map((s) => {
66
+ const party = s.party;
67
+ const amount = s.amount;
68
+ const share = s.share;
69
+ // Validate: party required, at least one of amount/share
70
+ if (!party || (amount === undefined && share === undefined)) {
71
+ return null;
72
+ }
73
+ const split = { party };
74
+ if (amount !== undefined)
75
+ split.amount = amount;
76
+ if (share !== undefined)
77
+ split.share = share;
78
+ if (s.currency)
79
+ split.currency = s.currency;
80
+ if (s.rail)
81
+ split.rail = s.rail;
82
+ if (s.account_ref)
83
+ split.account_ref = s.account_ref;
84
+ return split;
85
+ })
86
+ .filter((s) => s !== null);
87
+ // If no valid splits after filtering, set to undefined
88
+ if (splits.length === 0) {
89
+ splits = undefined;
90
+ }
91
+ }
92
+ else if (aggregator) {
93
+ // Single split for merchant when aggregator is known but no explicit splits
94
+ splits = [{ party: 'merchant', share: 1.0 }];
95
+ }
96
+ return { aggregator, splits };
97
+ }
98
+ /**
99
+ * Map x402 payTo.mode to PaymentEvidence.routing
100
+ *
101
+ * @param payToMode - x402 payTo mode value
102
+ * @returns Valid routing value or undefined
103
+ */
104
+ function mapRouting(payToMode) {
105
+ if (payToMode === 'direct' || payToMode === 'callback' || payToMode === 'role') {
106
+ return payToMode;
107
+ }
108
+ return undefined;
109
+ }
110
+ /**
111
+ * Normalize x402 invoice to PEAC PaymentEvidence
112
+ *
113
+ * Supports both v1 and v2 x402 formats. Default is auto-detection.
114
+ *
115
+ * @param invoice - x402 invoice object
116
+ * @param env - Environment ('live' or 'test')
117
+ * @param dialect - x402 dialect ('v1', 'v2', or 'auto')
118
+ * @returns Normalized PaymentEvidence
119
+ */
120
+ function fromInvoice(invoice, env = 'live', dialect = 'auto') {
121
+ // Validate required fields
122
+ if (!invoice.id) {
123
+ throw new Error('x402 invoice missing id');
124
+ }
125
+ if (typeof invoice.amount !== 'number' || invoice.amount < 0) {
126
+ throw new Error('x402 invoice invalid amount');
127
+ }
128
+ if (!invoice.currency || !/^[A-Z]{3}$/.test(invoice.currency)) {
129
+ throw new Error('x402 invoice invalid currency (must be uppercase ISO 4217)');
130
+ }
131
+ // Resolve dialect
132
+ const resolvedDialect = (0, helpers_1.resolveDialectFromInvoice)(invoice, dialect);
133
+ // Normalize network (canonical ID, not label)
134
+ const network = (0, helpers_1.normalizeNetworkId)(invoice.network);
135
+ // Build x402-specific evidence (namespaced, not top-level)
136
+ const evidence = {
137
+ invoice_id: invoice.id,
138
+ dialect: resolvedDialect,
139
+ };
140
+ // Add network label for human readability
141
+ const networkLabel = (0, helpers_1.getNetworkLabel)(network);
142
+ if (networkLabel) {
143
+ evidence.network_label = networkLabel;
144
+ }
145
+ // Add optional fields
146
+ if (invoice.session_id) {
147
+ evidence.session_id = invoice.session_id;
148
+ }
149
+ if (invoice.invoice_url) {
150
+ evidence.invoice_url = invoice.invoice_url;
151
+ }
152
+ if (invoice.memo) {
153
+ evidence.memo = invoice.memo;
154
+ }
155
+ if (invoice.metadata) {
156
+ evidence.metadata = invoice.metadata;
157
+ }
158
+ // v2: Add payTo if present
159
+ if (invoice.payTo) {
160
+ evidence.pay_to = invoice.payTo;
161
+ }
162
+ // Build aggregator and splits (v2 only)
163
+ const { aggregator, splits } = buildAggregatorAndSplits(invoice, resolvedDialect);
164
+ // Map routing from payTo.mode
165
+ const routing = mapRouting(invoice.payTo?.mode);
166
+ // Build PaymentEvidence
167
+ const result = {
168
+ rail: 'x402',
169
+ reference: invoice.id,
170
+ amount: invoice.amount,
171
+ currency: invoice.currency,
172
+ asset: invoice.currency,
173
+ env,
174
+ network,
175
+ evidence,
176
+ };
177
+ // Add optional top-level fields
178
+ if (aggregator) {
179
+ result.aggregator = aggregator;
180
+ }
181
+ if (splits) {
182
+ result.splits = splits;
183
+ }
184
+ if (routing) {
185
+ result.routing = routing;
186
+ }
187
+ return result;
188
+ }
189
+ /**
190
+ * Normalize x402 settlement to PEAC PaymentEvidence
191
+ *
192
+ * @param settlement - x402 settlement object
193
+ * @param env - Environment ('live' or 'test')
194
+ * @param dialect - x402 dialect ('v1', 'v2', or 'auto')
195
+ * @returns Normalized PaymentEvidence
196
+ */
197
+ function fromSettlement(settlement, env = 'live', dialect = 'auto') {
198
+ // Validate required fields
199
+ if (!settlement.id) {
200
+ throw new Error('x402 settlement missing id');
201
+ }
202
+ if (!settlement.invoice_id) {
203
+ throw new Error('x402 settlement missing invoice_id');
204
+ }
205
+ if (typeof settlement.amount !== 'number' || settlement.amount < 0) {
206
+ throw new Error('x402 settlement invalid amount');
207
+ }
208
+ if (!settlement.currency || !/^[A-Z]{3}$/.test(settlement.currency)) {
209
+ throw new Error('x402 settlement invalid currency (must be uppercase ISO 4217)');
210
+ }
211
+ // Resolve dialect (simplified for settlements - check network field)
212
+ const resolvedDialect = dialect !== 'auto' ? dialect : settlement.network?.includes(':') ? 'v2' : 'v1';
213
+ // Normalize network
214
+ const network = (0, helpers_1.normalizeNetworkId)(settlement.network);
215
+ // Build x402-specific evidence
216
+ const evidence = {
217
+ invoice_id: settlement.invoice_id,
218
+ settlement_id: settlement.id,
219
+ dialect: resolvedDialect,
220
+ };
221
+ // Add network label
222
+ const networkLabel = (0, helpers_1.getNetworkLabel)(network);
223
+ if (networkLabel) {
224
+ evidence.network_label = networkLabel;
225
+ }
226
+ // Add optional fields
227
+ if (settlement.settled_at) {
228
+ evidence.settled_at = settlement.settled_at;
229
+ }
230
+ if (settlement.metadata) {
231
+ evidence.metadata = settlement.metadata;
232
+ }
233
+ return {
234
+ rail: 'x402',
235
+ reference: settlement.invoice_id,
236
+ amount: settlement.amount,
237
+ currency: settlement.currency,
238
+ asset: settlement.currency,
239
+ env,
240
+ network,
241
+ evidence,
242
+ };
243
+ }
244
+ /**
245
+ * Normalize x402 webhook event to PEAC PaymentEvidence
246
+ *
247
+ * Supports:
248
+ * - invoice.paid
249
+ * - settlement.completed
250
+ *
251
+ * Dialect is auto-detected from headers if provided.
252
+ *
253
+ * @param event - x402 webhook event
254
+ * @param env - Environment ('live' or 'test')
255
+ * @param headers - HTTP response headers (optional, for dialect detection)
256
+ * @returns Normalized PaymentEvidence
257
+ */
258
+ function fromWebhookEvent(event, env = 'live', headers) {
259
+ const obj = event.data.object;
260
+ // Detect dialect from headers if provided
261
+ const dialect = headers ? (0, helpers_1.detectDialect)(headers) : 'auto';
262
+ // Determine object type by presence of fields
263
+ if ('invoice_id' in obj && ('settled_at' in obj || 'settlement_id' in obj)) {
264
+ // Settlement
265
+ return fromSettlement(obj, env, dialect);
266
+ }
267
+ else if ('amount' in obj && 'id' in obj) {
268
+ // Invoice
269
+ return fromInvoice(obj, env, dialect);
270
+ }
271
+ throw new Error(`Unsupported x402 webhook event type: ${event.type}`);
272
+ }
273
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * x402 type definitions
3
+ *
4
+ * Supports both v1 and v2 x402 protocol formats.
5
+ */
6
+ /**
7
+ * x402 payTo metadata (v2 only)
8
+ *
9
+ * Describes routing information for the payment.
10
+ */
11
+ export interface X402PayTo {
12
+ /** Routing mode: direct, callback, or role-based */
13
+ mode?: 'direct' | 'callback' | 'role';
14
+ /** Callback URL for payment completion (if mode === 'callback') */
15
+ callback_url?: string;
16
+ /** Role identifier (if mode === 'role') */
17
+ role?: string;
18
+ }
19
+ /**
20
+ * x402 Invoice (v1 + v2 compatible)
21
+ *
22
+ * v2 additions: network (CAIP-2), payTo
23
+ */
24
+ export interface X402Invoice {
25
+ /** Invoice identifier */
26
+ id: string;
27
+ /** Amount in smallest currency unit */
28
+ amount: number;
29
+ /** ISO 4217 currency code (uppercase) */
30
+ currency: string;
31
+ /** Session identifier (optional) */
32
+ session_id?: string;
33
+ /** Invoice URL for payment (optional) */
34
+ invoice_url?: string;
35
+ /** Memo/description (optional) */
36
+ memo?: string;
37
+ /** Additional metadata (optional) */
38
+ metadata?: Record<string, unknown>;
39
+ /** Network identifier: CAIP-2 for v2, "lightning" for v1 (optional) */
40
+ network?: string;
41
+ /** Payment routing metadata - v2 only (optional) */
42
+ payTo?: X402PayTo;
43
+ }
44
+ /**
45
+ * x402 Settlement (v1 + v2 compatible)
46
+ */
47
+ export interface X402Settlement {
48
+ /** Settlement identifier */
49
+ id: string;
50
+ /** Associated invoice ID */
51
+ invoice_id: string;
52
+ /** Amount in smallest currency unit */
53
+ amount: number;
54
+ /** ISO 4217 currency code (uppercase) */
55
+ currency: string;
56
+ /** Settlement timestamp (ISO 8601) */
57
+ settled_at?: string;
58
+ /** Additional metadata (optional) */
59
+ metadata?: Record<string, unknown>;
60
+ /** Network identifier: CAIP-2 for v2, "lightning" for v1 (optional) */
61
+ network?: string;
62
+ }
63
+ /**
64
+ * x402 Webhook event payload
65
+ */
66
+ export interface X402WebhookEvent {
67
+ /** Event type (e.g., "invoice.paid", "settlement.completed") */
68
+ type: string;
69
+ /** Event data */
70
+ data: {
71
+ object: X402Invoice | X402Settlement;
72
+ };
73
+ }
74
+ /**
75
+ * x402-specific evidence structure (inside PaymentEvidence.evidence)
76
+ *
77
+ * This is namespaced inside the opaque evidence field, not at the top level.
78
+ */
79
+ export interface X402Evidence {
80
+ /** Invoice ID */
81
+ invoice_id: string;
82
+ /** Which x402 dialect was used */
83
+ dialect: 'v1' | 'v2';
84
+ /** Human-readable network label (e.g., "Base", "Solana") */
85
+ network_label?: string;
86
+ /** x402 v2 payTo object (preserved as-is from invoice) */
87
+ pay_to?: X402PayTo;
88
+ /** Session ID (optional) */
89
+ session_id?: string;
90
+ /** Invoice URL (optional) */
91
+ invoice_url?: string;
92
+ /** Memo (optional) */
93
+ memo?: string;
94
+ /** Settlement ID (for settlements) */
95
+ settlement_id?: string;
96
+ /** Settled at timestamp (for settlements) */
97
+ settled_at?: string;
98
+ /** User-provided metadata */
99
+ metadata?: Record<string, unknown>;
100
+ }
101
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,oDAAoD;IACpD,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IACtC,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGnC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAGnC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,IAAI,EAAE;QACJ,MAAM,EAAE,WAAW,GAAG,cAAc,CAAC;KACtC,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,iBAAiB;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,OAAO,EAAE,IAAI,GAAG,IAAI,CAAC;IACrB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sBAAsB;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * x402 type definitions
4
+ *
5
+ * Supports both v1 and v2 x402 protocol formats.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;GAIG"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@peac/rails-x402",
3
+ "version": "0.9.18",
4
+ "description": "x402 payment rail adapter for PEAC protocol",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/peacprotocol/peac.git",
10
+ "directory": "packages/rails/x402"
11
+ },
12
+ "author": "jithinraj <7850727+jithinraj@users.noreply.github.com>",
13
+ "license": "Apache-2.0",
14
+ "bugs": {
15
+ "url": "https://github.com/peacprotocol/peac/issues"
16
+ },
17
+ "homepage": "https://github.com/peacprotocol/peac#readme",
18
+ "files": [
19
+ "dist",
20
+ "README.md"
21
+ ],
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest",
29
+ "clean": "rm -rf dist"
30
+ },
31
+ "dependencies": {
32
+ "@peac/schema": "workspace:*"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.10.0",
36
+ "typescript": "^5.3.3",
37
+ "vitest": "^1.1.0"
38
+ }
39
+ }