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.
- package/Readme.md +106 -0
- package/dist/src/index.d.ts +3 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +195 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/x402-standalone/client.d.ts +13 -0
- package/dist/src/x402-standalone/client.d.ts.map +1 -0
- package/dist/src/x402-standalone/client.js +41 -0
- package/dist/src/x402-standalone/client.js.map +1 -0
- package/dist/src/x402-standalone/exactEvmScheme.d.ts +13 -0
- package/dist/src/x402-standalone/exactEvmScheme.d.ts.map +1 -0
- package/dist/src/x402-standalone/exactEvmScheme.js +86 -0
- package/dist/src/x402-standalone/exactEvmScheme.js.map +1 -0
- package/dist/src/x402-standalone/fetch.d.ts +3 -0
- package/dist/src/x402-standalone/fetch.d.ts.map +1 -0
- package/dist/src/x402-standalone/fetch.js +48 -0
- package/dist/src/x402-standalone/fetch.js.map +1 -0
- package/dist/src/x402-standalone/gatelayer.d.ts +16 -0
- package/dist/src/x402-standalone/gatelayer.d.ts.map +1 -0
- package/dist/src/x402-standalone/gatelayer.js +29 -0
- package/dist/src/x402-standalone/gatelayer.js.map +1 -0
- package/dist/src/x402-standalone/http.d.ts +8 -0
- package/dist/src/x402-standalone/http.d.ts.map +1 -0
- package/dist/src/x402-standalone/http.js +26 -0
- package/dist/src/x402-standalone/http.js.map +1 -0
- package/dist/src/x402-standalone/index.d.ts +9 -0
- package/dist/src/x402-standalone/index.d.ts.map +1 -0
- package/dist/src/x402-standalone/index.js +8 -0
- package/dist/src/x402-standalone/index.js.map +1 -0
- package/dist/src/x402-standalone/signer.d.ts +4 -0
- package/dist/src/x402-standalone/signer.d.ts.map +1 -0
- package/dist/src/x402-standalone/signer.js +38 -0
- package/dist/src/x402-standalone/signer.js.map +1 -0
- package/dist/src/x402-standalone/types.d.ts +58 -0
- package/dist/src/x402-standalone/types.d.ts.map +1 -0
- package/dist/src/x402-standalone/types.js +5 -0
- package/dist/src/x402-standalone/types.js.map +1 -0
- package/dist/src/x402-standalone/utils.d.ts +17 -0
- package/dist/src/x402-standalone/utils.d.ts.map +1 -0
- package/dist/src/x402-standalone/utils.js +72 -0
- package/dist/src/x402-standalone/utils.js.map +1 -0
- package/dist/test/fetch.d.ts +2 -0
- package/dist/test/fetch.d.ts.map +1 -0
- package/dist/test/fetch.js +54 -0
- package/dist/test/fetch.js.map +1 -0
- 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 @@
|
|
|
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":";AACA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,0BAA0B,EAC1B,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,SAAS,eAAe,CAAC,QAAgB;IACvC,IAAI,GAAG,GAAG,QAAQ,CAAC;IACnB,SAAS,CAAC;QACR,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC/B,IAAI,MAAM,KAAK,GAAG;YAAE,OAAO,QAAQ,CAAC;QACpC,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;AAC/C,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;AAE5C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;AAC9E,MAAM,SAAS,GAAG,QAAQ;IACxB,CAAC,CAAC,CAAC,GAAG,EAAE;QACN,IAAI,CAAC;YACH,OAAO,iBAAiB,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,CAAC,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,EAAE;IACJ,CAAC,CAAC,IAAI,CAAC;AAET,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAa;IAC1C,IAAI,CAAC,SAAS;QAAE,OAAO;IACvB,MAAM,IAAI,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,GAAG,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IACnG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,SAAS,GAAG,cAAc,CAAC;AAEjC,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,QAAiB;IACvB,UAAU,EAAE;QACV,GAAG,EAAE;YACH,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,mFAAmF;SACtF;QACD,MAAM,EAAE;YACN,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,sDAAsD;SACpE;QACD,IAAI,EAAE;YACJ,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,4DAA4D;SAC/D;KACF;IACD,QAAQ,EAAE,CAAC,KAAK,CAAC;CAClB,CAAC;AAEF,MAAM,gBAAgB,GACpB,uHAAuH;IACvH,4GAA4G,CAAC;AAE/G,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,QAAQ,CAAC,yCAAyC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,qEAAqE,CAAC,CAAC;QACrF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,aAAa,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAkB,CAAC;IAEnG,MAAM,SAAS,GAAG,0BAA0B,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC1C,sEAAsE;IACtE,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;IACvD,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC;QACxB,IAAI,EAAE,uCAAuC;QAC7C,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IACH,MAAM,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IAE/D,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,CAAC;QACtD,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,gBAAgB;gBAC7B,WAAW,EAAE,YAAY;aAC1B;SACF;KACF,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,QAAQ,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,SAAS,IAAI,SAAS,SAAS,GAAG,EAAE,CAAC;gBAC9E,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;QACvD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,kCAAkC,EAAE,CAAC;gBAC9E,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC;QAC9E,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE/D,IAAI,CAAC;YACH,IAAI,IAAiB,CAAC;YACtB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;gBACrB,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAC3B,CAAC;iBAAM,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvE,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC9B,IAAI,CAAC;wBACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;oBACtB,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO;4BACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,sBAAsB,EAAE,CAAC;4BAClE,OAAO,EAAE,IAAI;yBACd,CAAC;oBACJ,CAAC;gBACH,CAAC;gBACD,IAAI,GAAG;oBACL,MAAM;oBACN,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBAC/C,IAAI,EAAE,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;iBACtD,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,gBAAgB,MAAM,EAAE,EAAE,CAAC;oBACpE,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,QAAQ,CAAC,aAAa,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC3C,QAAQ,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC;YAEvF,IAAI,IAAY,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAuB,CAAC;gBAC5D,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAChG,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,YAAY,CAAC;YACtB,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5C,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,QAAQ,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,EAAE,CAAC;oBAC9E,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACxE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,QAAQ,CAAC,eAAe,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;YAChH,MAAM,IAAI,GACR,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;gBACvF,CAAC,CAAC,iDAAiD;gBACnD,CAAC,CAAC,EAAE,CAAC;YACT,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,SAAS,OAAO,IAAI,IAAI,EAAE,EAAE,CAAC;gBACtE,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,IAAI,oBAAoB,EAAE,CAAC;IACzC,MAAM,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,QAAQ,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC/F,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC;IACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|
+
}
|