@agentcash/router 1.1.1 → 1.1.2

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/dist/index.cjs CHANGED
@@ -366,6 +366,11 @@ var RouteRegistry = class {
366
366
  // src/orchestrate.ts
367
367
  var import_server2 = require("next/server");
368
368
 
369
+ // src/auth/normalize-wallet.ts
370
+ function normalizeWalletAddress(address) {
371
+ return address.startsWith("0x") ? address.toLowerCase() : address;
372
+ }
373
+
369
374
  // src/plugin.ts
370
375
  function createDefaultContext(meta) {
371
376
  const ctx = {
@@ -877,6 +882,23 @@ function getRequirementNetwork(requirements, fallback) {
877
882
  const network = requirements?.network;
878
883
  return typeof network === "string" ? network : fallback;
879
884
  }
885
+ function siwxSignatureType(network) {
886
+ return network.startsWith("solana:") ? "ed25519" : "eip191";
887
+ }
888
+ function getSupportedChains(x402Accepts, fallbackNetwork) {
889
+ const seen = /* @__PURE__ */ new Set();
890
+ const chains = [];
891
+ for (const accept of x402Accepts) {
892
+ if (accept.network && !seen.has(accept.network)) {
893
+ seen.add(accept.network);
894
+ chains.push({ chainId: accept.network, type: siwxSignatureType(accept.network) });
895
+ }
896
+ }
897
+ if (chains.length === 0) {
898
+ chains.push({ chainId: fallbackNetwork, type: siwxSignatureType(fallbackNetwork) });
899
+ }
900
+ return chains;
901
+ }
880
902
  function createRequestHandler(routeEntry, handler, deps) {
881
903
  async function invoke(request, meta, pluginCtx, wallet, account, parsedBody) {
882
904
  const ctx = {
@@ -1004,12 +1026,14 @@ function createRequestHandler(routeEntry, handler, deps) {
1004
1026
  if (!siwxHeader && routeEntry.authMode === "siwx") {
1005
1027
  const url = new URL(request.url);
1006
1028
  const nonce = crypto.randomUUID().replace(/-/g, "");
1029
+ const supportedChains = getSupportedChains(deps.x402Accepts, deps.network);
1030
+ const primaryChain = supportedChains[0];
1007
1031
  const siwxInfo = {
1008
1032
  domain: url.hostname,
1009
1033
  uri: request.url,
1010
1034
  version: "1",
1011
- chainId: deps.network,
1012
- type: "eip191",
1035
+ chainId: primaryChain.chainId,
1036
+ type: primaryChain.type,
1013
1037
  nonce,
1014
1038
  issuedAt: (/* @__PURE__ */ new Date()).toISOString(),
1015
1039
  expirationTime: new Date(Date.now() + SIWX_CHALLENGE_EXPIRY_MS).toISOString(),
@@ -1033,7 +1057,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1033
1057
  "sign-in-with-x": {
1034
1058
  info: siwxInfo,
1035
1059
  // supportedChains at top level required by MCP tools for chain detection
1036
- supportedChains: [{ chainId: deps.network, type: "eip191" }],
1060
+ supportedChains,
1037
1061
  ...siwxSchema ? { schema: siwxSchema } : {}
1038
1062
  }
1039
1063
  }
@@ -1069,7 +1093,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1069
1093
  return response;
1070
1094
  }
1071
1095
  } else {
1072
- const wallet = siwx.wallet.toLowerCase();
1096
+ const wallet = normalizeWalletAddress(siwx.wallet);
1073
1097
  pluginCtx.setVerifiedWallet(wallet);
1074
1098
  if (routeEntry.authMode === "siwx") {
1075
1099
  firePluginHook(deps.plugin, "onAuthVerified", pluginCtx, {
@@ -1171,7 +1195,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1171
1195
  if (!verify?.valid) return await build402(request, routeEntry, deps, meta, pluginCtx);
1172
1196
  const { payload: verifyPayload, requirements: verifyRequirements } = verify;
1173
1197
  const matchedNetwork = getRequirementNetwork(verifyRequirements, deps.network);
1174
- const wallet = verify.payer.toLowerCase();
1198
+ const wallet = normalizeWalletAddress(verify.payer);
1175
1199
  pluginCtx.setVerifiedWallet(wallet);
1176
1200
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1177
1201
  protocol: "x402",
@@ -1273,7 +1297,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1273
1297
  const rawSource = credential?.source ?? "";
1274
1298
  const didParts = rawSource.split(":");
1275
1299
  const lastPart = didParts[didParts.length - 1];
1276
- const wallet = ((0, import_viem.isAddress)(lastPart) ? (0, import_viem.getAddress)(lastPart) : rawSource).toLowerCase();
1300
+ const wallet = normalizeWalletAddress((0, import_viem.isAddress)(lastPart) ? (0, import_viem.getAddress)(lastPart) : rawSource);
1277
1301
  pluginCtx.setVerifiedWallet(wallet);
1278
1302
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1279
1303
  protocol: "mpp",
@@ -1769,16 +1793,16 @@ var MemoryEntitlementStore = class {
1769
1793
  async has(route, wallet) {
1770
1794
  const wallets = this.routeToWallets.get(route);
1771
1795
  if (!wallets) return false;
1772
- return wallets.has(wallet.toLowerCase());
1796
+ return wallets.has(normalizeWalletAddress(wallet));
1773
1797
  }
1774
1798
  async grant(route, wallet) {
1775
- const normalizedWallet = wallet.toLowerCase();
1799
+ const normalized = normalizeWalletAddress(wallet);
1776
1800
  let wallets = this.routeToWallets.get(route);
1777
1801
  if (!wallets) {
1778
1802
  wallets = /* @__PURE__ */ new Set();
1779
1803
  this.routeToWallets.set(route, wallets);
1780
1804
  }
1781
- wallets.add(normalizedWallet);
1805
+ wallets.add(normalized);
1782
1806
  }
1783
1807
  };
1784
1808
  function detectRedisClientType2(client) {
@@ -1801,26 +1825,26 @@ function createRedisEntitlementStore(client, options) {
1801
1825
  return {
1802
1826
  async has(route, wallet) {
1803
1827
  const key = `${prefix}${route}`;
1804
- const normalizedWallet = wallet.toLowerCase();
1828
+ const normalized = normalizeWalletAddress(wallet);
1805
1829
  if (clientType === "upstash") {
1806
1830
  const redis2 = client;
1807
- const result2 = await redis2.sismember(key, normalizedWallet);
1831
+ const result2 = await redis2.sismember(key, normalized);
1808
1832
  return result2 === 1 || result2 === true;
1809
1833
  }
1810
1834
  const redis = client;
1811
- const result = await redis.sismember(key, normalizedWallet);
1835
+ const result = await redis.sismember(key, normalized);
1812
1836
  return result === 1;
1813
1837
  },
1814
1838
  async grant(route, wallet) {
1815
1839
  const key = `${prefix}${route}`;
1816
- const normalizedWallet = wallet.toLowerCase();
1840
+ const normalized = normalizeWalletAddress(wallet);
1817
1841
  if (clientType === "upstash") {
1818
1842
  const redis2 = client;
1819
- await redis2.sadd(key, normalizedWallet);
1843
+ await redis2.sadd(key, normalized);
1820
1844
  return;
1821
1845
  }
1822
1846
  const redis = client;
1823
- await redis.sadd(key, normalizedWallet);
1847
+ await redis.sadd(key, normalized);
1824
1848
  }
1825
1849
  };
1826
1850
  }
package/dist/index.js CHANGED
@@ -327,6 +327,11 @@ var RouteRegistry = class {
327
327
  // src/orchestrate.ts
328
328
  import { NextResponse as NextResponse2 } from "next/server";
329
329
 
330
+ // src/auth/normalize-wallet.ts
331
+ function normalizeWalletAddress(address) {
332
+ return address.startsWith("0x") ? address.toLowerCase() : address;
333
+ }
334
+
330
335
  // src/plugin.ts
331
336
  function createDefaultContext(meta) {
332
337
  const ctx = {
@@ -838,6 +843,23 @@ function getRequirementNetwork(requirements, fallback) {
838
843
  const network = requirements?.network;
839
844
  return typeof network === "string" ? network : fallback;
840
845
  }
846
+ function siwxSignatureType(network) {
847
+ return network.startsWith("solana:") ? "ed25519" : "eip191";
848
+ }
849
+ function getSupportedChains(x402Accepts, fallbackNetwork) {
850
+ const seen = /* @__PURE__ */ new Set();
851
+ const chains = [];
852
+ for (const accept of x402Accepts) {
853
+ if (accept.network && !seen.has(accept.network)) {
854
+ seen.add(accept.network);
855
+ chains.push({ chainId: accept.network, type: siwxSignatureType(accept.network) });
856
+ }
857
+ }
858
+ if (chains.length === 0) {
859
+ chains.push({ chainId: fallbackNetwork, type: siwxSignatureType(fallbackNetwork) });
860
+ }
861
+ return chains;
862
+ }
841
863
  function createRequestHandler(routeEntry, handler, deps) {
842
864
  async function invoke(request, meta, pluginCtx, wallet, account, parsedBody) {
843
865
  const ctx = {
@@ -965,12 +987,14 @@ function createRequestHandler(routeEntry, handler, deps) {
965
987
  if (!siwxHeader && routeEntry.authMode === "siwx") {
966
988
  const url = new URL(request.url);
967
989
  const nonce = crypto.randomUUID().replace(/-/g, "");
990
+ const supportedChains = getSupportedChains(deps.x402Accepts, deps.network);
991
+ const primaryChain = supportedChains[0];
968
992
  const siwxInfo = {
969
993
  domain: url.hostname,
970
994
  uri: request.url,
971
995
  version: "1",
972
- chainId: deps.network,
973
- type: "eip191",
996
+ chainId: primaryChain.chainId,
997
+ type: primaryChain.type,
974
998
  nonce,
975
999
  issuedAt: (/* @__PURE__ */ new Date()).toISOString(),
976
1000
  expirationTime: new Date(Date.now() + SIWX_CHALLENGE_EXPIRY_MS).toISOString(),
@@ -994,7 +1018,7 @@ function createRequestHandler(routeEntry, handler, deps) {
994
1018
  "sign-in-with-x": {
995
1019
  info: siwxInfo,
996
1020
  // supportedChains at top level required by MCP tools for chain detection
997
- supportedChains: [{ chainId: deps.network, type: "eip191" }],
1021
+ supportedChains,
998
1022
  ...siwxSchema ? { schema: siwxSchema } : {}
999
1023
  }
1000
1024
  }
@@ -1030,7 +1054,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1030
1054
  return response;
1031
1055
  }
1032
1056
  } else {
1033
- const wallet = siwx.wallet.toLowerCase();
1057
+ const wallet = normalizeWalletAddress(siwx.wallet);
1034
1058
  pluginCtx.setVerifiedWallet(wallet);
1035
1059
  if (routeEntry.authMode === "siwx") {
1036
1060
  firePluginHook(deps.plugin, "onAuthVerified", pluginCtx, {
@@ -1132,7 +1156,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1132
1156
  if (!verify?.valid) return await build402(request, routeEntry, deps, meta, pluginCtx);
1133
1157
  const { payload: verifyPayload, requirements: verifyRequirements } = verify;
1134
1158
  const matchedNetwork = getRequirementNetwork(verifyRequirements, deps.network);
1135
- const wallet = verify.payer.toLowerCase();
1159
+ const wallet = normalizeWalletAddress(verify.payer);
1136
1160
  pluginCtx.setVerifiedWallet(wallet);
1137
1161
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1138
1162
  protocol: "x402",
@@ -1234,7 +1258,7 @@ function createRequestHandler(routeEntry, handler, deps) {
1234
1258
  const rawSource = credential?.source ?? "";
1235
1259
  const didParts = rawSource.split(":");
1236
1260
  const lastPart = didParts[didParts.length - 1];
1237
- const wallet = (isAddress(lastPart) ? getAddress(lastPart) : rawSource).toLowerCase();
1261
+ const wallet = normalizeWalletAddress(isAddress(lastPart) ? getAddress(lastPart) : rawSource);
1238
1262
  pluginCtx.setVerifiedWallet(wallet);
1239
1263
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
1240
1264
  protocol: "mpp",
@@ -1730,16 +1754,16 @@ var MemoryEntitlementStore = class {
1730
1754
  async has(route, wallet) {
1731
1755
  const wallets = this.routeToWallets.get(route);
1732
1756
  if (!wallets) return false;
1733
- return wallets.has(wallet.toLowerCase());
1757
+ return wallets.has(normalizeWalletAddress(wallet));
1734
1758
  }
1735
1759
  async grant(route, wallet) {
1736
- const normalizedWallet = wallet.toLowerCase();
1760
+ const normalized = normalizeWalletAddress(wallet);
1737
1761
  let wallets = this.routeToWallets.get(route);
1738
1762
  if (!wallets) {
1739
1763
  wallets = /* @__PURE__ */ new Set();
1740
1764
  this.routeToWallets.set(route, wallets);
1741
1765
  }
1742
- wallets.add(normalizedWallet);
1766
+ wallets.add(normalized);
1743
1767
  }
1744
1768
  };
1745
1769
  function detectRedisClientType2(client) {
@@ -1762,26 +1786,26 @@ function createRedisEntitlementStore(client, options) {
1762
1786
  return {
1763
1787
  async has(route, wallet) {
1764
1788
  const key = `${prefix}${route}`;
1765
- const normalizedWallet = wallet.toLowerCase();
1789
+ const normalized = normalizeWalletAddress(wallet);
1766
1790
  if (clientType === "upstash") {
1767
1791
  const redis2 = client;
1768
- const result2 = await redis2.sismember(key, normalizedWallet);
1792
+ const result2 = await redis2.sismember(key, normalized);
1769
1793
  return result2 === 1 || result2 === true;
1770
1794
  }
1771
1795
  const redis = client;
1772
- const result = await redis.sismember(key, normalizedWallet);
1796
+ const result = await redis.sismember(key, normalized);
1773
1797
  return result === 1;
1774
1798
  },
1775
1799
  async grant(route, wallet) {
1776
1800
  const key = `${prefix}${route}`;
1777
- const normalizedWallet = wallet.toLowerCase();
1801
+ const normalized = normalizeWalletAddress(wallet);
1778
1802
  if (clientType === "upstash") {
1779
1803
  const redis2 = client;
1780
- await redis2.sadd(key, normalizedWallet);
1804
+ await redis2.sadd(key, normalized);
1781
1805
  return;
1782
1806
  }
1783
1807
  const redis = client;
1784
- await redis.sadd(key, normalizedWallet);
1808
+ await redis.sadd(key, normalized);
1785
1809
  }
1786
1810
  };
1787
1811
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentcash/router",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Unified route builder for Next.js App Router APIs with x402, MPP, SIWX, and API key auth",
5
5
  "type": "module",
6
6
  "exports": {