gatepay-local-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/Readme.md +106 -0
  2. package/dist/src/index.d.ts +3 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +195 -0
  5. package/dist/src/index.js.map +1 -0
  6. package/dist/src/x402-standalone/client.d.ts +13 -0
  7. package/dist/src/x402-standalone/client.d.ts.map +1 -0
  8. package/dist/src/x402-standalone/client.js +41 -0
  9. package/dist/src/x402-standalone/client.js.map +1 -0
  10. package/dist/src/x402-standalone/exactEvmScheme.d.ts +13 -0
  11. package/dist/src/x402-standalone/exactEvmScheme.d.ts.map +1 -0
  12. package/dist/src/x402-standalone/exactEvmScheme.js +86 -0
  13. package/dist/src/x402-standalone/exactEvmScheme.js.map +1 -0
  14. package/dist/src/x402-standalone/fetch.d.ts +3 -0
  15. package/dist/src/x402-standalone/fetch.d.ts.map +1 -0
  16. package/dist/src/x402-standalone/fetch.js +48 -0
  17. package/dist/src/x402-standalone/fetch.js.map +1 -0
  18. package/dist/src/x402-standalone/gatelayer.d.ts +16 -0
  19. package/dist/src/x402-standalone/gatelayer.d.ts.map +1 -0
  20. package/dist/src/x402-standalone/gatelayer.js +29 -0
  21. package/dist/src/x402-standalone/gatelayer.js.map +1 -0
  22. package/dist/src/x402-standalone/http.d.ts +8 -0
  23. package/dist/src/x402-standalone/http.d.ts.map +1 -0
  24. package/dist/src/x402-standalone/http.js +26 -0
  25. package/dist/src/x402-standalone/http.js.map +1 -0
  26. package/dist/src/x402-standalone/index.d.ts +9 -0
  27. package/dist/src/x402-standalone/index.d.ts.map +1 -0
  28. package/dist/src/x402-standalone/index.js +8 -0
  29. package/dist/src/x402-standalone/index.js.map +1 -0
  30. package/dist/src/x402-standalone/signer.d.ts +4 -0
  31. package/dist/src/x402-standalone/signer.d.ts.map +1 -0
  32. package/dist/src/x402-standalone/signer.js +38 -0
  33. package/dist/src/x402-standalone/signer.js.map +1 -0
  34. package/dist/src/x402-standalone/types.d.ts +58 -0
  35. package/dist/src/x402-standalone/types.d.ts.map +1 -0
  36. package/dist/src/x402-standalone/types.js +5 -0
  37. package/dist/src/x402-standalone/types.js.map +1 -0
  38. package/dist/src/x402-standalone/utils.d.ts +17 -0
  39. package/dist/src/x402-standalone/utils.d.ts.map +1 -0
  40. package/dist/src/x402-standalone/utils.js +72 -0
  41. package/dist/src/x402-standalone/utils.js.map +1 -0
  42. package/dist/test/fetch.d.ts +2 -0
  43. package/dist/test/fetch.d.ts.map +1 -0
  44. package/dist/test/fetch.js +54 -0
  45. package/dist/test/fetch.js.map +1 -0
  46. package/package.json +54 -0
