x402-proxy 0.11.3 → 0.11.5

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 (2) hide show
  1. package/dist/bin/cli.js +170 -42
  2. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -13,13 +13,14 @@ import http from "node:http";
13
13
  import { randomUUID } from "node:crypto";
14
14
  import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
15
15
  import { homedir } from "node:os";
16
+ import { AsyncLocalStorage } from "node:async_hooks";
16
17
  //#region packages/x402-proxy/src/openclaw/defaults.ts
17
18
  const DEFAULT_SURF_PROVIDER_ID = "surf";
18
19
  const DEFAULT_SURF_BASE_URL = "/x402-proxy/v1";
19
20
  const DEFAULT_SURF_UPSTREAM_URL = "https://surf.cascade.fyi/api/v1/inference";
20
- const DEFAULT_SURF_MODELS = [
21
- {
22
- id: "anthropic/claude-opus-4.6",
21
+ /** Known model metadata for cost/capability enrichment. */
22
+ const MODEL_METADATA = {
23
+ "anthropic/claude-opus-4.6": {
23
24
  name: "Claude Opus 4.6",
24
25
  maxTokens: 2e5,
25
26
  reasoning: true,
@@ -32,8 +33,20 @@ const DEFAULT_SURF_MODELS = [
32
33
  },
33
34
  contextWindow: 2e5
34
35
  },
35
- {
36
- id: "anthropic/claude-sonnet-4.6",
36
+ "anthropic/claude-opus-4.5": {
37
+ name: "Claude Opus 4.5",
38
+ maxTokens: 2e5,
39
+ reasoning: true,
40
+ input: ["text", "image"],
41
+ cost: {
42
+ input: .015,
43
+ output: .075,
44
+ cacheRead: .0015,
45
+ cacheWrite: .01875
46
+ },
47
+ contextWindow: 2e5
48
+ },
49
+ "anthropic/claude-sonnet-4.6": {
37
50
  name: "Claude Sonnet 4.6",
38
51
  maxTokens: 2e5,
39
52
  reasoning: true,
@@ -46,8 +59,20 @@ const DEFAULT_SURF_MODELS = [
46
59
  },
47
60
  contextWindow: 2e5
48
61
  },
49
- {
50
- id: "x-ai/grok-4.20-beta",
62
+ "anthropic/claude-sonnet-4.5": {
63
+ name: "Claude Sonnet 4.5",
64
+ maxTokens: 2e5,
65
+ reasoning: true,
66
+ input: ["text", "image"],
67
+ cost: {
68
+ input: .003,
69
+ output: .015,
70
+ cacheRead: 3e-4,
71
+ cacheWrite: .00375
72
+ },
73
+ contextWindow: 2e5
74
+ },
75
+ "x-ai/grok-4.20-beta": {
51
76
  name: "Grok 4.20 Beta",
52
77
  maxTokens: 131072,
53
78
  reasoning: true,
@@ -60,8 +85,33 @@ const DEFAULT_SURF_MODELS = [
60
85
  },
61
86
  contextWindow: 131072
62
87
  },
63
- {
64
- id: "minimax/minimax-m2.5",
88
+ "x-ai/grok-4.1-fast": {
89
+ name: "Grok 4.1 Fast",
90
+ maxTokens: 131072,
91
+ reasoning: false,
92
+ input: ["text"],
93
+ cost: {
94
+ input: .001,
95
+ output: .005,
96
+ cacheRead: 0,
97
+ cacheWrite: 0
98
+ },
99
+ contextWindow: 131072
100
+ },
101
+ "minimax/minimax-m2.7": {
102
+ name: "MiniMax M2.7",
103
+ maxTokens: 1e6,
104
+ reasoning: false,
105
+ input: ["text"],
106
+ cost: {
107
+ input: .001,
108
+ output: .005,
109
+ cacheRead: 0,
110
+ cacheWrite: 0
111
+ },
112
+ contextWindow: 1e6
113
+ },
114
+ "minimax/minimax-m2.5": {
65
115
  name: "MiniMax M2.5",
66
116
  maxTokens: 1e6,
67
117
  reasoning: false,
@@ -74,8 +124,7 @@ const DEFAULT_SURF_MODELS = [
74
124
  },
75
125
  contextWindow: 1e6
76
126
  },
77
- {
78
- id: "moonshotai/kimi-k2.5",
127
+ "moonshotai/kimi-k2.5": {
79
128
  name: "Kimi K2.5",
80
129
  maxTokens: 131072,
81
130
  reasoning: true,
@@ -88,8 +137,7 @@ const DEFAULT_SURF_MODELS = [
88
137
  },
89
138
  contextWindow: 131072
90
139
  },
91
- {
92
- id: "z-ai/glm-5",
140
+ "z-ai/glm-5": {
93
141
  name: "GLM-5",
94
142
  maxTokens: 128e3,
95
143
  reasoning: false,
@@ -101,8 +149,85 @@ const DEFAULT_SURF_MODELS = [
101
149
  cacheWrite: 0
102
150
  },
103
151
  contextWindow: 128e3
152
+ },
153
+ "z-ai/glm-5-turbo": {
154
+ name: "GLM-5 Turbo",
155
+ maxTokens: 128e3,
156
+ reasoning: false,
157
+ input: ["text"],
158
+ cost: {
159
+ input: .001,
160
+ output: .005,
161
+ cacheRead: 0,
162
+ cacheWrite: 0
163
+ },
164
+ contextWindow: 128e3
165
+ },
166
+ "qwen/qwen-2.5-7b-instruct": {
167
+ name: "Qwen 2.5 7B Instruct",
168
+ maxTokens: 32768,
169
+ reasoning: false,
170
+ input: ["text"],
171
+ cost: {
172
+ input: 5e-4,
173
+ output: .002,
174
+ cacheRead: 0,
175
+ cacheWrite: 0
176
+ },
177
+ contextWindow: 131072
178
+ },
179
+ "stepfun/step-3.5-flash": {
180
+ name: "Step 3.5 Flash",
181
+ maxTokens: 131072,
182
+ reasoning: false,
183
+ input: ["text"],
184
+ cost: {
185
+ input: .001,
186
+ output: .005,
187
+ cacheRead: 0,
188
+ cacheWrite: 0
189
+ },
190
+ contextWindow: 131072
191
+ },
192
+ "xiaomi/mimo-v2-pro": {
193
+ name: "MiMo V2 Pro",
194
+ maxTokens: 131072,
195
+ reasoning: true,
196
+ input: ["text"],
197
+ cost: {
198
+ input: .001,
199
+ output: .005,
200
+ cacheRead: 0,
201
+ cacheWrite: 0
202
+ },
203
+ contextWindow: 131072
104
204
  }
105
- ];
205
+ };
206
+ const DEFAULT_CONTEXT_WINDOW = 131072;
207
+ const ZERO_COST = {
208
+ input: 0,
209
+ output: 0,
210
+ cacheRead: 0,
211
+ cacheWrite: 0
212
+ };
213
+ function modelFromId(id) {
214
+ const known = MODEL_METADATA[id];
215
+ if (known) return {
216
+ id,
217
+ ...known
218
+ };
219
+ return {
220
+ id,
221
+ name: (id.split("/").pop() ?? id).replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
222
+ maxTokens: DEFAULT_CONTEXT_WINDOW,
223
+ reasoning: false,
224
+ input: ["text"],
225
+ cost: ZERO_COST,
226
+ contextWindow: DEFAULT_CONTEXT_WINDOW
227
+ };
228
+ }
229
+ /** Static fallback models used when upstream fetch fails. */
230
+ const DEFAULT_SURF_MODELS = Object.keys(MODEL_METADATA).map(modelFromId);
106
231
  function resolveProviders(config) {
107
232
  const defaultProtocol = resolveProtocol(config.protocol);
108
233
  const defaultMppSessionBudget = resolveMppSessionBudget(config.mppSessionBudget);
@@ -2321,7 +2446,7 @@ Wallet is auto-generated on first run. No env vars needed.`
2321
2446
  }
2322
2447
  const remoteClient = new Client({
2323
2448
  name: "x402-proxy",
2324
- version: "0.11.3"
2449
+ version: "0.11.5"
2325
2450
  });
2326
2451
  await connectTransport(remoteClient);
2327
2452
  function recordX402Payment(ctx) {
@@ -2352,7 +2477,7 @@ Wallet is auto-generated on first run. No env vars needed.`
2352
2477
  }
2353
2478
  const localServer = new Server({
2354
2479
  name: "x402-proxy",
2355
- version: "0.11.3"
2480
+ version: "0.11.5"
2356
2481
  }, { capabilities: {
2357
2482
  tools: tools.length > 0 ? {} : void 0,
2358
2483
  resources: remoteResources.length > 0 ? {} : void 0
@@ -2411,7 +2536,7 @@ Wallet is auto-generated on first run. No env vars needed.`
2411
2536
  const { privateKeyToAccount } = await import("../accounts-D5u2KBgr.js");
2412
2537
  const account = privateKeyToAccount(wallet.evmKey);
2413
2538
  const maxDeposit = config?.mppSessionBudget ?? "1";
2414
- let lastChallengeAmount;
2539
+ const challengeAmountStore = new AsyncLocalStorage();
2415
2540
  const wrappedMethods = tempo({
2416
2541
  account,
2417
2542
  maxDeposit
@@ -2419,13 +2544,14 @@ Wallet is auto-generated on first run. No env vars needed.`
2419
2544
  ...m,
2420
2545
  createCredential: async (params) => {
2421
2546
  const req = params.challenge.request;
2422
- if (req.amount) lastChallengeAmount = Number(req.amount) / 10 ** (req.decimals ?? 6);
2547
+ const store = challengeAmountStore.getStore();
2548
+ if (req.amount && store) store.amount = Number(req.amount) / 10 ** (req.decimals ?? 6);
2423
2549
  return m.createCredential(params);
2424
2550
  }
2425
2551
  }));
2426
2552
  const remoteClient = new Client({
2427
2553
  name: "x402-proxy",
2428
- version: "0.11.3"
2554
+ version: "0.11.5"
2429
2555
  });
2430
2556
  await connectTransport(remoteClient);
2431
2557
  const mppClient = McpClient.wrap(remoteClient, { methods: wrappedMethods });
@@ -2440,7 +2566,7 @@ Wallet is auto-generated on first run. No env vars needed.`
2440
2566
  }
2441
2567
  const localServer = new Server({
2442
2568
  name: "x402-proxy",
2443
- version: "0.11.3"
2569
+ version: "0.11.5"
2444
2570
  }, { capabilities: {
2445
2571
  tools: tools.length > 0 ? {} : void 0,
2446
2572
  resources: remoteResources.length > 0 ? {} : void 0
@@ -2448,28 +2574,30 @@ Wallet is auto-generated on first run. No env vars needed.`
2448
2574
  localServer.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: tools.map((t) => cloneTool(t)) }));
2449
2575
  localServer.setRequestHandler(CallToolRequestSchema, async (request) => {
2450
2576
  const { name, arguments: args } = request.params;
2451
- const result = await mppClient.callTool({
2452
- name,
2453
- arguments: args ?? {}
2577
+ const store = { amount: void 0 };
2578
+ return challengeAmountStore.run(store, async () => {
2579
+ const result = await mppClient.callTool({
2580
+ name,
2581
+ arguments: args ?? {}
2582
+ });
2583
+ if (result.receipt) {
2584
+ const record = {
2585
+ t: Date.now(),
2586
+ ok: true,
2587
+ kind: "mpp_payment",
2588
+ net: TEMPO_NETWORK,
2589
+ from: wallet.evmAddress ?? "unknown",
2590
+ tx: result.receipt.reference,
2591
+ amount: store.amount,
2592
+ token: "USDC",
2593
+ label: `mcp:${name}`
2594
+ };
2595
+ appendHistory(getHistoryPath(), record);
2596
+ const amountStr = store.amount !== void 0 ? formatAmount(store.amount, "USDC") : "";
2597
+ warn(` MPP payment for tool "${name}" (Tempo)${amountStr ? ` \u00b7 ${amountStr}` : ""}`);
2598
+ }
2599
+ return normalizeCallToolResult(result);
2454
2600
  });
2455
- if (result.receipt) {
2456
- const record = {
2457
- t: Date.now(),
2458
- ok: true,
2459
- kind: "mpp_payment",
2460
- net: TEMPO_NETWORK,
2461
- from: wallet.evmAddress ?? "unknown",
2462
- tx: result.receipt.reference,
2463
- amount: lastChallengeAmount,
2464
- token: "USDC",
2465
- label: `mcp:${name}`
2466
- };
2467
- appendHistory(getHistoryPath(), record);
2468
- const amountStr = lastChallengeAmount !== void 0 ? formatAmount(lastChallengeAmount, "USDC") : "";
2469
- warn(` MPP payment for tool "${name}" (Tempo)${amountStr ? ` \u00b7 ${amountStr}` : ""}`);
2470
- lastChallengeAmount = void 0;
2471
- }
2472
- return normalizeCallToolResult(result);
2473
2601
  });
2474
2602
  if (remoteResources.length > 0) {
2475
2603
  localServer.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: remoteResources.map((r) => cloneResource(r)) }));
@@ -2826,7 +2954,7 @@ const app = buildApplication(buildRouteMap({
2826
2954
  docs: { brief: "curl for x402 paid APIs" }
2827
2955
  }), {
2828
2956
  name: "x402-proxy",
2829
- versionInfo: { currentVersion: "0.11.3" },
2957
+ versionInfo: { currentVersion: "0.11.5" },
2830
2958
  scanner: { caseStyle: "allow-kebab-for-camel" }
2831
2959
  });
2832
2960
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "x402-proxy",
3
3
  "description": "curl for x402 paid APIs. Auto-pays any endpoint on Base, Solana, and Tempo.",
4
- "version": "0.11.3",
4
+ "version": "0.11.5",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "license": "Apache-2.0",