x402z-server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,53 @@
1
+ # x402z-server
2
+
3
+ Server-side helpers for the erc7984-mind-v1 x402 scheme.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add x402z-server
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```ts
14
+ import { createX402zServer } from "x402z-server";
15
+
16
+ const server = await createX402zServer({
17
+ facilitatorUrl: "http://localhost:8040",
18
+ asset: "0xToken",
19
+ eip712: { name: "FHEToken Confidential", version: "1" },
20
+ decimals: 6,
21
+ facilitatorAddress: "0xFacilitator",
22
+ routes: {
23
+ "GET /demo": {
24
+ accepts: {
25
+ payTo: "0xPayTo",
26
+ price: "1.0",
27
+ network: "eip155:11155111",
28
+ maxTimeoutSeconds: 300,
29
+ },
30
+ description: "Demo content",
31
+ mimeType: "text/plain",
32
+ },
33
+ },
34
+ onPaid: async () => ({
35
+ body: "demo content from server",
36
+ }),
37
+ });
38
+
39
+ server.listen(8080);
40
+ ```
41
+
42
+ ## API
43
+
44
+ - `createX402zServer(config)`
45
+ - `facilitatorUrl` (required): HTTP facilitator endpoint
46
+ - `asset`, `eip712`, `decimals`, `facilitatorAddress`: scheme config
47
+ - `routes`: map of `METHOD /path` to payment requirements
48
+ - `onPaid`: handler for successful payment (returns response body + optional headers)
49
+
50
+ ## Notes
51
+
52
+ - Scheme name: `erc7984-mind-v1`
53
+ - `confidential.facilitatorAddress` is included in requirements so clients can bind encrypted inputs.
@@ -0,0 +1,67 @@
1
+ import { SchemeNetworkServer, Network, Price, AssetAmount, PaymentRequirements } from '@x402/core/types';
2
+ export * from '@x402/core/types';
3
+ import { x402ResourceServer } from '@x402/core/server';
4
+ export { x402ResourceServer } from '@x402/core/server';
5
+ import * as http from 'http';
6
+ 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
+
8
+ type ConfidentialServerNetworkConfig = {
9
+ asset: `0x${string}`;
10
+ eip712: {
11
+ name: string;
12
+ version: string;
13
+ };
14
+ decimals?: number;
15
+ resourceHash?: `0x${string}`;
16
+ facilitatorAddress?: `0x${string}`;
17
+ };
18
+ type ConfidentialServerConfig = ConfidentialServerNetworkConfig | {
19
+ getNetworkConfig: (network: Network) => ConfidentialServerNetworkConfig;
20
+ };
21
+ declare class ConfidentialEvmScheme implements SchemeNetworkServer {
22
+ readonly scheme = "erc7984-mind-v1";
23
+ private readonly getConfig;
24
+ constructor(config: ConfidentialServerConfig);
25
+ parsePrice(price: Price, network: Network): Promise<AssetAmount>;
26
+ enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
27
+ x402Version: number;
28
+ scheme: string;
29
+ network: Network;
30
+ extra?: Record<string, unknown>;
31
+ }, extensionKeys: string[]): Promise<PaymentRequirements>;
32
+ private parseMoneyToDecimal;
33
+ private convertToTokenAmount;
34
+ }
35
+
36
+ type ConfidentialServerRegisterConfig = ConfidentialServerConfig & {
37
+ networks?: Network[];
38
+ };
39
+ declare function registerConfidentialEvmScheme(server: x402ResourceServer, config: ConfidentialServerRegisterConfig): x402ResourceServer;
40
+
41
+ type X402zRouteConfig = {
42
+ accepts: {
43
+ payTo: string;
44
+ price: string;
45
+ network: Network;
46
+ maxTimeoutSeconds: number;
47
+ };
48
+ description: string;
49
+ mimeType: string;
50
+ };
51
+ type X402zRouteHandler = (args: {
52
+ paymentRequirements: PaymentRequirements;
53
+ settleHeaders: Record<string, string>;
54
+ }) => Promise<{
55
+ status?: number;
56
+ headers?: Record<string, string>;
57
+ body: string;
58
+ }>;
59
+ type X402zServerConfig = ConfidentialServerRegisterConfig & {
60
+ facilitatorUrl: string;
61
+ routes: Record<string, X402zRouteConfig>;
62
+ onPaid: X402zRouteHandler;
63
+ debug?: boolean;
64
+ };
65
+ declare function createX402zServer(config: X402zServerConfig): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
66
+
67
+ export { ConfidentialEvmScheme, type ConfidentialServerConfig, type ConfidentialServerNetworkConfig, type ConfidentialServerRegisterConfig, type X402zRouteConfig, type X402zRouteHandler, type X402zServerConfig, createX402zServer, registerConfidentialEvmScheme };
@@ -0,0 +1,67 @@
1
+ import { SchemeNetworkServer, Network, Price, AssetAmount, PaymentRequirements } from '@x402/core/types';
2
+ export * from '@x402/core/types';
3
+ import { x402ResourceServer } from '@x402/core/server';
4
+ export { x402ResourceServer } from '@x402/core/server';
5
+ import * as http from 'http';
6
+ 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
+
8
+ type ConfidentialServerNetworkConfig = {
9
+ asset: `0x${string}`;
10
+ eip712: {
11
+ name: string;
12
+ version: string;
13
+ };
14
+ decimals?: number;
15
+ resourceHash?: `0x${string}`;
16
+ facilitatorAddress?: `0x${string}`;
17
+ };
18
+ type ConfidentialServerConfig = ConfidentialServerNetworkConfig | {
19
+ getNetworkConfig: (network: Network) => ConfidentialServerNetworkConfig;
20
+ };
21
+ declare class ConfidentialEvmScheme implements SchemeNetworkServer {
22
+ readonly scheme = "erc7984-mind-v1";
23
+ private readonly getConfig;
24
+ constructor(config: ConfidentialServerConfig);
25
+ parsePrice(price: Price, network: Network): Promise<AssetAmount>;
26
+ enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
27
+ x402Version: number;
28
+ scheme: string;
29
+ network: Network;
30
+ extra?: Record<string, unknown>;
31
+ }, extensionKeys: string[]): Promise<PaymentRequirements>;
32
+ private parseMoneyToDecimal;
33
+ private convertToTokenAmount;
34
+ }
35
+
36
+ type ConfidentialServerRegisterConfig = ConfidentialServerConfig & {
37
+ networks?: Network[];
38
+ };
39
+ declare function registerConfidentialEvmScheme(server: x402ResourceServer, config: ConfidentialServerRegisterConfig): x402ResourceServer;
40
+
41
+ type X402zRouteConfig = {
42
+ accepts: {
43
+ payTo: string;
44
+ price: string;
45
+ network: Network;
46
+ maxTimeoutSeconds: number;
47
+ };
48
+ description: string;
49
+ mimeType: string;
50
+ };
51
+ type X402zRouteHandler = (args: {
52
+ paymentRequirements: PaymentRequirements;
53
+ settleHeaders: Record<string, string>;
54
+ }) => Promise<{
55
+ status?: number;
56
+ headers?: Record<string, string>;
57
+ body: string;
58
+ }>;
59
+ type X402zServerConfig = ConfidentialServerRegisterConfig & {
60
+ facilitatorUrl: string;
61
+ routes: Record<string, X402zRouteConfig>;
62
+ onPaid: X402zRouteHandler;
63
+ debug?: boolean;
64
+ };
65
+ declare function createX402zServer(config: X402zServerConfig): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
66
+
67
+ export { ConfidentialEvmScheme, type ConfidentialServerConfig, type ConfidentialServerNetworkConfig, type ConfidentialServerRegisterConfig, type X402zRouteConfig, type X402zRouteHandler, type X402zServerConfig, createX402zServer, registerConfidentialEvmScheme };
package/dist/index.js ADDED
@@ -0,0 +1,229 @@
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
+ ConfidentialEvmScheme: () => ConfidentialEvmScheme,
24
+ HTTPFacilitatorClient: () => import_http4.HTTPFacilitatorClient,
25
+ createX402zServer: () => createX402zServer,
26
+ registerConfidentialEvmScheme: () => registerConfidentialEvmScheme,
27
+ x402HTTPResourceServer: () => import_http4.x402HTTPResourceServer,
28
+ x402ResourceServer: () => import_server2.x402ResourceServer
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/scheme.ts
33
+ var ConfidentialEvmScheme = class {
34
+ constructor(config) {
35
+ this.scheme = "erc7984-mind-v1";
36
+ if ("getNetworkConfig" in config) {
37
+ this.getConfig = config.getNetworkConfig;
38
+ } else {
39
+ this.getConfig = () => config;
40
+ }
41
+ }
42
+ async parsePrice(price, network) {
43
+ if (typeof price === "object" && price !== null && "amount" in price) {
44
+ if (!price.asset) {
45
+ throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);
46
+ }
47
+ return {
48
+ amount: price.amount,
49
+ asset: price.asset,
50
+ extra: price.extra || {}
51
+ };
52
+ }
53
+ const amount = this.parseMoneyToDecimal(price);
54
+ const config = this.getConfig(network);
55
+ return {
56
+ amount: this.convertToTokenAmount(amount.toString(), config.decimals ?? 6),
57
+ asset: config.asset,
58
+ extra: {
59
+ eip712: config.eip712,
60
+ confidential: {
61
+ maxClearAmount: amount.toString(),
62
+ resourceHash: config.resourceHash,
63
+ facilitatorAddress: config.facilitatorAddress
64
+ }
65
+ }
66
+ };
67
+ }
68
+ async enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
69
+ void supportedKind;
70
+ void extensionKeys;
71
+ const config = this.getConfig(paymentRequirements.network);
72
+ const extra = paymentRequirements.extra;
73
+ const nextExtra = {
74
+ ...paymentRequirements.extra || {},
75
+ eip712: extra?.eip712 ?? config.eip712,
76
+ confidential: {
77
+ maxClearAmount: extra?.confidential?.maxClearAmount ?? paymentRequirements.amount,
78
+ resourceHash: extra?.confidential?.resourceHash ?? config.resourceHash,
79
+ facilitatorAddress: extra?.confidential?.facilitatorAddress ?? config.facilitatorAddress
80
+ }
81
+ };
82
+ return {
83
+ ...paymentRequirements,
84
+ extra: nextExtra
85
+ };
86
+ }
87
+ parseMoneyToDecimal(money) {
88
+ if (typeof money === "number") {
89
+ return money;
90
+ }
91
+ const cleanMoney = money.replace(/^\$/, "").trim();
92
+ const amount = parseFloat(cleanMoney);
93
+ if (Number.isNaN(amount)) {
94
+ throw new Error(`Invalid money format: ${money}`);
95
+ }
96
+ return amount;
97
+ }
98
+ convertToTokenAmount(decimalAmount, decimals) {
99
+ const amount = parseFloat(decimalAmount);
100
+ if (Number.isNaN(amount)) {
101
+ throw new Error(`Invalid amount: ${decimalAmount}`);
102
+ }
103
+ const [intPart, decPart = ""] = String(amount).split(".");
104
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
105
+ return (intPart + paddedDec).replace(/^0+/, "") || "0";
106
+ }
107
+ };
108
+
109
+ // src/register.ts
110
+ function registerConfidentialEvmScheme(server, config) {
111
+ if ("networks" in config && config.networks && config.networks.length > 0) {
112
+ for (const network of config.networks) {
113
+ server.register(network, new ConfidentialEvmScheme(config));
114
+ }
115
+ return server;
116
+ }
117
+ server.register("eip155:*", new ConfidentialEvmScheme(config));
118
+ return server;
119
+ }
120
+
121
+ // src/http.ts
122
+ var import_node_http = require("http");
123
+ var import_node_url = require("url");
124
+ var import_server = require("@x402/core/server");
125
+ var import_http = require("@x402/core/http");
126
+ var import_http2 = require("@x402/core/http");
127
+ function buildAdapter(req) {
128
+ const url = new import_node_url.URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
129
+ return {
130
+ getHeader: (name) => {
131
+ const value = req.headers[name.toLowerCase()];
132
+ if (!value) return void 0;
133
+ return Array.isArray(value) ? value.join(",") : value;
134
+ },
135
+ getMethod: () => req.method ?? "GET",
136
+ getPath: () => url.pathname,
137
+ getUrl: () => url.toString(),
138
+ getAcceptHeader: () => req.headers.accept ?? "",
139
+ getUserAgent: () => req.headers["user-agent"] ?? ""
140
+ };
141
+ }
142
+ function sendText(res, status, headers, body) {
143
+ res.writeHead(status, headers);
144
+ res.end(body);
145
+ }
146
+ async function createX402zServer(config) {
147
+ const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
148
+ const facilitatorClient = new import_http2.HTTPFacilitatorClient({ url: config.facilitatorUrl });
149
+ const resourceServer = new import_server.x402ResourceServer(facilitatorClient);
150
+ registerConfidentialEvmScheme(resourceServer, config);
151
+ const routes = {};
152
+ for (const [path, route] of Object.entries(config.routes)) {
153
+ routes[path] = {
154
+ ...route,
155
+ accepts: {
156
+ ...route.accepts,
157
+ scheme: "erc7984-mind-v1"
158
+ }
159
+ };
160
+ }
161
+ const httpServer = new import_http.x402HTTPResourceServer(resourceServer, routes);
162
+ await httpServer.initialize();
163
+ const server = (0, import_node_http.createServer)(async (req, res) => {
164
+ const adapter = buildAdapter(req);
165
+ const method = adapter.getMethod();
166
+ const path = adapter.getPath();
167
+ const paymentHeader = adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
168
+ console.log(`[server] ${method} ${path}`);
169
+ if (debugEnabled && paymentHeader) {
170
+ console.debug("[x402z-server] payment header", paymentHeader);
171
+ }
172
+ const result = await httpServer.processHTTPRequest({
173
+ adapter,
174
+ path: adapter.getPath(),
175
+ method: adapter.getMethod()
176
+ });
177
+ if (result.type === "payment-error") {
178
+ res.writeHead(result.response.status, result.response.headers);
179
+ res.end(result.response.isHtml ? result.response.body : JSON.stringify(result.response.body ?? {}));
180
+ console.log(`[server] ${method} ${path} -> ${result.response.status}`);
181
+ return;
182
+ }
183
+ if (result.type === "payment-verified") {
184
+ const settle = await httpServer.processSettlement(result.paymentPayload, result.paymentRequirements);
185
+ if (!settle.success) {
186
+ res.writeHead(500, { "Content-Type": "application/json" });
187
+ res.end(JSON.stringify({ error: settle.errorReason }));
188
+ console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
189
+ return;
190
+ }
191
+ const payload = await config.onPaid({
192
+ paymentRequirements: result.paymentRequirements,
193
+ settleHeaders: settle.headers
194
+ });
195
+ const status = payload.status ?? 200;
196
+ const responseHeaders = {
197
+ "Content-Type": "text/plain",
198
+ ...settle.headers,
199
+ ...payload.headers ?? {}
200
+ };
201
+ if (debugEnabled) {
202
+ console.debug("[x402z-server] response", {
203
+ status,
204
+ headers: responseHeaders,
205
+ body: payload.body
206
+ });
207
+ }
208
+ sendText(res, status, responseHeaders, payload.body);
209
+ console.log(`[server] ${method} ${path} -> ${status}`);
210
+ return;
211
+ }
212
+ sendText(res, 200, { "Content-Type": "text/plain" }, "no payment required");
213
+ console.log(`[server] ${method} ${path} -> 200`);
214
+ });
215
+ return server;
216
+ }
217
+
218
+ // src/index.ts
219
+ var import_server2 = require("@x402/core/server");
220
+ var import_http4 = require("@x402/core/http");
221
+ // Annotate the CommonJS export names for ESM import in node:
222
+ 0 && (module.exports = {
223
+ ConfidentialEvmScheme,
224
+ HTTPFacilitatorClient,
225
+ createX402zServer,
226
+ registerConfidentialEvmScheme,
227
+ x402HTTPResourceServer,
228
+ x402ResourceServer
229
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,200 @@
1
+ // src/scheme.ts
2
+ var ConfidentialEvmScheme = class {
3
+ constructor(config) {
4
+ this.scheme = "erc7984-mind-v1";
5
+ if ("getNetworkConfig" in config) {
6
+ this.getConfig = config.getNetworkConfig;
7
+ } else {
8
+ this.getConfig = () => config;
9
+ }
10
+ }
11
+ async parsePrice(price, network) {
12
+ if (typeof price === "object" && price !== null && "amount" in price) {
13
+ if (!price.asset) {
14
+ throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);
15
+ }
16
+ return {
17
+ amount: price.amount,
18
+ asset: price.asset,
19
+ extra: price.extra || {}
20
+ };
21
+ }
22
+ const amount = this.parseMoneyToDecimal(price);
23
+ const config = this.getConfig(network);
24
+ return {
25
+ amount: this.convertToTokenAmount(amount.toString(), config.decimals ?? 6),
26
+ asset: config.asset,
27
+ extra: {
28
+ eip712: config.eip712,
29
+ confidential: {
30
+ maxClearAmount: amount.toString(),
31
+ resourceHash: config.resourceHash,
32
+ facilitatorAddress: config.facilitatorAddress
33
+ }
34
+ }
35
+ };
36
+ }
37
+ async enhancePaymentRequirements(paymentRequirements, supportedKind, extensionKeys) {
38
+ void supportedKind;
39
+ void extensionKeys;
40
+ const config = this.getConfig(paymentRequirements.network);
41
+ const extra = paymentRequirements.extra;
42
+ const nextExtra = {
43
+ ...paymentRequirements.extra || {},
44
+ eip712: extra?.eip712 ?? config.eip712,
45
+ confidential: {
46
+ maxClearAmount: extra?.confidential?.maxClearAmount ?? paymentRequirements.amount,
47
+ resourceHash: extra?.confidential?.resourceHash ?? config.resourceHash,
48
+ facilitatorAddress: extra?.confidential?.facilitatorAddress ?? config.facilitatorAddress
49
+ }
50
+ };
51
+ return {
52
+ ...paymentRequirements,
53
+ extra: nextExtra
54
+ };
55
+ }
56
+ parseMoneyToDecimal(money) {
57
+ if (typeof money === "number") {
58
+ return money;
59
+ }
60
+ const cleanMoney = money.replace(/^\$/, "").trim();
61
+ const amount = parseFloat(cleanMoney);
62
+ if (Number.isNaN(amount)) {
63
+ throw new Error(`Invalid money format: ${money}`);
64
+ }
65
+ return amount;
66
+ }
67
+ convertToTokenAmount(decimalAmount, decimals) {
68
+ const amount = parseFloat(decimalAmount);
69
+ if (Number.isNaN(amount)) {
70
+ throw new Error(`Invalid amount: ${decimalAmount}`);
71
+ }
72
+ const [intPart, decPart = ""] = String(amount).split(".");
73
+ const paddedDec = decPart.padEnd(decimals, "0").slice(0, decimals);
74
+ return (intPart + paddedDec).replace(/^0+/, "") || "0";
75
+ }
76
+ };
77
+
78
+ // src/register.ts
79
+ function registerConfidentialEvmScheme(server, config) {
80
+ if ("networks" in config && config.networks && config.networks.length > 0) {
81
+ for (const network of config.networks) {
82
+ server.register(network, new ConfidentialEvmScheme(config));
83
+ }
84
+ return server;
85
+ }
86
+ server.register("eip155:*", new ConfidentialEvmScheme(config));
87
+ return server;
88
+ }
89
+
90
+ // src/http.ts
91
+ import { createServer } from "http";
92
+ import { URL } from "url";
93
+ import { x402ResourceServer } from "@x402/core/server";
94
+ import { x402HTTPResourceServer } from "@x402/core/http";
95
+ import { HTTPFacilitatorClient } from "@x402/core/http";
96
+ function buildAdapter(req) {
97
+ const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
98
+ return {
99
+ getHeader: (name) => {
100
+ const value = req.headers[name.toLowerCase()];
101
+ if (!value) return void 0;
102
+ return Array.isArray(value) ? value.join(",") : value;
103
+ },
104
+ getMethod: () => req.method ?? "GET",
105
+ getPath: () => url.pathname,
106
+ getUrl: () => url.toString(),
107
+ getAcceptHeader: () => req.headers.accept ?? "",
108
+ getUserAgent: () => req.headers["user-agent"] ?? ""
109
+ };
110
+ }
111
+ function sendText(res, status, headers, body) {
112
+ res.writeHead(status, headers);
113
+ res.end(body);
114
+ }
115
+ async function createX402zServer(config) {
116
+ const debugEnabled = config.debug ?? process.env.X402Z_DEBUG === "1";
117
+ const facilitatorClient = new HTTPFacilitatorClient({ url: config.facilitatorUrl });
118
+ const resourceServer = new x402ResourceServer(facilitatorClient);
119
+ registerConfidentialEvmScheme(resourceServer, config);
120
+ const routes = {};
121
+ for (const [path, route] of Object.entries(config.routes)) {
122
+ routes[path] = {
123
+ ...route,
124
+ accepts: {
125
+ ...route.accepts,
126
+ scheme: "erc7984-mind-v1"
127
+ }
128
+ };
129
+ }
130
+ const httpServer = new x402HTTPResourceServer(resourceServer, routes);
131
+ await httpServer.initialize();
132
+ const server = createServer(async (req, res) => {
133
+ const adapter = buildAdapter(req);
134
+ const method = adapter.getMethod();
135
+ const path = adapter.getPath();
136
+ const paymentHeader = adapter.getHeader("x402-payment") ?? adapter.getHeader("x-payment");
137
+ console.log(`[server] ${method} ${path}`);
138
+ if (debugEnabled && paymentHeader) {
139
+ console.debug("[x402z-server] payment header", paymentHeader);
140
+ }
141
+ const result = await httpServer.processHTTPRequest({
142
+ adapter,
143
+ path: adapter.getPath(),
144
+ method: adapter.getMethod()
145
+ });
146
+ if (result.type === "payment-error") {
147
+ res.writeHead(result.response.status, result.response.headers);
148
+ res.end(result.response.isHtml ? result.response.body : JSON.stringify(result.response.body ?? {}));
149
+ console.log(`[server] ${method} ${path} -> ${result.response.status}`);
150
+ return;
151
+ }
152
+ if (result.type === "payment-verified") {
153
+ const settle = await httpServer.processSettlement(result.paymentPayload, result.paymentRequirements);
154
+ if (!settle.success) {
155
+ res.writeHead(500, { "Content-Type": "application/json" });
156
+ res.end(JSON.stringify({ error: settle.errorReason }));
157
+ console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
158
+ return;
159
+ }
160
+ const payload = await config.onPaid({
161
+ paymentRequirements: result.paymentRequirements,
162
+ settleHeaders: settle.headers
163
+ });
164
+ const status = payload.status ?? 200;
165
+ const responseHeaders = {
166
+ "Content-Type": "text/plain",
167
+ ...settle.headers,
168
+ ...payload.headers ?? {}
169
+ };
170
+ if (debugEnabled) {
171
+ console.debug("[x402z-server] response", {
172
+ status,
173
+ headers: responseHeaders,
174
+ body: payload.body
175
+ });
176
+ }
177
+ sendText(res, status, responseHeaders, payload.body);
178
+ console.log(`[server] ${method} ${path} -> ${status}`);
179
+ return;
180
+ }
181
+ sendText(res, 200, { "Content-Type": "text/plain" }, "no payment required");
182
+ console.log(`[server] ${method} ${path} -> 200`);
183
+ });
184
+ return server;
185
+ }
186
+
187
+ // src/index.ts
188
+ import { x402ResourceServer as x402ResourceServer2 } from "@x402/core/server";
189
+ import {
190
+ HTTPFacilitatorClient as HTTPFacilitatorClient2,
191
+ x402HTTPResourceServer as x402HTTPResourceServer2
192
+ } from "@x402/core/http";
193
+ export {
194
+ ConfidentialEvmScheme,
195
+ HTTPFacilitatorClient2 as HTTPFacilitatorClient,
196
+ createX402zServer,
197
+ registerConfidentialEvmScheme,
198
+ x402HTTPResourceServer2 as x402HTTPResourceServer,
199
+ x402ResourceServer2 as x402ResourceServer
200
+ };
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "x402z-server",
3
+ "version": "0.0.1",
4
+ "main": "./dist/index.js",
5
+ "module": "./dist/index.mjs",
6
+ "types": "./dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "dependencies": {
11
+ "@x402/core": "^2.0.0",
12
+ "x402z-shared": "0.0.1"
13
+ },
14
+ "devDependencies": {
15
+ "jest": "^29.7.0",
16
+ "ts-jest": "^29.2.5",
17
+ "@types/jest": "^29.5.12"
18
+ },
19
+ "scripts": {
20
+ "build": "tsup src/index.ts --format cjs,esm --dts",
21
+ "test": "jest"
22
+ }
23
+ }