@agentcash/router 1.1.9 → 1.2.0
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 +66 -6
- package/dist/index.js +66 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -625,8 +625,8 @@ function resolveMaxPrice(pricing) {
|
|
|
625
625
|
}
|
|
626
626
|
|
|
627
627
|
// src/orchestrate.ts
|
|
628
|
-
var
|
|
629
|
-
var
|
|
628
|
+
var import_mppx2 = require("mppx");
|
|
629
|
+
var import_viem2 = require("viem");
|
|
630
630
|
|
|
631
631
|
// src/protocols/x402.ts
|
|
632
632
|
init_x402_facilitators();
|
|
@@ -662,7 +662,14 @@ async function verifyX402Payment(opts) {
|
|
|
662
662
|
if (!matching) {
|
|
663
663
|
return invalidPaymentVerification();
|
|
664
664
|
}
|
|
665
|
-
|
|
665
|
+
let verify;
|
|
666
|
+
try {
|
|
667
|
+
verify = await server.verifyPayment(payload, matching);
|
|
668
|
+
} catch (err) {
|
|
669
|
+
const sc = err.statusCode;
|
|
670
|
+
if (sc && sc >= 400 && sc < 500) return invalidPaymentVerification();
|
|
671
|
+
throw err;
|
|
672
|
+
}
|
|
666
673
|
if (!verify.isValid) return invalidPaymentVerification();
|
|
667
674
|
return {
|
|
668
675
|
valid: true,
|
|
@@ -891,6 +898,22 @@ async function buildSIWXExtension() {
|
|
|
891
898
|
return declareSIWxExtension();
|
|
892
899
|
}
|
|
893
900
|
|
|
901
|
+
// src/auth/mpp-siwx.ts
|
|
902
|
+
var import_mppx = require("mppx");
|
|
903
|
+
var import_viem = require("viem");
|
|
904
|
+
async function verifyMppSiwx(request, mppx) {
|
|
905
|
+
const result = await mppx.charge({ amount: "0" })(request);
|
|
906
|
+
if (result.status === 402) {
|
|
907
|
+
return { valid: false, challenge: result.challenge };
|
|
908
|
+
}
|
|
909
|
+
const credential = import_mppx.Credential.fromRequest(request);
|
|
910
|
+
const rawSource = credential?.source ?? "";
|
|
911
|
+
const didParts = rawSource.split(":");
|
|
912
|
+
const lastPart = didParts[didParts.length - 1];
|
|
913
|
+
const wallet = normalizeWalletAddress((0, import_viem.isAddress)(lastPart) ? (0, import_viem.getAddress)(lastPart) : rawSource);
|
|
914
|
+
return { valid: true, wallet, withReceipt: result.withReceipt };
|
|
915
|
+
}
|
|
916
|
+
|
|
894
917
|
// src/auth/api-key.ts
|
|
895
918
|
async function verifyApiKey(request, resolver) {
|
|
896
919
|
const apiKey = request.headers.get("X-API-Key") ?? extractBearerToken(request.headers.get("Authorization"));
|
|
@@ -1056,6 +1079,33 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
1056
1079
|
}
|
|
1057
1080
|
}
|
|
1058
1081
|
const siwxHeader = request.headers.get("SIGN-IN-WITH-X");
|
|
1082
|
+
if (!siwxHeader && protocol === "mpp" && routeEntry.authMode === "siwx" && deps.mppx) {
|
|
1083
|
+
let mppSiwxResult;
|
|
1084
|
+
try {
|
|
1085
|
+
mppSiwxResult = await verifyMppSiwx(request, deps.mppx);
|
|
1086
|
+
} catch (err) {
|
|
1087
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1088
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
1089
|
+
level: "critical",
|
|
1090
|
+
message: `MPP SIWX verification failed: ${message}`,
|
|
1091
|
+
route: routeEntry.key
|
|
1092
|
+
});
|
|
1093
|
+
return fail(500, `MPP SIWX verification failed: ${message}`, meta, pluginCtx);
|
|
1094
|
+
}
|
|
1095
|
+
if (mppSiwxResult.valid) {
|
|
1096
|
+
pluginCtx.setVerifiedWallet(mppSiwxResult.wallet);
|
|
1097
|
+
firePluginHook(deps.plugin, "onAuthVerified", pluginCtx, {
|
|
1098
|
+
authMode: "siwx",
|
|
1099
|
+
wallet: mppSiwxResult.wallet,
|
|
1100
|
+
route: routeEntry.key
|
|
1101
|
+
});
|
|
1102
|
+
const authResponse = await handleAuth(mppSiwxResult.wallet, void 0);
|
|
1103
|
+
if (authResponse.status < 400) {
|
|
1104
|
+
return mppSiwxResult.withReceipt(authResponse);
|
|
1105
|
+
}
|
|
1106
|
+
return authResponse;
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1059
1109
|
if (!siwxHeader && routeEntry.authMode === "siwx") {
|
|
1060
1110
|
const url = new URL(request.url);
|
|
1061
1111
|
const nonce = crypto.randomUUID().replace(/-/g, "");
|
|
@@ -1111,6 +1161,16 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
1111
1161
|
headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }
|
|
1112
1162
|
});
|
|
1113
1163
|
if (encoded) response.headers.set("PAYMENT-REQUIRED", encoded);
|
|
1164
|
+
if (deps.mppx) {
|
|
1165
|
+
try {
|
|
1166
|
+
const mppChallenge = await deps.mppx.charge({ amount: "0" })(request);
|
|
1167
|
+
if (mppChallenge.status === 402) {
|
|
1168
|
+
const wwwAuth = mppChallenge.challenge.headers.get("WWW-Authenticate");
|
|
1169
|
+
if (wwwAuth) response.headers.set("WWW-Authenticate", wwwAuth);
|
|
1170
|
+
}
|
|
1171
|
+
} catch {
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1114
1174
|
firePluginResponse(deps, pluginCtx, meta, response);
|
|
1115
1175
|
return response;
|
|
1116
1176
|
}
|
|
@@ -1336,11 +1396,11 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
1336
1396
|
});
|
|
1337
1397
|
return await build402(request, routeEntry, deps, meta, pluginCtx, body.data);
|
|
1338
1398
|
}
|
|
1339
|
-
const credential =
|
|
1399
|
+
const credential = import_mppx2.Credential.fromRequest(request);
|
|
1340
1400
|
const rawSource = credential?.source ?? "";
|
|
1341
1401
|
const didParts = rawSource.split(":");
|
|
1342
1402
|
const lastPart = didParts[didParts.length - 1];
|
|
1343
|
-
const wallet = normalizeWalletAddress((0,
|
|
1403
|
+
const wallet = normalizeWalletAddress((0, import_viem2.isAddress)(lastPart) ? (0, import_viem2.getAddress)(lastPart) : rawSource);
|
|
1344
1404
|
pluginCtx.setVerifiedWallet(wallet);
|
|
1345
1405
|
firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
|
|
1346
1406
|
protocol: "mpp",
|
|
@@ -1419,7 +1479,7 @@ async function resolveDynamicPrice(bodyData, routeEntry, deps, pluginCtx, meta)
|
|
|
1419
1479
|
if (routeEntry.maxPrice) {
|
|
1420
1480
|
const calculated = parseFloat(price);
|
|
1421
1481
|
const max = parseFloat(routeEntry.maxPrice);
|
|
1422
|
-
if (calculated > max) {
|
|
1482
|
+
if (!Number.isFinite(calculated) || calculated > max) {
|
|
1423
1483
|
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
1424
1484
|
level: "warn",
|
|
1425
1485
|
message: `Price ${price} exceeds maxPrice ${routeEntry.maxPrice}, capping`,
|
package/dist/index.js
CHANGED
|
@@ -586,8 +586,8 @@ function resolveMaxPrice(pricing) {
|
|
|
586
586
|
}
|
|
587
587
|
|
|
588
588
|
// src/orchestrate.ts
|
|
589
|
-
import { Credential } from "mppx";
|
|
590
|
-
import { isAddress, getAddress } from "viem";
|
|
589
|
+
import { Credential as Credential2 } from "mppx";
|
|
590
|
+
import { isAddress as isAddress2, getAddress as getAddress2 } from "viem";
|
|
591
591
|
|
|
592
592
|
// src/protocols/x402.ts
|
|
593
593
|
init_x402_facilitators();
|
|
@@ -623,7 +623,14 @@ async function verifyX402Payment(opts) {
|
|
|
623
623
|
if (!matching) {
|
|
624
624
|
return invalidPaymentVerification();
|
|
625
625
|
}
|
|
626
|
-
|
|
626
|
+
let verify;
|
|
627
|
+
try {
|
|
628
|
+
verify = await server.verifyPayment(payload, matching);
|
|
629
|
+
} catch (err) {
|
|
630
|
+
const sc = err.statusCode;
|
|
631
|
+
if (sc && sc >= 400 && sc < 500) return invalidPaymentVerification();
|
|
632
|
+
throw err;
|
|
633
|
+
}
|
|
627
634
|
if (!verify.isValid) return invalidPaymentVerification();
|
|
628
635
|
return {
|
|
629
636
|
valid: true,
|
|
@@ -852,6 +859,22 @@ async function buildSIWXExtension() {
|
|
|
852
859
|
return declareSIWxExtension();
|
|
853
860
|
}
|
|
854
861
|
|
|
862
|
+
// src/auth/mpp-siwx.ts
|
|
863
|
+
import { Credential } from "mppx";
|
|
864
|
+
import { isAddress, getAddress } from "viem";
|
|
865
|
+
async function verifyMppSiwx(request, mppx) {
|
|
866
|
+
const result = await mppx.charge({ amount: "0" })(request);
|
|
867
|
+
if (result.status === 402) {
|
|
868
|
+
return { valid: false, challenge: result.challenge };
|
|
869
|
+
}
|
|
870
|
+
const credential = Credential.fromRequest(request);
|
|
871
|
+
const rawSource = credential?.source ?? "";
|
|
872
|
+
const didParts = rawSource.split(":");
|
|
873
|
+
const lastPart = didParts[didParts.length - 1];
|
|
874
|
+
const wallet = normalizeWalletAddress(isAddress(lastPart) ? getAddress(lastPart) : rawSource);
|
|
875
|
+
return { valid: true, wallet, withReceipt: result.withReceipt };
|
|
876
|
+
}
|
|
877
|
+
|
|
855
878
|
// src/auth/api-key.ts
|
|
856
879
|
async function verifyApiKey(request, resolver) {
|
|
857
880
|
const apiKey = request.headers.get("X-API-Key") ?? extractBearerToken(request.headers.get("Authorization"));
|
|
@@ -1017,6 +1040,33 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
1017
1040
|
}
|
|
1018
1041
|
}
|
|
1019
1042
|
const siwxHeader = request.headers.get("SIGN-IN-WITH-X");
|
|
1043
|
+
if (!siwxHeader && protocol === "mpp" && routeEntry.authMode === "siwx" && deps.mppx) {
|
|
1044
|
+
let mppSiwxResult;
|
|
1045
|
+
try {
|
|
1046
|
+
mppSiwxResult = await verifyMppSiwx(request, deps.mppx);
|
|
1047
|
+
} catch (err) {
|
|
1048
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1049
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
1050
|
+
level: "critical",
|
|
1051
|
+
message: `MPP SIWX verification failed: ${message}`,
|
|
1052
|
+
route: routeEntry.key
|
|
1053
|
+
});
|
|
1054
|
+
return fail(500, `MPP SIWX verification failed: ${message}`, meta, pluginCtx);
|
|
1055
|
+
}
|
|
1056
|
+
if (mppSiwxResult.valid) {
|
|
1057
|
+
pluginCtx.setVerifiedWallet(mppSiwxResult.wallet);
|
|
1058
|
+
firePluginHook(deps.plugin, "onAuthVerified", pluginCtx, {
|
|
1059
|
+
authMode: "siwx",
|
|
1060
|
+
wallet: mppSiwxResult.wallet,
|
|
1061
|
+
route: routeEntry.key
|
|
1062
|
+
});
|
|
1063
|
+
const authResponse = await handleAuth(mppSiwxResult.wallet, void 0);
|
|
1064
|
+
if (authResponse.status < 400) {
|
|
1065
|
+
return mppSiwxResult.withReceipt(authResponse);
|
|
1066
|
+
}
|
|
1067
|
+
return authResponse;
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1020
1070
|
if (!siwxHeader && routeEntry.authMode === "siwx") {
|
|
1021
1071
|
const url = new URL(request.url);
|
|
1022
1072
|
const nonce = crypto.randomUUID().replace(/-/g, "");
|
|
@@ -1072,6 +1122,16 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
1072
1122
|
headers: { "Content-Type": "application/json", "Cache-Control": "no-store" }
|
|
1073
1123
|
});
|
|
1074
1124
|
if (encoded) response.headers.set("PAYMENT-REQUIRED", encoded);
|
|
1125
|
+
if (deps.mppx) {
|
|
1126
|
+
try {
|
|
1127
|
+
const mppChallenge = await deps.mppx.charge({ amount: "0" })(request);
|
|
1128
|
+
if (mppChallenge.status === 402) {
|
|
1129
|
+
const wwwAuth = mppChallenge.challenge.headers.get("WWW-Authenticate");
|
|
1130
|
+
if (wwwAuth) response.headers.set("WWW-Authenticate", wwwAuth);
|
|
1131
|
+
}
|
|
1132
|
+
} catch {
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1075
1135
|
firePluginResponse(deps, pluginCtx, meta, response);
|
|
1076
1136
|
return response;
|
|
1077
1137
|
}
|
|
@@ -1297,11 +1357,11 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
1297
1357
|
});
|
|
1298
1358
|
return await build402(request, routeEntry, deps, meta, pluginCtx, body.data);
|
|
1299
1359
|
}
|
|
1300
|
-
const credential =
|
|
1360
|
+
const credential = Credential2.fromRequest(request);
|
|
1301
1361
|
const rawSource = credential?.source ?? "";
|
|
1302
1362
|
const didParts = rawSource.split(":");
|
|
1303
1363
|
const lastPart = didParts[didParts.length - 1];
|
|
1304
|
-
const wallet = normalizeWalletAddress(
|
|
1364
|
+
const wallet = normalizeWalletAddress(isAddress2(lastPart) ? getAddress2(lastPart) : rawSource);
|
|
1305
1365
|
pluginCtx.setVerifiedWallet(wallet);
|
|
1306
1366
|
firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
|
|
1307
1367
|
protocol: "mpp",
|
|
@@ -1380,7 +1440,7 @@ async function resolveDynamicPrice(bodyData, routeEntry, deps, pluginCtx, meta)
|
|
|
1380
1440
|
if (routeEntry.maxPrice) {
|
|
1381
1441
|
const calculated = parseFloat(price);
|
|
1382
1442
|
const max = parseFloat(routeEntry.maxPrice);
|
|
1383
|
-
if (calculated > max) {
|
|
1443
|
+
if (!Number.isFinite(calculated) || calculated > max) {
|
|
1384
1444
|
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
1385
1445
|
level: "warn",
|
|
1386
1446
|
message: `Price ${price} exceeds maxPrice ${routeEntry.maxPrice}, capping`,
|