@agentcash/router 0.2.0 → 0.2.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 +43 -17
- package/dist/index.d.cts +24 -2
- package/dist/index.d.ts +24 -2
- package/dist/index.js +43 -17
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -41,8 +41,9 @@ async function createX402Server(config) {
|
|
|
41
41
|
const { bazaarResourceServerExtension } = await import("@x402/extensions/bazaar");
|
|
42
42
|
const { siwxResourceServerExtension } = await import("@x402/extensions/sign-in-with-x");
|
|
43
43
|
const { facilitator: defaultFacilitator } = await import("@coinbase/x402");
|
|
44
|
-
const
|
|
45
|
-
const
|
|
44
|
+
const raw = config.facilitatorUrl ?? defaultFacilitator;
|
|
45
|
+
const facilitatorConfig = typeof raw === "string" ? { url: raw } : raw;
|
|
46
|
+
const client = new HTTPFacilitatorClient(facilitatorConfig);
|
|
46
47
|
const server = new x402ResourceServer(client);
|
|
47
48
|
registerExactEvmScheme(server);
|
|
48
49
|
server.registerExtension(bazaarResourceServerExtension);
|
|
@@ -53,7 +54,7 @@ async function createX402Server(config) {
|
|
|
53
54
|
async function retryInit(server, maxAttempts = 3, backoff = [1e3, 2e3, 4e3]) {
|
|
54
55
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
55
56
|
try {
|
|
56
|
-
await server.
|
|
57
|
+
await server.initialize();
|
|
57
58
|
return;
|
|
58
59
|
} catch (err) {
|
|
59
60
|
const is429 = err instanceof Error && (err.message.includes("429") || err.message.includes("rate limit"));
|
|
@@ -83,9 +84,15 @@ module.exports = __toCommonJS(index_exports);
|
|
|
83
84
|
// src/registry.ts
|
|
84
85
|
var RouteRegistry = class {
|
|
85
86
|
routes = /* @__PURE__ */ new Map();
|
|
87
|
+
// Silently overwrites on duplicate key. Next.js module loading order is
|
|
88
|
+
// non-deterministic during build — discovery stubs and real handlers may
|
|
89
|
+
// register the same route key in either order. Last writer wins.
|
|
90
|
+
// Prior art: ElysiaJS uses the same pattern (silent overwrite in router.history).
|
|
86
91
|
register(entry) {
|
|
87
|
-
if (this.routes.has(entry.key)) {
|
|
88
|
-
|
|
92
|
+
if (this.routes.has(entry.key) && typeof process !== "undefined" && process.env?.["NODE_ENV"] !== "production") {
|
|
93
|
+
console.warn(
|
|
94
|
+
`[agentcash/router] route '${entry.key}' registered twice \u2014 overwriting (this is expected for discovery stubs during next build)`
|
|
95
|
+
);
|
|
89
96
|
}
|
|
90
97
|
this.routes.set(entry.key, entry);
|
|
91
98
|
}
|
|
@@ -301,10 +308,10 @@ async function buildX402Challenge(server, routeEntry, request, price, payeeAddre
|
|
|
301
308
|
method: routeEntry.method,
|
|
302
309
|
description: routeEntry.description
|
|
303
310
|
};
|
|
304
|
-
const requirements = server.buildPaymentRequirementsFromOptions(options, {
|
|
311
|
+
const requirements = await server.buildPaymentRequirementsFromOptions([options], {
|
|
305
312
|
request
|
|
306
313
|
});
|
|
307
|
-
const paymentRequired = server.createPaymentRequiredResponse(
|
|
314
|
+
const paymentRequired = await server.createPaymentRequiredResponse(
|
|
308
315
|
requirements,
|
|
309
316
|
resource,
|
|
310
317
|
null,
|
|
@@ -324,7 +331,7 @@ async function verifyX402Payment(server, request, routeEntry, price, payeeAddres
|
|
|
324
331
|
price,
|
|
325
332
|
payTo: payeeAddress
|
|
326
333
|
};
|
|
327
|
-
const requirements = server.buildPaymentRequirementsFromOptions(options, {
|
|
334
|
+
const requirements = await server.buildPaymentRequirementsFromOptions([options], {
|
|
328
335
|
request
|
|
329
336
|
});
|
|
330
337
|
const matching = server.findMatchingRequirements(requirements, payload);
|
|
@@ -368,12 +375,12 @@ async function ensureMpay() {
|
|
|
368
375
|
}
|
|
369
376
|
async function buildMPPChallenge(routeEntry, request, mppConfig, price) {
|
|
370
377
|
await ensureMpay();
|
|
371
|
-
const
|
|
378
|
+
const methodIntent = tempo.charge({
|
|
372
379
|
amount: price,
|
|
373
380
|
currency: mppConfig.currency,
|
|
374
381
|
recipient: mppConfig.recipient ?? ""
|
|
375
|
-
};
|
|
376
|
-
const challenge = Challenge.fromIntent(
|
|
382
|
+
});
|
|
383
|
+
const challenge = Challenge.fromIntent(methodIntent, {
|
|
377
384
|
secretKey: mppConfig.secretKey,
|
|
378
385
|
realm: new URL(request.url).origin,
|
|
379
386
|
request
|
|
@@ -384,7 +391,7 @@ async function verifyMPPCredential(request, _routeEntry, mppConfig, price) {
|
|
|
384
391
|
await ensureMpay();
|
|
385
392
|
const credential = Credential.fromRequest(request);
|
|
386
393
|
if (!credential) return null;
|
|
387
|
-
const isValid = Challenge.verify(credential, { secretKey: mppConfig.secretKey });
|
|
394
|
+
const isValid = Challenge.verify(credential.challenge, { secretKey: mppConfig.secretKey });
|
|
388
395
|
if (!isValid) {
|
|
389
396
|
return { valid: false, payer: null };
|
|
390
397
|
}
|
|
@@ -408,7 +415,7 @@ async function buildMPPReceipt(reference) {
|
|
|
408
415
|
method: "tempo",
|
|
409
416
|
status: "success",
|
|
410
417
|
reference,
|
|
411
|
-
timestamp: Date.
|
|
418
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
412
419
|
});
|
|
413
420
|
return Receipt.serialize(receipt);
|
|
414
421
|
}
|
|
@@ -571,7 +578,12 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
571
578
|
try {
|
|
572
579
|
const { encodePaymentRequiredHeader } = await import("@x402/core/http");
|
|
573
580
|
encoded = encodePaymentRequiredHeader(paymentRequired);
|
|
574
|
-
} catch {
|
|
581
|
+
} catch (err) {
|
|
582
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
583
|
+
level: "warn",
|
|
584
|
+
message: `SIWX challenge header encoding failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
585
|
+
route: routeEntry.key
|
|
586
|
+
});
|
|
575
587
|
}
|
|
576
588
|
const response = new import_server2.NextResponse(JSON.stringify(paymentRequired), {
|
|
577
589
|
status: 402,
|
|
@@ -774,7 +786,12 @@ async function build402(request, routeEntry, deps, meta, pluginCtx) {
|
|
|
774
786
|
extensions
|
|
775
787
|
);
|
|
776
788
|
response.headers.set("PAYMENT-REQUIRED", encoded);
|
|
777
|
-
} catch {
|
|
789
|
+
} catch (err) {
|
|
790
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
791
|
+
level: "critical",
|
|
792
|
+
message: `x402 challenge build failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
793
|
+
route: routeEntry.key
|
|
794
|
+
});
|
|
778
795
|
}
|
|
779
796
|
}
|
|
780
797
|
if (routeEntry.protocols.includes("mpp") && deps.mppConfig) {
|
|
@@ -783,7 +800,12 @@ async function build402(request, routeEntry, deps, meta, pluginCtx) {
|
|
|
783
800
|
"WWW-Authenticate",
|
|
784
801
|
await buildMPPChallenge(routeEntry, request, deps.mppConfig, challengePrice)
|
|
785
802
|
);
|
|
786
|
-
} catch {
|
|
803
|
+
} catch (err) {
|
|
804
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
805
|
+
level: "critical",
|
|
806
|
+
message: `MPP challenge build failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
807
|
+
route: routeEntry.key
|
|
808
|
+
});
|
|
787
809
|
}
|
|
788
810
|
}
|
|
789
811
|
firePluginResponse(deps, pluginCtx, meta, response);
|
|
@@ -1158,7 +1180,11 @@ function createRouter(config) {
|
|
|
1158
1180
|
const baseUrl = typeof globalThis.process !== "undefined" ? process.env.NEXT_PUBLIC_BASE_URL ?? "http://localhost:3000" : "http://localhost:3000";
|
|
1159
1181
|
if (config.plugin?.init) {
|
|
1160
1182
|
try {
|
|
1161
|
-
config.plugin.init({ origin: baseUrl });
|
|
1183
|
+
const result = config.plugin.init({ origin: baseUrl });
|
|
1184
|
+
if (result && typeof result.catch === "function") {
|
|
1185
|
+
result.catch(() => {
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1162
1188
|
} catch {
|
|
1163
1189
|
}
|
|
1164
1190
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -82,6 +82,28 @@ interface AlertEvent {
|
|
|
82
82
|
meta?: Record<string, unknown>;
|
|
83
83
|
}
|
|
84
84
|
type AlertFn = (level: AlertLevel, message: string, meta?: Record<string, unknown>) => void;
|
|
85
|
+
interface X402Server {
|
|
86
|
+
initialize(): Promise<void>;
|
|
87
|
+
buildPaymentRequirementsFromOptions(options: Array<{
|
|
88
|
+
scheme: string;
|
|
89
|
+
network: string;
|
|
90
|
+
price: string;
|
|
91
|
+
payTo: string;
|
|
92
|
+
}>, context: {
|
|
93
|
+
request: Request;
|
|
94
|
+
}): Promise<unknown[]>;
|
|
95
|
+
createPaymentRequiredResponse(requirements: unknown[], resource: {
|
|
96
|
+
url: string;
|
|
97
|
+
method: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
}, error: string | null, extensions?: Record<string, unknown>): Promise<unknown>;
|
|
100
|
+
findMatchingRequirements(requirements: unknown[], payload: unknown): unknown;
|
|
101
|
+
verifyPayment(payload: unknown, requirements: unknown): Promise<{
|
|
102
|
+
isValid: boolean;
|
|
103
|
+
payer?: string;
|
|
104
|
+
}>;
|
|
105
|
+
settlePayment(payload: unknown, requirements: unknown): Promise<unknown>;
|
|
106
|
+
}
|
|
85
107
|
type ProtocolType = 'x402' | 'mpp';
|
|
86
108
|
type AuthMode = 'paid' | 'siwx' | 'apiKey' | 'unprotected';
|
|
87
109
|
interface TierConfig {
|
|
@@ -192,7 +214,7 @@ interface OpenAPIOptions {
|
|
|
192
214
|
}
|
|
193
215
|
|
|
194
216
|
interface OrchestrateDeps {
|
|
195
|
-
x402Server:
|
|
217
|
+
x402Server: X402Server | null;
|
|
196
218
|
initPromise: Promise<void>;
|
|
197
219
|
x402InitError?: string;
|
|
198
220
|
plugin?: RouterPlugin;
|
|
@@ -272,4 +294,4 @@ interface ServiceRouter {
|
|
|
272
294
|
}
|
|
273
295
|
declare function createRouter(config: RouterConfig): ServiceRouter;
|
|
274
296
|
|
|
275
|
-
export { type AlertEvent, type AlertFn, type AlertLevel, type AuthMode, type ErrorEvent, type HandlerContext, HttpError, MemoryNonceStore, type MonitorEntry, type NonceStore, type OveragePolicy, type PaidOptions, type PaymentEvent, type PluginContext, type PricingConfig, type ProtocolType, type ProviderConfig, type ProviderQuotaEvent, type QuotaInfo, type QuotaLevel, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, type ServiceRouter, type SettlementEvent, type TierConfig, consolePlugin, createRouter };
|
|
297
|
+
export { type AlertEvent, type AlertFn, type AlertLevel, type AuthMode, type ErrorEvent, type HandlerContext, HttpError, MemoryNonceStore, type MonitorEntry, type NonceStore, type OveragePolicy, type PaidOptions, type PaymentEvent, type PluginContext, type PricingConfig, type ProtocolType, type ProviderConfig, type ProviderQuotaEvent, type QuotaInfo, type QuotaLevel, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, type ServiceRouter, type SettlementEvent, type TierConfig, type X402Server, consolePlugin, createRouter };
|
package/dist/index.d.ts
CHANGED
|
@@ -82,6 +82,28 @@ interface AlertEvent {
|
|
|
82
82
|
meta?: Record<string, unknown>;
|
|
83
83
|
}
|
|
84
84
|
type AlertFn = (level: AlertLevel, message: string, meta?: Record<string, unknown>) => void;
|
|
85
|
+
interface X402Server {
|
|
86
|
+
initialize(): Promise<void>;
|
|
87
|
+
buildPaymentRequirementsFromOptions(options: Array<{
|
|
88
|
+
scheme: string;
|
|
89
|
+
network: string;
|
|
90
|
+
price: string;
|
|
91
|
+
payTo: string;
|
|
92
|
+
}>, context: {
|
|
93
|
+
request: Request;
|
|
94
|
+
}): Promise<unknown[]>;
|
|
95
|
+
createPaymentRequiredResponse(requirements: unknown[], resource: {
|
|
96
|
+
url: string;
|
|
97
|
+
method: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
}, error: string | null, extensions?: Record<string, unknown>): Promise<unknown>;
|
|
100
|
+
findMatchingRequirements(requirements: unknown[], payload: unknown): unknown;
|
|
101
|
+
verifyPayment(payload: unknown, requirements: unknown): Promise<{
|
|
102
|
+
isValid: boolean;
|
|
103
|
+
payer?: string;
|
|
104
|
+
}>;
|
|
105
|
+
settlePayment(payload: unknown, requirements: unknown): Promise<unknown>;
|
|
106
|
+
}
|
|
85
107
|
type ProtocolType = 'x402' | 'mpp';
|
|
86
108
|
type AuthMode = 'paid' | 'siwx' | 'apiKey' | 'unprotected';
|
|
87
109
|
interface TierConfig {
|
|
@@ -192,7 +214,7 @@ interface OpenAPIOptions {
|
|
|
192
214
|
}
|
|
193
215
|
|
|
194
216
|
interface OrchestrateDeps {
|
|
195
|
-
x402Server:
|
|
217
|
+
x402Server: X402Server | null;
|
|
196
218
|
initPromise: Promise<void>;
|
|
197
219
|
x402InitError?: string;
|
|
198
220
|
plugin?: RouterPlugin;
|
|
@@ -272,4 +294,4 @@ interface ServiceRouter {
|
|
|
272
294
|
}
|
|
273
295
|
declare function createRouter(config: RouterConfig): ServiceRouter;
|
|
274
296
|
|
|
275
|
-
export { type AlertEvent, type AlertFn, type AlertLevel, type AuthMode, type ErrorEvent, type HandlerContext, HttpError, MemoryNonceStore, type MonitorEntry, type NonceStore, type OveragePolicy, type PaidOptions, type PaymentEvent, type PluginContext, type PricingConfig, type ProtocolType, type ProviderConfig, type ProviderQuotaEvent, type QuotaInfo, type QuotaLevel, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, type ServiceRouter, type SettlementEvent, type TierConfig, consolePlugin, createRouter };
|
|
297
|
+
export { type AlertEvent, type AlertFn, type AlertLevel, type AuthMode, type ErrorEvent, type HandlerContext, HttpError, MemoryNonceStore, type MonitorEntry, type NonceStore, type OveragePolicy, type PaidOptions, type PaymentEvent, type PluginContext, type PricingConfig, type ProtocolType, type ProviderConfig, type ProviderQuotaEvent, type QuotaInfo, type QuotaLevel, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, type ServiceRouter, type SettlementEvent, type TierConfig, type X402Server, consolePlugin, createRouter };
|
package/dist/index.js
CHANGED
|
@@ -19,8 +19,9 @@ async function createX402Server(config) {
|
|
|
19
19
|
const { bazaarResourceServerExtension } = await import("@x402/extensions/bazaar");
|
|
20
20
|
const { siwxResourceServerExtension } = await import("@x402/extensions/sign-in-with-x");
|
|
21
21
|
const { facilitator: defaultFacilitator } = await import("@coinbase/x402");
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const raw = config.facilitatorUrl ?? defaultFacilitator;
|
|
23
|
+
const facilitatorConfig = typeof raw === "string" ? { url: raw } : raw;
|
|
24
|
+
const client = new HTTPFacilitatorClient(facilitatorConfig);
|
|
24
25
|
const server = new x402ResourceServer(client);
|
|
25
26
|
registerExactEvmScheme(server);
|
|
26
27
|
server.registerExtension(bazaarResourceServerExtension);
|
|
@@ -31,7 +32,7 @@ async function createX402Server(config) {
|
|
|
31
32
|
async function retryInit(server, maxAttempts = 3, backoff = [1e3, 2e3, 4e3]) {
|
|
32
33
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
33
34
|
try {
|
|
34
|
-
await server.
|
|
35
|
+
await server.initialize();
|
|
35
36
|
return;
|
|
36
37
|
} catch (err) {
|
|
37
38
|
const is429 = err instanceof Error && (err.message.includes("429") || err.message.includes("rate limit"));
|
|
@@ -49,9 +50,15 @@ var init_server = __esm({
|
|
|
49
50
|
// src/registry.ts
|
|
50
51
|
var RouteRegistry = class {
|
|
51
52
|
routes = /* @__PURE__ */ new Map();
|
|
53
|
+
// Silently overwrites on duplicate key. Next.js module loading order is
|
|
54
|
+
// non-deterministic during build — discovery stubs and real handlers may
|
|
55
|
+
// register the same route key in either order. Last writer wins.
|
|
56
|
+
// Prior art: ElysiaJS uses the same pattern (silent overwrite in router.history).
|
|
52
57
|
register(entry) {
|
|
53
|
-
if (this.routes.has(entry.key)) {
|
|
54
|
-
|
|
58
|
+
if (this.routes.has(entry.key) && typeof process !== "undefined" && process.env?.["NODE_ENV"] !== "production") {
|
|
59
|
+
console.warn(
|
|
60
|
+
`[agentcash/router] route '${entry.key}' registered twice \u2014 overwriting (this is expected for discovery stubs during next build)`
|
|
61
|
+
);
|
|
55
62
|
}
|
|
56
63
|
this.routes.set(entry.key, entry);
|
|
57
64
|
}
|
|
@@ -267,10 +274,10 @@ async function buildX402Challenge(server, routeEntry, request, price, payeeAddre
|
|
|
267
274
|
method: routeEntry.method,
|
|
268
275
|
description: routeEntry.description
|
|
269
276
|
};
|
|
270
|
-
const requirements = server.buildPaymentRequirementsFromOptions(options, {
|
|
277
|
+
const requirements = await server.buildPaymentRequirementsFromOptions([options], {
|
|
271
278
|
request
|
|
272
279
|
});
|
|
273
|
-
const paymentRequired = server.createPaymentRequiredResponse(
|
|
280
|
+
const paymentRequired = await server.createPaymentRequiredResponse(
|
|
274
281
|
requirements,
|
|
275
282
|
resource,
|
|
276
283
|
null,
|
|
@@ -290,7 +297,7 @@ async function verifyX402Payment(server, request, routeEntry, price, payeeAddres
|
|
|
290
297
|
price,
|
|
291
298
|
payTo: payeeAddress
|
|
292
299
|
};
|
|
293
|
-
const requirements = server.buildPaymentRequirementsFromOptions(options, {
|
|
300
|
+
const requirements = await server.buildPaymentRequirementsFromOptions([options], {
|
|
294
301
|
request
|
|
295
302
|
});
|
|
296
303
|
const matching = server.findMatchingRequirements(requirements, payload);
|
|
@@ -334,12 +341,12 @@ async function ensureMpay() {
|
|
|
334
341
|
}
|
|
335
342
|
async function buildMPPChallenge(routeEntry, request, mppConfig, price) {
|
|
336
343
|
await ensureMpay();
|
|
337
|
-
const
|
|
344
|
+
const methodIntent = tempo.charge({
|
|
338
345
|
amount: price,
|
|
339
346
|
currency: mppConfig.currency,
|
|
340
347
|
recipient: mppConfig.recipient ?? ""
|
|
341
|
-
};
|
|
342
|
-
const challenge = Challenge.fromIntent(
|
|
348
|
+
});
|
|
349
|
+
const challenge = Challenge.fromIntent(methodIntent, {
|
|
343
350
|
secretKey: mppConfig.secretKey,
|
|
344
351
|
realm: new URL(request.url).origin,
|
|
345
352
|
request
|
|
@@ -350,7 +357,7 @@ async function verifyMPPCredential(request, _routeEntry, mppConfig, price) {
|
|
|
350
357
|
await ensureMpay();
|
|
351
358
|
const credential = Credential.fromRequest(request);
|
|
352
359
|
if (!credential) return null;
|
|
353
|
-
const isValid = Challenge.verify(credential, { secretKey: mppConfig.secretKey });
|
|
360
|
+
const isValid = Challenge.verify(credential.challenge, { secretKey: mppConfig.secretKey });
|
|
354
361
|
if (!isValid) {
|
|
355
362
|
return { valid: false, payer: null };
|
|
356
363
|
}
|
|
@@ -374,7 +381,7 @@ async function buildMPPReceipt(reference) {
|
|
|
374
381
|
method: "tempo",
|
|
375
382
|
status: "success",
|
|
376
383
|
reference,
|
|
377
|
-
timestamp: Date.
|
|
384
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
378
385
|
});
|
|
379
386
|
return Receipt.serialize(receipt);
|
|
380
387
|
}
|
|
@@ -537,7 +544,12 @@ function createRequestHandler(routeEntry, handler, deps) {
|
|
|
537
544
|
try {
|
|
538
545
|
const { encodePaymentRequiredHeader } = await import("@x402/core/http");
|
|
539
546
|
encoded = encodePaymentRequiredHeader(paymentRequired);
|
|
540
|
-
} catch {
|
|
547
|
+
} catch (err) {
|
|
548
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
549
|
+
level: "warn",
|
|
550
|
+
message: `SIWX challenge header encoding failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
551
|
+
route: routeEntry.key
|
|
552
|
+
});
|
|
541
553
|
}
|
|
542
554
|
const response = new NextResponse2(JSON.stringify(paymentRequired), {
|
|
543
555
|
status: 402,
|
|
@@ -740,7 +752,12 @@ async function build402(request, routeEntry, deps, meta, pluginCtx) {
|
|
|
740
752
|
extensions
|
|
741
753
|
);
|
|
742
754
|
response.headers.set("PAYMENT-REQUIRED", encoded);
|
|
743
|
-
} catch {
|
|
755
|
+
} catch (err) {
|
|
756
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
757
|
+
level: "critical",
|
|
758
|
+
message: `x402 challenge build failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
759
|
+
route: routeEntry.key
|
|
760
|
+
});
|
|
744
761
|
}
|
|
745
762
|
}
|
|
746
763
|
if (routeEntry.protocols.includes("mpp") && deps.mppConfig) {
|
|
@@ -749,7 +766,12 @@ async function build402(request, routeEntry, deps, meta, pluginCtx) {
|
|
|
749
766
|
"WWW-Authenticate",
|
|
750
767
|
await buildMPPChallenge(routeEntry, request, deps.mppConfig, challengePrice)
|
|
751
768
|
);
|
|
752
|
-
} catch {
|
|
769
|
+
} catch (err) {
|
|
770
|
+
firePluginHook(deps.plugin, "onAlert", pluginCtx, {
|
|
771
|
+
level: "critical",
|
|
772
|
+
message: `MPP challenge build failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
773
|
+
route: routeEntry.key
|
|
774
|
+
});
|
|
753
775
|
}
|
|
754
776
|
}
|
|
755
777
|
firePluginResponse(deps, pluginCtx, meta, response);
|
|
@@ -1124,7 +1146,11 @@ function createRouter(config) {
|
|
|
1124
1146
|
const baseUrl = typeof globalThis.process !== "undefined" ? process.env.NEXT_PUBLIC_BASE_URL ?? "http://localhost:3000" : "http://localhost:3000";
|
|
1125
1147
|
if (config.plugin?.init) {
|
|
1126
1148
|
try {
|
|
1127
|
-
config.plugin.init({ origin: baseUrl });
|
|
1149
|
+
const result = config.plugin.init({ origin: baseUrl });
|
|
1150
|
+
if (result && typeof result.catch === "function") {
|
|
1151
|
+
result.catch(() => {
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1128
1154
|
} catch {
|
|
1129
1155
|
}
|
|
1130
1156
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentcash/router",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.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": {
|
|
@@ -70,6 +70,6 @@
|
|
|
70
70
|
"license": "MIT",
|
|
71
71
|
"repository": {
|
|
72
72
|
"type": "git",
|
|
73
|
-
"url": "https://github.com/merit-systems/agentcash-router"
|
|
73
|
+
"url": "git+https://github.com/merit-systems/agentcash-router.git"
|
|
74
74
|
}
|
|
75
75
|
}
|