@perkos/service-x402 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ import { Address, X402VerifyRequest, VerifyResponse, PaymentPayload, PaymentRequirements } from '@perkos/types-x402';
2
+ export { Address, DeferredPayload, ExactPayload, Hex, PaymentPayload, PaymentRequirements, SettleResponse, VerifyResponse, Voucher, X402SettleRequest, X402VerifyRequest } from '@perkos/types-x402';
3
+ import { SupportedNetwork } from '@perkos/util-chains';
4
+ export { SUPPORTED_NETWORKS, SupportedNetwork, getChainIdFromNetwork } from '@perkos/util-chains';
5
+ import { ExactSchemeVerifier } from '@perkos/scheme-exact';
6
+ export { ExactSchemeVerifier, createEIP712Domain as createExactEIP712Domain, generateNonce, parseSignature as parseExactSignature } from '@perkos/scheme-exact';
7
+ import { DeferredSchemeVerifier } from '@perkos/scheme-deferred';
8
+ export { DeferredSchemeVerifier, createEIP712Domain as createDeferredEIP712Domain, createVoucherMessage, createVoucherTuple, generateVoucherId, parseSignature as parseDeferredSignature } from '@perkos/scheme-deferred';
9
+
10
+ /**
11
+ * @perkos/service-x402
12
+ * Unified x402 payment protocol verification and settlement service
13
+ */
14
+
15
+ interface X402ServiceConfig {
16
+ /** Default network to use */
17
+ defaultNetwork?: SupportedNetwork;
18
+ /** RPC URL overrides by network */
19
+ rpcUrls?: Partial<Record<SupportedNetwork, string>>;
20
+ /** Enable deferred scheme */
21
+ deferredEnabled?: boolean;
22
+ /** Escrow addresses for deferred scheme by network */
23
+ escrowAddresses?: Partial<Record<SupportedNetwork, Address>>;
24
+ /** Token name overrides for exact scheme (by chainId) */
25
+ tokenNames?: Record<number, string>;
26
+ /** Token version overrides for exact scheme (by chainId) */
27
+ tokenVersions?: Record<number, string>;
28
+ }
29
+ interface SupportedResponse {
30
+ kinds: Array<{
31
+ scheme: "exact" | "deferred";
32
+ network: SupportedNetwork;
33
+ }>;
34
+ }
35
+ declare class X402Service {
36
+ private config;
37
+ private exactSchemes;
38
+ private deferredSchemes;
39
+ constructor(config?: X402ServiceConfig);
40
+ /**
41
+ * Convert CAIP-2 network format to legacy format
42
+ */
43
+ caip2ToLegacy(caip2: string): SupportedNetwork | null;
44
+ /**
45
+ * Convert legacy network format to CAIP-2 format
46
+ */
47
+ legacyToCaip2(network: SupportedNetwork): string | null;
48
+ /**
49
+ * Normalize network format (CAIP-2 or legacy) to legacy format
50
+ */
51
+ normalizeNetwork(network: string): SupportedNetwork | null;
52
+ /**
53
+ * Verify payment payload
54
+ */
55
+ verify(request: X402VerifyRequest): Promise<VerifyResponse>;
56
+ /**
57
+ * Verify payment without full request wrapper
58
+ */
59
+ verifyPayload(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
60
+ /**
61
+ * Get supported schemes and networks
62
+ */
63
+ getSupported(): SupportedResponse;
64
+ /**
65
+ * Check if a network is supported
66
+ */
67
+ isNetworkSupported(network: string): boolean;
68
+ /**
69
+ * Check if deferred scheme is enabled for a network
70
+ */
71
+ isDeferredEnabled(network: string): boolean;
72
+ /**
73
+ * Get exact scheme verifier for network
74
+ */
75
+ getExactScheme(network: SupportedNetwork): ExactSchemeVerifier | undefined;
76
+ /**
77
+ * Get deferred scheme verifier for network
78
+ */
79
+ getDeferredScheme(network: SupportedNetwork): DeferredSchemeVerifier | undefined;
80
+ /**
81
+ * Get default network
82
+ */
83
+ getDefaultNetwork(): SupportedNetwork;
84
+ }
85
+ /**
86
+ * Create a new X402 service instance
87
+ */
88
+ declare function createX402Service(config?: X402ServiceConfig): X402Service;
89
+ /**
90
+ * Create a minimal X402 service for verification only (no deferred scheme)
91
+ */
92
+ declare function createVerificationService(networks?: SupportedNetwork[], rpcUrls?: Partial<Record<SupportedNetwork, string>>): X402Service;
93
+
94
+ export { type SupportedResponse, X402Service, type X402ServiceConfig, createVerificationService, createX402Service };
@@ -0,0 +1,94 @@
1
+ import { Address, X402VerifyRequest, VerifyResponse, PaymentPayload, PaymentRequirements } from '@perkos/types-x402';
2
+ export { Address, DeferredPayload, ExactPayload, Hex, PaymentPayload, PaymentRequirements, SettleResponse, VerifyResponse, Voucher, X402SettleRequest, X402VerifyRequest } from '@perkos/types-x402';
3
+ import { SupportedNetwork } from '@perkos/util-chains';
4
+ export { SUPPORTED_NETWORKS, SupportedNetwork, getChainIdFromNetwork } from '@perkos/util-chains';
5
+ import { ExactSchemeVerifier } from '@perkos/scheme-exact';
6
+ export { ExactSchemeVerifier, createEIP712Domain as createExactEIP712Domain, generateNonce, parseSignature as parseExactSignature } from '@perkos/scheme-exact';
7
+ import { DeferredSchemeVerifier } from '@perkos/scheme-deferred';
8
+ export { DeferredSchemeVerifier, createEIP712Domain as createDeferredEIP712Domain, createVoucherMessage, createVoucherTuple, generateVoucherId, parseSignature as parseDeferredSignature } from '@perkos/scheme-deferred';
9
+
10
+ /**
11
+ * @perkos/service-x402
12
+ * Unified x402 payment protocol verification and settlement service
13
+ */
14
+
15
+ interface X402ServiceConfig {
16
+ /** Default network to use */
17
+ defaultNetwork?: SupportedNetwork;
18
+ /** RPC URL overrides by network */
19
+ rpcUrls?: Partial<Record<SupportedNetwork, string>>;
20
+ /** Enable deferred scheme */
21
+ deferredEnabled?: boolean;
22
+ /** Escrow addresses for deferred scheme by network */
23
+ escrowAddresses?: Partial<Record<SupportedNetwork, Address>>;
24
+ /** Token name overrides for exact scheme (by chainId) */
25
+ tokenNames?: Record<number, string>;
26
+ /** Token version overrides for exact scheme (by chainId) */
27
+ tokenVersions?: Record<number, string>;
28
+ }
29
+ interface SupportedResponse {
30
+ kinds: Array<{
31
+ scheme: "exact" | "deferred";
32
+ network: SupportedNetwork;
33
+ }>;
34
+ }
35
+ declare class X402Service {
36
+ private config;
37
+ private exactSchemes;
38
+ private deferredSchemes;
39
+ constructor(config?: X402ServiceConfig);
40
+ /**
41
+ * Convert CAIP-2 network format to legacy format
42
+ */
43
+ caip2ToLegacy(caip2: string): SupportedNetwork | null;
44
+ /**
45
+ * Convert legacy network format to CAIP-2 format
46
+ */
47
+ legacyToCaip2(network: SupportedNetwork): string | null;
48
+ /**
49
+ * Normalize network format (CAIP-2 or legacy) to legacy format
50
+ */
51
+ normalizeNetwork(network: string): SupportedNetwork | null;
52
+ /**
53
+ * Verify payment payload
54
+ */
55
+ verify(request: X402VerifyRequest): Promise<VerifyResponse>;
56
+ /**
57
+ * Verify payment without full request wrapper
58
+ */
59
+ verifyPayload(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
60
+ /**
61
+ * Get supported schemes and networks
62
+ */
63
+ getSupported(): SupportedResponse;
64
+ /**
65
+ * Check if a network is supported
66
+ */
67
+ isNetworkSupported(network: string): boolean;
68
+ /**
69
+ * Check if deferred scheme is enabled for a network
70
+ */
71
+ isDeferredEnabled(network: string): boolean;
72
+ /**
73
+ * Get exact scheme verifier for network
74
+ */
75
+ getExactScheme(network: SupportedNetwork): ExactSchemeVerifier | undefined;
76
+ /**
77
+ * Get deferred scheme verifier for network
78
+ */
79
+ getDeferredScheme(network: SupportedNetwork): DeferredSchemeVerifier | undefined;
80
+ /**
81
+ * Get default network
82
+ */
83
+ getDefaultNetwork(): SupportedNetwork;
84
+ }
85
+ /**
86
+ * Create a new X402 service instance
87
+ */
88
+ declare function createX402Service(config?: X402ServiceConfig): X402Service;
89
+ /**
90
+ * Create a minimal X402 service for verification only (no deferred scheme)
91
+ */
92
+ declare function createVerificationService(networks?: SupportedNetwork[], rpcUrls?: Partial<Record<SupportedNetwork, string>>): X402Service;
93
+
94
+ export { type SupportedResponse, X402Service, type X402ServiceConfig, createVerificationService, createX402Service };
package/dist/index.js ADDED
@@ -0,0 +1,301 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DeferredSchemeVerifier: () => import_scheme_deferred2.DeferredSchemeVerifier,
24
+ ExactSchemeVerifier: () => import_scheme_exact2.ExactSchemeVerifier,
25
+ SUPPORTED_NETWORKS: () => import_util_chains2.SUPPORTED_NETWORKS,
26
+ X402Service: () => X402Service,
27
+ createDeferredEIP712Domain: () => import_scheme_deferred2.createEIP712Domain,
28
+ createExactEIP712Domain: () => import_scheme_exact2.createEIP712Domain,
29
+ createVerificationService: () => createVerificationService,
30
+ createVoucherMessage: () => import_scheme_deferred2.createVoucherMessage,
31
+ createVoucherTuple: () => import_scheme_deferred2.createVoucherTuple,
32
+ createX402Service: () => createX402Service,
33
+ generateNonce: () => import_scheme_exact2.generateNonce,
34
+ generateVoucherId: () => import_scheme_deferred2.generateVoucherId,
35
+ getChainIdFromNetwork: () => import_util_chains2.getChainIdFromNetwork,
36
+ parseDeferredSignature: () => import_scheme_deferred2.parseSignature,
37
+ parseExactSignature: () => import_scheme_exact2.parseSignature
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+ var import_util_chains = require("@perkos/util-chains");
41
+ var import_scheme_exact = require("@perkos/scheme-exact");
42
+ var import_scheme_deferred = require("@perkos/scheme-deferred");
43
+ var import_util_chains2 = require("@perkos/util-chains");
44
+ var import_scheme_exact2 = require("@perkos/scheme-exact");
45
+ var import_scheme_deferred2 = require("@perkos/scheme-deferred");
46
+ var CAIP2_TO_LEGACY = {
47
+ // Avalanche
48
+ "eip155:43114": "avalanche",
49
+ "eip155:43113": "avalanche-fuji",
50
+ // Celo
51
+ "eip155:42220": "celo",
52
+ "eip155:11142220": "celo-sepolia",
53
+ // Base
54
+ "eip155:8453": "base",
55
+ "eip155:84532": "base-sepolia",
56
+ // Ethereum
57
+ "eip155:1": "ethereum",
58
+ "eip155:11155111": "sepolia",
59
+ // Polygon
60
+ "eip155:137": "polygon",
61
+ "eip155:80002": "polygon-amoy",
62
+ // Monad
63
+ "eip155:10142": "monad",
64
+ "eip155:10143": "monad-testnet",
65
+ // Arbitrum
66
+ "eip155:42161": "arbitrum",
67
+ "eip155:421614": "arbitrum-sepolia",
68
+ // Optimism
69
+ "eip155:10": "optimism",
70
+ "eip155:11155420": "optimism-sepolia"
71
+ };
72
+ var LEGACY_TO_CAIP2 = Object.fromEntries(
73
+ Object.entries(CAIP2_TO_LEGACY).map(([k, v]) => [v, k])
74
+ );
75
+ var X402Service = class {
76
+ constructor(config = {}) {
77
+ this.exactSchemes = /* @__PURE__ */ new Map();
78
+ this.deferredSchemes = /* @__PURE__ */ new Map();
79
+ this.config = {
80
+ defaultNetwork: "base-sepolia",
81
+ deferredEnabled: false,
82
+ ...config
83
+ };
84
+ for (const network of import_util_chains.SUPPORTED_NETWORKS) {
85
+ const chainId = (0, import_util_chains.getChainIdFromNetwork)(network);
86
+ if (chainId) {
87
+ this.exactSchemes.set(
88
+ network,
89
+ new import_scheme_exact.ExactSchemeVerifier({
90
+ network,
91
+ rpcUrl: this.config.rpcUrls?.[network],
92
+ tokenName: chainId ? this.config.tokenNames?.[chainId] : void 0,
93
+ tokenVersion: chainId ? this.config.tokenVersions?.[chainId] : void 0
94
+ })
95
+ );
96
+ }
97
+ }
98
+ if (this.config.deferredEnabled && this.config.escrowAddresses) {
99
+ for (const [network, escrowAddress] of Object.entries(this.config.escrowAddresses)) {
100
+ if (escrowAddress && import_util_chains.SUPPORTED_NETWORKS.includes(network)) {
101
+ try {
102
+ this.deferredSchemes.set(
103
+ network,
104
+ new import_scheme_deferred.DeferredSchemeVerifier({
105
+ network,
106
+ escrowAddress,
107
+ rpcUrl: this.config.rpcUrls?.[network]
108
+ })
109
+ );
110
+ } catch {
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
116
+ /**
117
+ * Convert CAIP-2 network format to legacy format
118
+ */
119
+ caip2ToLegacy(caip2) {
120
+ return CAIP2_TO_LEGACY[caip2] || null;
121
+ }
122
+ /**
123
+ * Convert legacy network format to CAIP-2 format
124
+ */
125
+ legacyToCaip2(network) {
126
+ return LEGACY_TO_CAIP2[network] || null;
127
+ }
128
+ /**
129
+ * Normalize network format (CAIP-2 or legacy) to legacy format
130
+ */
131
+ normalizeNetwork(network) {
132
+ if (import_util_chains.SUPPORTED_NETWORKS.includes(network)) {
133
+ return network;
134
+ }
135
+ if (network.includes(":")) {
136
+ return this.caip2ToLegacy(network);
137
+ }
138
+ return null;
139
+ }
140
+ /**
141
+ * Verify payment payload
142
+ */
143
+ async verify(request) {
144
+ const { paymentPayload, paymentRequirements } = request;
145
+ const isV1 = request.x402Version === 1 && paymentPayload.x402Version === 1;
146
+ const isV2 = request.x402Version === 2 && paymentPayload.x402Version === 2;
147
+ if (!isV1 && !isV2) {
148
+ return {
149
+ isValid: false,
150
+ invalidReason: `Unsupported x402 version. Expected 1 or 2, got ${request.x402Version} (payload: ${paymentPayload.x402Version})`,
151
+ payer: null
152
+ };
153
+ }
154
+ const normalizedPayloadNetwork = this.normalizeNetwork(paymentPayload.network);
155
+ const normalizedRequirementsNetwork = this.normalizeNetwork(paymentRequirements.network);
156
+ if (!normalizedPayloadNetwork) {
157
+ return {
158
+ isValid: false,
159
+ invalidReason: `Unsupported network: ${paymentPayload.network}`,
160
+ payer: null
161
+ };
162
+ }
163
+ if (!normalizedRequirementsNetwork) {
164
+ return {
165
+ isValid: false,
166
+ invalidReason: `Unsupported network: ${paymentRequirements.network}`,
167
+ payer: null
168
+ };
169
+ }
170
+ if (normalizedPayloadNetwork !== normalizedRequirementsNetwork) {
171
+ return {
172
+ isValid: false,
173
+ invalidReason: `Network mismatch between payload (${paymentPayload.network}) and requirements (${paymentRequirements.network})`,
174
+ payer: null
175
+ };
176
+ }
177
+ if (paymentPayload.scheme !== paymentRequirements.scheme) {
178
+ return {
179
+ isValid: false,
180
+ invalidReason: "Scheme mismatch",
181
+ payer: null
182
+ };
183
+ }
184
+ const network = normalizedPayloadNetwork;
185
+ if (paymentPayload.scheme === "exact") {
186
+ const exactScheme = this.exactSchemes.get(network);
187
+ if (!exactScheme) {
188
+ return {
189
+ isValid: false,
190
+ invalidReason: `Exact scheme not initialized for network: ${network}`,
191
+ payer: null
192
+ };
193
+ }
194
+ return exactScheme.verify(
195
+ paymentPayload.payload,
196
+ paymentRequirements
197
+ );
198
+ } else if (paymentPayload.scheme === "deferred") {
199
+ const deferredScheme = this.deferredSchemes.get(network);
200
+ if (!deferredScheme) {
201
+ return {
202
+ isValid: false,
203
+ invalidReason: `Deferred scheme not enabled for network: ${network}`,
204
+ payer: null
205
+ };
206
+ }
207
+ return deferredScheme.verify(
208
+ paymentPayload.payload,
209
+ paymentRequirements
210
+ );
211
+ } else {
212
+ return {
213
+ isValid: false,
214
+ invalidReason: `Unsupported scheme: ${paymentPayload.scheme}`,
215
+ payer: null
216
+ };
217
+ }
218
+ }
219
+ /**
220
+ * Verify payment without full request wrapper
221
+ */
222
+ async verifyPayload(payload, requirements) {
223
+ return this.verify({
224
+ x402Version: payload.x402Version,
225
+ paymentPayload: payload,
226
+ paymentRequirements: requirements
227
+ });
228
+ }
229
+ /**
230
+ * Get supported schemes and networks
231
+ */
232
+ getSupported() {
233
+ const kinds = [];
234
+ for (const network of this.exactSchemes.keys()) {
235
+ kinds.push({ scheme: "exact", network });
236
+ }
237
+ for (const network of this.deferredSchemes.keys()) {
238
+ kinds.push({ scheme: "deferred", network });
239
+ }
240
+ return { kinds };
241
+ }
242
+ /**
243
+ * Check if a network is supported
244
+ */
245
+ isNetworkSupported(network) {
246
+ const normalized = this.normalizeNetwork(network);
247
+ return normalized !== null && this.exactSchemes.has(normalized);
248
+ }
249
+ /**
250
+ * Check if deferred scheme is enabled for a network
251
+ */
252
+ isDeferredEnabled(network) {
253
+ const normalized = this.normalizeNetwork(network);
254
+ return normalized !== null && this.deferredSchemes.has(normalized);
255
+ }
256
+ /**
257
+ * Get exact scheme verifier for network
258
+ */
259
+ getExactScheme(network) {
260
+ return this.exactSchemes.get(network);
261
+ }
262
+ /**
263
+ * Get deferred scheme verifier for network
264
+ */
265
+ getDeferredScheme(network) {
266
+ return this.deferredSchemes.get(network);
267
+ }
268
+ /**
269
+ * Get default network
270
+ */
271
+ getDefaultNetwork() {
272
+ return this.config.defaultNetwork || "base-sepolia";
273
+ }
274
+ };
275
+ function createX402Service(config) {
276
+ return new X402Service(config);
277
+ }
278
+ function createVerificationService(networks, rpcUrls) {
279
+ return new X402Service({
280
+ deferredEnabled: false,
281
+ rpcUrls
282
+ });
283
+ }
284
+ // Annotate the CommonJS export names for ESM import in node:
285
+ 0 && (module.exports = {
286
+ DeferredSchemeVerifier,
287
+ ExactSchemeVerifier,
288
+ SUPPORTED_NETWORKS,
289
+ X402Service,
290
+ createDeferredEIP712Domain,
291
+ createExactEIP712Domain,
292
+ createVerificationService,
293
+ createVoucherMessage,
294
+ createVoucherTuple,
295
+ createX402Service,
296
+ generateNonce,
297
+ generateVoucherId,
298
+ getChainIdFromNetwork,
299
+ parseDeferredSignature,
300
+ parseExactSignature
301
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,280 @@
1
+ // src/index.ts
2
+ import {
3
+ SUPPORTED_NETWORKS,
4
+ getChainIdFromNetwork
5
+ } from "@perkos/util-chains";
6
+ import { ExactSchemeVerifier } from "@perkos/scheme-exact";
7
+ import { DeferredSchemeVerifier } from "@perkos/scheme-deferred";
8
+ import {
9
+ SUPPORTED_NETWORKS as SUPPORTED_NETWORKS2,
10
+ getChainIdFromNetwork as getChainIdFromNetwork2
11
+ } from "@perkos/util-chains";
12
+ import {
13
+ ExactSchemeVerifier as ExactSchemeVerifier2,
14
+ parseSignature,
15
+ createEIP712Domain,
16
+ generateNonce
17
+ } from "@perkos/scheme-exact";
18
+ import {
19
+ DeferredSchemeVerifier as DeferredSchemeVerifier2,
20
+ parseSignature as parseSignature2,
21
+ createEIP712Domain as createEIP712Domain2,
22
+ generateVoucherId,
23
+ createVoucherMessage,
24
+ createVoucherTuple
25
+ } from "@perkos/scheme-deferred";
26
+ var CAIP2_TO_LEGACY = {
27
+ // Avalanche
28
+ "eip155:43114": "avalanche",
29
+ "eip155:43113": "avalanche-fuji",
30
+ // Celo
31
+ "eip155:42220": "celo",
32
+ "eip155:11142220": "celo-sepolia",
33
+ // Base
34
+ "eip155:8453": "base",
35
+ "eip155:84532": "base-sepolia",
36
+ // Ethereum
37
+ "eip155:1": "ethereum",
38
+ "eip155:11155111": "sepolia",
39
+ // Polygon
40
+ "eip155:137": "polygon",
41
+ "eip155:80002": "polygon-amoy",
42
+ // Monad
43
+ "eip155:10142": "monad",
44
+ "eip155:10143": "monad-testnet",
45
+ // Arbitrum
46
+ "eip155:42161": "arbitrum",
47
+ "eip155:421614": "arbitrum-sepolia",
48
+ // Optimism
49
+ "eip155:10": "optimism",
50
+ "eip155:11155420": "optimism-sepolia"
51
+ };
52
+ var LEGACY_TO_CAIP2 = Object.fromEntries(
53
+ Object.entries(CAIP2_TO_LEGACY).map(([k, v]) => [v, k])
54
+ );
55
+ var X402Service = class {
56
+ constructor(config = {}) {
57
+ this.exactSchemes = /* @__PURE__ */ new Map();
58
+ this.deferredSchemes = /* @__PURE__ */ new Map();
59
+ this.config = {
60
+ defaultNetwork: "base-sepolia",
61
+ deferredEnabled: false,
62
+ ...config
63
+ };
64
+ for (const network of SUPPORTED_NETWORKS) {
65
+ const chainId = getChainIdFromNetwork(network);
66
+ if (chainId) {
67
+ this.exactSchemes.set(
68
+ network,
69
+ new ExactSchemeVerifier({
70
+ network,
71
+ rpcUrl: this.config.rpcUrls?.[network],
72
+ tokenName: chainId ? this.config.tokenNames?.[chainId] : void 0,
73
+ tokenVersion: chainId ? this.config.tokenVersions?.[chainId] : void 0
74
+ })
75
+ );
76
+ }
77
+ }
78
+ if (this.config.deferredEnabled && this.config.escrowAddresses) {
79
+ for (const [network, escrowAddress] of Object.entries(this.config.escrowAddresses)) {
80
+ if (escrowAddress && SUPPORTED_NETWORKS.includes(network)) {
81
+ try {
82
+ this.deferredSchemes.set(
83
+ network,
84
+ new DeferredSchemeVerifier({
85
+ network,
86
+ escrowAddress,
87
+ rpcUrl: this.config.rpcUrls?.[network]
88
+ })
89
+ );
90
+ } catch {
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ /**
97
+ * Convert CAIP-2 network format to legacy format
98
+ */
99
+ caip2ToLegacy(caip2) {
100
+ return CAIP2_TO_LEGACY[caip2] || null;
101
+ }
102
+ /**
103
+ * Convert legacy network format to CAIP-2 format
104
+ */
105
+ legacyToCaip2(network) {
106
+ return LEGACY_TO_CAIP2[network] || null;
107
+ }
108
+ /**
109
+ * Normalize network format (CAIP-2 or legacy) to legacy format
110
+ */
111
+ normalizeNetwork(network) {
112
+ if (SUPPORTED_NETWORKS.includes(network)) {
113
+ return network;
114
+ }
115
+ if (network.includes(":")) {
116
+ return this.caip2ToLegacy(network);
117
+ }
118
+ return null;
119
+ }
120
+ /**
121
+ * Verify payment payload
122
+ */
123
+ async verify(request) {
124
+ const { paymentPayload, paymentRequirements } = request;
125
+ const isV1 = request.x402Version === 1 && paymentPayload.x402Version === 1;
126
+ const isV2 = request.x402Version === 2 && paymentPayload.x402Version === 2;
127
+ if (!isV1 && !isV2) {
128
+ return {
129
+ isValid: false,
130
+ invalidReason: `Unsupported x402 version. Expected 1 or 2, got ${request.x402Version} (payload: ${paymentPayload.x402Version})`,
131
+ payer: null
132
+ };
133
+ }
134
+ const normalizedPayloadNetwork = this.normalizeNetwork(paymentPayload.network);
135
+ const normalizedRequirementsNetwork = this.normalizeNetwork(paymentRequirements.network);
136
+ if (!normalizedPayloadNetwork) {
137
+ return {
138
+ isValid: false,
139
+ invalidReason: `Unsupported network: ${paymentPayload.network}`,
140
+ payer: null
141
+ };
142
+ }
143
+ if (!normalizedRequirementsNetwork) {
144
+ return {
145
+ isValid: false,
146
+ invalidReason: `Unsupported network: ${paymentRequirements.network}`,
147
+ payer: null
148
+ };
149
+ }
150
+ if (normalizedPayloadNetwork !== normalizedRequirementsNetwork) {
151
+ return {
152
+ isValid: false,
153
+ invalidReason: `Network mismatch between payload (${paymentPayload.network}) and requirements (${paymentRequirements.network})`,
154
+ payer: null
155
+ };
156
+ }
157
+ if (paymentPayload.scheme !== paymentRequirements.scheme) {
158
+ return {
159
+ isValid: false,
160
+ invalidReason: "Scheme mismatch",
161
+ payer: null
162
+ };
163
+ }
164
+ const network = normalizedPayloadNetwork;
165
+ if (paymentPayload.scheme === "exact") {
166
+ const exactScheme = this.exactSchemes.get(network);
167
+ if (!exactScheme) {
168
+ return {
169
+ isValid: false,
170
+ invalidReason: `Exact scheme not initialized for network: ${network}`,
171
+ payer: null
172
+ };
173
+ }
174
+ return exactScheme.verify(
175
+ paymentPayload.payload,
176
+ paymentRequirements
177
+ );
178
+ } else if (paymentPayload.scheme === "deferred") {
179
+ const deferredScheme = this.deferredSchemes.get(network);
180
+ if (!deferredScheme) {
181
+ return {
182
+ isValid: false,
183
+ invalidReason: `Deferred scheme not enabled for network: ${network}`,
184
+ payer: null
185
+ };
186
+ }
187
+ return deferredScheme.verify(
188
+ paymentPayload.payload,
189
+ paymentRequirements
190
+ );
191
+ } else {
192
+ return {
193
+ isValid: false,
194
+ invalidReason: `Unsupported scheme: ${paymentPayload.scheme}`,
195
+ payer: null
196
+ };
197
+ }
198
+ }
199
+ /**
200
+ * Verify payment without full request wrapper
201
+ */
202
+ async verifyPayload(payload, requirements) {
203
+ return this.verify({
204
+ x402Version: payload.x402Version,
205
+ paymentPayload: payload,
206
+ paymentRequirements: requirements
207
+ });
208
+ }
209
+ /**
210
+ * Get supported schemes and networks
211
+ */
212
+ getSupported() {
213
+ const kinds = [];
214
+ for (const network of this.exactSchemes.keys()) {
215
+ kinds.push({ scheme: "exact", network });
216
+ }
217
+ for (const network of this.deferredSchemes.keys()) {
218
+ kinds.push({ scheme: "deferred", network });
219
+ }
220
+ return { kinds };
221
+ }
222
+ /**
223
+ * Check if a network is supported
224
+ */
225
+ isNetworkSupported(network) {
226
+ const normalized = this.normalizeNetwork(network);
227
+ return normalized !== null && this.exactSchemes.has(normalized);
228
+ }
229
+ /**
230
+ * Check if deferred scheme is enabled for a network
231
+ */
232
+ isDeferredEnabled(network) {
233
+ const normalized = this.normalizeNetwork(network);
234
+ return normalized !== null && this.deferredSchemes.has(normalized);
235
+ }
236
+ /**
237
+ * Get exact scheme verifier for network
238
+ */
239
+ getExactScheme(network) {
240
+ return this.exactSchemes.get(network);
241
+ }
242
+ /**
243
+ * Get deferred scheme verifier for network
244
+ */
245
+ getDeferredScheme(network) {
246
+ return this.deferredSchemes.get(network);
247
+ }
248
+ /**
249
+ * Get default network
250
+ */
251
+ getDefaultNetwork() {
252
+ return this.config.defaultNetwork || "base-sepolia";
253
+ }
254
+ };
255
+ function createX402Service(config) {
256
+ return new X402Service(config);
257
+ }
258
+ function createVerificationService(networks, rpcUrls) {
259
+ return new X402Service({
260
+ deferredEnabled: false,
261
+ rpcUrls
262
+ });
263
+ }
264
+ export {
265
+ DeferredSchemeVerifier2 as DeferredSchemeVerifier,
266
+ ExactSchemeVerifier2 as ExactSchemeVerifier,
267
+ SUPPORTED_NETWORKS2 as SUPPORTED_NETWORKS,
268
+ X402Service,
269
+ createEIP712Domain2 as createDeferredEIP712Domain,
270
+ createEIP712Domain as createExactEIP712Domain,
271
+ createVerificationService,
272
+ createVoucherMessage,
273
+ createVoucherTuple,
274
+ createX402Service,
275
+ generateNonce,
276
+ generateVoucherId,
277
+ getChainIdFromNetwork2 as getChainIdFromNetwork,
278
+ parseSignature2 as parseDeferredSignature,
279
+ parseSignature as parseExactSignature
280
+ };
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@perkos/service-x402",
3
+ "version": "1.0.0",
4
+ "description": "Unified x402 payment protocol verification and settlement service",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "x402",
24
+ "payment",
25
+ "protocol",
26
+ "verification",
27
+ "settlement",
28
+ "ethereum",
29
+ "web3",
30
+ "crypto"
31
+ ],
32
+ "author": "PerkOS",
33
+ "license": "MIT",
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/PerkOS-xyz/pkg-service-x402"
37
+ },
38
+ "dependencies": {
39
+ "@perkos/types-x402": "^1.0.0",
40
+ "@perkos/util-chains": "^1.0.0",
41
+ "@perkos/scheme-exact": "^1.0.0",
42
+ "@perkos/scheme-deferred": "^1.0.0",
43
+ "viem": "^2.28.2"
44
+ },
45
+ "devDependencies": {
46
+ "tsup": "^8.5.0",
47
+ "typescript": "^5.8.3"
48
+ }
49
+ }