x402z-server 0.0.19 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # x402z-server
2
2
 
3
- Server-side helpers for the erc7984-mind-v1 x402 scheme.
3
+ Server-side helpers for erc7984-mind-v1 and exact x402 schemes.
4
4
 
5
5
  ## Install
6
6
 
@@ -27,20 +27,25 @@ const relayer = await createRelayer({
27
27
 
28
28
  const server = await createX402zServer({
29
29
  facilitatorUrl: "http://localhost:8040",
30
- asset: "0xToken",
31
- eip712: { name: "FHEToken Confidential", version: "1" },
32
- decimals: 6,
33
- batcherAddress: "0xBatcher",
34
- signer: { address, signTypedData },
35
- relayer,
30
+ confidential: {
31
+ asset: "0xToken",
32
+ eip712: { name: "FHEToken Confidential", version: "1" },
33
+ decimals: 6,
34
+ batcherAddress: "0xBatcher",
35
+ signer: { address, signTypedData },
36
+ relayer,
37
+ },
36
38
  routes: {
37
39
  "GET /demo": {
38
- accepts: {
39
- payTo: "0xPayTo",
40
- price: "1.0",
41
- network: "eip155:11155111",
42
- maxTimeoutSeconds: 300,
43
- },
40
+ accepts: [
41
+ {
42
+ scheme: "erc7984-mind-v1",
43
+ payTo: "0xPayTo",
44
+ price: "1.0",
45
+ network: "eip155:11155111",
46
+ maxTimeoutSeconds: 300,
47
+ },
48
+ ],
44
49
  description: "Demo content",
45
50
  mimeType: "text/plain",
46
51
  },
@@ -57,9 +62,10 @@ server.listen(8080);
57
62
 
58
63
  - `createX402zServer(config)`
59
64
  - `facilitatorUrl` (required): HTTP facilitator endpoint
60
- - `asset`, `eip712`, `decimals`, `batcherAddress`: scheme config
61
- - `signer` (required): signer used to decrypt transfer amounts
62
- - `relayer` (required): FHEVM relayer instance used for decryption
65
+ - `confidential` (optional): confidential scheme config (required if any route uses `erc7984-mind-v1`)
66
+ - `confidential.signer`: signer used to decrypt transfer amounts
67
+ - `confidential.relayer`: FHEVM relayer instance used for decryption
68
+ - `confidential.asset`, `confidential.eip712`, `confidential.decimals`, `confidential.batcherAddress`: optional overrides; when omitted, defaults are pulled from the facilitator `/supported` response
63
69
  - `routes`: map of `METHOD /path` to payment requirements
64
70
  - `onPaid`: handler for successful payment (returns response body + optional headers)
65
71
 
@@ -67,9 +73,37 @@ server.listen(8080);
67
73
 
68
74
  See `examples/README.md` for the full-process server + facilitator setup.
69
75
 
76
+ ## Exact scheme (ERC20) usage
77
+
78
+ ```ts
79
+ import { createX402zServer } from "x402z-server";
80
+
81
+ const server = await createX402zServer({
82
+ facilitatorUrl: "http://localhost:8040",
83
+ routes: {
84
+ "GET /erc20-demo": {
85
+ accepts: [
86
+ {
87
+ scheme: "exact",
88
+ payTo: "0xYourAddress",
89
+ price: "$0.01",
90
+ network: "eip155:84532",
91
+ },
92
+ ],
93
+ description: "Exact USDC payment demo",
94
+ mimeType: "text/plain",
95
+ },
96
+ },
97
+ onPaid: async () => ({ body: "paid content" }),
98
+ });
99
+
100
+ server.listen(8090);
101
+ ```
102
+
70
103
  ## Notes
71
104
 
72
- - Scheme name: `erc7984-mind-v1`
105
+ - Confidential scheme name: `erc7984-mind-v1`
106
+ - Exact scheme name: `exact`
73
107
  - `confidential.batcherAddress` is required in requirements; clients bind encrypted inputs to it.
74
108
 
75
109
  ## API surface
@@ -87,8 +121,10 @@ Types:
87
121
  - `X402zServerNetworkOptions`: network config for the scheme.
88
122
  - `X402zServerRegistrationOptions`: registration options for the scheme.
89
123
  - `X402zRouteOptions`: route config for paywalled endpoints.
124
+ - `X402zRouteAccept`: accept config item for confidential or exact schemes.
90
125
  - `X402zRouteHandler`: handler signature for paid requests.
91
126
  - `X402zServerOptions`: options for `createX402zServer`.
127
+ - `X402zConfidentialServerConfig`: options for confidential server config.
92
128
  - `CompiledRoute`: compiled route metadata.
93
129
  - `DynamicPayTo`: callback for dynamic payee address.
94
130
  - `DynamicPrice`: callback for dynamic pricing.
package/dist/index.d.mts CHANGED
@@ -6,7 +6,10 @@ import * as http from 'http';
6
6
  import { RelayerSigner, RelayerInstance } from 'x402z-shared';
7
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 X402zServerNetworkOptions = {
9
+ type NoScheme$1 = {
10
+ scheme?: never;
11
+ };
12
+ type X402zServerNetworkOptions = NoScheme$1 & {
10
13
  asset: `0x${string}`;
11
14
  eip712: {
12
15
  name: string;
@@ -39,13 +42,24 @@ type X402zServerRegistrationOptions = X402zServerSchemeOptions & {
39
42
  };
40
43
  declare function registerX402zEvmServerScheme(server: x402ResourceServer, config: X402zServerRegistrationOptions): x402ResourceServer;
41
44
 
42
- type X402zRouteOptions = {
43
- accepts: {
44
- payTo: string;
45
- price: string;
46
- network: Network;
47
- maxTimeoutSeconds: number;
48
- };
45
+ type X402zRouteAccept = {
46
+ scheme: "erc7984-mind-v1";
47
+ payTo: string;
48
+ price: string;
49
+ network: Network;
50
+ maxTimeoutSeconds: number;
51
+ } | {
52
+ scheme: "exact";
53
+ payTo: string;
54
+ price: Price;
55
+ network: Network;
56
+ maxTimeoutSeconds?: number;
57
+ };
58
+ type NoScheme = {
59
+ scheme?: never;
60
+ };
61
+ type X402zRouteOptions = NoScheme & {
62
+ accepts: X402zRouteAccept[];
49
63
  description: string;
50
64
  mimeType: string;
51
65
  };
@@ -57,12 +71,8 @@ type X402zRouteHandler = (args: {
57
71
  headers?: Record<string, string>;
58
72
  body: string;
59
73
  }>;
60
- type X402zServerOptions = X402zServerRegistrationOptions & {
74
+ type X402zBaseServerOptions = {
61
75
  facilitatorUrl: string;
62
- routes: Record<string, X402zRouteOptions>;
63
- onPaid: X402zRouteHandler;
64
- signer: RelayerSigner;
65
- relayer: RelayerInstance;
66
76
  debug?: boolean;
67
77
  cors?: {
68
78
  allowOrigin: string;
@@ -73,6 +83,25 @@ type X402zServerOptions = X402zServerRegistrationOptions & {
73
83
  maxAgeSeconds?: number;
74
84
  };
75
85
  };
86
+ type X402zConfidentialServerConfig = {
87
+ getNetworkConfig?: (network: Network) => X402zServerNetworkOptions;
88
+ networks?: Network[];
89
+ asset?: `0x${string}`;
90
+ eip712?: {
91
+ name: string;
92
+ version: string;
93
+ };
94
+ decimals?: number;
95
+ resourceHash?: `0x${string}`;
96
+ batcherAddress?: `0x${string}`;
97
+ signer: RelayerSigner;
98
+ relayer: RelayerInstance;
99
+ } & NoScheme;
100
+ type X402zServerOptions = X402zBaseServerOptions & {
101
+ routes: Record<string, X402zRouteOptions>;
102
+ onPaid: X402zRouteHandler;
103
+ confidential?: X402zConfidentialServerConfig;
104
+ } & NoScheme;
76
105
  declare function createX402zServer(config: X402zServerOptions): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
77
106
 
78
- export { X402zEvmServerScheme, type X402zRouteHandler, type X402zRouteOptions, type X402zServerNetworkOptions, type X402zServerOptions, type X402zServerRegistrationOptions, type X402zServerSchemeOptions, createX402zServer, registerX402zEvmServerScheme };
107
+ export { type X402zConfidentialServerConfig, X402zEvmServerScheme, type X402zRouteAccept, type X402zRouteHandler, type X402zRouteOptions, type X402zServerNetworkOptions, type X402zServerOptions, type X402zServerRegistrationOptions, type X402zServerSchemeOptions, createX402zServer, registerX402zEvmServerScheme };
package/dist/index.d.ts CHANGED
@@ -6,7 +6,10 @@ import * as http from 'http';
6
6
  import { RelayerSigner, RelayerInstance } from 'x402z-shared';
7
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 X402zServerNetworkOptions = {
9
+ type NoScheme$1 = {
10
+ scheme?: never;
11
+ };
12
+ type X402zServerNetworkOptions = NoScheme$1 & {
10
13
  asset: `0x${string}`;
11
14
  eip712: {
12
15
  name: string;
@@ -39,13 +42,24 @@ type X402zServerRegistrationOptions = X402zServerSchemeOptions & {
39
42
  };
40
43
  declare function registerX402zEvmServerScheme(server: x402ResourceServer, config: X402zServerRegistrationOptions): x402ResourceServer;
41
44
 
42
- type X402zRouteOptions = {
43
- accepts: {
44
- payTo: string;
45
- price: string;
46
- network: Network;
47
- maxTimeoutSeconds: number;
48
- };
45
+ type X402zRouteAccept = {
46
+ scheme: "erc7984-mind-v1";
47
+ payTo: string;
48
+ price: string;
49
+ network: Network;
50
+ maxTimeoutSeconds: number;
51
+ } | {
52
+ scheme: "exact";
53
+ payTo: string;
54
+ price: Price;
55
+ network: Network;
56
+ maxTimeoutSeconds?: number;
57
+ };
58
+ type NoScheme = {
59
+ scheme?: never;
60
+ };
61
+ type X402zRouteOptions = NoScheme & {
62
+ accepts: X402zRouteAccept[];
49
63
  description: string;
50
64
  mimeType: string;
51
65
  };
@@ -57,12 +71,8 @@ type X402zRouteHandler = (args: {
57
71
  headers?: Record<string, string>;
58
72
  body: string;
59
73
  }>;
60
- type X402zServerOptions = X402zServerRegistrationOptions & {
74
+ type X402zBaseServerOptions = {
61
75
  facilitatorUrl: string;
62
- routes: Record<string, X402zRouteOptions>;
63
- onPaid: X402zRouteHandler;
64
- signer: RelayerSigner;
65
- relayer: RelayerInstance;
66
76
  debug?: boolean;
67
77
  cors?: {
68
78
  allowOrigin: string;
@@ -73,6 +83,25 @@ type X402zServerOptions = X402zServerRegistrationOptions & {
73
83
  maxAgeSeconds?: number;
74
84
  };
75
85
  };
86
+ type X402zConfidentialServerConfig = {
87
+ getNetworkConfig?: (network: Network) => X402zServerNetworkOptions;
88
+ networks?: Network[];
89
+ asset?: `0x${string}`;
90
+ eip712?: {
91
+ name: string;
92
+ version: string;
93
+ };
94
+ decimals?: number;
95
+ resourceHash?: `0x${string}`;
96
+ batcherAddress?: `0x${string}`;
97
+ signer: RelayerSigner;
98
+ relayer: RelayerInstance;
99
+ } & NoScheme;
100
+ type X402zServerOptions = X402zBaseServerOptions & {
101
+ routes: Record<string, X402zRouteOptions>;
102
+ onPaid: X402zRouteHandler;
103
+ confidential?: X402zConfidentialServerConfig;
104
+ } & NoScheme;
76
105
  declare function createX402zServer(config: X402zServerOptions): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
77
106
 
78
- export { X402zEvmServerScheme, type X402zRouteHandler, type X402zRouteOptions, type X402zServerNetworkOptions, type X402zServerOptions, type X402zServerRegistrationOptions, type X402zServerSchemeOptions, createX402zServer, registerX402zEvmServerScheme };
107
+ export { type X402zConfidentialServerConfig, X402zEvmServerScheme, type X402zRouteAccept, type X402zRouteHandler, type X402zRouteOptions, type X402zServerNetworkOptions, type X402zServerOptions, type X402zServerRegistrationOptions, type X402zServerSchemeOptions, createX402zServer, registerX402zEvmServerScheme };
package/dist/index.js CHANGED
@@ -20,12 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- HTTPFacilitatorClient: () => import_http3.HTTPFacilitatorClient,
23
+ HTTPFacilitatorClient: () => import_http2.HTTPFacilitatorClient,
24
24
  X402zEvmServerScheme: () => X402zEvmServerScheme,
25
25
  createX402zServer: () => createX402zServer,
26
26
  registerX402zEvmServerScheme: () => registerX402zEvmServerScheme,
27
- x402HTTPResourceServer: () => import_http3.x402HTTPResourceServer,
28
- x402ResourceServer: () => import_server3.x402ResourceServer
27
+ x402HTTPResourceServer: () => import_http2.x402HTTPResourceServer,
28
+ x402ResourceServer: () => import_server4.x402ResourceServer
29
29
  });
30
30
  module.exports = __toCommonJS(index_exports);
31
31
 
@@ -124,9 +124,9 @@ var import_node_http = require("http");
124
124
  var import_node_url = require("url");
125
125
  var import_server = require("@x402/core/server");
126
126
  var import_http = require("@x402/core/http");
127
- var import_http2 = require("@x402/core/http");
128
127
  var import_x402z_shared = require("x402z-shared");
129
128
  var import_viem = require("viem");
129
+ var import_server2 = require("@x402/evm/exact/server");
130
130
  function getRelayerRpcUrl(relayer) {
131
131
  const network = relayer.network;
132
132
  if (typeof network === "string") {
@@ -150,24 +150,181 @@ function buildAdapter(req) {
150
150
  };
151
151
  }
152
152
  function sendText(res, status, headers, body) {
153
- res.writeHead(status, headers);
153
+ res.writeHead(status, void 0, headers);
154
154
  res.end(body);
155
155
  }
156
+ async function fetchSupported(facilitatorUrl, fetchFn) {
157
+ const base = facilitatorUrl.replace(/\/$/, "");
158
+ const response = await fetchFn(`${base}/supported`);
159
+ if (!response.ok) {
160
+ throw new Error(`Failed to fetch supported schemes: ${response.status}`);
161
+ }
162
+ return response.json();
163
+ }
164
+ function normalizeExactDefaults(extra) {
165
+ const exact = extra?.exact ?? null;
166
+ if (!exact?.asset) {
167
+ return null;
168
+ }
169
+ const name = exact.eip712?.name ?? exact.name;
170
+ const version = exact.eip712?.version ?? exact.version;
171
+ if (!name || !version) {
172
+ return null;
173
+ }
174
+ return {
175
+ asset: exact.asset,
176
+ decimals: exact.decimals ?? 6,
177
+ name,
178
+ version
179
+ };
180
+ }
181
+ function normalizeConfidentialDefaults(extra) {
182
+ const confidential = extra?.confidential ?? null;
183
+ if (!confidential?.asset || !confidential.eip712?.name || !confidential.eip712?.version) {
184
+ return null;
185
+ }
186
+ if (!confidential.batcherAddress) {
187
+ return null;
188
+ }
189
+ return {
190
+ asset: confidential.asset,
191
+ eip712: {
192
+ name: confidential.eip712.name,
193
+ version: confidential.eip712.version
194
+ },
195
+ decimals: confidential.decimals ?? 6,
196
+ batcherAddress: confidential.batcherAddress,
197
+ resourceHash: confidential.resourceHash
198
+ };
199
+ }
200
+ function parseMoneyToDecimal(money) {
201
+ if (typeof money === "number") {
202
+ return money;
203
+ }
204
+ if (typeof money !== "string") {
205
+ throw new Error("Invalid price type for exact scheme");
206
+ }
207
+ const clean = money.replace(/^\$/, "").trim();
208
+ const amount = Number.parseFloat(clean);
209
+ if (Number.isNaN(amount)) {
210
+ throw new Error(`Invalid money format: ${money}`);
211
+ }
212
+ return amount;
213
+ }
214
+ function convertToTokenAmount(amount, decimals) {
215
+ const [intPart, decPart = ""] = String(amount).split(".");
216
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
217
+ return (intPart + paddedDec).replace(/^0+/, "") || "0";
218
+ }
156
219
  async function createX402zServer(config) {
157
220
  const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
158
- const facilitatorClient = new import_http2.HTTPFacilitatorClient({ url: config.facilitatorUrl });
221
+ const fetchFn = globalThis.fetch;
222
+ const facilitatorClient = new import_http.HTTPFacilitatorClient({ url: config.facilitatorUrl });
159
223
  const resourceServer = new import_server.x402ResourceServer(facilitatorClient);
160
- registerX402zEvmServerScheme(resourceServer, config);
161
- const relayer = config.relayer;
162
- const rpcUrl = getRelayerRpcUrl(relayer);
224
+ const wantsExact = Object.values(config.routes).some(
225
+ (route) => route.accepts.some((accept) => accept.scheme === "exact")
226
+ );
227
+ const wantsConfidential = Object.values(config.routes).some(
228
+ (route) => route.accepts.some((accept) => accept.scheme === "erc7984-mind-v1")
229
+ );
230
+ const confidentialConfig = config.confidential;
231
+ if (wantsConfidential && !confidentialConfig) {
232
+ throw new Error("confidential config is required when using erc7984-mind-v1 routes");
233
+ }
234
+ const needsExactDefaults = Object.values(config.routes).some(
235
+ (route) => route.accepts.some((accept) => accept.scheme === "exact" && typeof accept.price !== "object")
236
+ );
237
+ let supportedExactDefaults = {};
238
+ if (wantsExact && needsExactDefaults) {
239
+ if (!fetchFn) {
240
+ throw new Error("fetch is required to load exact defaults from facilitator");
241
+ }
242
+ const supported = await fetchSupported(config.facilitatorUrl, fetchFn);
243
+ for (const kind of supported.kinds ?? []) {
244
+ if (kind.scheme !== "exact") continue;
245
+ const normalized = normalizeExactDefaults(kind.extra);
246
+ if (normalized) {
247
+ supportedExactDefaults[kind.network] = normalized;
248
+ }
249
+ }
250
+ }
251
+ if (wantsConfidential && confidentialConfig) {
252
+ let supportedDefaults = {};
253
+ const needsSupportedDefaults = !confidentialConfig.getNetworkConfig && (!confidentialConfig.asset || !confidentialConfig.eip712 || !confidentialConfig.batcherAddress);
254
+ if (needsSupportedDefaults) {
255
+ if (!fetchFn) {
256
+ throw new Error("fetch is required to load confidential defaults from facilitator");
257
+ }
258
+ const supported = await fetchSupported(config.facilitatorUrl, fetchFn);
259
+ for (const kind of supported.kinds ?? []) {
260
+ if (kind.scheme !== "erc7984-mind-v1") continue;
261
+ const normalized = normalizeConfidentialDefaults(kind.extra);
262
+ if (normalized) {
263
+ supportedDefaults[kind.network] = normalized;
264
+ }
265
+ }
266
+ }
267
+ const getNetworkConfig = confidentialConfig.getNetworkConfig ?? ((network) => {
268
+ const base = supportedDefaults[network] ?? {};
269
+ const override = {
270
+ asset: confidentialConfig.asset,
271
+ eip712: confidentialConfig.eip712,
272
+ decimals: confidentialConfig.decimals,
273
+ resourceHash: confidentialConfig.resourceHash,
274
+ batcherAddress: confidentialConfig.batcherAddress
275
+ };
276
+ const merged = {
277
+ ...base,
278
+ ...Object.fromEntries(Object.entries(override).filter(([, value]) => value !== void 0))
279
+ };
280
+ if (!merged.decimals) {
281
+ merged.decimals = 6;
282
+ }
283
+ if (!merged.asset || !merged.eip712?.name || !merged.eip712?.version || !merged.batcherAddress) {
284
+ throw new Error(`Missing confidential defaults for network ${network}`);
285
+ }
286
+ return merged;
287
+ });
288
+ registerX402zEvmServerScheme(resourceServer, {
289
+ getNetworkConfig,
290
+ networks: confidentialConfig.networks
291
+ });
292
+ }
293
+ if (wantsExact) {
294
+ (0, import_server2.registerExactEvmScheme)(resourceServer, {});
295
+ }
296
+ const relayer = confidentialConfig?.relayer;
297
+ const rpcUrl = relayer ? getRelayerRpcUrl(relayer) : null;
163
298
  const routes = {};
164
299
  for (const [path, route] of Object.entries(config.routes)) {
300
+ const accepts = route.accepts.map((accept) => {
301
+ if (accept.scheme !== "exact") {
302
+ return accept;
303
+ }
304
+ if (typeof accept.price === "object") {
305
+ return accept;
306
+ }
307
+ const defaults = supportedExactDefaults[accept.network];
308
+ if (!defaults) {
309
+ throw new Error(`Missing exact defaults for network ${accept.network}`);
310
+ }
311
+ const decimalAmount = parseMoneyToDecimal(accept.price);
312
+ const amount = convertToTokenAmount(decimalAmount, defaults.decimals);
313
+ return {
314
+ ...accept,
315
+ price: {
316
+ amount,
317
+ asset: defaults.asset,
318
+ extra: {
319
+ name: defaults.name,
320
+ version: defaults.version
321
+ }
322
+ }
323
+ };
324
+ });
165
325
  routes[path] = {
166
326
  ...route,
167
- accepts: {
168
- ...route.accepts,
169
- scheme: "erc7984-mind-v1"
170
- }
327
+ accepts
171
328
  };
172
329
  }
173
330
  const httpServer = new import_http.x402HTTPResourceServer(resourceServer, routes);
@@ -177,7 +334,9 @@ async function createX402zServer(config) {
177
334
  const method = adapter.getMethod();
178
335
  const path = adapter.getPath();
179
336
  const paymentHeader = adapter.getHeader("payment-signature") ?? adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
180
- console.log(`[server] ${method} ${path}`);
337
+ if (debugEnabled) {
338
+ console.debug(`[server] ${method} ${path}`);
339
+ }
181
340
  const corsHeaders = config.cors ? {
182
341
  "Access-Control-Allow-Origin": config.cors.allowOrigin,
183
342
  "Access-Control-Allow-Methods": config.cors.allowMethods ?? "GET,POST,OPTIONS",
@@ -208,7 +367,9 @@ async function createX402zServer(config) {
208
367
  if (result.type === "payment-error") {
209
368
  res.writeHead(result.response.status, { ...corsHeaders, ...result.response.headers });
210
369
  res.end(result.response.isHtml ? result.response.body : JSON.stringify(result.response.body ?? {}));
211
- console.log(`[server] ${method} ${path} -> ${result.response.status}`);
370
+ if (debugEnabled) {
371
+ console.debug(`[server] ${method} ${path} -> ${result.response.status}`);
372
+ }
212
373
  return;
213
374
  }
214
375
  if (result.type === "payment-verified") {
@@ -216,68 +377,91 @@ async function createX402zServer(config) {
216
377
  if (!settle.success) {
217
378
  res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
218
379
  res.end(JSON.stringify({ error: settle.errorReason }));
219
- console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
380
+ if (debugEnabled) {
381
+ console.debug(`[server] ${method} ${path} -> 500 settlement_failed`);
382
+ }
220
383
  return;
221
384
  }
222
- try {
223
- const observerClient = (0, import_viem.createPublicClient)({
224
- transport: (0, import_viem.http)(rpcUrl)
225
- });
226
- const payTo = (0, import_viem.getAddress)(result.paymentRequirements.payTo);
227
- const observer = await observerClient.readContract({
228
- address: (0, import_viem.getAddress)(result.paymentRequirements.asset),
229
- abi: import_x402z_shared.confidentialTokenAbi,
230
- functionName: "observer",
231
- args: [payTo]
232
- });
233
- const signerAddress = (0, import_viem.getAddress)(config.signer.address);
234
- if (!observer || !(0, import_viem.isAddressEqual)(observer, signerAddress)) {
385
+ if (result.paymentRequirements.scheme === "erc7984-mind-v1") {
386
+ try {
387
+ if (!confidentialConfig || !relayer || !rpcUrl) {
388
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
389
+ res.end(JSON.stringify({ error: "confidential_config_missing" }));
390
+ if (debugEnabled) {
391
+ console.debug(`[server] ${method} ${path} -> 500 confidential_config_missing`);
392
+ }
393
+ return;
394
+ }
395
+ const observerClient = (0, import_viem.createPublicClient)({
396
+ transport: (0, import_viem.http)(rpcUrl)
397
+ });
398
+ const payTo = (0, import_viem.getAddress)(result.paymentRequirements.payTo);
399
+ const observer = await observerClient.readContract({
400
+ address: (0, import_viem.getAddress)(result.paymentRequirements.asset),
401
+ abi: import_x402z_shared.confidentialTokenAbi,
402
+ functionName: "observer",
403
+ args: [payTo]
404
+ });
405
+ const signerAddress = (0, import_viem.getAddress)(confidentialConfig.signer.address);
406
+ if (!observer || !(0, import_viem.isAddressEqual)(observer, signerAddress)) {
407
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
408
+ res.end(JSON.stringify({ error: "observer_required" }));
409
+ if (debugEnabled) {
410
+ console.debug(`[server] ${method} ${path} -> 500 observer_required`);
411
+ }
412
+ return;
413
+ }
414
+ const batch = settle;
415
+ const transferredHandle = batch.batch?.transferredHandle;
416
+ if (!transferredHandle) {
417
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
418
+ res.end(JSON.stringify({ error: "missing_transferred_handle" }));
419
+ if (debugEnabled) {
420
+ console.debug(`[server] ${method} ${path} -> 500 missing_transferred_handle`);
421
+ }
422
+ return;
423
+ }
424
+ const decryptedAmount = await (0, import_x402z_shared.decryptEuint64)(
425
+ relayer,
426
+ transferredHandle,
427
+ result.paymentRequirements.asset,
428
+ confidentialConfig.signer
429
+ );
430
+ const expected = BigInt(result.paymentRequirements.amount);
431
+ if (decryptedAmount !== expected) {
432
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
433
+ res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
434
+ if (debugEnabled) {
435
+ console.debug(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
436
+ }
437
+ return;
438
+ }
439
+ } catch (error) {
440
+ if (debugEnabled) {
441
+ console.error("[server] settlement verification error", error);
442
+ }
235
443
  res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
236
- res.end(JSON.stringify({ error: "observer_required" }));
237
- console.log(`[server] ${method} ${path} -> 500 observer_required`);
444
+ res.end(JSON.stringify({ error: "settlement_verification_failed" }));
445
+ if (debugEnabled) {
446
+ console.debug(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
447
+ }
238
448
  return;
239
449
  }
240
- const batch = settle;
241
- const transferredHandle = batch.batch?.transferredHandle;
242
- if (!transferredHandle) {
243
- res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
244
- res.end(JSON.stringify({ error: "missing_transferred_handle" }));
245
- console.log(`[server] ${method} ${path} -> 500 missing_transferred_handle`);
246
- return;
247
- }
248
- const decryptedAmount = await (0, import_x402z_shared.decryptEuint64)(
249
- relayer,
250
- transferredHandle,
251
- result.paymentRequirements.asset,
252
- config.signer
253
- );
254
- const expected = BigInt(result.paymentRequirements.amount);
255
- if (decryptedAmount !== expected) {
256
- res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
257
- res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
258
- console.log(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
259
- return;
260
- }
261
- } catch (error) {
262
- res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
263
- res.end(JSON.stringify({ error: "settlement_verification_failed" }));
264
- console.log(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
265
- if (debugEnabled) {
266
- console.debug("[x402z-server] settlement verification error", error);
267
- }
268
- return;
269
450
  }
451
+ const settleHeaders = settle.headers ?? {};
270
452
  const payload = await config.onPaid({
271
453
  paymentRequirements: result.paymentRequirements,
272
- settleHeaders: settle.headers
454
+ settleHeaders
273
455
  });
274
456
  const status = payload.status ?? 200;
275
457
  const responseHeaders = {
276
458
  ...corsHeaders,
277
- "Content-Type": "text/plain",
278
- ...settle.headers,
459
+ ...settleHeaders,
279
460
  ...payload.headers ?? {}
280
461
  };
462
+ if (!responseHeaders["Content-Type"] && !responseHeaders["content-type"]) {
463
+ responseHeaders["Content-Type"] = "text/plain";
464
+ }
281
465
  if (debugEnabled) {
282
466
  console.debug("[x402z-server] response", {
283
467
  status,
@@ -286,7 +470,9 @@ async function createX402zServer(config) {
286
470
  });
287
471
  }
288
472
  sendText(res, status, responseHeaders, payload.body);
289
- console.log(`[server] ${method} ${path} -> ${status}`);
473
+ if (debugEnabled) {
474
+ console.debug(`[server] ${method} ${path} -> ${status}`);
475
+ }
290
476
  return;
291
477
  }
292
478
  sendText(
@@ -295,14 +481,16 @@ async function createX402zServer(config) {
295
481
  { ...corsHeaders, "Content-Type": "text/plain" },
296
482
  "no payment required"
297
483
  );
298
- console.log(`[server] ${method} ${path} -> 200`);
484
+ if (debugEnabled) {
485
+ console.debug(`[server] ${method} ${path} -> 200`);
486
+ }
299
487
  });
300
488
  return server;
301
489
  }
302
490
 
303
491
  // src/index.ts
304
- var import_server3 = require("@x402/core/server");
305
- var import_http3 = require("@x402/core/http");
492
+ var import_server4 = require("@x402/core/server");
493
+ var import_http2 = require("@x402/core/http");
306
494
  // Annotate the CommonJS export names for ESM import in node:
307
495
  0 && (module.exports = {
308
496
  HTTPFacilitatorClient,
package/dist/index.mjs CHANGED
@@ -92,10 +92,14 @@ function registerX402zEvmServerScheme(server, config) {
92
92
  import { createServer } from "http";
93
93
  import { URL } from "url";
94
94
  import { x402ResourceServer } from "@x402/core/server";
95
- import { decodePaymentSignatureHeader, x402HTTPResourceServer } from "@x402/core/http";
96
- import { HTTPFacilitatorClient } from "@x402/core/http";
95
+ import {
96
+ decodePaymentSignatureHeader,
97
+ x402HTTPResourceServer,
98
+ HTTPFacilitatorClient
99
+ } from "@x402/core/http";
97
100
  import { confidentialTokenAbi, decryptEuint64 } from "x402z-shared";
98
101
  import { createPublicClient, getAddress, http, isAddressEqual } from "viem";
102
+ import { registerExactEvmScheme } from "@x402/evm/exact/server";
99
103
  function getRelayerRpcUrl(relayer) {
100
104
  const network = relayer.network;
101
105
  if (typeof network === "string") {
@@ -119,24 +123,181 @@ function buildAdapter(req) {
119
123
  };
120
124
  }
121
125
  function sendText(res, status, headers, body) {
122
- res.writeHead(status, headers);
126
+ res.writeHead(status, void 0, headers);
123
127
  res.end(body);
124
128
  }
129
+ async function fetchSupported(facilitatorUrl, fetchFn) {
130
+ const base = facilitatorUrl.replace(/\/$/, "");
131
+ const response = await fetchFn(`${base}/supported`);
132
+ if (!response.ok) {
133
+ throw new Error(`Failed to fetch supported schemes: ${response.status}`);
134
+ }
135
+ return response.json();
136
+ }
137
+ function normalizeExactDefaults(extra) {
138
+ const exact = extra?.exact ?? null;
139
+ if (!exact?.asset) {
140
+ return null;
141
+ }
142
+ const name = exact.eip712?.name ?? exact.name;
143
+ const version = exact.eip712?.version ?? exact.version;
144
+ if (!name || !version) {
145
+ return null;
146
+ }
147
+ return {
148
+ asset: exact.asset,
149
+ decimals: exact.decimals ?? 6,
150
+ name,
151
+ version
152
+ };
153
+ }
154
+ function normalizeConfidentialDefaults(extra) {
155
+ const confidential = extra?.confidential ?? null;
156
+ if (!confidential?.asset || !confidential.eip712?.name || !confidential.eip712?.version) {
157
+ return null;
158
+ }
159
+ if (!confidential.batcherAddress) {
160
+ return null;
161
+ }
162
+ return {
163
+ asset: confidential.asset,
164
+ eip712: {
165
+ name: confidential.eip712.name,
166
+ version: confidential.eip712.version
167
+ },
168
+ decimals: confidential.decimals ?? 6,
169
+ batcherAddress: confidential.batcherAddress,
170
+ resourceHash: confidential.resourceHash
171
+ };
172
+ }
173
+ function parseMoneyToDecimal(money) {
174
+ if (typeof money === "number") {
175
+ return money;
176
+ }
177
+ if (typeof money !== "string") {
178
+ throw new Error("Invalid price type for exact scheme");
179
+ }
180
+ const clean = money.replace(/^\$/, "").trim();
181
+ const amount = Number.parseFloat(clean);
182
+ if (Number.isNaN(amount)) {
183
+ throw new Error(`Invalid money format: ${money}`);
184
+ }
185
+ return amount;
186
+ }
187
+ function convertToTokenAmount(amount, decimals) {
188
+ const [intPart, decPart = ""] = String(amount).split(".");
189
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
190
+ return (intPart + paddedDec).replace(/^0+/, "") || "0";
191
+ }
125
192
  async function createX402zServer(config) {
126
193
  const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
194
+ const fetchFn = globalThis.fetch;
127
195
  const facilitatorClient = new HTTPFacilitatorClient({ url: config.facilitatorUrl });
128
196
  const resourceServer = new x402ResourceServer(facilitatorClient);
129
- registerX402zEvmServerScheme(resourceServer, config);
130
- const relayer = config.relayer;
131
- const rpcUrl = getRelayerRpcUrl(relayer);
197
+ const wantsExact = Object.values(config.routes).some(
198
+ (route) => route.accepts.some((accept) => accept.scheme === "exact")
199
+ );
200
+ const wantsConfidential = Object.values(config.routes).some(
201
+ (route) => route.accepts.some((accept) => accept.scheme === "erc7984-mind-v1")
202
+ );
203
+ const confidentialConfig = config.confidential;
204
+ if (wantsConfidential && !confidentialConfig) {
205
+ throw new Error("confidential config is required when using erc7984-mind-v1 routes");
206
+ }
207
+ const needsExactDefaults = Object.values(config.routes).some(
208
+ (route) => route.accepts.some((accept) => accept.scheme === "exact" && typeof accept.price !== "object")
209
+ );
210
+ let supportedExactDefaults = {};
211
+ if (wantsExact && needsExactDefaults) {
212
+ if (!fetchFn) {
213
+ throw new Error("fetch is required to load exact defaults from facilitator");
214
+ }
215
+ const supported = await fetchSupported(config.facilitatorUrl, fetchFn);
216
+ for (const kind of supported.kinds ?? []) {
217
+ if (kind.scheme !== "exact") continue;
218
+ const normalized = normalizeExactDefaults(kind.extra);
219
+ if (normalized) {
220
+ supportedExactDefaults[kind.network] = normalized;
221
+ }
222
+ }
223
+ }
224
+ if (wantsConfidential && confidentialConfig) {
225
+ let supportedDefaults = {};
226
+ const needsSupportedDefaults = !confidentialConfig.getNetworkConfig && (!confidentialConfig.asset || !confidentialConfig.eip712 || !confidentialConfig.batcherAddress);
227
+ if (needsSupportedDefaults) {
228
+ if (!fetchFn) {
229
+ throw new Error("fetch is required to load confidential defaults from facilitator");
230
+ }
231
+ const supported = await fetchSupported(config.facilitatorUrl, fetchFn);
232
+ for (const kind of supported.kinds ?? []) {
233
+ if (kind.scheme !== "erc7984-mind-v1") continue;
234
+ const normalized = normalizeConfidentialDefaults(kind.extra);
235
+ if (normalized) {
236
+ supportedDefaults[kind.network] = normalized;
237
+ }
238
+ }
239
+ }
240
+ const getNetworkConfig = confidentialConfig.getNetworkConfig ?? ((network) => {
241
+ const base = supportedDefaults[network] ?? {};
242
+ const override = {
243
+ asset: confidentialConfig.asset,
244
+ eip712: confidentialConfig.eip712,
245
+ decimals: confidentialConfig.decimals,
246
+ resourceHash: confidentialConfig.resourceHash,
247
+ batcherAddress: confidentialConfig.batcherAddress
248
+ };
249
+ const merged = {
250
+ ...base,
251
+ ...Object.fromEntries(Object.entries(override).filter(([, value]) => value !== void 0))
252
+ };
253
+ if (!merged.decimals) {
254
+ merged.decimals = 6;
255
+ }
256
+ if (!merged.asset || !merged.eip712?.name || !merged.eip712?.version || !merged.batcherAddress) {
257
+ throw new Error(`Missing confidential defaults for network ${network}`);
258
+ }
259
+ return merged;
260
+ });
261
+ registerX402zEvmServerScheme(resourceServer, {
262
+ getNetworkConfig,
263
+ networks: confidentialConfig.networks
264
+ });
265
+ }
266
+ if (wantsExact) {
267
+ registerExactEvmScheme(resourceServer, {});
268
+ }
269
+ const relayer = confidentialConfig?.relayer;
270
+ const rpcUrl = relayer ? getRelayerRpcUrl(relayer) : null;
132
271
  const routes = {};
133
272
  for (const [path, route] of Object.entries(config.routes)) {
273
+ const accepts = route.accepts.map((accept) => {
274
+ if (accept.scheme !== "exact") {
275
+ return accept;
276
+ }
277
+ if (typeof accept.price === "object") {
278
+ return accept;
279
+ }
280
+ const defaults = supportedExactDefaults[accept.network];
281
+ if (!defaults) {
282
+ throw new Error(`Missing exact defaults for network ${accept.network}`);
283
+ }
284
+ const decimalAmount = parseMoneyToDecimal(accept.price);
285
+ const amount = convertToTokenAmount(decimalAmount, defaults.decimals);
286
+ return {
287
+ ...accept,
288
+ price: {
289
+ amount,
290
+ asset: defaults.asset,
291
+ extra: {
292
+ name: defaults.name,
293
+ version: defaults.version
294
+ }
295
+ }
296
+ };
297
+ });
134
298
  routes[path] = {
135
299
  ...route,
136
- accepts: {
137
- ...route.accepts,
138
- scheme: "erc7984-mind-v1"
139
- }
300
+ accepts
140
301
  };
141
302
  }
142
303
  const httpServer = new x402HTTPResourceServer(resourceServer, routes);
@@ -146,7 +307,9 @@ async function createX402zServer(config) {
146
307
  const method = adapter.getMethod();
147
308
  const path = adapter.getPath();
148
309
  const paymentHeader = adapter.getHeader("payment-signature") ?? adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
149
- console.log(`[server] ${method} ${path}`);
310
+ if (debugEnabled) {
311
+ console.debug(`[server] ${method} ${path}`);
312
+ }
150
313
  const corsHeaders = config.cors ? {
151
314
  "Access-Control-Allow-Origin": config.cors.allowOrigin,
152
315
  "Access-Control-Allow-Methods": config.cors.allowMethods ?? "GET,POST,OPTIONS",
@@ -177,7 +340,9 @@ async function createX402zServer(config) {
177
340
  if (result.type === "payment-error") {
178
341
  res.writeHead(result.response.status, { ...corsHeaders, ...result.response.headers });
179
342
  res.end(result.response.isHtml ? result.response.body : JSON.stringify(result.response.body ?? {}));
180
- console.log(`[server] ${method} ${path} -> ${result.response.status}`);
343
+ if (debugEnabled) {
344
+ console.debug(`[server] ${method} ${path} -> ${result.response.status}`);
345
+ }
181
346
  return;
182
347
  }
183
348
  if (result.type === "payment-verified") {
@@ -185,68 +350,91 @@ async function createX402zServer(config) {
185
350
  if (!settle.success) {
186
351
  res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
187
352
  res.end(JSON.stringify({ error: settle.errorReason }));
188
- console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
353
+ if (debugEnabled) {
354
+ console.debug(`[server] ${method} ${path} -> 500 settlement_failed`);
355
+ }
189
356
  return;
190
357
  }
191
- try {
192
- const observerClient = createPublicClient({
193
- transport: http(rpcUrl)
194
- });
195
- const payTo = getAddress(result.paymentRequirements.payTo);
196
- const observer = await observerClient.readContract({
197
- address: getAddress(result.paymentRequirements.asset),
198
- abi: confidentialTokenAbi,
199
- functionName: "observer",
200
- args: [payTo]
201
- });
202
- const signerAddress = getAddress(config.signer.address);
203
- if (!observer || !isAddressEqual(observer, signerAddress)) {
204
- res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
205
- res.end(JSON.stringify({ error: "observer_required" }));
206
- console.log(`[server] ${method} ${path} -> 500 observer_required`);
207
- return;
208
- }
209
- const batch = settle;
210
- const transferredHandle = batch.batch?.transferredHandle;
211
- if (!transferredHandle) {
358
+ if (result.paymentRequirements.scheme === "erc7984-mind-v1") {
359
+ try {
360
+ if (!confidentialConfig || !relayer || !rpcUrl) {
361
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
362
+ res.end(JSON.stringify({ error: "confidential_config_missing" }));
363
+ if (debugEnabled) {
364
+ console.debug(`[server] ${method} ${path} -> 500 confidential_config_missing`);
365
+ }
366
+ return;
367
+ }
368
+ const observerClient = createPublicClient({
369
+ transport: http(rpcUrl)
370
+ });
371
+ const payTo = getAddress(result.paymentRequirements.payTo);
372
+ const observer = await observerClient.readContract({
373
+ address: getAddress(result.paymentRequirements.asset),
374
+ abi: confidentialTokenAbi,
375
+ functionName: "observer",
376
+ args: [payTo]
377
+ });
378
+ const signerAddress = getAddress(confidentialConfig.signer.address);
379
+ if (!observer || !isAddressEqual(observer, signerAddress)) {
380
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
381
+ res.end(JSON.stringify({ error: "observer_required" }));
382
+ if (debugEnabled) {
383
+ console.debug(`[server] ${method} ${path} -> 500 observer_required`);
384
+ }
385
+ return;
386
+ }
387
+ const batch = settle;
388
+ const transferredHandle = batch.batch?.transferredHandle;
389
+ if (!transferredHandle) {
390
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
391
+ res.end(JSON.stringify({ error: "missing_transferred_handle" }));
392
+ if (debugEnabled) {
393
+ console.debug(`[server] ${method} ${path} -> 500 missing_transferred_handle`);
394
+ }
395
+ return;
396
+ }
397
+ const decryptedAmount = await decryptEuint64(
398
+ relayer,
399
+ transferredHandle,
400
+ result.paymentRequirements.asset,
401
+ confidentialConfig.signer
402
+ );
403
+ const expected = BigInt(result.paymentRequirements.amount);
404
+ if (decryptedAmount !== expected) {
405
+ res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
406
+ res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
407
+ if (debugEnabled) {
408
+ console.debug(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
409
+ }
410
+ return;
411
+ }
412
+ } catch (error) {
413
+ if (debugEnabled) {
414
+ console.error("[server] settlement verification error", error);
415
+ }
212
416
  res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
213
- res.end(JSON.stringify({ error: "missing_transferred_handle" }));
214
- console.log(`[server] ${method} ${path} -> 500 missing_transferred_handle`);
417
+ res.end(JSON.stringify({ error: "settlement_verification_failed" }));
418
+ if (debugEnabled) {
419
+ console.debug(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
420
+ }
215
421
  return;
216
422
  }
217
- const decryptedAmount = await decryptEuint64(
218
- relayer,
219
- transferredHandle,
220
- result.paymentRequirements.asset,
221
- config.signer
222
- );
223
- const expected = BigInt(result.paymentRequirements.amount);
224
- if (decryptedAmount !== expected) {
225
- res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
226
- res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
227
- console.log(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
228
- return;
229
- }
230
- } catch (error) {
231
- res.writeHead(500, { ...corsHeaders, "Content-Type": "application/json" });
232
- res.end(JSON.stringify({ error: "settlement_verification_failed" }));
233
- console.log(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
234
- if (debugEnabled) {
235
- console.debug("[x402z-server] settlement verification error", error);
236
- }
237
- return;
238
423
  }
424
+ const settleHeaders = settle.headers ?? {};
239
425
  const payload = await config.onPaid({
240
426
  paymentRequirements: result.paymentRequirements,
241
- settleHeaders: settle.headers
427
+ settleHeaders
242
428
  });
243
429
  const status = payload.status ?? 200;
244
430
  const responseHeaders = {
245
431
  ...corsHeaders,
246
- "Content-Type": "text/plain",
247
- ...settle.headers,
432
+ ...settleHeaders,
248
433
  ...payload.headers ?? {}
249
434
  };
435
+ if (!responseHeaders["Content-Type"] && !responseHeaders["content-type"]) {
436
+ responseHeaders["Content-Type"] = "text/plain";
437
+ }
250
438
  if (debugEnabled) {
251
439
  console.debug("[x402z-server] response", {
252
440
  status,
@@ -255,7 +443,9 @@ async function createX402zServer(config) {
255
443
  });
256
444
  }
257
445
  sendText(res, status, responseHeaders, payload.body);
258
- console.log(`[server] ${method} ${path} -> ${status}`);
446
+ if (debugEnabled) {
447
+ console.debug(`[server] ${method} ${path} -> ${status}`);
448
+ }
259
449
  return;
260
450
  }
261
451
  sendText(
@@ -264,7 +454,9 @@ async function createX402zServer(config) {
264
454
  { ...corsHeaders, "Content-Type": "text/plain" },
265
455
  "no payment required"
266
456
  );
267
- console.log(`[server] ${method} ${path} -> 200`);
457
+ if (debugEnabled) {
458
+ console.debug(`[server] ${method} ${path} -> 200`);
459
+ }
268
460
  });
269
461
  return server;
270
462
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x402z-server",
3
- "version": "0.0.19",
3
+ "version": "0.1.12",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -8,9 +8,10 @@
8
8
  "dist"
9
9
  ],
10
10
  "dependencies": {
11
- "@x402/core": "^2.0.0",
11
+ "@x402/core": "^2.2.0",
12
+ "@x402/evm": "^2.2.0",
12
13
  "viem": "^2.43.3",
13
- "x402z-shared": "0.0.19"
14
+ "x402z-shared": "0.1.0"
14
15
  },
15
16
  "devDependencies": {
16
17
  "jest": "^29.7.0",