x402-proxy 0.8.3 → 0.8.4

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 CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.4] - 2026-03-24
11
+
12
+ ### Fixed
13
+ - Servers returning Solana payment options with EVM-format `payTo` addresses (e.g. `0x...`) no longer crash with a base58 decode error - malformed options are filtered out and valid options are used instead
14
+ - When all payment options from a server have mismatched address formats, a clear error is shown instead of a cryptic codec failure
15
+
10
16
  ## [0.8.3] - 2026-03-24
11
17
 
12
18
  ### Added
@@ -230,7 +236,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
230
236
  - `appendHistory` / `readHistory` / `calcSpend` - JSONL transaction history
231
237
  - Re-exports from `@x402/fetch`, `@x402/svm`, `@x402/evm`
232
238
 
233
- [Unreleased]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.3...HEAD
239
+ [Unreleased]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.4...HEAD
240
+ [0.8.4]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.3...v0.8.4
234
241
  [0.8.3]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.2...v0.8.3
235
242
  [0.8.2]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.1...v0.8.2
236
243
  [0.8.1]: https://github.com/cascade-protocol/x402-proxy/compare/v0.8.0...v0.8.1
package/dist/bin/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as getHistoryPath, c as loadConfig, i as getConfigDirShort, l as loadWalletFile, s as isConfigured, u as saveConfig } from "../derive-BR6N1ZjI.js";
3
- import { _ as error, b as warn, c as resolveWallet, d as displayNetwork, f as formatAmount, g as dim, h as readHistory, l as appendHistory, m as formatUsdcValue, o as walletInfoCommand, p as formatTxLine, s as buildX402Client, u as calcSpend, v as info, y as isTTY } from "../wallet-CeY5DPj-.js";
3
+ import { _ as error, b as warn, c as resolveWallet, d as displayNetwork, f as formatAmount, g as dim, h as readHistory, l as appendHistory, m as formatUsdcValue, o as walletInfoCommand, p as formatTxLine, s as buildX402Client, u as calcSpend, v as info, y as isTTY } from "../wallet-BiX5_XFY.js";
4
4
  import { n as setupCommand } from "../setup-Di_b5Vp9.js";
5
- import { n as statusCommand } from "../status-S3t-XV_M.js";
5
+ import { n as statusCommand } from "../status-DvSu8reM.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";
@@ -398,7 +398,7 @@ Examples:
398
398
  };
