@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 +39 -15
- package/dist/index.js +39 -15
- package/package.json +1 -1
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:
|
|
1012
|
-
type:
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
1796
|
+
return wallets.has(normalizeWalletAddress(wallet));
|
|
1773
1797
|
}
|
|
1774
1798
|
async grant(route, wallet) {
|
|
1775
|
-
const
|
|
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(
|
|
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
|
|
1828
|
+
const normalized = normalizeWalletAddress(wallet);
|
|
1805
1829
|
if (clientType === "upstash") {
|
|
1806
1830
|
const redis2 = client;
|
|
1807
|
-
const result2 = await redis2.sismember(key,
|
|
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,
|
|
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
|
|
1840
|
+
const normalized = normalizeWalletAddress(wallet);
|
|
1817
1841
|
if (clientType === "upstash") {
|
|
1818
1842
|
const redis2 = client;
|
|
1819
|
-
await redis2.sadd(key,
|
|
1843
|
+
await redis2.sadd(key, normalized);
|
|
1820
1844
|
return;
|
|
1821
1845
|
}
|
|
1822
1846
|
const redis = client;
|
|
1823
|
-
await redis.sadd(key,
|
|
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:
|
|
973
|
-
type:
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
1757
|
+
return wallets.has(normalizeWalletAddress(wallet));
|
|
1734
1758
|
}
|
|
1735
1759
|
async grant(route, wallet) {
|
|
1736
|
-
const
|
|
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(
|
|
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
|
|
1789
|
+
const normalized = normalizeWalletAddress(wallet);
|
|
1766
1790
|
if (clientType === "upstash") {
|
|
1767
1791
|
const redis2 = client;
|
|
1768
|
-
const result2 = await redis2.sismember(key,
|
|
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,
|
|
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
|
|
1801
|
+
const normalized = normalizeWalletAddress(wallet);
|
|
1778
1802
|
if (clientType === "upstash") {
|
|
1779
1803
|
const redis2 = client;
|
|
1780
|
-
await redis2.sadd(key,
|
|
1804
|
+
await redis2.sadd(key, normalized);
|
|
1781
1805
|
return;
|
|
1782
1806
|
}
|
|
1783
1807
|
const redis = client;
|
|
1784
|
-
await redis.sadd(key,
|
|
1808
|
+
await redis.sadd(key, normalized);
|
|
1785
1809
|
}
|
|
1786
1810
|
};
|
|
1787
1811
|
}
|