@agentcash/router 1.10.2 → 1.10.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/README.md +1 -1
- package/dist/index.cjs +158 -74
- package/dist/index.d.cts +17 -4
- package/dist/index.d.ts +17 -4
- package/dist/index.js +157 -74
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ The recommended entry point reads its config from `process.env`. A copy-paste `.
|
|
|
57
57
|
|-----|----------|---------|
|
|
58
58
|
| `MPP_SECRET_KEY` | when MPP is enabled | Server-side MPP secret. Presence toggles MPP on. |
|
|
59
59
|
| `MPP_CURRENCY` | when MPP is enabled | Tempo currency address. Use `TEMPO_USDC_ADDRESS` for Tempo USDC. |
|
|
60
|
-
| `TEMPO_RPC_URL` |
|
|
60
|
+
| `TEMPO_RPC_URL` | no | Tempo JSON-RPC endpoint for MPP on-chain verification. Defaults to the public `DEFAULT_TEMPO_RPC_URL` (`https://rpc.tempo.xyz`). Override only if you have a dedicated endpoint. |
|
|
61
61
|
| `MPP_OPERATOR_KEY` | no | Signs server-side close/settle. When set, MPP session mode is enabled automatically (required for `.metered()`: both streaming and request-mode per-tick billing). Address must equal the payee. |
|
|
62
62
|
| `MPP_FEE_PAYER_KEY` | no | Sponsors client gas for channel open/topUp. Must resolve to a different address than `MPP_OPERATOR_KEY` (Tempo rejects fee-delegated txs where `sender === feePayer`). |
|
|
63
63
|
|
package/dist/index.cjs
CHANGED
|
@@ -31,7 +31,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
31
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
32
|
|
|
33
33
|
// src/constants.ts
|
|
34
|
-
var BASE_MAINNET_NETWORK, SOLANA_MAINNET_NETWORK, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, ZERO_EVM_ADDRESS, DEFAULT_SOLANA_FACILITATOR_URL;
|
|
34
|
+
var BASE_MAINNET_NETWORK, SOLANA_MAINNET_NETWORK, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, ZERO_EVM_ADDRESS, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL;
|
|
35
35
|
var init_constants = __esm({
|
|
36
36
|
"src/constants.ts"() {
|
|
37
37
|
"use strict";
|
|
@@ -43,6 +43,7 @@ var init_constants = __esm({
|
|
|
43
43
|
BASE_USDC_DECIMALS = 6;
|
|
44
44
|
ZERO_EVM_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
45
45
|
DEFAULT_SOLANA_FACILITATOR_URL = "https://facilitator.corbits.dev";
|
|
46
|
+
DEFAULT_TEMPO_RPC_URL = "https://rpc.tempo.xyz";
|
|
46
47
|
}
|
|
47
48
|
});
|
|
48
49
|
|
|
@@ -470,6 +471,7 @@ __export(index_exports, {
|
|
|
470
471
|
BASE_USDC_ADDRESS: () => BASE_USDC_ADDRESS,
|
|
471
472
|
BASE_USDC_DECIMALS: () => BASE_USDC_DECIMALS,
|
|
472
473
|
DEFAULT_SOLANA_FACILITATOR_URL: () => DEFAULT_SOLANA_FACILITATOR_URL,
|
|
474
|
+
DEFAULT_TEMPO_RPC_URL: () => DEFAULT_TEMPO_RPC_URL,
|
|
473
475
|
HttpError: () => HttpError,
|
|
474
476
|
RouterConfigError: () => RouterConfigError,
|
|
475
477
|
SOLANA_MAINNET_NETWORK: () => SOLANA_MAINNET_NETWORK,
|
|
@@ -539,7 +541,8 @@ var HEADERS = {
|
|
|
539
541
|
X402_PAYMENT_LEGACY: "X-PAYMENT",
|
|
540
542
|
X402_PAYMENT_REQUIRED: "PAYMENT-REQUIRED",
|
|
541
543
|
X402_PAYMENT_RESPONSE: "PAYMENT-RESPONSE",
|
|
542
|
-
MPP_PAYMENT_RECEIPT: "Payment-Receipt"
|
|
544
|
+
MPP_PAYMENT_RECEIPT: "Payment-Receipt",
|
|
545
|
+
REQUEST_ID: "X-Request-ID"
|
|
543
546
|
};
|
|
544
547
|
var AUTH_SCHEME = {
|
|
545
548
|
BEARER: "Bearer ",
|
|
@@ -569,19 +572,19 @@ function firePluginHook(plugin, method, ...args) {
|
|
|
569
572
|
const result = fn.apply(plugin, args);
|
|
570
573
|
if (result && typeof result.catch === "function") {
|
|
571
574
|
result.catch((error) => {
|
|
572
|
-
console.error(
|
|
573
|
-
`[router] ERROR ${method}: ${error instanceof Error ? error.message : String(error)}`
|
|
574
|
-
);
|
|
575
|
+
console.error(`[router] ERROR ${method}: ${formatUnknownError(error)}`);
|
|
575
576
|
});
|
|
576
577
|
}
|
|
577
578
|
return result;
|
|
578
579
|
} catch (error) {
|
|
579
|
-
console.error(
|
|
580
|
-
`[router] ERROR ${method}: ${error instanceof Error ? error.message : String(error)}`
|
|
581
|
-
);
|
|
580
|
+
console.error(`[router] ERROR ${method}: ${formatUnknownError(error)}`);
|
|
582
581
|
return void 0;
|
|
583
582
|
}
|
|
584
583
|
}
|
|
584
|
+
function formatUnknownError(error) {
|
|
585
|
+
if (error instanceof Error) return error.stack ?? error.message;
|
|
586
|
+
return String(error);
|
|
587
|
+
}
|
|
585
588
|
|
|
586
589
|
// src/plugin/reporter.ts
|
|
587
590
|
function createReporter(plugin, pluginCtx, route) {
|
|
@@ -672,7 +675,8 @@ function firePaymentVerified(ctx, event) {
|
|
|
672
675
|
function firePaymentSettled(ctx, event) {
|
|
673
676
|
firePluginHook(ctx.deps.plugin, "onPaymentSettled", ctx.pluginCtx, event);
|
|
674
677
|
}
|
|
675
|
-
function firePluginResponse(ctx, response, requestBody, responseBody) {
|
|
678
|
+
function firePluginResponse(ctx, response, requestBody, responseBody, failure) {
|
|
679
|
+
attachRequestId(response, ctx.meta.requestId);
|
|
676
680
|
firePluginHook(ctx.deps.plugin, "onResponse", ctx.pluginCtx, {
|
|
677
681
|
statusCode: response.status,
|
|
678
682
|
statusText: response.statusText,
|
|
@@ -683,11 +687,9 @@ function firePluginResponse(ctx, response, requestBody, responseBody) {
|
|
|
683
687
|
responseBody
|
|
684
688
|
});
|
|
685
689
|
if (response.status >= 400 && response.status !== 402) {
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
settled: false
|
|
690
|
-
});
|
|
690
|
+
const error = buildErrorEvent(ctx, response, failure);
|
|
691
|
+
if (response.status >= 500) logRouterFailure(error);
|
|
692
|
+
firePluginHook(ctx.deps.plugin, "onError", ctx.pluginCtx, error);
|
|
691
693
|
}
|
|
692
694
|
}
|
|
693
695
|
function fireProviderQuota(ctx, response, handlerResult) {
|
|
@@ -719,6 +721,67 @@ function computeQuotaLevel(remaining, warn, critical) {
|
|
|
719
721
|
if (warn !== void 0 && remaining <= warn) return "warn";
|
|
720
722
|
return "healthy";
|
|
721
723
|
}
|
|
724
|
+
function attachRequestId(response, requestId) {
|
|
725
|
+
try {
|
|
726
|
+
if (!response.headers.has(HEADERS.REQUEST_ID)) {
|
|
727
|
+
response.headers.set(HEADERS.REQUEST_ID, requestId);
|
|
728
|
+
}
|
|
729
|
+
} catch {
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
function buildErrorEvent(ctx, response, failure) {
|
|
733
|
+
const error = errorDetails(failure?.cause);
|
|
734
|
+
const responseMessage = response.statusText || `HTTP ${response.status}`;
|
|
735
|
+
const message = failure?.message ?? error.message ?? responseMessage;
|
|
736
|
+
return {
|
|
737
|
+
status: response.status,
|
|
738
|
+
message,
|
|
739
|
+
settled: failure?.settled ?? false,
|
|
740
|
+
requestId: ctx.meta.requestId,
|
|
741
|
+
route: ctx.meta.route,
|
|
742
|
+
method: ctx.meta.method,
|
|
743
|
+
duration: Date.now() - ctx.meta.startTime,
|
|
744
|
+
walletAddress: ctx.meta.walletAddress,
|
|
745
|
+
verifiedWallet: ctx.pluginCtx.verifiedWallet,
|
|
746
|
+
clientId: ctx.meta.clientId,
|
|
747
|
+
sessionId: ctx.meta.sessionId,
|
|
748
|
+
errorName: error.name,
|
|
749
|
+
stack: error.stack,
|
|
750
|
+
cause: failure?.cause
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
function errorDetails(error) {
|
|
754
|
+
if (error instanceof Error) {
|
|
755
|
+
return {
|
|
756
|
+
message: error.message,
|
|
757
|
+
name: error.name,
|
|
758
|
+
stack: error.stack
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
if (typeof error === "object" && error !== null) {
|
|
762
|
+
const record = error;
|
|
763
|
+
return {
|
|
764
|
+
message: typeof record.message === "string" ? record.message : void 0,
|
|
765
|
+
name: typeof record.name === "string" ? record.name : void 0,
|
|
766
|
+
stack: typeof record.stack === "string" ? record.stack : void 0
|
|
767
|
+
};
|
|
768
|
+
}
|
|
769
|
+
if (typeof error === "string") return { message: error };
|
|
770
|
+
return {};
|
|
771
|
+
}
|
|
772
|
+
function logRouterFailure(error) {
|
|
773
|
+
console.error(`[router] ERROR ${error.route ?? "unknown"} ${error.status}: ${error.message}`, {
|
|
774
|
+
requestId: error.requestId,
|
|
775
|
+
method: error.method,
|
|
776
|
+
duration: error.duration,
|
|
777
|
+
walletAddress: error.walletAddress,
|
|
778
|
+
verifiedWallet: error.verifiedWallet,
|
|
779
|
+
clientId: error.clientId,
|
|
780
|
+
sessionId: error.sessionId,
|
|
781
|
+
errorName: error.errorName,
|
|
782
|
+
stack: error.stack
|
|
783
|
+
});
|
|
784
|
+
}
|
|
722
785
|
|
|
723
786
|
// src/pipeline/steps/parse-body.ts
|
|
724
787
|
async function parseBody(ctx, request = ctx.request) {
|
|
@@ -728,20 +791,19 @@ async function parseBody(ctx, request = ctx.request) {
|
|
|
728
791
|
raw = await bufferBody(request);
|
|
729
792
|
} catch (err) {
|
|
730
793
|
if (!(err instanceof MalformedJsonError)) throw err;
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
794
|
+
const responseBody2 = { success: false, error: "Invalid JSON", issues: [] };
|
|
795
|
+
const response2 = import_server.NextResponse.json(responseBody2, { status: 400 });
|
|
796
|
+
firePluginResponse(ctx, response2, void 0, responseBody2, {
|
|
797
|
+
message: responseBody2.error,
|
|
798
|
+
cause: err
|
|
799
|
+
});
|
|
736
800
|
return { ok: false, response: response2 };
|
|
737
801
|
}
|
|
738
802
|
const result = validateBody(raw, ctx.routeEntry.bodySchema);
|
|
739
803
|
if (result.success) return { ok: true, data: result.data };
|
|
740
|
-
const
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
);
|
|
744
|
-
firePluginResponse(ctx, response);
|
|
804
|
+
const responseBody = { success: false, error: result.error, issues: result.issues };
|
|
805
|
+
const response = import_server.NextResponse.json(responseBody, { status: 400 });
|
|
806
|
+
firePluginResponse(ctx, response, raw, responseBody, { message: result.error });
|
|
745
807
|
return { ok: false, response };
|
|
746
808
|
}
|
|
747
809
|
|
|
@@ -753,11 +815,9 @@ function validateQuery(ctx) {
|
|
|
753
815
|
const params = Object.fromEntries(ctx.request.nextUrl.searchParams.entries());
|
|
754
816
|
const result = validateBody(params, querySchema);
|
|
755
817
|
if (result.success) return { ok: true, data: result.data };
|
|
756
|
-
const
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
);
|
|
760
|
-
firePluginResponse(ctx, response);
|
|
818
|
+
const responseBody = { success: false, error: result.error, issues: result.issues };
|
|
819
|
+
const response = import_server2.NextResponse.json(responseBody, { status: 400 });
|
|
820
|
+
firePluginResponse(ctx, response, params, responseBody, { message: result.error });
|
|
761
821
|
return { ok: false, response };
|
|
762
822
|
}
|
|
763
823
|
|
|
@@ -776,9 +836,13 @@ function handlerFailureError(response) {
|
|
|
776
836
|
|
|
777
837
|
// src/pipeline/steps/fail.ts
|
|
778
838
|
var import_server3 = require("next/server");
|
|
779
|
-
function fail(ctx, status, message, requestBody) {
|
|
780
|
-
const
|
|
781
|
-
|
|
839
|
+
function fail(ctx, status, message, requestBody, failure) {
|
|
840
|
+
const responseBody = { success: false, error: message };
|
|
841
|
+
const response = import_server3.NextResponse.json(responseBody, { status });
|
|
842
|
+
firePluginResponse(ctx, response, requestBody, responseBody, {
|
|
843
|
+
...failure,
|
|
844
|
+
message: failure?.message ?? message
|
|
845
|
+
});
|
|
782
846
|
return response;
|
|
783
847
|
}
|
|
784
848
|
|
|
@@ -854,9 +918,10 @@ async function runHandler(ctx, handlerCtx) {
|
|
|
854
918
|
function errorResult(error) {
|
|
855
919
|
const status = error instanceof HttpError ? error.status : typeof error?.status === "number" ? error.status : 500;
|
|
856
920
|
const message = error instanceof Error ? error.message : "Internal error";
|
|
921
|
+
const responseBody = { success: false, error: message };
|
|
857
922
|
return {
|
|
858
|
-
response: import_server4.NextResponse.json(
|
|
859
|
-
rawResult:
|
|
923
|
+
response: import_server4.NextResponse.json(responseBody, { status }),
|
|
924
|
+
rawResult: responseBody,
|
|
860
925
|
handlerError: error
|
|
861
926
|
};
|
|
862
927
|
}
|
|
@@ -868,9 +933,9 @@ function isThenable(value) {
|
|
|
868
933
|
}
|
|
869
934
|
|
|
870
935
|
// src/pipeline/steps/finalize/response.ts
|
|
871
|
-
function finalize(ctx, response, rawResult, requestBody) {
|
|
936
|
+
function finalize(ctx, response, rawResult, requestBody, failure) {
|
|
872
937
|
fireProviderQuota(ctx, response, rawResult);
|
|
873
|
-
firePluginResponse(ctx, response, requestBody, rawResult);
|
|
938
|
+
firePluginResponse(ctx, response, requestBody, rawResult, failure);
|
|
874
939
|
return response;
|
|
875
940
|
}
|
|
876
941
|
|
|
@@ -956,7 +1021,9 @@ async function settleAndFinalizeRequest(args) {
|
|
|
956
1021
|
});
|
|
957
1022
|
if (!settle.ok) {
|
|
958
1023
|
if (onSettleError) await onSettleError(settle.error, settle.failMessage);
|
|
959
|
-
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body
|
|
1024
|
+
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body, {
|
|
1025
|
+
cause: settle.error
|
|
1026
|
+
});
|
|
960
1027
|
}
|
|
961
1028
|
return runPostSettleEpilogue({
|
|
962
1029
|
ctx,
|
|
@@ -991,7 +1058,9 @@ async function settleAndFinalizeStream(args) {
|
|
|
991
1058
|
report
|
|
992
1059
|
});
|
|
993
1060
|
if (!settle.ok) {
|
|
994
|
-
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body
|
|
1061
|
+
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body, {
|
|
1062
|
+
cause: settle.error
|
|
1063
|
+
});
|
|
995
1064
|
}
|
|
996
1065
|
return runPostSettleEpilogue({
|
|
997
1066
|
ctx,
|
|
@@ -1018,7 +1087,13 @@ async function runHandlerOnly(ctx, wallet, account) {
|
|
|
1018
1087
|
const validateErr = await runValidate(ctx, body.data);
|
|
1019
1088
|
if (validateErr) return validateErr;
|
|
1020
1089
|
const result = await invokeUnauthed(ctx, wallet, account, body.data);
|
|
1021
|
-
return finalize(
|
|
1090
|
+
return finalize(
|
|
1091
|
+
ctx,
|
|
1092
|
+
result.response,
|
|
1093
|
+
result.rawResult,
|
|
1094
|
+
body.data,
|
|
1095
|
+
result.handlerError === void 0 ? void 0 : { cause: result.handlerError }
|
|
1096
|
+
);
|
|
1022
1097
|
}
|
|
1023
1098
|
|
|
1024
1099
|
// src/pipeline/steps/run-before-settle.ts
|
|
@@ -1574,7 +1649,7 @@ async function verifyHashMode(args, info) {
|
|
|
1574
1649
|
}
|
|
1575
1650
|
if (chargeResult.status === 402) {
|
|
1576
1651
|
const reason = await readChallengeReason(chargeResult.challenge);
|
|
1577
|
-
const detail = reason || "credential may be invalid, or check TEMPO_RPC_URL
|
|
1652
|
+
const detail = reason || "credential may be invalid, or check your TEMPO_RPC_URL endpoint";
|
|
1578
1653
|
report("warn", `MPP credential rejected: ${detail}`);
|
|
1579
1654
|
return { ok: false, kind: "invalid" };
|
|
1580
1655
|
}
|
|
@@ -2457,11 +2532,9 @@ async function buildChallengeResponse(ctx, pricing, body, failure) {
|
|
|
2457
2532
|
challengePrice = pricing ? await pricing.challengeQuote(body) : "0";
|
|
2458
2533
|
} catch (err) {
|
|
2459
2534
|
const message = errorMessage(err, "Price calculation failed");
|
|
2460
|
-
const
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
);
|
|
2464
|
-
firePluginResponse(ctx, errorResponse);
|
|
2535
|
+
const responseBody2 = { success: false, error: message };
|
|
2536
|
+
const errorResponse = import_server5.NextResponse.json(responseBody2, { status: errorStatus(err, 500) });
|
|
2537
|
+
firePluginResponse(ctx, errorResponse, body, responseBody2, { message, cause: err });
|
|
2465
2538
|
return errorResponse;
|
|
2466
2539
|
}
|
|
2467
2540
|
const extensions = await buildChallengeExtensions(ctx);
|
|
@@ -2493,11 +2566,9 @@ async function buildChallengeResponse(ctx, pricing, body, failure) {
|
|
|
2493
2566
|
const message = `${strategy.protocol} challenge build failed: ${errorMessage(err, String(err))}`;
|
|
2494
2567
|
ctx.report("critical", message);
|
|
2495
2568
|
if (strategy.protocol === "x402") {
|
|
2496
|
-
const
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
);
|
|
2500
|
-
firePluginResponse(ctx, errorResponse);
|
|
2569
|
+
const responseBody2 = { success: false, error: message };
|
|
2570
|
+
const errorResponse = import_server5.NextResponse.json(responseBody2, { status: 500 });
|
|
2571
|
+
firePluginResponse(ctx, errorResponse, body, responseBody2, { message, cause: err });
|
|
2501
2572
|
return errorResponse;
|
|
2502
2573
|
}
|
|
2503
2574
|
}
|
|
@@ -2656,10 +2727,11 @@ function toResponse(rawResult) {
|
|
|
2656
2727
|
function errorResult2(error) {
|
|
2657
2728
|
const status = error instanceof HttpError ? error.status : typeof error?.status === "number" ? error.status : 500;
|
|
2658
2729
|
const message = error instanceof Error ? error.message : "Internal error";
|
|
2730
|
+
const responseBody = { success: false, error: message };
|
|
2659
2731
|
return {
|
|
2660
2732
|
kind: "request",
|
|
2661
|
-
response: import_server7.NextResponse.json(
|
|
2662
|
-
rawResult:
|
|
2733
|
+
response: import_server7.NextResponse.json(responseBody, { status }),
|
|
2734
|
+
rawResult: responseBody,
|
|
2663
2735
|
handlerError: error
|
|
2664
2736
|
};
|
|
2665
2737
|
}
|
|
@@ -2790,7 +2862,13 @@ async function runDynamicRequestFlow(args) {
|
|
|
2790
2862
|
handlerError: result.handlerError
|
|
2791
2863
|
};
|
|
2792
2864
|
if (result.response.status >= 400) {
|
|
2793
|
-
return finalize(
|
|
2865
|
+
return finalize(
|
|
2866
|
+
ctx,
|
|
2867
|
+
result.response,
|
|
2868
|
+
result.rawResult,
|
|
2869
|
+
body,
|
|
2870
|
+
failureFromCause(result.handlerError)
|
|
2871
|
+
);
|
|
2794
2872
|
}
|
|
2795
2873
|
const beforeErr = await runBeforeSettle(ctx, settleScope);
|
|
2796
2874
|
if (beforeErr) return beforeErr;
|
|
@@ -2812,6 +2890,9 @@ async function runDynamicRequestFlow(args) {
|
|
|
2812
2890
|
}
|
|
2813
2891
|
});
|
|
2814
2892
|
}
|
|
2893
|
+
function failureFromCause(cause) {
|
|
2894
|
+
return cause === void 0 ? void 0 : { cause };
|
|
2895
|
+
}
|
|
2815
2896
|
function computeBilledAmount(routeEntry, result) {
|
|
2816
2897
|
if (routeEntry.billing === "upto") {
|
|
2817
2898
|
const total = result.uptoContext?.atomicTotal() ?? 0n;
|
|
@@ -2976,7 +3057,13 @@ async function runStaticRequestFlow(args) {
|
|
|
2976
3057
|
if (result.response.status >= 400) {
|
|
2977
3058
|
const settledScope = settleScope;
|
|
2978
3059
|
await runSettledHandlerError(ctx, settledScope);
|
|
2979
|
-
return finalize(
|
|
3060
|
+
return finalize(
|
|
3061
|
+
ctx,
|
|
3062
|
+
result.response,
|
|
3063
|
+
result.rawResult,
|
|
3064
|
+
body,
|
|
3065
|
+
failureFromCause2(result.handlerError)
|
|
3066
|
+
);
|
|
2980
3067
|
}
|
|
2981
3068
|
return settleAndFinalizeRequest({
|
|
2982
3069
|
ctx,
|
|
@@ -2989,7 +3076,13 @@ async function runStaticRequestFlow(args) {
|
|
|
2989
3076
|
});
|
|
2990
3077
|
}
|
|
2991
3078
|
if (result.response.status >= 400) {
|
|
2992
|
-
return finalize(
|
|
3079
|
+
return finalize(
|
|
3080
|
+
ctx,
|
|
3081
|
+
result.response,
|
|
3082
|
+
result.rawResult,
|
|
3083
|
+
body,
|
|
3084
|
+
failureFromCause2(result.handlerError)
|
|
3085
|
+
);
|
|
2993
3086
|
}
|
|
2994
3087
|
const beforeErr = await runBeforeSettle(ctx, settleScope);
|
|
2995
3088
|
if (beforeErr) return beforeErr;
|
|
@@ -3010,6 +3103,9 @@ async function runStaticRequestFlow(args) {
|
|
|
3010
3103
|
}
|
|
3011
3104
|
});
|
|
3012
3105
|
}
|
|
3106
|
+
function failureFromCause2(cause) {
|
|
3107
|
+
return cause === void 0 ? void 0 : { cause };
|
|
3108
|
+
}
|
|
3013
3109
|
|
|
3014
3110
|
// src/pipeline/flows/static/static-paid.ts
|
|
3015
3111
|
async function runStaticPaidFlow(ctx) {
|
|
@@ -4464,7 +4560,7 @@ var envShape = {
|
|
|
4464
4560
|
}).optional(),
|
|
4465
4561
|
TEMPO_RPC_URL: import_zod.z.string().refine(isUrl, {
|
|
4466
4562
|
params: { code: "invalid_mpp_rpc_url", ...mpp },
|
|
4467
|
-
message: "TEMPO_RPC_URL must be a valid URL \u2014
|
|
4563
|
+
message: "TEMPO_RPC_URL must be a valid URL \u2014 the Tempo JSON-RPC endpoint used for MPP on-chain verification. Optional; defaults to the public DEFAULT_TEMPO_RPC_URL."
|
|
4468
4564
|
}).optional(),
|
|
4469
4565
|
MPP_OPERATOR_KEY: import_zod.z.string().refine(isEvmPrivateKey, {
|
|
4470
4566
|
params: { code: "invalid_mpp_operator_key", ...mpp },
|
|
@@ -4505,14 +4601,6 @@ var EnvInputSchema = import_zod.z.object(envShape).passthrough().superRefine((en
|
|
|
4505
4601
|
["MPP_CURRENCY"]
|
|
4506
4602
|
);
|
|
4507
4603
|
}
|
|
4508
|
-
if (env.TEMPO_RPC_URL === void 0) {
|
|
4509
|
-
addIssue(
|
|
4510
|
-
ctx,
|
|
4511
|
-
{ code: "missing_mpp_rpc_url", ...mpp },
|
|
4512
|
-
"TEMPO_RPC_URL is required when MPP is enabled \u2014 authenticated Tempo JSON-RPC endpoint. Public rpc.tempo.xyz returns 401.",
|
|
4513
|
-
["TEMPO_RPC_URL"]
|
|
4514
|
-
);
|
|
4515
|
-
}
|
|
4516
4604
|
}
|
|
4517
4605
|
const collision = operatorAddressesCollide(env.MPP_OPERATOR_KEY, env.MPP_FEE_PAYER_KEY);
|
|
4518
4606
|
if (collision) {
|
|
@@ -4644,7 +4732,7 @@ function validateX402Config(config, env) {
|
|
|
4644
4732
|
}
|
|
4645
4733
|
return issues;
|
|
4646
4734
|
}
|
|
4647
|
-
function validateMppConfig(config
|
|
4735
|
+
function validateMppConfig(config) {
|
|
4648
4736
|
const m = config.mpp;
|
|
4649
4737
|
if (!m) {
|
|
4650
4738
|
return [
|
|
@@ -4692,12 +4780,6 @@ function validateMppConfig(config, env) {
|
|
|
4692
4780
|
`MPP recipient '${placeholder}' is a placeholder address and cannot receive payments.`
|
|
4693
4781
|
);
|
|
4694
4782
|
}
|
|
4695
|
-
if (!m.rpcUrl && !env.TEMPO_RPC_URL) {
|
|
4696
|
-
push(
|
|
4697
|
-
"missing_mpp_rpc_url",
|
|
4698
|
-
"MPP requires an authenticated Tempo RPC URL. Set TEMPO_RPC_URL env var or pass rpcUrl in the mpp config object."
|
|
4699
|
-
);
|
|
4700
|
-
}
|
|
4701
4783
|
if (m.feePayerKey && !isEvmPrivateKey(m.feePayerKey)) {
|
|
4702
4784
|
push(
|
|
4703
4785
|
"invalid_mpp_fee_payer_key",
|
|
@@ -4804,7 +4886,7 @@ function routerConfigFromEnv(options) {
|
|
|
4804
4886
|
const mppConfig = mppEnabled ? {
|
|
4805
4887
|
secretKey: env.MPP_SECRET_KEY,
|
|
4806
4888
|
currency: canonicalizeEvm(env.MPP_CURRENCY),
|
|
4807
|
-
rpcUrl: env.TEMPO_RPC_URL,
|
|
4889
|
+
rpcUrl: env.TEMPO_RPC_URL ?? DEFAULT_TEMPO_RPC_URL,
|
|
4808
4890
|
recipient: payeeAddress,
|
|
4809
4891
|
...env.MPP_FEE_PAYER_KEY ? { feePayerKey: env.MPP_FEE_PAYER_KEY } : {},
|
|
4810
4892
|
...env.MPP_OPERATOR_KEY ? { operatorKey: env.MPP_OPERATOR_KEY, session: {} } : {}
|
|
@@ -4855,7 +4937,7 @@ function getRouterConfigIssues(config, options = {}) {
|
|
|
4855
4937
|
});
|
|
4856
4938
|
}
|
|
4857
4939
|
if (protocols.includes("x402")) issues.push(...validateX402Config(config, env));
|
|
4858
|
-
if (protocols.includes("mpp")) issues.push(...validateMppConfig(config
|
|
4940
|
+
if (protocols.includes("mpp")) issues.push(...validateMppConfig(config));
|
|
4859
4941
|
return issues;
|
|
4860
4942
|
}
|
|
4861
4943
|
|
|
@@ -4927,6 +5009,7 @@ function getMppxStreamingContext(args) {
|
|
|
4927
5009
|
}
|
|
4928
5010
|
|
|
4929
5011
|
// src/init/mpp.ts
|
|
5012
|
+
init_constants();
|
|
4930
5013
|
async function initMpp(config, resolvedBaseUrl, kvStore, configError) {
|
|
4931
5014
|
if (configError) return { initError: configError };
|
|
4932
5015
|
if (!config.mpp) return {};
|
|
@@ -4935,7 +5018,7 @@ async function initMpp(config, resolvedBaseUrl, kvStore, configError) {
|
|
|
4935
5018
|
const { createClient, http } = await import("viem");
|
|
4936
5019
|
const { tempo: tempoChain } = await import("viem/chains");
|
|
4937
5020
|
const { privateKeyToAccount: privateKeyToAccount2 } = await import("viem/accounts");
|
|
4938
|
-
const rpcUrl = config.mpp.rpcUrl ?? process.env.TEMPO_RPC_URL;
|
|
5021
|
+
const rpcUrl = config.mpp.rpcUrl ?? process.env.TEMPO_RPC_URL ?? DEFAULT_TEMPO_RPC_URL;
|
|
4939
5022
|
const tempoClient = createClient({ chain: tempoChain, transport: http(rpcUrl) });
|
|
4940
5023
|
const getClient = async () => tempoClient;
|
|
4941
5024
|
const operatorAccount = config.mpp.operatorKey ? privateKeyToAccount2(config.mpp.operatorKey) : void 0;
|
|
@@ -5113,6 +5196,7 @@ function createRouterFromEnv(options) {
|
|
|
5113
5196
|
BASE_USDC_ADDRESS,
|
|
5114
5197
|
BASE_USDC_DECIMALS,
|
|
5115
5198
|
DEFAULT_SOLANA_FACILITATOR_URL,
|
|
5199
|
+
DEFAULT_TEMPO_RPC_URL,
|
|
5116
5200
|
HttpError,
|
|
5117
5201
|
RouterConfigError,
|
|
5118
5202
|
SOLANA_MAINNET_NETWORK,
|
package/dist/index.d.cts
CHANGED
|
@@ -77,13 +77,24 @@ interface ResponseMeta {
|
|
|
77
77
|
headers: Record<string, string>;
|
|
78
78
|
/** Parsed request body (when .body() was used). undefined when no body was parsed. */
|
|
79
79
|
requestBody?: unknown;
|
|
80
|
-
/** Handler return value
|
|
80
|
+
/** Handler return value or structured router-generated error body. */
|
|
81
81
|
responseBody?: unknown;
|
|
82
82
|
}
|
|
83
83
|
interface ErrorEvent {
|
|
84
84
|
status: number;
|
|
85
85
|
message: string;
|
|
86
86
|
settled: boolean;
|
|
87
|
+
requestId?: string;
|
|
88
|
+
route?: string;
|
|
89
|
+
method?: string;
|
|
90
|
+
duration?: number;
|
|
91
|
+
walletAddress?: string | null;
|
|
92
|
+
verifiedWallet?: string | null;
|
|
93
|
+
clientId?: string | null;
|
|
94
|
+
sessionId?: string | null;
|
|
95
|
+
errorName?: string;
|
|
96
|
+
stack?: string;
|
|
97
|
+
cause?: unknown;
|
|
87
98
|
}
|
|
88
99
|
interface AuthEvent {
|
|
89
100
|
/** Authentication mode that was verified */
|
|
@@ -411,7 +422,7 @@ interface RouterConfig {
|
|
|
411
422
|
currency: string;
|
|
412
423
|
/** MPP payee address (EVM). Overrides `payeeAddress` for MPP only. Required when `payeeAddress` is unset. MUST equal `operatorKey`'s derived address when `session` is enabled. */
|
|
413
424
|
recipient?: string;
|
|
414
|
-
/** Tempo RPC URL for on-chain verification. Falls back to `TEMPO_RPC_URL`. */
|
|
425
|
+
/** Tempo RPC URL for on-chain verification. Falls back to `TEMPO_RPC_URL`, then to the public `DEFAULT_TEMPO_RPC_URL`. */
|
|
415
426
|
rpcUrl?: string;
|
|
416
427
|
/** Hex private key. Signs channel close/settle; required for `session`. Address MUST equal `recipient`/payee — mppx asserts sender===payee on settle. Validated at init. */
|
|
417
428
|
operatorKey?: string;
|
|
@@ -793,7 +804,7 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, TOutput = unde
|
|
|
793
804
|
private register;
|
|
794
805
|
}
|
|
795
806
|
|
|
796
|
-
type RouterConfigIssueCode = 'missing_base_url' | 'invalid_base_url' | 'empty_protocols' | 'missing_x402_accepts' | 'missing_x402_network' | 'unsupported_x402_network' | 'missing_x402_asset' | 'invalid_x402_decimals' | 'missing_x402_payee' | 'invalid_x402_payee' | 'invalid_solana_payee' | 'invalid_solana_facilitator_url' | 'missing_cdp_keys' | 'placeholder_payee' | 'missing_mpp_config' | 'missing_mpp_secret_key' | 'missing_mpp_currency' | 'invalid_mpp_currency' | 'missing_mpp_recipient' | 'invalid_mpp_recipient' | '
|
|
807
|
+
type RouterConfigIssueCode = 'missing_base_url' | 'invalid_base_url' | 'empty_protocols' | 'missing_x402_accepts' | 'missing_x402_network' | 'unsupported_x402_network' | 'missing_x402_asset' | 'invalid_x402_decimals' | 'missing_x402_payee' | 'invalid_x402_payee' | 'invalid_solana_payee' | 'invalid_solana_facilitator_url' | 'missing_cdp_keys' | 'placeholder_payee' | 'missing_mpp_config' | 'missing_mpp_secret_key' | 'missing_mpp_currency' | 'invalid_mpp_currency' | 'missing_mpp_recipient' | 'invalid_mpp_recipient' | 'invalid_mpp_rpc_url' | 'invalid_mpp_fee_payer_key' | 'invalid_mpp_operator_key' | 'mpp_operator_equals_fee_payer' | 'mpp_operator_recipient_mismatch' | 'missing_discovery_title' | 'missing_discovery_description' | 'missing_discovery_guidance' | 'invalid_server_url' | 'kv_url_without_token' | 'kv_token_without_url' | 'invalid_kv_url' | 'missing_kv_in_production';
|
|
797
808
|
type RouterConfigIssueSeverity = 'error' | 'warning';
|
|
798
809
|
interface RouterConfigIssue {
|
|
799
810
|
code: RouterConfigIssueCode;
|
|
@@ -870,6 +881,8 @@ declare const BASE_USDC_DECIMALS = 6;
|
|
|
870
881
|
declare const ZERO_EVM_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
871
882
|
/** Public Solana x402 facilitator. Override per-deployment via `SOLANA_FACILITATOR_URL`. */
|
|
872
883
|
declare const DEFAULT_SOLANA_FACILITATOR_URL = "https://facilitator.corbits.dev";
|
|
884
|
+
/** Public Tempo JSON-RPC endpoint used for MPP on-chain verification. Override per-deployment via `TEMPO_RPC_URL`. */
|
|
885
|
+
declare const DEFAULT_TEMPO_RPC_URL = "https://rpc.tempo.xyz";
|
|
873
886
|
|
|
874
887
|
interface MonitorEntry {
|
|
875
888
|
provider: string;
|
|
@@ -912,4 +925,4 @@ declare function createRouter<const P extends Record<string, string> = Record<ne
|
|
|
912
925
|
*/
|
|
913
926
|
declare function createRouterFromEnv<const P extends Record<string, string> = Record<never, string>>(options: CreateRouterFromEnvOptions<P>): ServiceRouter<Extract<keyof P, string>>;
|
|
914
927
|
|
|
915
|
-
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
|
928
|
+
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
package/dist/index.d.ts
CHANGED
|
@@ -77,13 +77,24 @@ interface ResponseMeta {
|
|
|
77
77
|
headers: Record<string, string>;
|
|
78
78
|
/** Parsed request body (when .body() was used). undefined when no body was parsed. */
|
|
79
79
|
requestBody?: unknown;
|
|
80
|
-
/** Handler return value
|
|
80
|
+
/** Handler return value or structured router-generated error body. */
|
|
81
81
|
responseBody?: unknown;
|
|
82
82
|
}
|
|
83
83
|
interface ErrorEvent {
|
|
84
84
|
status: number;
|
|
85
85
|
message: string;
|
|
86
86
|
settled: boolean;
|
|
87
|
+
requestId?: string;
|
|
88
|
+
route?: string;
|
|
89
|
+
method?: string;
|
|
90
|
+
duration?: number;
|
|
91
|
+
walletAddress?: string | null;
|
|
92
|
+
verifiedWallet?: string | null;
|
|
93
|
+
clientId?: string | null;
|
|
94
|
+
sessionId?: string | null;
|
|
95
|
+
errorName?: string;
|
|
96
|
+
stack?: string;
|
|
97
|
+
cause?: unknown;
|
|
87
98
|
}
|
|
88
99
|
interface AuthEvent {
|
|
89
100
|
/** Authentication mode that was verified */
|
|
@@ -411,7 +422,7 @@ interface RouterConfig {
|
|
|
411
422
|
currency: string;
|
|
412
423
|
/** MPP payee address (EVM). Overrides `payeeAddress` for MPP only. Required when `payeeAddress` is unset. MUST equal `operatorKey`'s derived address when `session` is enabled. */
|
|
413
424
|
recipient?: string;
|
|
414
|
-
/** Tempo RPC URL for on-chain verification. Falls back to `TEMPO_RPC_URL`. */
|
|
425
|
+
/** Tempo RPC URL for on-chain verification. Falls back to `TEMPO_RPC_URL`, then to the public `DEFAULT_TEMPO_RPC_URL`. */
|
|
415
426
|
rpcUrl?: string;
|
|
416
427
|
/** Hex private key. Signs channel close/settle; required for `session`. Address MUST equal `recipient`/payee — mppx asserts sender===payee on settle. Validated at init. */
|
|
417
428
|
operatorKey?: string;
|
|
@@ -793,7 +804,7 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, TOutput = unde
|
|
|
793
804
|
private register;
|
|
794
805
|
}
|
|
795
806
|
|
|
796
|
-
type RouterConfigIssueCode = 'missing_base_url' | 'invalid_base_url' | 'empty_protocols' | 'missing_x402_accepts' | 'missing_x402_network' | 'unsupported_x402_network' | 'missing_x402_asset' | 'invalid_x402_decimals' | 'missing_x402_payee' | 'invalid_x402_payee' | 'invalid_solana_payee' | 'invalid_solana_facilitator_url' | 'missing_cdp_keys' | 'placeholder_payee' | 'missing_mpp_config' | 'missing_mpp_secret_key' | 'missing_mpp_currency' | 'invalid_mpp_currency' | 'missing_mpp_recipient' | 'invalid_mpp_recipient' | '
|
|
807
|
+
type RouterConfigIssueCode = 'missing_base_url' | 'invalid_base_url' | 'empty_protocols' | 'missing_x402_accepts' | 'missing_x402_network' | 'unsupported_x402_network' | 'missing_x402_asset' | 'invalid_x402_decimals' | 'missing_x402_payee' | 'invalid_x402_payee' | 'invalid_solana_payee' | 'invalid_solana_facilitator_url' | 'missing_cdp_keys' | 'placeholder_payee' | 'missing_mpp_config' | 'missing_mpp_secret_key' | 'missing_mpp_currency' | 'invalid_mpp_currency' | 'missing_mpp_recipient' | 'invalid_mpp_recipient' | 'invalid_mpp_rpc_url' | 'invalid_mpp_fee_payer_key' | 'invalid_mpp_operator_key' | 'mpp_operator_equals_fee_payer' | 'mpp_operator_recipient_mismatch' | 'missing_discovery_title' | 'missing_discovery_description' | 'missing_discovery_guidance' | 'invalid_server_url' | 'kv_url_without_token' | 'kv_token_without_url' | 'invalid_kv_url' | 'missing_kv_in_production';
|
|
797
808
|
type RouterConfigIssueSeverity = 'error' | 'warning';
|
|
798
809
|
interface RouterConfigIssue {
|
|
799
810
|
code: RouterConfigIssueCode;
|
|
@@ -870,6 +881,8 @@ declare const BASE_USDC_DECIMALS = 6;
|
|
|
870
881
|
declare const ZERO_EVM_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
871
882
|
/** Public Solana x402 facilitator. Override per-deployment via `SOLANA_FACILITATOR_URL`. */
|
|
872
883
|
declare const DEFAULT_SOLANA_FACILITATOR_URL = "https://facilitator.corbits.dev";
|
|
884
|
+
/** Public Tempo JSON-RPC endpoint used for MPP on-chain verification. Override per-deployment via `TEMPO_RPC_URL`. */
|
|
885
|
+
declare const DEFAULT_TEMPO_RPC_URL = "https://rpc.tempo.xyz";
|
|
873
886
|
|
|
874
887
|
interface MonitorEntry {
|
|
875
888
|
provider: string;
|
|
@@ -912,4 +925,4 @@ declare function createRouter<const P extends Record<string, string> = Record<ne
|
|
|
912
925
|
*/
|
|
913
926
|
declare function createRouterFromEnv<const P extends Record<string, string> = Record<never, string>>(options: CreateRouterFromEnvOptions<P>): ServiceRouter<Extract<keyof P, string>>;
|
|
914
927
|
|
|
915
|
-
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
|
928
|
+
export { BASE_MAINNET_NETWORK, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, type CreateRouterFromEnvOptions, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL, type DiscoveryConfig, type HandlerContext, HttpError, type KvStore, type PaidOptions, type ProtocolType, type RouterConfig, RouterConfigError, type RouterConfigIssue, type RouterConfigIssueCode, type RouterConfigIssueSeverity, type RouterPlugin, SOLANA_MAINNET_NETWORK, type ServiceRouter, type SettlementErrorContext, type SettlementLifecycleContext, type SettlementSettledContext, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, type X402FacilitatorsConfig, ZERO_EVM_ADDRESS, createRouter, createRouterFromEnv, routerConfigFromEnv };
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var __export = (target, all) => {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
// src/constants.ts
|
|
12
|
-
var BASE_MAINNET_NETWORK, SOLANA_MAINNET_NETWORK, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, ZERO_EVM_ADDRESS, DEFAULT_SOLANA_FACILITATOR_URL;
|
|
12
|
+
var BASE_MAINNET_NETWORK, SOLANA_MAINNET_NETWORK, TEMPO_USDC_ADDRESS, TEMPO_USDC_DECIMALS, BASE_USDC_ADDRESS, BASE_USDC_DECIMALS, ZERO_EVM_ADDRESS, DEFAULT_SOLANA_FACILITATOR_URL, DEFAULT_TEMPO_RPC_URL;
|
|
13
13
|
var init_constants = __esm({
|
|
14
14
|
"src/constants.ts"() {
|
|
15
15
|
"use strict";
|
|
@@ -21,6 +21,7 @@ var init_constants = __esm({
|
|
|
21
21
|
BASE_USDC_DECIMALS = 6;
|
|
22
22
|
ZERO_EVM_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
23
23
|
DEFAULT_SOLANA_FACILITATOR_URL = "https://facilitator.corbits.dev";
|
|
24
|
+
DEFAULT_TEMPO_RPC_URL = "https://rpc.tempo.xyz";
|
|
24
25
|
}
|
|
25
26
|
});
|
|
26
27
|
|
|
@@ -498,7 +499,8 @@ var HEADERS = {
|
|
|
498
499
|
X402_PAYMENT_LEGACY: "X-PAYMENT",
|
|
499
500
|
X402_PAYMENT_REQUIRED: "PAYMENT-REQUIRED",
|
|
500
501
|
X402_PAYMENT_RESPONSE: "PAYMENT-RESPONSE",
|
|
501
|
-
MPP_PAYMENT_RECEIPT: "Payment-Receipt"
|
|
502
|
+
MPP_PAYMENT_RECEIPT: "Payment-Receipt",
|
|
503
|
+
REQUEST_ID: "X-Request-ID"
|
|
502
504
|
};
|
|
503
505
|
var AUTH_SCHEME = {
|
|
504
506
|
BEARER: "Bearer ",
|
|
@@ -528,19 +530,19 @@ function firePluginHook(plugin, method, ...args) {
|
|
|
528
530
|
const result = fn.apply(plugin, args);
|
|
529
531
|
if (result && typeof result.catch === "function") {
|
|
530
532
|
result.catch((error) => {
|
|
531
|
-
console.error(
|
|
532
|
-
`[router] ERROR ${method}: ${error instanceof Error ? error.message : String(error)}`
|
|
533
|
-
);
|
|
533
|
+
console.error(`[router] ERROR ${method}: ${formatUnknownError(error)}`);
|
|
534
534
|
});
|
|
535
535
|
}
|
|
536
536
|
return result;
|
|
537
537
|
} catch (error) {
|
|
538
|
-
console.error(
|
|
539
|
-
`[router] ERROR ${method}: ${error instanceof Error ? error.message : String(error)}`
|
|
540
|
-
);
|
|
538
|
+
console.error(`[router] ERROR ${method}: ${formatUnknownError(error)}`);
|
|
541
539
|
return void 0;
|
|
542
540
|
}
|
|
543
541
|
}
|
|
542
|
+
function formatUnknownError(error) {
|
|
543
|
+
if (error instanceof Error) return error.stack ?? error.message;
|
|
544
|
+
return String(error);
|
|
545
|
+
}
|
|
544
546
|
|
|
545
547
|
// src/plugin/reporter.ts
|
|
546
548
|
function createReporter(plugin, pluginCtx, route) {
|
|
@@ -631,7 +633,8 @@ function firePaymentVerified(ctx, event) {
|
|
|
631
633
|
function firePaymentSettled(ctx, event) {
|
|
632
634
|
firePluginHook(ctx.deps.plugin, "onPaymentSettled", ctx.pluginCtx, event);
|
|
633
635
|
}
|
|
634
|
-
function firePluginResponse(ctx, response, requestBody, responseBody) {
|
|
636
|
+
function firePluginResponse(ctx, response, requestBody, responseBody, failure) {
|
|
637
|
+
attachRequestId(response, ctx.meta.requestId);
|
|
635
638
|
firePluginHook(ctx.deps.plugin, "onResponse", ctx.pluginCtx, {
|
|
636
639
|
statusCode: response.status,
|
|
637
640
|
statusText: response.statusText,
|
|
@@ -642,11 +645,9 @@ function firePluginResponse(ctx, response, requestBody, responseBody) {
|
|
|
642
645
|
responseBody
|
|
643
646
|
});
|
|
644
647
|
if (response.status >= 400 && response.status !== 402) {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
settled: false
|
|
649
|
-
});
|
|
648
|
+
const error = buildErrorEvent(ctx, response, failure);
|
|
649
|
+
if (response.status >= 500) logRouterFailure(error);
|
|
650
|
+
firePluginHook(ctx.deps.plugin, "onError", ctx.pluginCtx, error);
|
|
650
651
|
}
|
|
651
652
|
}
|
|
652
653
|
function fireProviderQuota(ctx, response, handlerResult) {
|
|
@@ -678,6 +679,67 @@ function computeQuotaLevel(remaining, warn, critical) {
|
|
|
678
679
|
if (warn !== void 0 && remaining <= warn) return "warn";
|
|
679
680
|
return "healthy";
|
|
680
681
|
}
|
|
682
|
+
function attachRequestId(response, requestId) {
|
|
683
|
+
try {
|
|
684
|
+
if (!response.headers.has(HEADERS.REQUEST_ID)) {
|
|
685
|
+
response.headers.set(HEADERS.REQUEST_ID, requestId);
|
|
686
|
+
}
|
|
687
|
+
} catch {
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
function buildErrorEvent(ctx, response, failure) {
|
|
691
|
+
const error = errorDetails(failure?.cause);
|
|
692
|
+
const responseMessage = response.statusText || `HTTP ${response.status}`;
|
|
693
|
+
const message = failure?.message ?? error.message ?? responseMessage;
|
|
694
|
+
return {
|
|
695
|
+
status: response.status,
|
|
696
|
+
message,
|
|
697
|
+
settled: failure?.settled ?? false,
|
|
698
|
+
requestId: ctx.meta.requestId,
|
|
699
|
+
route: ctx.meta.route,
|
|
700
|
+
method: ctx.meta.method,
|
|
701
|
+
duration: Date.now() - ctx.meta.startTime,
|
|
702
|
+
walletAddress: ctx.meta.walletAddress,
|
|
703
|
+
verifiedWallet: ctx.pluginCtx.verifiedWallet,
|
|
704
|
+
clientId: ctx.meta.clientId,
|
|
705
|
+
sessionId: ctx.meta.sessionId,
|
|
706
|
+
errorName: error.name,
|
|
707
|
+
stack: error.stack,
|
|
708
|
+
cause: failure?.cause
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
function errorDetails(error) {
|
|
712
|
+
if (error instanceof Error) {
|
|
713
|
+
return {
|
|
714
|
+
message: error.message,
|
|
715
|
+
name: error.name,
|
|
716
|
+
stack: error.stack
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
if (typeof error === "object" && error !== null) {
|
|
720
|
+
const record = error;
|
|
721
|
+
return {
|
|
722
|
+
message: typeof record.message === "string" ? record.message : void 0,
|
|
723
|
+
name: typeof record.name === "string" ? record.name : void 0,
|
|
724
|
+
stack: typeof record.stack === "string" ? record.stack : void 0
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
if (typeof error === "string") return { message: error };
|
|
728
|
+
return {};
|
|
729
|
+
}
|
|
730
|
+
function logRouterFailure(error) {
|
|
731
|
+
console.error(`[router] ERROR ${error.route ?? "unknown"} ${error.status}: ${error.message}`, {
|
|
732
|
+
requestId: error.requestId,
|
|
733
|
+
method: error.method,
|
|
734
|
+
duration: error.duration,
|
|
735
|
+
walletAddress: error.walletAddress,
|
|
736
|
+
verifiedWallet: error.verifiedWallet,
|
|
737
|
+
clientId: error.clientId,
|
|
738
|
+
sessionId: error.sessionId,
|
|
739
|
+
errorName: error.errorName,
|
|
740
|
+
stack: error.stack
|
|
741
|
+
});
|
|
742
|
+
}
|
|
681
743
|
|
|
682
744
|
// src/pipeline/steps/parse-body.ts
|
|
683
745
|
async function parseBody(ctx, request = ctx.request) {
|
|
@@ -687,20 +749,19 @@ async function parseBody(ctx, request = ctx.request) {
|
|
|
687
749
|
raw = await bufferBody(request);
|
|
688
750
|
} catch (err) {
|
|
689
751
|
if (!(err instanceof MalformedJsonError)) throw err;
|
|
690
|
-
const
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
752
|
+
const responseBody2 = { success: false, error: "Invalid JSON", issues: [] };
|
|
753
|
+
const response2 = NextResponse.json(responseBody2, { status: 400 });
|
|
754
|
+
firePluginResponse(ctx, response2, void 0, responseBody2, {
|
|
755
|
+
message: responseBody2.error,
|
|
756
|
+
cause: err
|
|
757
|
+
});
|
|
695
758
|
return { ok: false, response: response2 };
|
|
696
759
|
}
|
|
697
760
|
const result = validateBody(raw, ctx.routeEntry.bodySchema);
|
|
698
761
|
if (result.success) return { ok: true, data: result.data };
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
);
|
|
703
|
-
firePluginResponse(ctx, response);
|
|
762
|
+
const responseBody = { success: false, error: result.error, issues: result.issues };
|
|
763
|
+
const response = NextResponse.json(responseBody, { status: 400 });
|
|
764
|
+
firePluginResponse(ctx, response, raw, responseBody, { message: result.error });
|
|
704
765
|
return { ok: false, response };
|
|
705
766
|
}
|
|
706
767
|
|
|
@@ -712,11 +773,9 @@ function validateQuery(ctx) {
|
|
|
712
773
|
const params = Object.fromEntries(ctx.request.nextUrl.searchParams.entries());
|
|
713
774
|
const result = validateBody(params, querySchema);
|
|
714
775
|
if (result.success) return { ok: true, data: result.data };
|
|
715
|
-
const
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
);
|
|
719
|
-
firePluginResponse(ctx, response);
|
|
776
|
+
const responseBody = { success: false, error: result.error, issues: result.issues };
|
|
777
|
+
const response = NextResponse2.json(responseBody, { status: 400 });
|
|
778
|
+
firePluginResponse(ctx, response, params, responseBody, { message: result.error });
|
|
720
779
|
return { ok: false, response };
|
|
721
780
|
}
|
|
722
781
|
|
|
@@ -735,9 +794,13 @@ function handlerFailureError(response) {
|
|
|
735
794
|
|
|
736
795
|
// src/pipeline/steps/fail.ts
|
|
737
796
|
import { NextResponse as NextResponse3 } from "next/server";
|
|
738
|
-
function fail(ctx, status, message, requestBody) {
|
|
739
|
-
const
|
|
740
|
-
|
|
797
|
+
function fail(ctx, status, message, requestBody, failure) {
|
|
798
|
+
const responseBody = { success: false, error: message };
|
|
799
|
+
const response = NextResponse3.json(responseBody, { status });
|
|
800
|
+
firePluginResponse(ctx, response, requestBody, responseBody, {
|
|
801
|
+
...failure,
|
|
802
|
+
message: failure?.message ?? message
|
|
803
|
+
});
|
|
741
804
|
return response;
|
|
742
805
|
}
|
|
743
806
|
|
|
@@ -813,9 +876,10 @@ async function runHandler(ctx, handlerCtx) {
|
|
|
813
876
|
function errorResult(error) {
|
|
814
877
|
const status = error instanceof HttpError ? error.status : typeof error?.status === "number" ? error.status : 500;
|
|
815
878
|
const message = error instanceof Error ? error.message : "Internal error";
|
|
879
|
+
const responseBody = { success: false, error: message };
|
|
816
880
|
return {
|
|
817
|
-
response: NextResponse4.json(
|
|
818
|
-
rawResult:
|
|
881
|
+
response: NextResponse4.json(responseBody, { status }),
|
|
882
|
+
rawResult: responseBody,
|
|
819
883
|
handlerError: error
|
|
820
884
|
};
|
|
821
885
|
}
|
|
@@ -827,9 +891,9 @@ function isThenable(value) {
|
|
|
827
891
|
}
|
|
828
892
|
|
|
829
893
|
// src/pipeline/steps/finalize/response.ts
|
|
830
|
-
function finalize(ctx, response, rawResult, requestBody) {
|
|
894
|
+
function finalize(ctx, response, rawResult, requestBody, failure) {
|
|
831
895
|
fireProviderQuota(ctx, response, rawResult);
|
|
832
|
-
firePluginResponse(ctx, response, requestBody, rawResult);
|
|
896
|
+
firePluginResponse(ctx, response, requestBody, rawResult, failure);
|
|
833
897
|
return response;
|
|
834
898
|
}
|
|
835
899
|
|
|
@@ -915,7 +979,9 @@ async function settleAndFinalizeRequest(args) {
|
|
|
915
979
|
});
|
|
916
980
|
if (!settle.ok) {
|
|
917
981
|
if (onSettleError) await onSettleError(settle.error, settle.failMessage);
|
|
918
|
-
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body
|
|
982
|
+
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body, {
|
|
983
|
+
cause: settle.error
|
|
984
|
+
});
|
|
919
985
|
}
|
|
920
986
|
return runPostSettleEpilogue({
|
|
921
987
|
ctx,
|
|
@@ -950,7 +1016,9 @@ async function settleAndFinalizeStream(args) {
|
|
|
950
1016
|
report
|
|
951
1017
|
});
|
|
952
1018
|
if (!settle.ok) {
|
|
953
|
-
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body
|
|
1019
|
+
return fail(ctx, settle.failStatus ?? 500, settle.failMessage, body, {
|
|
1020
|
+
cause: settle.error
|
|
1021
|
+
});
|
|
954
1022
|
}
|
|
955
1023
|
return runPostSettleEpilogue({
|
|
956
1024
|
ctx,
|
|
@@ -977,7 +1045,13 @@ async function runHandlerOnly(ctx, wallet, account) {
|
|
|
977
1045
|
const validateErr = await runValidate(ctx, body.data);
|
|
978
1046
|
if (validateErr) return validateErr;
|
|
979
1047
|
const result = await invokeUnauthed(ctx, wallet, account, body.data);
|
|
980
|
-
return finalize(
|
|
1048
|
+
return finalize(
|
|
1049
|
+
ctx,
|
|
1050
|
+
result.response,
|
|
1051
|
+
result.rawResult,
|
|
1052
|
+
body.data,
|
|
1053
|
+
result.handlerError === void 0 ? void 0 : { cause: result.handlerError }
|
|
1054
|
+
);
|
|
981
1055
|
}
|
|
982
1056
|
|
|
983
1057
|
// src/pipeline/steps/run-before-settle.ts
|
|
@@ -1533,7 +1607,7 @@ async function verifyHashMode(args, info) {
|
|
|
1533
1607
|
}
|
|
1534
1608
|
if (chargeResult.status === 402) {
|
|
1535
1609
|
const reason = await readChallengeReason(chargeResult.challenge);
|
|
1536
|
-
const detail = reason || "credential may be invalid, or check TEMPO_RPC_URL
|
|
1610
|
+
const detail = reason || "credential may be invalid, or check your TEMPO_RPC_URL endpoint";
|
|
1537
1611
|
report("warn", `MPP credential rejected: ${detail}`);
|
|
1538
1612
|
return { ok: false, kind: "invalid" };
|
|
1539
1613
|
}
|
|
@@ -2416,11 +2490,9 @@ async function buildChallengeResponse(ctx, pricing, body, failure) {
|
|
|
2416
2490
|
challengePrice = pricing ? await pricing.challengeQuote(body) : "0";
|
|
2417
2491
|
} catch (err) {
|
|
2418
2492
|
const message = errorMessage(err, "Price calculation failed");
|
|
2419
|
-
const
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
);
|
|
2423
|
-
firePluginResponse(ctx, errorResponse);
|
|
2493
|
+
const responseBody2 = { success: false, error: message };
|
|
2494
|
+
const errorResponse = NextResponse5.json(responseBody2, { status: errorStatus(err, 500) });
|
|
2495
|
+
firePluginResponse(ctx, errorResponse, body, responseBody2, { message, cause: err });
|
|
2424
2496
|
return errorResponse;
|
|
2425
2497
|
}
|
|
2426
2498
|
const extensions = await buildChallengeExtensions(ctx);
|
|
@@ -2452,11 +2524,9 @@ async function buildChallengeResponse(ctx, pricing, body, failure) {
|
|
|
2452
2524
|
const message = `${strategy.protocol} challenge build failed: ${errorMessage(err, String(err))}`;
|
|
2453
2525
|
ctx.report("critical", message);
|
|
2454
2526
|
if (strategy.protocol === "x402") {
|
|
2455
|
-
const
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
);
|
|
2459
|
-
firePluginResponse(ctx, errorResponse);
|
|
2527
|
+
const responseBody2 = { success: false, error: message };
|
|
2528
|
+
const errorResponse = NextResponse5.json(responseBody2, { status: 500 });
|
|
2529
|
+
firePluginResponse(ctx, errorResponse, body, responseBody2, { message, cause: err });
|
|
2460
2530
|
return errorResponse;
|
|
2461
2531
|
}
|
|
2462
2532
|
}
|
|
@@ -2615,10 +2685,11 @@ function toResponse(rawResult) {
|
|
|
2615
2685
|
function errorResult2(error) {
|
|
2616
2686
|
const status = error instanceof HttpError ? error.status : typeof error?.status === "number" ? error.status : 500;
|
|
2617
2687
|
const message = error instanceof Error ? error.message : "Internal error";
|
|
2688
|
+
const responseBody = { success: false, error: message };
|
|
2618
2689
|
return {
|
|
2619
2690
|
kind: "request",
|
|
2620
|
-
response: NextResponse7.json(
|
|
2621
|
-
rawResult:
|
|
2691
|
+
response: NextResponse7.json(responseBody, { status }),
|
|
2692
|
+
rawResult: responseBody,
|
|
2622
2693
|
handlerError: error
|
|
2623
2694
|
};
|
|
2624
2695
|
}
|
|
@@ -2749,7 +2820,13 @@ async function runDynamicRequestFlow(args) {
|
|
|
2749
2820
|
handlerError: result.handlerError
|
|
2750
2821
|
};
|
|
2751
2822
|
if (result.response.status >= 400) {
|
|
2752
|
-
return finalize(
|
|
2823
|
+
return finalize(
|
|
2824
|
+
ctx,
|
|
2825
|
+
result.response,
|
|
2826
|
+
result.rawResult,
|
|
2827
|
+
body,
|
|
2828
|
+
failureFromCause(result.handlerError)
|
|
2829
|
+
);
|
|
2753
2830
|
}
|
|
2754
2831
|
const beforeErr = await runBeforeSettle(ctx, settleScope);
|
|
2755
2832
|
if (beforeErr) return beforeErr;
|
|
@@ -2771,6 +2848,9 @@ async function runDynamicRequestFlow(args) {
|
|
|
2771
2848
|
}
|
|
2772
2849
|
});
|
|
2773
2850
|
}
|
|
2851
|
+
function failureFromCause(cause) {
|
|
2852
|
+
return cause === void 0 ? void 0 : { cause };
|
|
2853
|
+
}
|
|
2774
2854
|
function computeBilledAmount(routeEntry, result) {
|
|
2775
2855
|
if (routeEntry.billing === "upto") {
|
|
2776
2856
|
const total = result.uptoContext?.atomicTotal() ?? 0n;
|
|
@@ -2935,7 +3015,13 @@ async function runStaticRequestFlow(args) {
|
|
|
2935
3015
|
if (result.response.status >= 400) {
|
|
2936
3016
|
const settledScope = settleScope;
|
|
2937
3017
|
await runSettledHandlerError(ctx, settledScope);
|
|
2938
|
-
return finalize(
|
|
3018
|
+
return finalize(
|
|
3019
|
+
ctx,
|
|
3020
|
+
result.response,
|
|
3021
|
+
result.rawResult,
|
|
3022
|
+
body,
|
|
3023
|
+
failureFromCause2(result.handlerError)
|
|
3024
|
+
);
|
|
2939
3025
|
}
|
|
2940
3026
|
return settleAndFinalizeRequest({
|
|
2941
3027
|
ctx,
|
|
@@ -2948,7 +3034,13 @@ async function runStaticRequestFlow(args) {
|
|
|
2948
3034
|
});
|
|
2949
3035
|
}
|
|
2950
3036
|
if (result.response.status >= 400) {
|
|
2951
|
-
return finalize(
|
|
3037
|
+
return finalize(
|
|
3038
|
+
ctx,
|
|
3039
|
+
result.response,
|
|
3040
|
+
result.rawResult,
|
|
3041
|
+
body,
|
|
3042
|
+
failureFromCause2(result.handlerError)
|
|
3043
|
+
);
|
|
2952
3044
|
}
|
|
2953
3045
|
const beforeErr = await runBeforeSettle(ctx, settleScope);
|
|
2954
3046
|
if (beforeErr) return beforeErr;
|
|
@@ -2969,6 +3061,9 @@ async function runStaticRequestFlow(args) {
|
|
|
2969
3061
|
}
|
|
2970
3062
|
});
|
|
2971
3063
|
}
|
|
3064
|
+
function failureFromCause2(cause) {
|
|
3065
|
+
return cause === void 0 ? void 0 : { cause };
|
|
3066
|
+
}
|
|
2972
3067
|
|
|
2973
3068
|
// src/pipeline/flows/static/static-paid.ts
|
|
2974
3069
|
async function runStaticPaidFlow(ctx) {
|
|
@@ -4423,7 +4518,7 @@ var envShape = {
|
|
|
4423
4518
|
}).optional(),
|
|
4424
4519
|
TEMPO_RPC_URL: z.string().refine(isUrl, {
|
|
4425
4520
|
params: { code: "invalid_mpp_rpc_url", ...mpp },
|
|
4426
|
-
message: "TEMPO_RPC_URL must be a valid URL \u2014
|
|
4521
|
+
message: "TEMPO_RPC_URL must be a valid URL \u2014 the Tempo JSON-RPC endpoint used for MPP on-chain verification. Optional; defaults to the public DEFAULT_TEMPO_RPC_URL."
|
|
4427
4522
|
}).optional(),
|
|
4428
4523
|
MPP_OPERATOR_KEY: z.string().refine(isEvmPrivateKey, {
|
|
4429
4524
|
params: { code: "invalid_mpp_operator_key", ...mpp },
|
|
@@ -4464,14 +4559,6 @@ var EnvInputSchema = z.object(envShape).passthrough().superRefine((env, ctx) =>
|
|
|
4464
4559
|
["MPP_CURRENCY"]
|
|
4465
4560
|
);
|
|
4466
4561
|
}
|
|
4467
|
-
if (env.TEMPO_RPC_URL === void 0) {
|
|
4468
|
-
addIssue(
|
|
4469
|
-
ctx,
|
|
4470
|
-
{ code: "missing_mpp_rpc_url", ...mpp },
|
|
4471
|
-
"TEMPO_RPC_URL is required when MPP is enabled \u2014 authenticated Tempo JSON-RPC endpoint. Public rpc.tempo.xyz returns 401.",
|
|
4472
|
-
["TEMPO_RPC_URL"]
|
|
4473
|
-
);
|
|
4474
|
-
}
|
|
4475
4562
|
}
|
|
4476
4563
|
const collision = operatorAddressesCollide(env.MPP_OPERATOR_KEY, env.MPP_FEE_PAYER_KEY);
|
|
4477
4564
|
if (collision) {
|
|
@@ -4603,7 +4690,7 @@ function validateX402Config(config, env) {
|
|
|
4603
4690
|
}
|
|
4604
4691
|
return issues;
|
|
4605
4692
|
}
|
|
4606
|
-
function validateMppConfig(config
|
|
4693
|
+
function validateMppConfig(config) {
|
|
4607
4694
|
const m = config.mpp;
|
|
4608
4695
|
if (!m) {
|
|
4609
4696
|
return [
|
|
@@ -4651,12 +4738,6 @@ function validateMppConfig(config, env) {
|
|
|
4651
4738
|
`MPP recipient '${placeholder}' is a placeholder address and cannot receive payments.`
|
|
4652
4739
|
);
|
|
4653
4740
|
}
|
|
4654
|
-
if (!m.rpcUrl && !env.TEMPO_RPC_URL) {
|
|
4655
|
-
push(
|
|
4656
|
-
"missing_mpp_rpc_url",
|
|
4657
|
-
"MPP requires an authenticated Tempo RPC URL. Set TEMPO_RPC_URL env var or pass rpcUrl in the mpp config object."
|
|
4658
|
-
);
|
|
4659
|
-
}
|
|
4660
4741
|
if (m.feePayerKey && !isEvmPrivateKey(m.feePayerKey)) {
|
|
4661
4742
|
push(
|
|
4662
4743
|
"invalid_mpp_fee_payer_key",
|
|
@@ -4763,7 +4844,7 @@ function routerConfigFromEnv(options) {
|
|
|
4763
4844
|
const mppConfig = mppEnabled ? {
|
|
4764
4845
|
secretKey: env.MPP_SECRET_KEY,
|
|
4765
4846
|
currency: canonicalizeEvm(env.MPP_CURRENCY),
|
|
4766
|
-
rpcUrl: env.TEMPO_RPC_URL,
|
|
4847
|
+
rpcUrl: env.TEMPO_RPC_URL ?? DEFAULT_TEMPO_RPC_URL,
|
|
4767
4848
|
recipient: payeeAddress,
|
|
4768
4849
|
...env.MPP_FEE_PAYER_KEY ? { feePayerKey: env.MPP_FEE_PAYER_KEY } : {},
|
|
4769
4850
|
...env.MPP_OPERATOR_KEY ? { operatorKey: env.MPP_OPERATOR_KEY, session: {} } : {}
|
|
@@ -4814,7 +4895,7 @@ function getRouterConfigIssues(config, options = {}) {
|
|
|
4814
4895
|
});
|
|
4815
4896
|
}
|
|
4816
4897
|
if (protocols.includes("x402")) issues.push(...validateX402Config(config, env));
|
|
4817
|
-
if (protocols.includes("mpp")) issues.push(...validateMppConfig(config
|
|
4898
|
+
if (protocols.includes("mpp")) issues.push(...validateMppConfig(config));
|
|
4818
4899
|
return issues;
|
|
4819
4900
|
}
|
|
4820
4901
|
|
|
@@ -4886,6 +4967,7 @@ function getMppxStreamingContext(args) {
|
|
|
4886
4967
|
}
|
|
4887
4968
|
|
|
4888
4969
|
// src/init/mpp.ts
|
|
4970
|
+
init_constants();
|
|
4889
4971
|
async function initMpp(config, resolvedBaseUrl, kvStore, configError) {
|
|
4890
4972
|
if (configError) return { initError: configError };
|
|
4891
4973
|
if (!config.mpp) return {};
|
|
@@ -4894,7 +4976,7 @@ async function initMpp(config, resolvedBaseUrl, kvStore, configError) {
|
|
|
4894
4976
|
const { createClient, http } = await import("viem");
|
|
4895
4977
|
const { tempo: tempoChain } = await import("viem/chains");
|
|
4896
4978
|
const { privateKeyToAccount: privateKeyToAccount2 } = await import("viem/accounts");
|
|
4897
|
-
const rpcUrl = config.mpp.rpcUrl ?? process.env.TEMPO_RPC_URL;
|
|
4979
|
+
const rpcUrl = config.mpp.rpcUrl ?? process.env.TEMPO_RPC_URL ?? DEFAULT_TEMPO_RPC_URL;
|
|
4898
4980
|
const tempoClient = createClient({ chain: tempoChain, transport: http(rpcUrl) });
|
|
4899
4981
|
const getClient = async () => tempoClient;
|
|
4900
4982
|
const operatorAccount = config.mpp.operatorKey ? privateKeyToAccount2(config.mpp.operatorKey) : void 0;
|
|
@@ -5071,6 +5153,7 @@ export {
|
|
|
5071
5153
|
BASE_USDC_ADDRESS,
|
|
5072
5154
|
BASE_USDC_DECIMALS,
|
|
5073
5155
|
DEFAULT_SOLANA_FACILITATOR_URL,
|
|
5156
|
+
DEFAULT_TEMPO_RPC_URL,
|
|
5074
5157
|
HttpError,
|
|
5075
5158
|
RouterConfigError,
|
|
5076
5159
|
SOLANA_MAINNET_NETWORK,
|