399
399
  if (!url) {
400
400
  if (isConfigured()) {
401
- const { displayStatus } = await import("../status-CJPUbh6Z.js");
401
+ const { displayStatus } = await import("../status-DjudJ6fD.js");
402
402
  await displayStatus();
403
403
  console.log();
404
404
  console.log(pc.dim(" Commands:"));
@@ -463,7 +463,7 @@ Examples:
463
463
  verbose(`protocol: ${resolvedProtocol ?? "auto-detect"}, maxDeposit: ${maxDeposit}`);
464
464
  let preferredNetwork = config?.defaultNetwork;
465
465
  if (!preferredNetwork && wallet.evmAddress && wallet.solanaAddress) {
466
- const { fetchAllBalances } = await import("../wallet-CJBRFJw8.js");
466
+ const { fetchAllBalances } = await import("../wallet-BkZ0DOJL.js");
467
467
  const balances = await fetchAllBalances(wallet.evmAddress, wallet.solanaAddress);
468
468
  const evmUsdc = balances.evm ? Number(balances.evm.usdc) : 0;
469
469
  const solUsdc = balances.sol ? Number(balances.sol.usdc) : 0;
@@ -630,7 +630,7 @@ Examples:
630
630
  const hasSolana = accepts.some((a) => a.network.startsWith("solana:"));
631
631
  const hasMpp = detected.mpp;
632
632
  const hasOther = accepts.some((a) => !a.network.startsWith("eip155:") && !a.network.startsWith("solana:"));
633
- const { fetchAllBalances } = await import("../wallet-CJBRFJw8.js");
633
+ const { fetchAllBalances } = await import("../wallet-BkZ0DOJL.js");
634
634
  const balances = await fetchAllBalances(wallet.evmAddress, wallet.solanaAddress);
635
635
  const evmUsdc = hasEvm && balances.evm ? Number(balances.evm.usdc) : 0;
636
636
  const solUsdc = hasSolana && balances.sol ? Number(balances.sol.usdc) : 0;
@@ -840,7 +840,7 @@ Add to your MCP client config (Claude, Cursor, etc.):
840
840
  async function startX402Proxy() {
841
841
  let preferredNetwork = config?.defaultNetwork;
842
842
  if (!preferredNetwork && wallet.evmAddress && wallet.solanaAddress) {
843
- const { fetchAllBalances } = await import("../wallet-CJBRFJw8.js");
843
+ const { fetchAllBalances } = await import("../wallet-BkZ0DOJL.js");
844
844
  const balances = await fetchAllBalances(wallet.evmAddress, wallet.solanaAddress);
845
845
  const evmUsdc = balances.evm ? Number(balances.evm.usdc) : 0;
846
846
  const solUsdc = balances.sol ? Number(balances.sol.usdc) : 0;
@@ -860,7 +860,7 @@ Add to your MCP client config (Claude, Cursor, etc.):
860
860
  }
861
861
  const remoteClient = new Client({
862
862
  name: "x402-proxy",
863
- version: "0.8.3"
863
+ version: "0.8.4"
864
864
  });
865
865
  const x402Mcp = new x402MCPClient(remoteClient, x402PaymentClient, {
866
866
  autoPayment: true,
@@ -898,7 +898,7 @@ Add to your MCP client config (Claude, Cursor, etc.):
898
898
  }
899
899
  const localServer = new Server({
900
900
  name: "x402-proxy",
901
- version: "0.8.3"
901
+ version: "0.8.4"
902
902
  }, { capabilities: {
903
903
  tools: tools.length > 0 ? {} : void 0,
904
904
  resources: remoteResources.length > 0 ? {} : void 0
@@ -993,7 +993,7 @@ Add to your MCP client config (Claude, Cursor, etc.):
993
993
  }));
994
994
  const remoteClient = new Client({
995
995
  name: "x402-proxy",
996
- version: "0.8.3"
996
+ version: "0.8.4"
997
997
  });
998
998
  await connectTransport(remoteClient);
999
999
  const mppClient = McpClient.wrap(remoteClient, { methods: wrappedMethods });
@@ -1008,7 +1008,7 @@ Add to your MCP client config (Claude, Cursor, etc.):
1008
1008
  }
1009
1009
  const localServer = new Server({
1010
1010
  name: "x402-proxy",
1011
- version: "0.8.3"
1011
+ version: "0.8.4"
1012
1012
  }, { capabilities: {
1013
1013
  tools: tools.length > 0 ? {} : void 0,
1014
1014
  resources: remoteResources.length > 0 ? {} : void 0
@@ -1220,7 +1220,7 @@ const routes = buildRouteMap({
1220
1220
  });
1221
1221
  const app = buildApplication(routes, {
1222
1222
  name: "x402-proxy",
1223
- versionInfo: { currentVersion: "0.8.3" },
1223
+ versionInfo: { currentVersion: "0.8.4" },
1224
1224
  scanner: { caseStyle: "allow-kebab-for-camel" }
1225
1225
  });
1226
1226
 
@@ -726,7 +726,7 @@ function createWalletCommand(ctx) {
726
726
  try {
727
727
  const snap = await getWalletSnapshot(ctx.rpcUrl, walletAddress, ctx.historyPath);
728
728
  const solscanUrl = `https://solscan.io/account/${walletAddress}`;
729
- const lines = [`x402-proxy v0.8.3`];
729
+ const lines = [`x402-proxy v0.8.4`];
730
730
  const defaultModel = ctx.allModels[0];
731
731
  if (defaultModel) lines.push("", `**Model** - ${defaultModel.name} (${defaultModel.provider})`);
732
732
  lines.push("", `**[Wallet](${solscanUrl})**`, `\`${walletAddress}\``);
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { n as statusCommand, t as displayStatus } from "./status-S3t-XV_M.js";
2
+ import { n as statusCommand, t as displayStatus } from "./status-DvSu8reM.js";
3
3
 
4
4
  export { displayStatus };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { a as getHistoryPath, c as loadConfig, i as getConfigDirShort } from "./derive-BR6N1ZjI.js";
3
- import { c as resolveWallet, f as formatAmount, g as dim, h as readHistory, m as formatUsdcValue, n as fetchAllBalances, p as formatTxLine, t as balanceLine, u as calcSpend } from "./wallet-CeY5DPj-.js";
3
+ import { c as resolveWallet, f as formatAmount, g as dim, h as readHistory, m as formatUsdcValue, n as fetchAllBalances, p as formatTxLine, t as balanceLine, u as calcSpend } from "./wallet-BiX5_XFY.js";
4
4
  import { buildCommand } from "@stricli/core";
5
5
  import pc from "picocolors";
6
6
 
@@ -236,6 +236,28 @@ function networkToCaipPrefix(name) {
236
236
  default: return name;
237
237
  }
238
238
  }
239
+ /**
240
+ * Validate that payTo addresses match the network format.
241
+ * Filters out malformed entries (e.g. EVM hex address on a Solana network).
242
+ */
243
+ function createAddressValidationPolicy() {
244
+ return (_version, reqs) => {
245
+ const malformed = [];
246
+ const valid = reqs.filter((r) => {
247
+ if (r.network.startsWith("solana:") && r.payTo.startsWith("0x")) {
248
+ malformed.push(`Solana option has EVM-format payTo (${r.payTo})`);
249
+ return false;
250
+ }
251
+ if (r.network.startsWith("eip155:") && !r.payTo.startsWith("0x")) {
252
+ malformed.push(`EVM option has non-EVM payTo (${r.payTo})`);
253
+ return false;
254
+ }
255
+ return true;
256
+ });
257
+ if (valid.length === 0 && malformed.length > 0) throw new Error(`Server returned only malformed payment options:\n ${malformed.join("\n ")}\nThe server's payTo addresses don't match the advertised networks.`);
258
+ return valid;
259
+ };
260
+ }
239
261
  function createNetworkFilter(network) {
240
262
  const prefix = networkToCaipPrefix(network);
241
263
  return (_version, reqs) => {
@@ -269,6 +291,7 @@ async function buildX402Client(wallet, opts) {
269
291
  const { createKeyPairSignerFromBytes } = await import("@solana/kit");
270
292
  registerExactSvmScheme(client, { signer: await createKeyPairSignerFromBytes(wallet.solanaKey) });
271
293
  }
294
+ client.registerPolicy(createAddressValidationPolicy());
272
295
  if (opts?.network) client.registerPolicy(createNetworkFilter(opts.network));
273
296
  const daily = opts?.spendLimitDaily;
274
297
  const perTx = opts?.spendLimitPerTx;
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as fetchTempoBalances, i as fetchSolanaBalances, n as fetchAllBalances, o as walletInfoCommand, r as fetchEvmBalances, t as balanceLine } from "./wallet-CeY5DPj-.js";
2
+ import { a as fetchTempoBalances, i as fetchSolanaBalances, n as fetchAllBalances, o as walletInfoCommand, r as fetchEvmBalances, t as balanceLine } from "./wallet-BiX5_XFY.js";
3
3
 
4
4
  export { fetchAllBalances };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x402-proxy",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "curl for x402 paid APIs. Auto-pays any endpoint on Base, Solana, and Tempo. Also works as an OpenClaw plugin.",
5
5
  "type": "module",
6
6
  "sideEffects": false,