x402-proxy 0.4.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -2
- package/dist/bin/cli.js +58 -31
- package/dist/{status-DrC0uxCS.js → status-BVIU3-b6.js} +1 -1
- package/dist/{status-DxW72Hx6.js → status-BoH_1kIH.js} +1 -1
- package/dist/{wallet-BHywTzdN.js → wallet-BMYYtAP6.js} +20 -8
- package/dist/wallet-BoY0fgX7.js +4 -0
- package/package.json +1 -1
- package/dist/wallet-DFhJWn3o.js +0 -4
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.5.1] - 2026-03-19
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Solana USDC balance showing 0.0000 instead of actual balance due to `getTokenAccountsByOwner` being rate-limited (429) on public Solana RPC
|
|
14
|
+
- Replaced with offline ATA derivation via `@solana/kit` + lightweight `getTokenAccountBalance` call that works reliably on any public RPC
|
|
15
|
+
- RPC errors now show `?` instead of silently displaying `0.0000`
|
|
16
|
+
|
|
17
|
+
## [0.5.0] - 2026-03-16
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- MCP proxy graduated from alpha to stable - removed alpha warning and label
|
|
21
|
+
- MCP proxy uses low-level `Server` class instead of `McpServer` to proxy raw JSON schemas verbatim without Zod conversion
|
|
22
|
+
- MCP proxy now forwards blob resource contents (previously only text was proxied)
|
|
23
|
+
- MCP content type widened to pass through all MCP content types (image, audio, resource_link) not just text
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
- MCP proxy forwards `notifications/tools/list_changed` and `notifications/resources/list_changed` from remote servers so local clients stay in sync with dynamic tool/resource updates
|
|
27
|
+
|
|
10
28
|
## [0.4.2] - 2026-03-16
|
|
11
29
|
|
|
12
30
|
### Fixed
|
|
@@ -105,7 +123,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
105
123
|
### Added
|
|
106
124
|
- CLI binary accessible via `npx x402-proxy`
|
|
107
125
|
- `fetch` command (default) - curl-like HTTP client with automatic x402 payment
|
|
108
|
-
- `mcp` command
|
|
126
|
+
- `mcp` command - MCP stdio proxy with auto-payment for AI agents
|
|
109
127
|
- `setup` command - interactive onboarding wizard with @clack/prompts
|
|
110
128
|
- `status` command - config, wallet, and spend summary
|
|
111
129
|
- `wallet` subcommand with `info`, `history`, `fund`, `export-key`
|
|
@@ -129,7 +147,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
129
147
|
- `appendHistory` / `readHistory` / `calcSpend` - JSONL transaction history
|
|
130
148
|
- Re-exports from `@x402/fetch`, `@x402/svm`, `@x402/evm`
|
|
131
149
|
|
|
132
|
-
[Unreleased]: https://github.com/cascade-protocol/x402-proxy/compare/v0.
|
|
150
|
+
[Unreleased]: https://github.com/cascade-protocol/x402-proxy/compare/v0.5.1...HEAD
|
|
151
|
+
[0.5.1]: https://github.com/cascade-protocol/x402-proxy/compare/v0.5.0...v0.5.1
|
|
152
|
+
[0.5.0]: https://github.com/cascade-protocol/x402-proxy/compare/v0.4.2...v0.5.0
|
|
133
153
|
[0.4.2]: https://github.com/cascade-protocol/x402-proxy/compare/v0.4.1...v0.4.2
|
|
134
154
|
[0.4.1]: https://github.com/cascade-protocol/x402-proxy/compare/v0.4.0...v0.4.1
|
|
135
155
|
[0.4.0]: https://github.com/cascade-protocol/x402-proxy/compare/v0.3.2...v0.4.0
|
package/dist/bin/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as buildX402Client, c as error, d as warn, f as appendHistory, g as readHistory, h as formatTxLine, i as walletInfoCommand, l as info, m as displayNetwork, o as resolveWallet, p as calcSpend, s as dim, u as isTTY } from "../wallet-
|
|
2
|
+
import { a as buildX402Client, c as error, d as warn, f as appendHistory, g as readHistory, h as formatTxLine, i as walletInfoCommand, l as info, m as displayNetwork, o as resolveWallet, p as calcSpend, s as dim, u as isTTY } from "../wallet-BMYYtAP6.js";
|
|
3
3
|
import { c as isConfigured, i as ensureConfigDir, l as loadConfig, o as getHistoryPath, u as loadWalletFile } from "../derive-CISr_ond.js";
|
|
4
4
|
import { n as setupCommand } from "../setup-gla-Qyqi.js";
|
|
5
|
-
import { n as statusCommand } from "../status-
|
|
5
|
+
import { n as statusCommand } from "../status-BoH_1kIH.js";
|
|
6
6
|
import { buildApplication, buildCommand, buildRouteMap, run } from "@stricli/core";
|
|
7
7
|
import pc from "picocolors";
|
|
8
8
|
import { decodePaymentResponseHeader, wrapFetchWithPayment } from "@x402/fetch";
|
|
@@ -118,7 +118,7 @@ Examples:
|
|
|
118
118
|
async func(flags, url) {
|
|
119
119
|
if (!url) {
|
|
120
120
|
if (isConfigured()) {
|
|
121
|
-
const { displayStatus } = await import("../status-
|
|
121
|
+
const { displayStatus } = await import("../status-BVIU3-b6.js");
|
|
122
122
|
await displayStatus();
|
|
123
123
|
console.log();
|
|
124
124
|
console.log(pc.dim(" Commands:"));
|
|
@@ -179,7 +179,7 @@ Examples:
|
|
|
179
179
|
const config = loadConfig();
|
|
180
180
|
let preferredNetwork = config?.defaultNetwork;
|
|
181
181
|
if (!preferredNetwork && wallet.evmAddress && wallet.solanaAddress) {
|
|
182
|
-
const { fetchEvmBalances, fetchSolanaBalances } = await import("../wallet-
|
|
182
|
+
const { fetchEvmBalances, fetchSolanaBalances } = await import("../wallet-BoY0fgX7.js");
|
|
183
183
|
const [evmBal, solBal] = await Promise.allSettled([fetchEvmBalances(wallet.evmAddress), fetchSolanaBalances(wallet.solanaAddress)]);
|
|
184
184
|
const evmUsdc = evmBal.status === "fulfilled" ? Number(evmBal.value?.usdc ?? 0) : 0;
|
|
185
185
|
const solUsdc = solBal.status === "fulfilled" ? Number(solBal.value?.usdc ?? 0) : 0;
|
|
@@ -231,7 +231,7 @@ Examples:
|
|
|
231
231
|
const hasEvm = accepts.some((a) => a.network.startsWith("eip155:"));
|
|
232
232
|
const hasSolana = accepts.some((a) => a.network.startsWith("solana:"));
|
|
233
233
|
const hasOther = accepts.some((a) => !a.network.startsWith("eip155:") && !a.network.startsWith("solana:"));
|
|
234
|
-
const { fetchEvmBalances, fetchSolanaBalances } = await import("../wallet-
|
|
234
|
+
const { fetchEvmBalances, fetchSolanaBalances } = await import("../wallet-BoY0fgX7.js");
|
|
235
235
|
let evmUsdc = 0;
|
|
236
236
|
let solUsdc = 0;
|
|
237
237
|
if (hasEvm && wallet.evmAddress) try {
|
|
@@ -330,7 +330,7 @@ Examples:
|
|
|
330
330
|
//#region src/commands/mcp.ts
|
|
331
331
|
const mcpCommand = buildCommand({
|
|
332
332
|
docs: {
|
|
333
|
-
brief: "Start MCP stdio proxy with x402 payment
|
|
333
|
+
brief: "Start MCP stdio proxy with x402 payment",
|
|
334
334
|
fullDescription: `Start an MCP stdio proxy with automatic x402 payment for AI agents.
|
|
335
335
|
|
|
336
336
|
Add to your MCP client config (Claude, Cursor, etc.):
|
|
@@ -376,14 +376,13 @@ Add to your MCP client config (Claude, Cursor, etc.):
|
|
|
376
376
|
error("No wallet configured.\nRun:\n $ npx x402-proxy setup\n\nOr set X402_PROXY_WALLET_MNEMONIC");
|
|
377
377
|
process.exit(1);
|
|
378
378
|
}
|
|
379
|
-
warn("Note: MCP proxy is alpha - please report issues.");
|
|
380
379
|
dim(`x402-proxy MCP proxy -> ${remoteUrl}`);
|
|
381
380
|
if (wallet.evmAddress) dim(` EVM: ${wallet.evmAddress}`);
|
|
382
381
|
if (wallet.solanaAddress) dim(` Solana: ${wallet.solanaAddress}`);
|
|
383
382
|
const config = loadConfig();
|
|
384
383
|
let preferredNetwork = config?.defaultNetwork;
|
|
385
384
|
if (!preferredNetwork && wallet.evmAddress && wallet.solanaAddress) {
|
|
386
|
-
const { fetchEvmBalances, fetchSolanaBalances } = await import("../wallet-
|
|
385
|
+
const { fetchEvmBalances, fetchSolanaBalances } = await import("../wallet-BoY0fgX7.js");
|
|
387
386
|
const [evmBal, solBal] = await Promise.allSettled([fetchEvmBalances(wallet.evmAddress), fetchSolanaBalances(wallet.solanaAddress)]);
|
|
388
387
|
const evmUsdc = evmBal.status === "fulfilled" ? Number(evmBal.value?.usdc ?? 0) : 0;
|
|
389
388
|
const solUsdc = solBal.status === "fulfilled" ? Number(solBal.value?.usdc ?? 0) : 0;
|
|
@@ -399,13 +398,14 @@ Add to your MCP client config (Claude, Cursor, etc.):
|
|
|
399
398
|
const { Client } = await import("@modelcontextprotocol/sdk/client/index.js");
|
|
400
399
|
const { SSEClientTransport } = await import("@modelcontextprotocol/sdk/client/sse.js");
|
|
401
400
|
const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
402
|
-
const {
|
|
401
|
+
const { Server } = await import("@modelcontextprotocol/sdk/server/index.js");
|
|
403
402
|
const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
|
|
404
403
|
const { x402MCPClient } = await import("@x402/mcp");
|
|
405
|
-
const
|
|
404
|
+
const remoteClient = new Client({
|
|
406
405
|
name: "x402-proxy",
|
|
407
|
-
version: "0.
|
|
408
|
-
})
|
|
406
|
+
version: "0.5.1"
|
|
407
|
+
});
|
|
408
|
+
const x402Mcp = new x402MCPClient(remoteClient, x402PaymentClient, {
|
|
409
409
|
autoPayment: true,
|
|
410
410
|
onPaymentRequested: (ctx) => {
|
|
411
411
|
const accept = ctx.paymentRequired.accepts?.[0];
|
|
@@ -447,31 +447,58 @@ Add to your MCP client config (Claude, Cursor, etc.):
|
|
|
447
447
|
error(`Failed to connect to ${remoteUrl}: ${err instanceof Error ? err.message : String(err)}`);
|
|
448
448
|
process.exit(1);
|
|
449
449
|
}
|
|
450
|
-
|
|
450
|
+
let { tools } = await x402Mcp.listTools();
|
|
451
451
|
dim(` ${tools.length} tools available`);
|
|
452
|
-
|
|
452
|
+
let remoteResources = [];
|
|
453
|
+
try {
|
|
454
|
+
remoteResources = (await x402Mcp.listResources()).resources;
|
|
455
|
+
if (remoteResources.length > 0) dim(` ${remoteResources.length} resources available`);
|
|
456
|
+
} catch {
|
|
457
|
+
dim(" Resources not available from remote");
|
|
458
|
+
}
|
|
459
|
+
const localServer = new Server({
|
|
453
460
|
name: "x402-proxy",
|
|
454
|
-
version: "0.
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
|
|
461
|
+
version: "0.5.1"
|
|
462
|
+
}, { capabilities: {
|
|
463
|
+
tools: tools.length > 0 ? {} : void 0,
|
|
464
|
+
resources: remoteResources.length > 0 ? {} : void 0
|
|
465
|
+
} });
|
|
466
|
+
const { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ToolListChangedNotificationSchema, ResourceListChangedNotificationSchema } = await import("@modelcontextprotocol/sdk/types.js");
|
|
467
|
+
localServer.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: tools.map((t) => ({
|
|
468
|
+
name: t.name,
|
|
469
|
+
description: t.description,
|
|
470
|
+
inputSchema: t.inputSchema,
|
|
471
|
+
annotations: t.annotations
|
|
472
|
+
})) }));
|
|
473
|
+
localServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
474
|
+
const { name, arguments: args } = request.params;
|
|
475
|
+
const result = await x402Mcp.callTool(name, args ?? {});
|
|
458
476
|
return {
|
|
459
477
|
content: result.content,
|
|
460
478
|
isError: result.isError
|
|
461
479
|
};
|
|
462
480
|
});
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
481
|
+
if (remoteResources.length > 0) {
|
|
482
|
+
localServer.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: remoteResources.map((r) => ({
|
|
483
|
+
name: r.name,
|
|
484
|
+
uri: r.uri,
|
|
485
|
+
description: r.description,
|
|
486
|
+
mimeType: r.mimeType
|
|
487
|
+
})) }));
|
|
488
|
+
localServer.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
489
|
+
return { contents: (await x402Mcp.readResource({ uri: request.params.uri })).contents.map((c) => ({ ...c })) };
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
remoteClient.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
|
|
493
|
+
tools = (await x402Mcp.listTools()).tools;
|
|
494
|
+
dim(` Tools updated: ${tools.length} available`);
|
|
495
|
+
await localServer.notification({ method: "notifications/tools/list_changed" });
|
|
496
|
+
});
|
|
497
|
+
if (remoteResources.length > 0) remoteClient.setNotificationHandler(ResourceListChangedNotificationSchema, async () => {
|
|
498
|
+
remoteResources = (await x402Mcp.listResources()).resources;
|
|
499
|
+
dim(` Resources updated: ${remoteResources.length} available`);
|
|
500
|
+
await localServer.notification({ method: "notifications/resources/list_changed" });
|
|
501
|
+
});
|
|
475
502
|
const stdioTransport = new StdioServerTransport();
|
|
476
503
|
await localServer.connect(stdioTransport);
|
|
477
504
|
dim(" MCP proxy running (stdio)");
|
|
@@ -608,7 +635,7 @@ const routes = buildRouteMap({
|
|
|
608
635
|
});
|
|
609
636
|
const app = buildApplication(routes, {
|
|
610
637
|
name: "x402-proxy",
|
|
611
|
-
versionInfo: { currentVersion: "0.
|
|
638
|
+
versionInfo: { currentVersion: "0.5.1" },
|
|
612
639
|
scanner: { caseStyle: "allow-kebab-for-camel" }
|
|
613
640
|
});
|
|
614
641
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { g as readHistory, h as formatTxLine, n as fetchEvmBalances, o as resolveWallet, p as calcSpend, r as fetchSolanaBalances, s as dim, t as balanceLine } from "./wallet-
|
|
2
|
+
import { g as readHistory, h as formatTxLine, n as fetchEvmBalances, o as resolveWallet, p as calcSpend, r as fetchSolanaBalances, s as dim, t as balanceLine } from "./wallet-BMYYtAP6.js";
|
|
3
3
|
import { a as getConfigDirShort, l as loadConfig, o as getHistoryPath } from "./derive-CISr_ond.js";
|
|
4
4
|
import { buildCommand } from "@stricli/core";
|
|
5
5
|
import pc from "picocolors";
|
|
@@ -12,6 +12,7 @@ import { registerExactSvmScheme } from "@x402/svm/exact/client";
|
|
|
12
12
|
import { createPublicClient, http } from "viem";
|
|
13
13
|
import { privateKeyToAccount } from "viem/accounts";
|
|
14
14
|
import { base } from "viem/chains";
|
|
15
|
+
import { address, getAddressEncoder, getProgramDerivedAddress } from "@solana/kit";
|
|
15
16
|
|
|
16
17
|
//#region src/history.ts
|
|
17
18
|
const HISTORY_MAX_LINES = 1e3;
|
|
@@ -285,6 +286,8 @@ const BASE_RPC = "https://mainnet.base.org";
|
|
|
285
286
|
const SOLANA_RPC = "https://api.mainnet-beta.solana.com";
|
|
286
287
|
const USDC_BASE = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
287
288
|
const USDC_SOLANA_MINT = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
289
|
+
const TOKEN_PROGRAM = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
290
|
+
const ATA_PROGRAM = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
288
291
|
async function rpcCall(url, method, params) {
|
|
289
292
|
return (await fetch(url, {
|
|
290
293
|
method: "POST",
|
|
@@ -308,17 +311,26 @@ async function fetchEvmBalances(address) {
|
|
|
308
311
|
usdc: usdcRes.result ? (Number(BigInt(usdcRes.result)) / 1e6).toFixed(4) : "?"
|
|
309
312
|
};
|
|
310
313
|
}
|
|
311
|
-
async function
|
|
312
|
-
const
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
314
|
+
async function getUsdcAta(owner) {
|
|
315
|
+
const encoder = getAddressEncoder();
|
|
316
|
+
const [ata] = await getProgramDerivedAddress({
|
|
317
|
+
programAddress: address(ATA_PROGRAM),
|
|
318
|
+
seeds: [
|
|
319
|
+
encoder.encode(address(owner)),
|
|
320
|
+
encoder.encode(address(TOKEN_PROGRAM)),
|
|
321
|
+
encoder.encode(address(USDC_SOLANA_MINT))
|
|
322
|
+
]
|
|
323
|
+
});
|
|
324
|
+
return ata;
|
|
325
|
+
}
|
|
326
|
+
async function fetchSolanaBalances(ownerAddress) {
|
|
327
|
+
const ata = await getUsdcAta(ownerAddress);
|
|
328
|
+
const [solRes, usdcRes] = await Promise.all([rpcCall(SOLANA_RPC, "getBalance", [ownerAddress]), rpcCall(SOLANA_RPC, "getTokenAccountBalance", [ata])]);
|
|
317
329
|
const sol = solRes.result?.value != null ? (solRes.result.value / 1e9).toFixed(6) : "?";
|
|
318
|
-
const
|
|
330
|
+
const usdcVal = usdcRes.result?.value;
|
|
319
331
|
return {
|
|
320
332
|
sol,
|
|
321
|
-
usdc:
|
|
333
|
+
usdc: usdcVal ? Number(usdcVal.uiAmountString).toFixed(4) : usdcVal === void 0 ? "?" : "0.0000"
|
|
322
334
|
};
|
|
323
335
|
}
|
|
324
336
|
function balanceLine(usdc, native, nativeSymbol) {
|
package/package.json
CHANGED
package/dist/wallet-DFhJWn3o.js
DELETED