x402z-server 0.0.7 → 0.0.9

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
@@ -8,13 +8,19 @@ Server-side helpers for the erc7984-mind-v1 x402 scheme.
8
8
  pnpm add x402z-server
9
9
  ```
10
10
 
11
+ ## Folder map
12
+
13
+ - `src/http/`: server HTTP helpers
14
+ - `src/scheme/`: scheme implementation + registration
15
+ - `src/index.ts`: public exports
16
+
11
17
  ## Usage
12
18
 
13
19
  ```ts
14
20
  import { createX402zServer } from "x402z-server";
15
- import { createRelayerInstance, SepoliaConfig } from "x402z-shared";
21
+ import { createRelayer, SepoliaConfig } from "x402z-shared";
16
22
 
17
- const relayer = await createRelayerInstance({
23
+ const relayer = await createRelayer({
18
24
  ...SepoliaConfig,
19
25
  network: "https://sepolia.infura.io/v3/...",
20
26
  });
package/dist/index.d.mts CHANGED
@@ -4,9 +4,9 @@ import { x402ResourceServer } from '@x402/core/server';
4
4
  export { x402ResourceServer } from '@x402/core/server';
5
5
  import * as http from 'http';
6
6
  import { RelayerSigner, RelayerInstance } from 'x402z-shared';
7
- export { CompiledRoute, DynamicPayTo, DynamicPrice, FacilitatorClient, FacilitatorConfig, HTTPAdapter, HTTPFacilitatorClient, HTTPProcessResult, HTTPRequestContext, HTTPResponseInstructions, PaymentOption, PaywallConfig, PaywallProvider, ProcessSettleFailureResponse, ProcessSettleResultResponse, ProcessSettleSuccessResponse, RouteConfig, RouteConfigurationError, RouteValidationError, RoutesConfig, UnpaidResponseBody, UnpaidResponseResult, x402HTTPResourceServer } from '@x402/core/http';
7
+ export { CompiledRoute, DynamicPayTo, DynamicPrice, FacilitatorClient, FacilitatorConfig, HTTPAdapter, HTTPFacilitatorClient, HTTPProcessResult, HTTPRequestContext, HTTPResponseInstructions, PaymentOption, PaywallConfig, PaywallProvider, ProcessSettleFailureResponse, ProcessSettleResultResponse, ProcessSettleSuccessResponse, RouteConfigurationError, RouteValidationError, RoutesConfig, UnpaidResponseBody, UnpaidResponseResult, x402HTTPResourceServer } from '@x402/core/http';
8
8
 
9
- type ConfidentialServerNetworkConfig = {
9
+ type X402zServerNetworkOptions = {
10
10
  asset: `0x${string}`;
11
11
  eip712: {
12
12
  name: string;
@@ -16,13 +16,13 @@ type ConfidentialServerNetworkConfig = {
16
16
  resourceHash?: `0x${string}`;
17
17
  batcherAddress: `0x${string}`;
18
18
  };
19
- type ConfidentialServerConfig = ConfidentialServerNetworkConfig | {
20
- getNetworkConfig: (network: Network) => ConfidentialServerNetworkConfig;
19
+ type X402zServerSchemeOptions = X402zServerNetworkOptions | {
20
+ getNetworkConfig: (network: Network) => X402zServerNetworkOptions;
21
21
  };
22
- declare class ConfidentialEvmScheme implements SchemeNetworkServer {
22
+ declare class X402zEvmServerScheme implements SchemeNetworkServer {
23
23
  readonly scheme = "erc7984-mind-v1";
24
24
  private readonly getConfig;
25
- constructor(config: ConfidentialServerConfig);
25
+ constructor(config: X402zServerSchemeOptions);
26
26
  parsePrice(price: Price, network: Network): Promise<AssetAmount>;
27
27
  enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
28
28
  x402Version: number;
@@ -34,12 +34,12 @@ declare class ConfidentialEvmScheme implements SchemeNetworkServer {
34
34
  private convertToTokenAmount;
35
35
  }
36
36
 
37
- type ConfidentialServerRegisterConfig = ConfidentialServerConfig & {
37
+ type X402zServerRegistrationOptions = X402zServerSchemeOptions & {
38
38
  networks?: Network[];
39
39
  };
40
- declare function registerConfidentialEvmScheme(server: x402ResourceServer, config: ConfidentialServerRegisterConfig): x402ResourceServer;
40
+ declare function registerX402zEvmServerScheme(server: x402ResourceServer, config: X402zServerRegistrationOptions): x402ResourceServer;
41
41
 
42
- type X402zRouteConfig = {
42
+ type X402zRouteOptions = {
43
43
  accepts: {
44
44
  payTo: string;
45
45
  price: string;
@@ -57,14 +57,22 @@ type X402zRouteHandler = (args: {
57
57
  headers?: Record<string, string>;
58
58
  body: string;
59
59
  }>;
60
- type X402zServerConfig = ConfidentialServerRegisterConfig & {
60
+ type X402zServerOptions = X402zServerRegistrationOptions & {
61
61
  facilitatorUrl: string;
62
- routes: Record<string, X402zRouteConfig>;
62
+ routes: Record<string, X402zRouteOptions>;
63
63
  onPaid: X402zRouteHandler;
64
64
  signer: RelayerSigner;
65
65
  relayer: RelayerInstance;
66
66
  debug?: boolean;
67
+ cors?: {
68
+ allowOrigin: string;
69
+ allowMethods?: string;
70
+ allowHeaders?: string;
71
+ exposeHeaders?: string;
72
+ allowCredentials?: boolean;
73
+ maxAgeSeconds?: number;
74
+ };
67
75
  };
68
- declare function createX402zServer(config: X402zServerConfig): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
76
+ declare function createX402zServer(config: X402zServerOptions): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
69
77
 
70
- export { ConfidentialEvmScheme, type ConfidentialServerConfig, type ConfidentialServerNetworkConfig, type ConfidentialServerRegisterConfig, type X402zRouteConfig, type X402zRouteHandler, type X402zServerConfig, createX402zServer, registerConfidentialEvmScheme };
78
+ export { X402zEvmServerScheme, type X402zRouteHandler, type X402zRouteOptions, type X402zServerNetworkOptions, type X402zServerOptions, type X402zServerRegistrationOptions, type X402zServerSchemeOptions, createX402zServer, registerX402zEvmServerScheme };
package/dist/index.d.ts CHANGED
@@ -4,9 +4,9 @@ import { x402ResourceServer } from '@x402/core/server';
4
4
  export { x402ResourceServer } from '@x402/core/server';
5
5
  import * as http from 'http';
6
6
  import { RelayerSigner, RelayerInstance } from 'x402z-shared';
7
- export { CompiledRoute, DynamicPayTo, DynamicPrice, FacilitatorClient, FacilitatorConfig, HTTPAdapter, HTTPFacilitatorClient, HTTPProcessResult, HTTPRequestContext, HTTPResponseInstructions, PaymentOption, PaywallConfig, PaywallProvider, ProcessSettleFailureResponse, ProcessSettleResultResponse, ProcessSettleSuccessResponse, RouteConfig, RouteConfigurationError, RouteValidationError, RoutesConfig, UnpaidResponseBody, UnpaidResponseResult, x402HTTPResourceServer } from '@x402/core/http';
7
+ export { CompiledRoute, DynamicPayTo, DynamicPrice, FacilitatorClient, FacilitatorConfig, HTTPAdapter, HTTPFacilitatorClient, HTTPProcessResult, HTTPRequestContext, HTTPResponseInstructions, PaymentOption, PaywallConfig, PaywallProvider, ProcessSettleFailureResponse, ProcessSettleResultResponse, ProcessSettleSuccessResponse, RouteConfigurationError, RouteValidationError, RoutesConfig, UnpaidResponseBody, UnpaidResponseResult, x402HTTPResourceServer } from '@x402/core/http';
8
8
 
9
- type ConfidentialServerNetworkConfig = {
9
+ type X402zServerNetworkOptions = {
10
10
  asset: `0x${string}`;
11
11
  eip712: {
12
12
  name: string;
@@ -16,13 +16,13 @@ type ConfidentialServerNetworkConfig = {
16
16
  resourceHash?: `0x${string}`;
17
17
  batcherAddress: `0x${string}`;
18
18
  };
19
- type ConfidentialServerConfig = ConfidentialServerNetworkConfig | {
20
- getNetworkConfig: (network: Network) => ConfidentialServerNetworkConfig;
19
+ type X402zServerSchemeOptions = X402zServerNetworkOptions | {
20
+ getNetworkConfig: (network: Network) => X402zServerNetworkOptions;
21
21
  };
22
- declare class ConfidentialEvmScheme implements SchemeNetworkServer {
22
+ declare class X402zEvmServerScheme implements SchemeNetworkServer {
23
23
  readonly scheme = "erc7984-mind-v1";
24
24
  private readonly getConfig;
25
- constructor(config: ConfidentialServerConfig);
25
+ constructor(config: X402zServerSchemeOptions);
26
26
  parsePrice(price: Price, network: Network): Promise<AssetAmount>;
27
27
  enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
28
28
  x402Version: number;
@@ -34,12 +34,12 @@ declare class ConfidentialEvmScheme implements SchemeNetworkServer {
34
34
  private convertToTokenAmount;
35
35
  }
36
36
 
37
- type ConfidentialServerRegisterConfig = ConfidentialServerConfig & {
37
+ type X402zServerRegistrationOptions = X402zServerSchemeOptions & {
38
38
  networks?: Network[];
39
39
  };
40
- declare function registerConfidentialEvmScheme(server: x402ResourceServer, config: ConfidentialServerRegisterConfig): x402ResourceServer;
40
+ declare function registerX402zEvmServerScheme(server: x402ResourceServer, config: X402zServerRegistrationOptions): x402ResourceServer;
41
41
 
42
- type X402zRouteConfig = {
42
+ type X402zRouteOptions = {
43
43
  accepts: {
44
44
  payTo: string;
45
45
  price: string;
@@ -57,14 +57,22 @@ type X402zRouteHandler = (args: {
57
57
  headers?: Record<string, string>;
58
58
  body: string;
59
59
  }>;
60
- type X402zServerConfig = ConfidentialServerRegisterConfig & {
60
+ type X402zServerOptions = X402zServerRegistrationOptions & {
61
61
  facilitatorUrl: string;
62
- routes: Record<string, X402zRouteConfig>;
62
+ routes: Record<string, X402zRouteOptions>;
63
63
  onPaid: X402zRouteHandler;
64
64
  signer: RelayerSigner;
65
65
  relayer: RelayerInstance;
66
66
  debug?: boolean;
67
+ cors?: {
68
+ allowOrigin: string;
69
+ allowMethods?: string;
70
+ allowHeaders?: string;
71
+ exposeHeaders?: string;
72
+ allowCredentials?: boolean;
73
+ maxAgeSeconds?: number;
74
+ };
67
75
  };
68
- declare function createX402zServer(config: X402zServerConfig): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
76
+ declare function createX402zServer(config: X402zServerOptions): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
69
77
 
70
- export { ConfidentialEvmScheme, type ConfidentialServerConfig, type ConfidentialServerNetworkConfig, type ConfidentialServerRegisterConfig, type X402zRouteConfig, type X402zRouteHandler, type X402zServerConfig, createX402zServer, registerConfidentialEvmScheme };
78
+ export { X402zEvmServerScheme, type X402zRouteHandler, type X402zRouteOptions, type X402zServerNetworkOptions, type X402zServerOptions, type X402zServerRegistrationOptions, type X402zServerSchemeOptions, createX402zServer, registerX402zEvmServerScheme };
package/dist/index.js CHANGED
@@ -20,17 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- ConfidentialEvmScheme: () => ConfidentialEvmScheme,
24
- HTTPFacilitatorClient: () => import_http4.HTTPFacilitatorClient,
23
+ HTTPFacilitatorClient: () => import_http3.HTTPFacilitatorClient,
24
+ X402zEvmServerScheme: () => X402zEvmServerScheme,
25
25
  createX402zServer: () => createX402zServer,
26
- registerConfidentialEvmScheme: () => registerConfidentialEvmScheme,
27
- x402HTTPResourceServer: () => import_http4.x402HTTPResourceServer,
28
- x402ResourceServer: () => import_server2.x402ResourceServer
26
+ registerX402zEvmServerScheme: () => registerX402zEvmServerScheme,
27
+ x402HTTPResourceServer: () => import_http3.x402HTTPResourceServer,
28
+ x402ResourceServer: () => import_server3.x402ResourceServer
29
29
  });
30
30
  module.exports = __toCommonJS(index_exports);
31
31
 
32
- // src/scheme.ts
33
- var ConfidentialEvmScheme = class {
32
+ // src/scheme/scheme.ts
33
+ var X402zEvmServerScheme = class {
34
34
  constructor(config) {
35
35
  this.scheme = "erc7984-mind-v1";
36
36
  if ("getNetworkConfig" in config) {
@@ -107,19 +107,19 @@ var ConfidentialEvmScheme = class {
107
107
  }
108
108
  };
109
109
 
110
- // src/register.ts
111
- function registerConfidentialEvmScheme(server, config) {
110
+ // src/scheme/register.ts
111
+ function registerX402zEvmServerScheme(server, config) {
112
112
  if ("networks" in config && config.networks && config.networks.length > 0) {
113
113
  for (const network of config.networks) {
114
- server.register(network, new ConfidentialEvmScheme(config));
114
+ server.register(network, new X402zEvmServerScheme(config));
115
115
  }
116
116
  return server;
117
117
  }
118
- server.register("eip155:*", new ConfidentialEvmScheme(config));
118
+ server.register("eip155:*", new X402zEvmServerScheme(config));
119
119
  return server;
120
120
  }
121
121
 
122
- // src/http.ts
122
+ // src/http/server.ts
123
123
  var import_node_http = require("http");
124
124
  var import_node_url = require("url");
125
125
  var import_server = require("@x402/core/server");
@@ -157,7 +157,7 @@ async function createX402zServer(config) {
157
157
  const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
158
158
  const facilitatorClient = new import_http2.HTTPFacilitatorClient({ url: config.facilitatorUrl });
159
159
  const resourceServer = new import_server.x402ResourceServer(facilitatorClient);
160
- registerConfidentialEvmScheme(resourceServer, config);
160
+ registerX402zEvmServerScheme(resourceServer, config);
161
161
  const relayer = config.relayer;
162
162
  const rpcUrl = getRelayerRpcUrl(relayer);
163
163
  const routes = {};
@@ -176,10 +176,29 @@ async function createX402zServer(config) {
176
176
  const adapter = buildAdapter(req);
177
177
  const method = adapter.getMethod();
178
178
  const path = adapter.getPath();
179
- const paymentHeader = adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
179
+ const paymentHeader = adapter.getHeader("payment-signature") ?? adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
180
180
  console.log(`[server] ${method} ${path}`);
181
+ const corsHeaders = config.cors ? {
182
+ "Access-Control-Allow-Origin": config.cors.allowOrigin,
183
+ "Access-Control-Allow-Methods": config.cors.allowMethods ?? "GET,POST,OPTIONS",
184
+ "Access-Control-Allow-Headers": config.cors.allowHeaders ?? "content-type,x402-payment,x-payment,payment-signature",
185
+ "Access-Control-Expose-Headers": config.cors.exposeHeaders ?? "payment-required,payment-signature,x402-payment,x-payment,x-settle,content-type",
186
+ "Access-Control-Max-Age": String(config.cors.maxAgeSeconds ?? 600),
187
+ ...config.cors.allowCredentials ? { "Access-Control-Allow-Credentials": "true" } : {}
188
+ } : {};
189
+ if (method === "OPTIONS") {
190
+ res.writeHead(204, corsHeaders);
191
+ res.end();
192
+ return;
193
+ }
181
194
  if (debugEnabled && paymentHeader) {
182
195
  console.debug("[x402z-server] payment header", paymentHeader);
196
+ try {
197
+ const decoded = (0, import_http.decodePaymentSignatureHeader)(paymentHeader);
198
+ console.debug("[x402z-server] payment payload", decoded);
199
+ } catch (error) {
200
+ console.debug("[x402z-server] payment payload decode failed", error);
201
+ }
183
202
  }
184
203
  const result = await httpServer.processHTTPRequest({
185
204
  adapter,
@@ -187,7 +206,7 @@ async function createX402zServer(config) {
187
206
  method: adapter.getMethod()
188
207
  });
189
208
  if (result.type === "payment-error") {
190
- res.writeHead(result.response.status, result.response.headers);
209
+ res.writeHead(result.response.status, { ...corsHeaders, ...result.response.headers });
191
210
  res.end(result.response.isHtml ? result.response.body : JSON.stringify(result.response.body ?? {}));
192
211
  console.log(`[server] ${method} ${path} -> ${result.response.status}`);
193
212
  return;
@@ -195,7 +214,7 @@ async function createX402zServer(config) {
195
214
  if (result.type === "payment-verified") {
196
215
  const settle = await httpServer.processSettlement(result.paymentPayload, result.paymentRequirements);
197
216
  if (!settle.success) {
198
- res.writeHead(500, { "Content-Type": "application/json" });
217
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
199
218
  res.end(JSON.stringify({ error: settle.errorReason }));
200
219
  console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
201
220
  return;
@@ -213,7 +232,7 @@ async function createX402zServer(config) {
213
232
  });
214
233
  const signerAddress = (0, import_viem.getAddress)(config.signer.address);
215
234
  if (!observer || !(0, import_viem.isAddressEqual)(observer, signerAddress)) {
216
- res.writeHead(500, { "Content-Type": "application/json" });
235
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
217
236
  res.end(JSON.stringify({ error: "observer_required" }));
218
237
  console.log(`[server] ${method} ${path} -> 500 observer_required`);
219
238
  return;
@@ -221,12 +240,12 @@ async function createX402zServer(config) {
221
240
  const batch = settle;
222
241
  const transferredHandle = batch.batch?.transferredHandle;
223
242
  if (!transferredHandle) {
224
- res.writeHead(500, { "Content-Type": "application/json" });
243
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
225
244
  res.end(JSON.stringify({ error: "missing_transferred_handle" }));
226
245
  console.log(`[server] ${method} ${path} -> 500 missing_transferred_handle`);
227
246
  return;
228
247
  }
229
- const decryptedAmount = await (0, import_x402z_shared.userDecryptEuint64)(
248
+ const decryptedAmount = await (0, import_x402z_shared.decryptEuint64)(
230
249
  relayer,
231
250
  transferredHandle,
232
251
  result.paymentRequirements.asset,
@@ -234,13 +253,13 @@ async function createX402zServer(config) {
234
253
  );
235
254
  const expected = BigInt(result.paymentRequirements.amount);
236
255
  if (decryptedAmount !== expected) {
237
- res.writeHead(500, { "Content-Type": "application/json" });
256
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
238
257
  res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
239
258
  console.log(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
240
259
  return;
241
260
  }
242
261
  } catch (error) {
243
- res.writeHead(500, { "Content-Type": "application/json" });
262
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
244
263
  res.end(JSON.stringify({ error: "settlement_verification_failed" }));
245
264
  console.log(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
246
265
  if (debugEnabled) {
@@ -254,6 +273,7 @@ async function createX402zServer(config) {
254
273
  });
255
274
  const status = payload.status ?? 200;
256
275
  const responseHeaders = {
276
+ ...corsHeaders,
257
277
  "Content-Type": "text/plain",
258
278
  ...settle.headers,
259
279
  ...payload.headers ?? {}
@@ -269,21 +289,26 @@ async function createX402zServer(config) {
269
289
  console.log(`[server] ${method} ${path} -> ${status}`);
270
290
  return;
271
291
  }
272
- sendText(res, 200, { "Content-Type": "text/plain" }, "no payment required");
292
+ sendText(
293
+ res,
294
+ 200,
295
+ { ...corsHeaders, "Content-Type": "text/plain" },
296
+ "no payment required"
297
+ );
273
298
  console.log(`[server] ${method} ${path} -> 200`);
274
299
  });
275
300
  return server;
276
301
  }
277
302
 
278
303
  // src/index.ts
279
- var import_server2 = require("@x402/core/server");
280
- var import_http4 = require("@x402/core/http");
304
+ var import_server3 = require("@x402/core/server");
305
+ var import_http3 = require("@x402/core/http");
281
306
  // Annotate the CommonJS export names for ESM import in node:
282
307
  0 && (module.exports = {
283
- ConfidentialEvmScheme,
284
308
  HTTPFacilitatorClient,
309
+ X402zEvmServerScheme,
285
310
  createX402zServer,
286
- registerConfidentialEvmScheme,
311
+ registerX402zEvmServerScheme,
287
312
  x402HTTPResourceServer,
288
313
  x402ResourceServer
289
314
  });
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- // src/scheme.ts
2
- var ConfidentialEvmScheme = class {
1
+ // src/scheme/scheme.ts
2
+ var X402zEvmServerScheme = class {
3
3
  constructor(config) {
4
4
  this.scheme = "erc7984-mind-v1";
5
5
  if ("getNetworkConfig" in config) {
@@ -76,25 +76,25 @@ var ConfidentialEvmScheme = class {
76
76
  }
77
77
  };
78
78
 
79
- // src/register.ts
80
- function registerConfidentialEvmScheme(server, config) {
79
+ // src/scheme/register.ts
80
+ function registerX402zEvmServerScheme(server, config) {
81
81
  if ("networks" in config && config.networks && config.networks.length > 0) {
82
82
  for (const network of config.networks) {
83
- server.register(network, new ConfidentialEvmScheme(config));
83
+ server.register(network, new X402zEvmServerScheme(config));
84
84
  }
85
85
  return server;
86
86
  }
87
- server.register("eip155:*", new ConfidentialEvmScheme(config));
87
+ server.register("eip155:*", new X402zEvmServerScheme(config));
88
88
  return server;
89
89
  }
90
90
 
91
- // src/http.ts
91
+ // src/http/server.ts
92
92
  import { createServer } from "http";
93
93
  import { URL } from "url";
94
94
  import { x402ResourceServer } from "@x402/core/server";
95
- import { x402HTTPResourceServer } from "@x402/core/http";
95
+ import { decodePaymentSignatureHeader, x402HTTPResourceServer } from "@x402/core/http";
96
96
  import { HTTPFacilitatorClient } from "@x402/core/http";
97
- import { confidentialTokenAbi, userDecryptEuint64 } from "x402z-shared";
97
+ import { confidentialTokenAbi, decryptEuint64 } from "x402z-shared";
98
98
  import { createPublicClient, getAddress, http, isAddressEqual } from "viem";
99
99
  function getRelayerRpcUrl(relayer) {
100
100
  const network = relayer.network;
@@ -126,7 +126,7 @@ async function createX402zServer(config) {
126
126
  const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
127
127
  const facilitatorClient = new HTTPFacilitatorClient({ url: config.facilitatorUrl });
128
128
  const resourceServer = new x402ResourceServer(facilitatorClient);
129
- registerConfidentialEvmScheme(resourceServer, config);
129
+ registerX402zEvmServerScheme(resourceServer, config);
130
130
  const relayer = config.relayer;
131
131
  const rpcUrl = getRelayerRpcUrl(relayer);
132
132
  const routes = {};
@@ -145,10 +145,29 @@ async function createX402zServer(config) {
145
145
  const adapter = buildAdapter(req);
146
146
  const method = adapter.getMethod();
147
147
  const path = adapter.getPath();
148
- const paymentHeader = adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
148
+ const paymentHeader = adapter.getHeader("payment-signature") ?? adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
149
149
  console.log(`[server] ${method} ${path}`);
150
+ const corsHeaders = config.cors ? {
151
+ "Access-Control-Allow-Origin": config.cors.allowOrigin,
152
+ "Access-Control-Allow-Methods": config.cors.allowMethods ?? "GET,POST,OPTIONS",
153
+ "Access-Control-Allow-Headers": config.cors.allowHeaders ?? "content-type,x402-payment,x-payment,payment-signature",
154
+ "Access-Control-Expose-Headers": config.cors.exposeHeaders ?? "payment-required,payment-signature,x402-payment,x-payment,x-settle,content-type",
155
+ "Access-Control-Max-Age": String(config.cors.maxAgeSeconds ?? 600),
156
+ ...config.cors.allowCredentials ? { "Access-Control-Allow-Credentials": "true" } : {}
157
+ } : {};
158
+ if (method === "OPTIONS") {
159
+ res.writeHead(204, corsHeaders);
160
+ res.end();
161
+ return;
162
+ }
150
163
  if (debugEnabled && paymentHeader) {
151
164
  console.debug("[x402z-server] payment header", paymentHeader);
165
+ try {
166
+ const decoded = decodePaymentSignatureHeader(paymentHeader);
167
+ console.debug("[x402z-server] payment payload", decoded);
168
+ } catch (error) {
169
+ console.debug("[x402z-server] payment payload decode failed", error);
170
+ }
152
171
  }
153
172
  const result = await httpServer.processHTTPRequest({
154
173
  adapter,
@@ -156,7 +175,7 @@ async function createX402zServer(config) {
156
175
  method: adapter.getMethod()
157
176
  });
158
177
  if (result.type === "payment-error") {
159
- res.writeHead(result.response.status, result.response.headers);
178
+ res.writeHead(result.response.status, { ...corsHeaders, ...result.response.headers });
160
179
  res.end(result.response.isHtml ? result.response.body : JSON.stringify(result.response.body ?? {}));
161
180
  console.log(`[server] ${method} ${path} -> ${result.response.status}`);
162
181
  return;
@@ -164,7 +183,7 @@ async function createX402zServer(config) {
164
183
  if (result.type === "payment-verified") {
165
184
  const settle = await httpServer.processSettlement(result.paymentPayload, result.paymentRequirements);
166
185
  if (!settle.success) {
167
- res.writeHead(500, { "Content-Type": "application/json" });
186
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
168
187
  res.end(JSON.stringify({ error: settle.errorReason }));
169
188
  console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
170
189
  return;
@@ -182,7 +201,7 @@ async function createX402zServer(config) {
182
201
  });
183
202
  const signerAddress = getAddress(config.signer.address);
184
203
  if (!observer || !isAddressEqual(observer, signerAddress)) {
185
- res.writeHead(500, { "Content-Type": "application/json" });
204
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
186
205
  res.end(JSON.stringify({ error: "observer_required" }));
187
206
  console.log(`[server] ${method} ${path} -> 500 observer_required`);
188
207
  return;
@@ -190,12 +209,12 @@ async function createX402zServer(config) {
190
209
  const batch = settle;
191
210
  const transferredHandle = batch.batch?.transferredHandle;
192
211
  if (!transferredHandle) {
193
- res.writeHead(500, { "Content-Type": "application/json" });
212
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
194
213
  res.end(JSON.stringify({ error: "missing_transferred_handle" }));
195
214
  console.log(`[server] ${method} ${path} -> 500 missing_transferred_handle`);
196
215
  return;
197
216
  }
198
- const decryptedAmount = await userDecryptEuint64(
217
+ const decryptedAmount = await decryptEuint64(
199
218
  relayer,
200
219
  transferredHandle,
201
220
  result.paymentRequirements.asset,
@@ -203,13 +222,13 @@ async function createX402zServer(config) {
203
222
  );
204
223
  const expected = BigInt(result.paymentRequirements.amount);
205
224
  if (decryptedAmount !== expected) {
206
- res.writeHead(500, { "Content-Type": "application/json" });
225
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
207
226
  res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
208
227
  console.log(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
209
228
  return;
210
229
  }
211
230
  } catch (error) {
212
- res.writeHead(500, { "Content-Type": "application/json" });
231
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
213
232
  res.end(JSON.stringify({ error: "settlement_verification_failed" }));
214
233
  console.log(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
215
234
  if (debugEnabled) {
@@ -223,6 +242,7 @@ async function createX402zServer(config) {
223
242
  });
224
243
  const status = payload.status ?? 200;
225
244
  const responseHeaders = {
245
+ ...corsHeaders,
226
246
  "Content-Type": "text/plain",
227
247
  ...settle.headers,
228
248
  ...payload.headers ?? {}
@@ -238,7 +258,12 @@ async function createX402zServer(config) {
238
258
  console.log(`[server] ${method} ${path} -> ${status}`);
239
259
  return;
240
260
  }
241
- sendText(res, 200, { "Content-Type": "text/plain" }, "no payment required");
261
+ sendText(
262
+ res,
263
+ 200,
264
+ { ...corsHeaders, "Content-Type": "text/plain" },
265
+ "no payment required"
266
+ );
242
267
  console.log(`[server] ${method} ${path} -> 200`);
243
268
  });
244
269
  return server;
@@ -251,10 +276,10 @@ import {
251
276
  x402HTTPResourceServer as x402HTTPResourceServer2
252
277
  } from "@x402/core/http";
253
278
  export {
254
- ConfidentialEvmScheme,
255
279
  HTTPFacilitatorClient2 as HTTPFacilitatorClient,
280
+ X402zEvmServerScheme,
256
281
  createX402zServer,
257
- registerConfidentialEvmScheme,
282
+ registerX402zEvmServerScheme,
258
283
  x402HTTPResourceServer2 as x402HTTPResourceServer,
259
284
  x402ResourceServer2 as x402ResourceServer
260
285
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x402z-server",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -10,7 +10,7 @@
10
10
  "dependencies": {
11
11
  "@x402/core": "^2.0.0",
12
12
  "viem": "^2.43.3",
13
- "x402z-shared": "0.0.7"
13
+ "x402z-shared": "0.0.9"
14
14
  },
15
15
  "devDependencies": {
16
16
  "jest": "^29.7.0",