package/Readme.md ADDED
@@ -0,0 +1,106 @@
1
+ # gatepay-local-mcp
2
+
3
+ A local (stdio) MCP server that sends HTTP requests to **x402 payment-protected** endpoints. On `402 Payment Required`, it creates the payment payload, signs with your EVM key, and retries the request with the payment header. Exposes a single tool: `x402_request`.
4
+
5
+ ## Features
6
+
7
+ - **One tool** — `x402_request`: request any URL with optional method and JSON body; 402 is handled automatically (parse → sign → retry).
8
+ - **No @x402/* deps** — x402 logic is implemented in-repo under `x402-standalone/` (EVM exact scheme; supports `eth`, `base`, etc.).
9
+ - **Cursor / Claude Desktop** — add the server via `mcp.json` and set `EVM_PRIVATE_KEY` in `env`; no code changes needed.
10
+
11
+ ## Quick Start (Cursor / Claude Desktop)
12
+
13
+ ### With authentication (required for x402 payment)
14
+
15
+ `EVM_PRIVATE_KEY` is required; the server will not start without it.
16
+
17
+ ```json
18
+ {
19
+ "mcpServers": {
20
+ "gatepay-mcp": {
21
+ "command": "npx",
22
+ "args": ["-y", "gatepay-local-mcp"],
23
+ "env": {
24
+ "EVM_PRIVATE_KEY": "your-evm-private-key-hex-with-or-without-0x-prefix"
25
+ }
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ Put this in your MCP config (e.g. `~/.cursor/mcp.json`), then restart Cursor or reload MCP. The AI can then call `x402_request` for x402-protected URLs.
32
+
33
+ ### Optional: debug logging
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "gatepay-mcp": {
39
+ "command": "npx",
40
+ "args": ["-y", "gatepay-local-mcp"],
41
+ "env": {
42
+ "EVM_PRIVATE_KEY": "your-evm-private-key"
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ Use `tail -f /tmp/x402-debug.log` to watch requests and errors.
50
+
51
+ ## Environment Variables
52
+
53
+ | Variable | Required | Default | Description |
54
+ | -------- | -------- | ------- | ----------- |
55
+ | `EVM_PRIVATE_KEY` | **Yes** | — | EVM wallet private key (hex, with or without `0x`) for x402 payment signing |
56
+ | `X402_DEBUG_LOG` or `MCP_X402_DEBUG_LOG` | No | — | File path for debug log (append-only; use `tail -f` to inspect) |
57
+
58
+ ## Available Tools
59
+
60
+ ### x402_request
61
+
62
+ Execute one HTTP request to an x402-protected endpoint. If the server responds with `402 Payment Required`, the tool parses the payment requirements, builds and signs the payment payload, and retries the request with the `PAYMENT-SIGNATURE` header.
63
+
64
+ **Use only for endpoints that require payment (402).** Do not use for public or non-402 endpoints.
65
+
66
+ | Argument | Type | Required | Description |
67
+ | -------- | ---- | -------- | ----------- |
68
+ | `url` | string | **Yes** | Full URL of the endpoint (e.g. `http://localhost:8080/flight/order`) |
69
+ | `method` | string | No | `GET`, `POST`, `PUT`, or `PATCH`. Default: `POST`. |
70
+ | `body` | string | No | JSON string for request body (POST/PUT/PATCH). Omit for GET. |
71
+
72
+ **Examples (as passed by the client):**
73
+
74
+ - GET: `{ "url": "https://api.example.com/resource" }`
75
+ - POST: `{ "url": "https://api.example.com/order", "method": "POST", "body": "{\"flightId\":\"FL001\",\"uid\":\"100\"}" }`
76
+
77
+ ## Development
78
+
79
+ ```bash
80
+ # Install dependencies
81
+ pnpm install
82
+
83
+ # Build (output in dist/)
84
+ pnpm run build
85
+
86
+ # Run MCP locally (loads .env from package/repo root for EVM_PRIVATE_KEY)
87
+ pnpm start
88
+ # or without build step
89
+ pnpm run dev
90
+
91
+ # Run the fetch demo (POST to a configurable x402 endpoint)
92
+ pnpm run fetch
93
+ ```
94
+
95
+ The fetch demo uses `RESOURCE_SERVER_URL` (default `http://localhost:4021`) and `ENDPOINT_PATH` (default `/weather`); set them in `.env` or the shell. See `test/fetch.ts` to change URL, method, or body.
96
+
97
+ ## How it works
98
+
99
+ - On first request, the server may respond with `402` and `PAYMENT-REQUIRED` (or a JSON body with payment requirements).
100
+ - The client parses requirements, selects a supported scheme/network (e.g. `exact` + `eth`/`base`), builds the EIP-3009–style payload, and signs with `EVM_PRIVATE_KEY`.
101
+ - It retries the same request with `PAYMENT-SIGNATURE` (and `Access-Control-Expose-Headers` for `PAYMENT-RESPONSE`).
102
+ - The final response (200 or error) and optional `PAYMENT-RESPONSE` header are returned to the caller.
103
+
104
+ ## License
105
+
106
+ MIT
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,195 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * x402 stdio bridge — standalone, no @x402/* dependencies.
4
+ *
5
+ * All x402 logic is inlined under x402-standalone/ so this package
6
+ * can be published and run via `npx -y gatepay-local-mcp` without
7
+ * depending on unpublished @x402/core, @x402/evm, @x402/fetch.
8
+ *
9
+ * One MCP tool: x402_request
10
+ * - url: full URL (required)
11
+ * - method: GET | POST | PUT | PATCH (default POST)
12
+ * - body: JSON string for request body (POST/PUT/PATCH); omit for GET
13
+ *
14
+ * Env:
15
+ * EVM_PRIVATE_KEY (required; when run via npx, pass via MCP "env" config)
16
+ * X402_DEBUG_LOG (optional) path to file — when set, append debug logs here (tail -f to debug)
17
+ */
18
+ import { config } from "dotenv";
19
+ import { createWriteStream, existsSync } from "node:fs";
20
+ import { fileURLToPath } from "node:url";
21
+ import { dirname, join } from "node:path";
22
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
23
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
24
+ import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
25
+ import { X402ClientStandalone, ExactEvmScheme, createSignerFromPrivateKey, wrapFetchWithPayment, } from "./x402-standalone/index.js";
26
+ const __dirname = dirname(fileURLToPath(import.meta.url));
27
+ function findPackageRoot(startDir) {
28
+ let dir = startDir;
29
+ for (;;) {
30
+ if (existsSync(join(dir, "package.json")))
31
+ return dir;
32
+ const parent = join(dir, "..");
33
+ if (parent === dir)
34
+ return startDir;
35
+ dir = parent;
36
+ }
37
+ }
38
+ const packageRoot = findPackageRoot(__dirname);
39
+ config({ path: join(packageRoot, ".env") });
40
+ const LOG_PATH = process.env.X402_DEBUG_LOG ?? process.env.MCP_X402_DEBUG_LOG;
41
+ const logStream = LOG_PATH
42
+ ? (() => {
43
+ try {
44
+ return createWriteStream(LOG_PATH, { flags: "a" });
45
+ }
46
+ catch (e) {
47
+ console.error("X402 debug log open failed:", e);
48
+ return null;
49
+ }
50
+ })()
51
+ : null;
52
+ function debugLog(msg, obj) {
53
+ if (!logStream)
54
+ return;
55
+ const line = `${new Date().toISOString()} ${msg}${obj != null ? " " + JSON.stringify(obj) : ""}\n`;
56
+ logStream.write(line);
57
+ }
58
+ const TOOL_NAME = "x402_request";
59
+ const INPUT_SCHEMA = {
60
+ type: "object",
61
+ properties: {
62
+ url: {
63
+ type: "string",
64
+ description: "Full URL of the x402-protected endpoint. Must be included in Skill; do not guess.",
65
+ },
66
+ method: {
67
+ type: "string",
68
+ description: "HTTP method: GET, POST, PUT, or PATCH. Default POST.",
69
+ },
70
+ body: {
71
+ type: "string",
72
+ description: 'JSON string request body for POST/PUT/PATCH. Omit for GET.',
73
+ },
74
+ },
75
+ required: ["url"],
76
+ };
77
+ const TOOL_DESCRIPTION = "Execute a single HTTP request with automatic x402 payment on 402. Use ONLY for endpoints that require payment (402). " +
78
+ "Pass full url and JSON body string as documented in the Skill. Do not use for plain/public list endpoints.";
79
+ async function main() {
80
+ const rawEvmKey = process.env.EVM_PRIVATE_KEY?.trim();
81
+ if (!rawEvmKey) {
82
+ debugLog("startup failed: EVM_PRIVATE_KEY missing");
83
+ console.error("❌ EVM_PRIVATE_KEY is required (wallet private key for x402 payment)");
84
+ process.exit(1);
85
+ }
86
+ const evmPrivateKey = (rawEvmKey.startsWith("0x") ? rawEvmKey : `0x${rawEvmKey}`);
87
+ const evmSigner = createSignerFromPrivateKey(evmPrivateKey);
88
+ const client = new X402ClientStandalone();
89
+ //client.register("gatelayer_testnet", new ExactEvmScheme(evmSigner));
90
+ client.register("eth", new ExactEvmScheme(evmSigner));
91
+ client.register("base", new ExactEvmScheme(evmSigner));
92
+ const fetchWithPayment = wrapFetchWithPayment(fetch, client);
93
+ const server = new Server({
94
+ name: "x402 Paid Request Bridge (standalone)",
95
+ version: "1.0.0",
96
+ });
97
+ server.registerCapabilities({ tools: { listChanged: false } });
98
+ server.setRequestHandler(ListToolsRequestSchema, () => ({
99
+ tools: [
100
+ {
101
+ name: TOOL_NAME,
102
+ description: TOOL_DESCRIPTION,
103
+ inputSchema: INPUT_SCHEMA,
104
+ },
105
+ ],
106
+ }));
107
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
108
+ const { name, arguments: args } = request.params;
109
+ debugLog("tool call", { name, args });
110
+ if (name !== TOOL_NAME) {
111
+ return {
112
+ content: [{ type: "text", text: `未知工具: ${name}. 仅支持 ${TOOL_NAME}。` }],
113
+ isError: true,
114
+ };
115
+ }
116
+ const params = (args ?? {});
117
+ const url = String(params.url ?? "").trim();
118
+ if (!url || !url.startsWith("http")) {
119
+ return {
120
+ content: [{ type: "text", text: "缺少或无效参数 url(需完整 http/https URL)。" }],
121
+ isError: true,
122
+ };
123
+ }
124
+ const method = String(params.method ?? "POST").trim().toUpperCase() || "POST";
125
+ const bodyStr = params.body != null ? String(params.body) : "";
126
+ try {
127
+ let init;
128
+ if (method === "GET") {
129
+ init = { method: "GET" };
130
+ }
131
+ else if (method === "POST" || method === "PUT" || method === "PATCH") {
132
+ if (bodyStr && bodyStr.trim()) {
133
+ try {
134
+ JSON.parse(bodyStr);
135
+ }
136
+ catch {
137
+ return {
138
+ content: [{ type: "text", text: "body 必须是合法 JSON 字符串。" }],
139
+ isError: true,
140
+ };
141
+ }
142
+ }
143
+ init = {
144
+ method,
145
+ headers: { "Content-Type": "application/json" },
146
+ body: bodyStr && bodyStr.trim() ? bodyStr : undefined,
147
+ };
148
+ }
149
+ else {
150
+ return {
151
+ content: [{ type: "text", text: `不支持的 method: ${method}` }],
152
+ isError: true,
153
+ };
154
+ }
155
+ debugLog("fetch start", { url, method });
156
+ const response = await fetchWithPayment(url, init);
157
+ const responseText = await response.text();
158
+ debugLog("fetch done", { url, status: response.status, textLen: responseText.length });
159
+ let text;
160
+ try {
161
+ const json = JSON.parse(responseText);
162
+ text = json.data != null ? JSON.stringify(json.data, null, 2) : JSON.stringify(json, null, 2);
163
+ }
164
+ catch {
165
+ text = responseText;
166
+ }
167
+ if (!response.ok && response.status !== 402) {
168
+ return {
169
+ content: [{ type: "text", text: `HTTP ${response.status}: ${text}` }],
170
+ isError: true,
171
+ };
172
+ }
173
+ return { content: [{ type: "text", text }], isError: false };
174
+ }
175
+ catch (err) {
176
+ const message = err instanceof Error ? err.message : String(err);
177
+ debugLog("request error", { url, method, error: message, stack: err instanceof Error ? err.stack : undefined });
178
+ const hint = message.toLowerCase().includes("fetch") || message.toLowerCase().includes("econnrefused")
179
+ ? " 请确认 url 可访问;402 支付需 EVM_PRIVATE_KEY 对应钱包有足够余额。"
180
+ : "";
181
+ return {
182
+ content: [{ type: "text", text: `请求失败: ${message}.${hint}` }],
183
+ isError: true,
184
+ };
185
+ }
186
+ });
187
+ const stdio = new StdioServerTransport();
188
+ await server.connect(stdio);
189
+ }
190
+ main().catch((err) => {
191
+ debugLog("fatal", { error: String(err), stack: err instanceof Error ? err.stack : undefined });
192
+ console.error("Fatal error:", err);
193
+ process.exit(1);
194
+ });
195
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Minimal x402 client: single network + scheme (gatelayer_testnet + exact), no @x402/* deps.
3
+ */
4
+ import type { PaymentPayload, PaymentRequired, SchemeNetworkClient } from "./types.js";
5
+ declare const X402_VERSION = 2;
6
+ export declare class X402ClientStandalone {
7
+ private readonly schemesByNetwork;
8
+ register(network: string, client: SchemeNetworkClient): this;
9
+ createPaymentPayload(paymentRequired: PaymentRequired): Promise<PaymentPayload>;
10
+ private selectPaymentRequirements;
11
+ }
12
+ export { X402_VERSION };
13
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAuB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAG5G,QAAA,MAAM,YAAY,IAAI,CAAC;AAEvB,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4D;IAE7F,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAQtD,oBAAoB,CAAC,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IA2BrF,OAAO,CAAC,yBAAyB;CAgBlC;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { findByNetworkAndScheme } from "./utils.js";
2
+ const X402_VERSION = 2;
3
+ export class X402ClientStandalone {
4
+ constructor() {
5
+ this.schemesByNetwork = new Map();
6
+ }
7
+ register(network, client) {
8
+ if (!this.schemesByNetwork.has(network)) {
9
+ this.schemesByNetwork.set(network, new Map());
10
+ }
11
+ this.schemesByNetwork.get(network).set(client.scheme, client);
12
+ return this;
13
+ }
14
+ async createPaymentPayload(paymentRequired) {
15
+ const requirements = this.selectPaymentRequirements(paymentRequired.x402Version, paymentRequired.accepts);
16
+ const schemeClient = findByNetworkAndScheme(this.schemesByNetwork, requirements.scheme, requirements.network);
17
+ if (!schemeClient) {
18
+ throw new Error(`No client registered for scheme ${requirements.scheme} and network ${requirements.network}`);
19
+ }
20
+ const partial = await schemeClient.createPaymentPayload(paymentRequired.x402Version, requirements);
21
+ return {
22
+ ...partial,
23
+ resource: paymentRequired.resource,
24
+ accepted: requirements,
25
+ extensions: paymentRequired.extensions,
26
+ };
27
+ }
28
+ selectPaymentRequirements(x402Version, accepts) {
29
+ const byNetwork = this.schemesByNetwork;
30
+ const supported = accepts.filter((r) => {
31
+ const schemes = byNetwork.get(r.network);
32
+ return schemes?.has(r.scheme);
33
+ });
34
+ if (supported.length === 0) {
35
+ throw new Error(`No registered client supports any of the payment requirements (x402 v${x402Version})`);
36
+ }
37
+ return supported[0];
38
+ }
39
+ }
40
+ export { X402_VERSION };
41
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/x402-standalone/client.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB,MAAM,OAAO,oBAAoB;IAAjC;QACmB,qBAAgB,GAAkD,IAAI,GAAG,EAAE,CAAC;IAqD/F,CAAC;IAnDC,QAAQ,CAAC,OAAe,EAAE,MAA2B;QACnD,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,eAAgC;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC,yBAAyB,CACjD,eAAe,CAAC,WAAW,EAC3B,eAAe,CAAC,OAAO,CACxB,CAAC;QACF,MAAM,YAAY,GAAG,sBAAsB,CACzC,IAAI,CAAC,gBAAgB,EACrB,YAAY,CAAC,MAAM,EACnB,YAAY,CAAC,OAAO,CACrB,CAAC;QACF,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,mCAAmC,YAAY,CAAC,MAAM,gBAAgB,YAAY,CAAC,OAAO,EAAE,CAC7F,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,oBAAoB,CACrD,eAAe,CAAC,WAAW,EAC3B,YAAY,CACb,CAAC;QACF,OAAO;YACL,GAAG,OAAO;YACV,QAAQ,EAAE,eAAe,CAAC,QAAQ;YAClC,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,eAAe,CAAC,UAAU;SACvC,CAAC;IACJ,CAAC;IAEO,yBAAyB,CAC/B,WAAmB,EACnB,OAA8B;QAE9B,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC;QACxC,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YACrC,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,wEAAwE,WAAW,GAAG,CACvF,CAAC;QACJ,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC;IACtB,CAAC;CACF;AAED,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Exact EVM scheme: create payment payload + sign (no @x402/* deps).
3
+ */
4
+ import type { PaymentPayload, PaymentRequirements } from "./types.js";
5
+ import type { ClientEvmSigner, SchemeNetworkClient } from "./types.js";
6
+ export declare class ExactEvmScheme implements SchemeNetworkClient {
7
+ private readonly signer;
8
+ readonly scheme = "exact";
9
+ constructor(signer: ClientEvmSigner);
10
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
11
+ private signAuthorization;
12
+ }
13
+ //# sourceMappingURL=exactEvmScheme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exactEvmScheme.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/exactEvmScheme.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,KAAK,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAmBvE,qBAAa,cAAe,YAAW,mBAAmB;IAG5C,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,QAAQ,CAAC,MAAM,WAAW;gBAEG,MAAM,EAAE,eAAe;IAE9C,oBAAoB,CACxB,WAAW,EAAE,MAAM,EACnB,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;YA4B7C,iBAAiB;CAyDhC"}
@@ -0,0 +1,86 @@
1
+ import { getAddress } from "viem";
2
+ import { buildEip712DigestTransferWithAuthorization, getGatelayerTestnetDomainSeparator, } from "./gatelayer.js";
3
+ import { createNonce, getEvmChainIdFromNetwork } from "./utils.js";
4
+ const authorizationTypes = {
5
+ TransferWithAuthorization: [
6
+ { name: "from", type: "address" },
7
+ { name: "to", type: "address" },
8
+ { name: "value", type: "uint256" },
9
+ { name: "validAfter", type: "uint256" },
10
+ { name: "validBefore", type: "uint256" },
11
+ { name: "nonce", type: "bytes32" },
12
+ ],
13
+ };
14
+ export class ExactEvmScheme {
15
+ constructor(signer) {
16
+ this.signer = signer;
17
+ this.scheme = "exact";
18
+ }
19
+ async createPaymentPayload(x402Version, paymentRequirements) {
20
+ const nonce = createNonce();
21
+ const now = Math.floor(Date.now() / 1000);
22
+ const maxTimeoutSeconds = Number(paymentRequirements.maxTimeoutSeconds);
23
+ const maxTimeout = Number.isFinite(maxTimeoutSeconds) && maxTimeoutSeconds > 0 ? maxTimeoutSeconds : 600;
24
+ const amount = paymentRequirements.amount;
25
+ const amountStr = amount != null && amount !== "" ? String(amount) : undefined;
26
+ if (amountStr === undefined) {
27
+ throw new Error("Payment requirements missing amount (required for EIP-3009 value). Check server 402 response accepts[].amount.");
28
+ }
29
+ const authorization = {
30
+ from: this.signer.address,
31
+ to: getAddress(paymentRequirements.payTo),
32
+ value: amountStr,
33
+ validAfter: (now - 600).toString(),
34
+ validBefore: (now + maxTimeout).toString(),
35
+ nonce,
36
+ };
37
+ const signature = await this.signAuthorization(authorization, paymentRequirements);
38
+ const payload = { authorization, signature };
39
+ return { x402Version, payload };
40
+ }
41
+ async signAuthorization(authorization, requirements) {
42
+ const domainSeparator = String(requirements.network) === "gatelayer_testnet"
43
+ ? getGatelayerTestnetDomainSeparator(requirements.asset ?? "")
44
+ : undefined;
45
+ if (domainSeparator) {
46
+ if (typeof this.signer.signDigest !== "function") {
47
+ throw new Error("For gatelayer_testnet use a signer with signDigest (e.g. createSignerFromPrivateKey).");
48
+ }
49
+ const digest = buildEip712DigestTransferWithAuthorization(domainSeparator, {
50
+ from: authorization.from,
51
+ to: authorization.to,
52
+ value: authorization.value,
53
+ validAfter: authorization.validAfter,
54
+ validBefore: authorization.validBefore,
55
+ nonce: authorization.nonce,
56
+ });
57
+ return this.signer.signDigest(digest);
58
+ }
59
+ const chainId = getEvmChainIdFromNetwork(requirements.network);
60
+ if (!requirements.extra?.name || !requirements.extra?.version) {
61
+ throw new Error(`EIP-712 domain parameters (name, version) are required in payment requirements for asset ${requirements.asset}`);
62
+ }
63
+ const { name, version } = requirements.extra;
64
+ const domain = {
65
+ name,
66
+ version,
67
+ chainId,
68
+ verifyingContract: getAddress(requirements.asset),
69
+ };
70
+ const message = {
71
+ from: getAddress(authorization.from),
72
+ to: getAddress(authorization.to),
73
+ value: BigInt(authorization.value),
74
+ validAfter: BigInt(authorization.validAfter),
75
+ validBefore: BigInt(authorization.validBefore),
76
+ nonce: authorization.nonce,
77
+ };
78
+ return await this.signer.signTypedData({
79
+ domain,
80
+ types: authorizationTypes,
81
+ primaryType: "TransferWithAuthorization",
82
+ message,
83
+ });
84
+ }
85
+ }
86
+ //# sourceMappingURL=exactEvmScheme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exactEvmScheme.js","sourceRoot":"","sources":["../../../src/x402-standalone/exactEvmScheme.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { X402ClientStandalone } from "./client.js";
2
+ export declare function wrapFetchWithPayment(fetchFn: typeof globalThis.fetch, client: X402ClientStandalone): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
3
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/fetch.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAIxD,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,EAChC,MAAM,EAAE,oBAAoB,GAC3B,CAAC,KAAK,EAAE,WAAW,GAAG,GAAG,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAuDrE"}
@@ -0,0 +1,48 @@
1
+ import { getPaymentRequiredResponse, encodePaymentSignatureHeader } from "./http.js";
2
+ import { normalizePaymentRequirements } from "./utils.js";
3
+ export function wrapFetchWithPayment(fetchFn, client) {
4
+ return async (input, init) => {
5
+ const request = new Request(input, init);
6
+ const clonedRequest = request.clone();
7
+ const response = await fetchFn(request);
8
+ if (response.status !== 402)
9
+ return response;
10
+ let paymentRequired;
11
+ try {
12
+ const getHeader = (name) => response.headers.get(name);
13
+ const responseText = await response.text();
14
+ let body;
15
+ try {
16
+ if (responseText)
17
+ body = JSON.parse(responseText);
18
+ }
19
+ catch {
20
+ /* ignore */
21
+ }
22
+ paymentRequired = getPaymentRequiredResponse(getHeader, body);
23
+ }
24
+ catch (error) {
25
+ throw new Error(`Failed to parse payment requirements: ${error instanceof Error ? error.message : "Unknown error"}`);
26
+ }
27
+ paymentRequired = {
28
+ ...paymentRequired,
29
+ accepts: normalizePaymentRequirements(paymentRequired.accepts),
30
+ };
31
+ let paymentPayload;
32
+ try {
33
+ paymentPayload = await client.createPaymentPayload(paymentRequired);
34
+ }
35
+ catch (error) {
36
+ throw new Error(`Failed to create payment payload: ${error instanceof Error ? error.message : "Unknown error"}`);
37
+ }
38
+ if (clonedRequest.headers.has("PAYMENT-SIGNATURE") ||
39
+ clonedRequest.headers.has("X-PAYMENT")) {
40
+ throw new Error("Payment already attempted");
41
+ }
42
+ const encoded = encodePaymentSignatureHeader(paymentPayload);
43
+ clonedRequest.headers.set("PAYMENT-SIGNATURE", encoded);
44
+ clonedRequest.headers.set("Access-Control-Expose-Headers", "PAYMENT-RESPONSE,X-PAYMENT-RESPONSE");
45
+ return fetchFn(clonedRequest);
46
+ };
47
+ }
48
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/x402-standalone/fetch.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAC;AACrF,OAAO,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAE1D,MAAM,UAAU,oBAAoB,CAClC,OAAgC,EAChC,MAA4B;IAE5B,OAAO,KAAK,EAAE,KAAwB,EAAE,IAAkB,EAAE,EAAE;QAC5D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAEtC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACxC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,QAAQ,CAAC;QAE7C,IAAI,eAAgC,CAAC;QACrC,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/D,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,IAAiC,CAAC;YACtC,IAAI,CAAC;gBACH,IAAI,YAAY;oBAAE,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAoB,CAAC;YACvE,CAAC;YAAC,MAAM,CAAC;gBACP,YAAY;YACd,CAAC;YACD,eAAe,GAAG,0BAA0B,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,yCAAyC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CACpG,CAAC;QACJ,CAAC;QAED,eAAe,GAAG;YAChB,GAAG,eAAe;YAClB,OAAO,EAAE,4BAA4B,CAAC,eAAe,CAAC,OAAO,CAAC;SAC/D,CAAC;QAEF,IAAI,cAA8B,CAAC;QACnC,IAAI,CAAC;YACH,cAAc,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,eAAe,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CACb,qCAAqC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAChG,CAAC;QACJ,CAAC;QAED,IACE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;YAC9C,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,EACtC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,OAAO,GAAG,4BAA4B,CAAC,cAAc,CAAC,CAAC;QAC7D,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;QACxD,aAAa,CAAC,OAAO,CAAC,GAAG,CACvB,+BAA+B,EAC/B,qCAAqC,CACtC,CAAC;QAEF,OAAO,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Gate Layer Testnet EIP-3009 digest (no @x402/* deps).
3
+ */
4
+ import type { Hex } from "viem";
5
+ export declare const GATELAYER_TESTNET_TOKEN_DOMAIN_SEPARATORS: Record<string, Hex>;
6
+ export declare function getGatelayerTestnetDomainSeparator(asset: string): Hex | undefined;
7
+ export interface TransferWithAuthorizationLike {
8
+ from: string;
9
+ to: string;
10
+ value: string;
11
+ validAfter: string;
12
+ validBefore: string;
13
+ nonce: Hex;
14
+ }
15
+ export declare function buildEip712DigestTransferWithAuthorization(domainSeparator: Hex, authorization: TransferWithAuthorizationLike): Hex;
16
+ //# sourceMappingURL=gatelayer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gatelayer.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/gatelayer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAGhC,eAAO,MAAM,yCAAyC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAKzE,CAAC;AAEF,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAEjF;AAKD,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,GAAG,CAAC;CACZ;AAMD,wBAAgB,0CAA0C,CACxD,eAAe,EAAE,GAAG,EACpB,aAAa,EAAE,6BAA6B,GAC3C,GAAG,CAeL"}
@@ -0,0 +1,29 @@
1
+ import { concatHex, keccak256, padHex, toHex } from "viem";
2
+ export const GATELAYER_TESTNET_TOKEN_DOMAIN_SEPARATORS = {
3
+ "0x9be8df37c788b244cfc28e46654ad5ec28a880af": "0x2c2d6b621e73a4a094449d1894717413742130fb20149ec48340ca0354d1a707",
4
+ "0x081ff58e7d7105ad400f4cc76becfd8684013a4d": "0x7c6ddc1021fbf24f4dbe62b331d83549a44e91bee3d396a33171bebe573b0fab",
5
+ };
6
+ export function getGatelayerTestnetDomainSeparator(asset) {
7
+ return GATELAYER_TESTNET_TOKEN_DOMAIN_SEPARATORS[asset?.toLowerCase() ?? ""];
8
+ }
9
+ const TRANSFER_WITH_AUTHORIZATION_TYPE = "TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)";
10
+ function transferWithAuthorizationTypeHash() {
11
+ return keccak256(new Uint8Array(new TextEncoder().encode(TRANSFER_WITH_AUTHORIZATION_TYPE)));
12
+ }
13
+ export function buildEip712DigestTransferWithAuthorization(domainSeparator, authorization) {
14
+ const typeHash = transferWithAuthorizationTypeHash();
15
+ const encoded = concatHex([
16
+ typeHash,
17
+ padHex(authorization.from, { size: 32 }),
18
+ padHex(authorization.to, { size: 32 }),
19
+ padHex(toHex(BigInt(authorization.value)), { size: 32 }),
20
+ padHex(toHex(BigInt(authorization.validAfter)), { size: 32 }),
21
+ padHex(toHex(BigInt(authorization.validBefore)), { size: 32 }),
22
+ authorization.nonce.length === 66
23
+ ? authorization.nonce
24
+ : padHex(authorization.nonce, { size: 32 }),
25
+ ]);
26
+ const structHash = keccak256(encoded);
27
+ return keccak256(concatHex(["0x1901", domainSeparator, structHash]));
28
+ }
29
+ //# sourceMappingURL=gatelayer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gatelayer.js","sourceRoot":"","sources":["../../../src/x402-standalone/gatelayer.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,MAAM,CAAC;AAE3D,MAAM,CAAC,MAAM,yCAAyC,GAAwB;IAC5E,4CAA4C,EAC1C,oEAA2E;IAC7E,4CAA4C,EAC1C,oEAA2E;CAC9E,CAAC;AAEF,MAAM,UAAU,kCAAkC,CAAC,KAAa;IAC9D,OAAO,yCAAyC,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,gCAAgC,GACpC,uHAAuH,CAAC;AAW1H,SAAS,iCAAiC;IACxC,OAAO,SAAS,CAAC,IAAI,UAAU,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,UAAU,0CAA0C,CACxD,eAAoB,EACpB,aAA4C;IAE5C,MAAM,QAAQ,GAAG,iCAAiC,EAAE,CAAC;IACrD,MAAM,OAAO,GAAG,SAAS,CAAC;QACxB,QAAQ;QACR,MAAM,CAAC,aAAa,CAAC,IAAW,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC/C,MAAM,CAAC,aAAa,CAAC,EAAS,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACxD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC7D,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QAC9D,aAAa,CAAC,KAAK,CAAC,MAAM,KAAK,EAAE;YAC/B,CAAC,CAAE,aAAa,CAAC,KAAa;YAC9B,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAY,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;KACrD,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,SAAS,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Standalone x402 HTTP: decode/encode payment required & payload (no @x402/* deps).
3
+ */
4
+ import type { PaymentPayload, PaymentRequired } from "./types.js";
5
+ export declare function decodePaymentRequiredHeader(paymentRequiredHeader: string): PaymentRequired;
6
+ export declare function encodePaymentSignatureHeader(paymentPayload: PaymentPayload): string;
7
+ export declare function getPaymentRequiredResponse(getHeader: (name: string) => string | null | undefined, body?: unknown): PaymentRequired;
8
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlE,wBAAgB,2BAA2B,CAAC,qBAAqB,EAAE,MAAM,GAAG,eAAe,CAK1F;AAED,wBAAgB,4BAA4B,CAAC,cAAc,EAAE,cAAc,GAAG,MAAM,CAEnF;AAED,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,EACtD,IAAI,CAAC,EAAE,OAAO,GACb,eAAe,CAgBjB"}
@@ -0,0 +1,26 @@
1
+ import { Base64EncodedRegex, safeBase64Decode, safeBase64Encode } from "./utils.js";
2
+ export function decodePaymentRequiredHeader(paymentRequiredHeader) {
3
+ if (!Base64EncodedRegex.test(paymentRequiredHeader)) {
4
+ throw new Error("Invalid payment required header");
5
+ }
6
+ return JSON.parse(safeBase64Decode(paymentRequiredHeader));
7
+ }
8
+ export function encodePaymentSignatureHeader(paymentPayload) {
9
+ return safeBase64Encode(JSON.stringify(paymentPayload));
10
+ }
11
+ export function getPaymentRequiredResponse(getHeader, body) {
12
+ const paymentRequired = getHeader("PAYMENT-REQUIRED");
13
+ if (paymentRequired) {
14
+ return decodePaymentRequiredHeader(paymentRequired);
15
+ }
16
+ if (body &&
17
+ typeof body === "object" &&
18
+ "x402Version" in body &&
19
+ "resource" in body &&
20
+ "accepts" in body &&
21
+ Array.isArray(body.accepts)) {
22
+ return body;
23
+ }
24
+ throw new Error("Invalid payment required response");
25
+ }
26
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/x402-standalone/http.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEpF,MAAM,UAAU,2BAA2B,CAAC,qBAA6B;IACvE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAoB,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,cAA8B;IACzE,OAAO,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,SAAsD,EACtD,IAAc;IAEd,MAAM,eAAe,GAAG,SAAS,CAAC,kBAAkB,CAAC,CAAC;IACtD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,2BAA2B,CAAC,eAAe,CAAC,CAAC;IACtD,CAAC;IACD,IACE,IAAI;QACJ,OAAO,IAAI,KAAK,QAAQ;QACxB,aAAa,IAAI,IAAI;QACrB,UAAU,IAAI,IAAI;QAClB,SAAS,IAAI,IAAI;QACjB,KAAK,CAAC,OAAO,CAAE,IAAwB,CAAC,OAAO,CAAC,EAChD,CAAC;QACD,OAAO,IAAuB,CAAC;IACjC,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;AACvD,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Standalone x402 (no @x402/* deps). For use by stdio-bridge-x402-request-standalone.
3
+ */
4
+ export { X402ClientStandalone } from "./client.js";
5
+ export { ExactEvmScheme } from "./exactEvmScheme.js";
6
+ export { createSignerFromPrivateKey } from "./signer.js";
7
+ export { wrapFetchWithPayment } from "./fetch.js";
8
+ export type { PaymentRequired, PaymentRequirements } from "./types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Standalone x402 (no @x402/* deps). For use by stdio-bridge-x402-request-standalone.
3
+ */
4
+ export { X402ClientStandalone } from "./client.js";
5
+ export { ExactEvmScheme } from "./exactEvmScheme.js";
6
+ export { createSignerFromPrivateKey } from "./signer.js";
7
+ export { wrapFetchWithPayment } from "./fetch.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/x402-standalone/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Hex } from "viem";
2
+ import type { ClientEvmSigner } from "./types.js";
3
+ export declare function createSignerFromPrivateKey(privateKey: Hex): ClientEvmSigner;
4
+ //# sourceMappingURL=signer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/signer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAGhC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgClD,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,GAAG,GAAG,eAAe,CAQ3E"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * EVM signer from private key with signDigest for gatelayer_testnet (no @x402/* deps).
3
+ */
4
+ import { signAsync } from "@noble/secp256k1";
5
+ import { hexToBytes } from "viem";
6
+ import { privateKeyToAccount } from "viem/accounts";
7
+ function toHexFromBytes(bytes) {
8
+ return Array.from(bytes)
9
+ .map((b) => b.toString(16).padStart(2, "0"))
10
+ .join("");
11
+ }
12
+ async function signDigestWithPrivateKey(digest, privateKey) {
13
+ const msg = hexToBytes(digest);
14
+ if (msg.length !== 32)
15
+ throw new Error(`Digest must be 32 bytes, got ${msg.length}`);
16
+ const key = hexToBytes(privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`);
17
+ const sig = (await signAsync(msg, key));
18
+ const compact = sig.toCompactRawBytes();
19
+ if (compact.length !== 64) {
20
+ throw new Error(`Expected 64-byte compact signature, got ${compact.length}`);
21
+ }
22
+ const recovery = sig.recovery ?? 0;
23
+ const v = 27 + (recovery & 1);
24
+ const rHex = toHexFromBytes(compact.slice(0, 32));
25
+ const sHex = toHexFromBytes(compact.slice(32, 64));
26
+ const vHex = v.toString(16).padStart(2, "0");
27
+ return `0x${rHex}${sHex}${vHex}`;
28
+ }
29
+ export function createSignerFromPrivateKey(privateKey) {
30
+ const key = (privateKey.startsWith("0x") ? privateKey : `0x${privateKey}`);
31
+ const account = privateKeyToAccount(key);
32
+ return {
33
+ address: account.address,
34
+ signTypedData: (msg) => account.signTypedData(msg),
35
+ signDigest: (digest) => signDigestWithPrivateKey(digest, key),
36
+ };
37
+ }
38
+ //# sourceMappingURL=signer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signer.js","sourceRoot":"","sources":["../../../src/x402-standalone/signer.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAKpD,SAAS,cAAc,CAAC,KAAiB;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;SAC3C,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,MAAW,EACX,UAAe;IAEf,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACrF,MAAM,GAAG,GAAG,UAAU,CACpB,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAC7D,CAAC;IACF,MAAM,GAAG,GAAG,CAAC,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAwB,CAAC;IAC/D,MAAM,OAAO,GAAG,GAAG,CAAC,iBAAiB,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,2CAA2C,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC7C,OAAO,KAAK,IAAI,GAAG,IAAI,GAAG,IAAI,EAAmB,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,UAAe;IACxD,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAQ,CAAC;IAClF,MAAM,OAAO,GAAG,mBAAmB,CAAC,GAAoB,CAAC,CAAC;IAC1D,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC;QAClD,UAAU,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,wBAAwB,CAAC,MAAM,EAAE,GAAG,CAAC;KAC9D,CAAC;AACJ,CAAC"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Standalone x402 types (no @x402/* deps).
3
+ */
4
+ export type Network = string;
5
+ export interface ResourceInfo {
6
+ url: string;
7
+ description: string;
8
+ mimeType: string;
9
+ }
10
+ export interface PaymentRequirements {
11
+ scheme: string;
12
+ network: Network;
13
+ asset: string;
14
+ amount: string;
15
+ payTo: string;
16
+ maxTimeoutSeconds: number;
17
+ extra: Record<string, unknown>;
18
+ }
19
+ export interface PaymentRequired {
20
+ x402Version: number;
21
+ error?: string;
22
+ resource: ResourceInfo;
23
+ accepts: PaymentRequirements[];
24
+ extensions?: Record<string, unknown>;
25
+ }
26
+ export interface PaymentPayload {
27
+ x402Version: number;
28
+ resource: ResourceInfo;
29
+ accepted: PaymentRequirements;
30
+ payload: Record<string, unknown>;
31
+ extensions?: Record<string, unknown>;
32
+ }
33
+ export interface ExactEvmPayloadV2 {
34
+ authorization: {
35
+ from: string;
36
+ to: string;
37
+ value: string;
38
+ validAfter: string;
39
+ validBefore: string;
40
+ nonce: `0x${string}`;
41
+ };
42
+ signature: `0x${string}`;
43
+ }
44
+ export type ClientEvmSigner = {
45
+ readonly address: `0x${string}`;
46
+ signTypedData(message: {
47
+ domain: Record<string, unknown>;
48
+ types: Record<string, unknown>;
49
+ primaryType: string;
50
+ message: Record<string, unknown>;
51
+ }): Promise<`0x${string}`>;
52
+ signDigest?(digest: `0x${string}`): Promise<`0x${string}`>;
53
+ };
54
+ export interface SchemeNetworkClient {
55
+ scheme: string;
56
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
57
+ }
58
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,KAAK,MAAM,EAAE,CAAC;KACtB,CAAC;IACF,SAAS,EAAE,KAAK,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,KAAK,MAAM,EAAE,CAAC;IAChC,aAAa,CAAC,OAAO,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,GAAG,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;IAC3B,UAAU,CAAC,CAAC,MAAM,EAAE,KAAK,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC;CAC5D,CAAC;AAEF,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,oBAAoB,CAClB,WAAW,EAAE,MAAM,EACnB,mBAAmB,EAAE,mBAAmB,GACvC,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC,CAAC;CAC7D"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Standalone x402 types (no @x402/* deps).
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/x402-standalone/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Standalone x402 utils: base64, createNonce, client lookup (no @x402/* deps).
3
+ */
4
+ import type { PaymentRequirements } from "./types.js";
5
+ export declare const Base64EncodedRegex: RegExp;
6
+ export declare function safeBase64Encode(data: string): string;
7
+ export declare function safeBase64Decode(data: string): string;
8
+ export declare function findSchemesByNetwork<T>(map: Map<string, Map<string, T>>, network: string): Map<string, T> | undefined;
9
+ export declare function findByNetworkAndScheme<T>(map: Map<string, Map<string, T>>, scheme: string, network: string): T | undefined;
10
+ export declare function createNonce(): `0x${string}`;
11
+ export declare const CHAIN_ID_GATELAYER_TESTNET = 10087;
12
+ export declare const CHAIN_ID_GATELAYER = 10088;
13
+ export declare const CHAIN_ID_ETH = 1;
14
+ export declare const CHAIN_ID_BASE = 8453;
15
+ export declare function getEvmChainIdFromNetwork(network: string): number;
16
+ export declare function normalizePaymentRequirements(accepts: PaymentRequirements[]): PaymentRequirements[];
17
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/x402-standalone/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGtD,eAAO,MAAM,kBAAkB,QAA2B,CAAC;AAE3D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOrD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED,wBAAgB,oBAAoB,CAAC,CAAC,EACpC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAChC,OAAO,EAAE,MAAM,GACd,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,SAAS,CAE5B;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,CAAC,GAAG,SAAS,CAEf;AAED,wBAAgB,WAAW,IAAI,KAAK,MAAM,EAAE,CAO3C;AAID,eAAO,MAAM,0BAA0B,QAAQ,CAAC;AAChD,eAAO,MAAM,kBAAkB,QAAQ,CAAC;AACxC,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,aAAa,OAAO,CAAC;AAElC,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAehE;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,mBAAmB,EAAE,CAWlG"}
@@ -0,0 +1,72 @@
1
+ import { toHex } from "viem";
2
+ export const Base64EncodedRegex = /^[A-Za-z0-9+/]*={0,2}$/;
3
+ export function safeBase64Encode(data) {
4
+ if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") {
5
+ const bytes = new TextEncoder().encode(data);
6
+ const binaryString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
7
+ return globalThis.btoa(binaryString);
8
+ }
9
+ return Buffer.from(data, "utf8").toString("base64");
10
+ }
11
+ export function safeBase64Decode(data) {
12
+ if (typeof globalThis !== "undefined" && typeof globalThis.atob === "function") {
13
+ const binaryString = globalThis.atob(data);
14
+ const bytes = new Uint8Array(binaryString.length);
15
+ for (let i = 0; i < binaryString.length; i++) {
16
+ bytes[i] = binaryString.charCodeAt(i);
17
+ }
18
+ return new TextDecoder("utf-8").decode(bytes);
19
+ }
20
+ return Buffer.from(data, "base64").toString("utf-8");
21
+ }
22
+ export function findSchemesByNetwork(map, network) {
23
+ return map.get(network);
24
+ }
25
+ export function findByNetworkAndScheme(map, scheme, network) {
26
+ return findSchemesByNetwork(map, network)?.get(scheme);
27
+ }
28
+ export function createNonce() {
29
+ const cryptoObj = typeof globalThis.crypto !== "undefined"
30
+ ? globalThis.crypto
31
+ : globalThis.crypto;
32
+ if (!cryptoObj)
33
+ throw new Error("Crypto API not available");
34
+ return toHex(cryptoObj.getRandomValues(new Uint8Array(32)));
35
+ }
36
+ const DEFAULT_MAX_TIMEOUT_SECONDS = 600;
37
+ export const CHAIN_ID_GATELAYER_TESTNET = 10087;
38
+ export const CHAIN_ID_GATELAYER = 10088;
39
+ export const CHAIN_ID_ETH = 1;
40
+ export const CHAIN_ID_BASE = 8453;
41
+ export function getEvmChainIdFromNetwork(network) {
42
+ const s = network.trim();
43
+ if (s === "gatelayer_testnet" || s === "eip155:10087")
44
+ return CHAIN_ID_GATELAYER_TESTNET;
45
+ if (s.startsWith("eip155:")) {
46
+ const chainIdStr = s.slice(7).trim();
47
+ const chainId = parseInt(chainIdStr, 10);
48
+ if (Number.isNaN(chainId) || chainIdStr === "" || String(chainId) !== chainIdStr) {
49
+ throw new Error(`unsupported network format: ${network} (expected eip155:CHAIN_ID)`);
50
+ }
51
+ return chainId;
52
+ }
53
+ if (s === "gatelayer")
54
+ return CHAIN_ID_GATELAYER;
55
+ if (s === "eth")
56
+ return CHAIN_ID_ETH;
57
+ if (s === "base")
58
+ return CHAIN_ID_BASE;
59
+ throw new Error(`unsupported network format: ${network} (expected eip155:CHAIN_ID or gatelayer_testnet)`);
60
+ }
61
+ export function normalizePaymentRequirements(accepts) {
62
+ return accepts.map((a) => {
63
+ const amount = a.amount;
64
+ const amountStr = amount != null && amount !== "" ? String(amount) : "0";
65
+ const maxTimeoutSeconds = Number(a.maxTimeoutSeconds);
66
+ const maxTimeout = Number.isFinite(maxTimeoutSeconds) && maxTimeoutSeconds > 0
67
+ ? maxTimeoutSeconds
68
+ : DEFAULT_MAX_TIMEOUT_SECONDS;
69
+ return { ...a, amount: amountStr, maxTimeoutSeconds: maxTimeout };
70
+ });
71
+ }
72
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/x402-standalone/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../test/fetch.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import { config } from "dotenv";
2
+ import { X402ClientStandalone, ExactEvmScheme, createSignerFromPrivateKey, wrapFetchWithPayment, } from "../src/x402-standalone/index.js";
3
+ import { safeBase64Decode } from "../src/x402-standalone/utils.js";
4
+ config();
5
+ const evmPrivateKey = process.env.EVM_PRIVATE_KEY;
6
+ const baseURL = process.env.RESOURCE_SERVER_URL || "http://localhost:4021";
7
+ const endpointPath = process.env.ENDPOINT_PATH || "/weather";
8
+ const url = `${baseURL}${endpointPath}`;
9
+ function getPaymentSettleResponse(getHeader) {
10
+ const raw = getHeader("PAYMENT-RESPONSE") ?? getHeader("X-PAYMENT-RESPONSE") ?? null;
11
+ if (!raw)
12
+ return null;
13
+ try {
14
+ return JSON.parse(safeBase64Decode(raw));
15
+ }
16
+ catch {
17
+ return { raw };
18
+ }
19
+ }
20
+ /**
21
+ * Example: use project-internal x402-standalone to request x402-protected endpoints.
22
+ *
23
+ * Registers gatelayer_testnet + exact EVM scheme only (no @x402/* deps).
24
+ *
25
+ * Required environment variables:
26
+ * - EVM_PRIVATE_KEY: The private key of the EVM signer
27
+ */
28
+ async function main() {
29
+ const evmSigner = createSignerFromPrivateKey(evmPrivateKey);
30
+ const client = new X402ClientStandalone();
31
+ client.register("eth", new ExactEvmScheme(evmSigner));
32
+ client.register("base", new ExactEvmScheme(evmSigner));
33
+ const fetchWithPayment = wrapFetchWithPayment(fetch, client);
34
+ console.log(`Making request to: ${url}\n`);
35
+ const response = await fetchWithPayment(url, {
36
+ method: "POST",
37
+ headers: { "Content-Type": "application/json" },
38
+ body: JSON.stringify({}),
39
+ });
40
+ const body = await response.json();
41
+ console.log("Response body:", body);
42
+ if (response.ok) {
43
+ const paymentResponse = getPaymentSettleResponse((name) => response.headers.get(name));
44
+ console.log("\nPayment response:", paymentResponse);
45
+ }
46
+ else {
47
+ console.log(`\nNo payment settled (response status: ${response.status})`);
48
+ }
49
+ }
50
+ main().catch(error => {
51
+ console.error(error?.response?.data?.error ?? error);
52
+ process.exit(1);
53
+ });
54
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../test/fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEnE,MAAM,EAAE,CAAC;AAET,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,eAAgC,CAAC;AACnE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,uBAAuB,CAAC;AAC3E,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,UAAU,CAAC;AAC7D,MAAM,GAAG,GAAG,GAAG,OAAO,GAAG,YAAY,EAAE,CAAC;AAExC,SAAS,wBAAwB,CAAC,SAA0C;IAC1E,MAAM,GAAG,GACP,SAAS,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC;IAC3E,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAY,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,EAAE,CAAC;IACjB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,0BAA0B,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC1C,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IAEvD,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE7D,OAAO,CAAC,GAAG,CAAC,sBAAsB,GAAG,IAAI,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE;QAC3C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;KACzB,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAEpC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,eAAe,GAAG,wBAAwB,CAAC,CAAC,IAAI,EAAE,EAAE,CACxD,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAC3B,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,0CAA0C,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC;IACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "gatepay-local-mcp",
3
+ "version": "1.0.0",
4
+ "description": "Gatepay Local (stdio) MCP server",
5
+ "type": "module",
6
+ "main": "dist/src/index.js",
7
+ "types": "dist/src/index.d.ts",
8
+ "bin": {
9
+ "gatepay-mcp": "dist/src/index.js"
10
+ },
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "prepublishOnly": "npm run build",
17
+ "start": "tsx src/index.ts",
18
+ "dev": "tsx src/index.ts",
19
+ "test": "tsx test/fetch.ts",
20
+ "fetch": "tsx test/fetch.ts",
21
+ "format": "prettier -c .prettierrc --write \"**/*.{ts,js,cjs,json,md}\"",
22
+ "format:check": "prettier -c .prettierrc --check \"**/*.{ts,js,cjs,json,md}\"",
23
+ "lint": "eslint . --fix",
24
+ "lint:check": "eslint ."
25
+ },
26
+ "dependencies": {
27
+ "@noble/secp256k1": "^2.2.0",
28
+ "@modelcontextprotocol/sdk": "^1.12.1",
29
+ "dotenv": "^16.4.7",
30
+ "viem": "^2.39.0"
31
+ },
32
+ "keywords": [
33
+ "x402",
34
+ "mcp",
35
+ "payment",
36
+ "stdio",
37
+ "model-context-protocol"
38
+ ],
39
+ "license": "MIT",
40
+ "devDependencies": {
41
+ "globals": "^15.14.0",
42
+ "@types/node": "^22.0.0",
43
+ "@eslint/js": "^9.24.0",
44
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
45
+ "@typescript-eslint/parser": "^8.29.1",
46
+ "eslint": "^9.24.0",
47
+ "eslint-plugin-import": "^2.31.0",
48
+ "eslint-plugin-jsdoc": "^50.6.9",
49
+ "eslint-plugin-prettier": "^5.2.6",
50
+ "prettier": "3.5.2",
51
+ "tsx": "^4.7.0",
52
+ "typescript": "^5.3.0"
53
+ }
54
+ }