@agentcash/router 0.6.5 → 0.6.7

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/.claude/CLAUDE.md CHANGED
@@ -131,17 +131,18 @@ router
131
131
 
132
132
  ## Environment Variables
133
133
 
134
- ### Base URL Resolution
134
+ ### Base URL
135
135
 
136
- `baseUrl` is auto-detected most consumers don't need to pass it:
136
+ `baseUrl` is **required** in `RouterConfig`. No auto-detection, no fallbacks. The realm is load-bearing for payment matching (MPP memo indexing, 402 challenge realm), so it must be explicitly set.
137
137
 
138
- 1. **`config.baseUrl`** — Explicit override (for non-Vercel deployments)
139
- 2. **`VERCEL_URL`** — Auto-detected on Vercel (set by the platform on every build and deployment)
140
- 3. **`localhost:PORT`** — Fallback for local dev (`PORT` env var, defaults to 3000)
141
-
142
- In production on a non-Vercel host, pass `baseUrl` explicitly. On Vercel, it just works. In dev, it just works. No custom env vars needed.
138
+ ```typescript
139
+ createRouter({
140
+ baseUrl: process.env.BASE_URL!,
141
+ // ...
142
+ })
143
+ ```
143
144
 
144
- **Do NOT use `NEXT_PUBLIC_BASE_URL`.** It was removed in 0.6.5. The library handles base URL resolution internally.
145
+ If `baseUrl` is missing, `createRouter` throws immediately in dev and prod. This ensures devs discover the issue on first `pnpm dev` rather than deploying with a wrong realm.
145
146
 
146
147
  ### CDP API Keys
147
148
 
package/dist/index.cjs CHANGED
@@ -369,6 +369,7 @@ function resolveMaxPrice(pricing) {
369
369
 
370
370
  // src/orchestrate.ts
371
371
  var import_mppx = require("mppx");
372
+ var import_viem = require("viem");
372
373
 
373
374
  // src/protocols/x402.ts
374
375
  async function buildX402Challenge(server, routeEntry, request, price, payeeAddress, network, extensions) {
@@ -871,13 +872,16 @@ function createRequestHandler(routeEntry, handler, deps) {
871
872
  return await build402(request, routeEntry, deps, meta, pluginCtx);
872
873
  }
873
874
  const credential = import_mppx.Credential.fromRequest(request);
874
- const wallet = (credential?.source ?? "").toLowerCase();
875
+ const rawSource = credential?.source ?? "";
876
+ const didParts = rawSource.split(":");
877
+ const lastPart = didParts[didParts.length - 1];
878
+ const wallet = ((0, import_viem.isAddress)(lastPart) ? (0, import_viem.getAddress)(lastPart) : rawSource).toLowerCase();
875
879
  pluginCtx.setVerifiedWallet(wallet);
876
880
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
877
881
  protocol: "mpp",
878
882
  payer: wallet,
879
883
  amount: price,
880
- network: "tempo:42431"
884
+ network: "tempo:4217"
881
885
  });
882
886
  const { response, rawResult } = await invoke(
883
887
  request,
@@ -1467,21 +1471,17 @@ function createRouter(config) {
1467
1471
  const registry = new RouteRegistry();
1468
1472
  const nonceStore = config.siwx?.nonceStore ?? new MemoryNonceStore();
1469
1473
  const network = config.network ?? "eip155:8453";
1470
- const baseUrl = config.baseUrl ?? (typeof globalThis.process !== "undefined" && process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : void 0);
1471
- if (config.protocols && config.protocols.length === 0) {
1474
+ if (!config.baseUrl) {
1472
1475
  throw new Error(
1473
- "RouterConfig.protocols cannot be empty. Omit the field to use default ['x402'] or specify protocols explicitly."
1476
+ '[router] baseUrl is required in RouterConfig. Set it to your production domain (e.g., "https://api.example.com"). The realm is used for payment matching and must be correct.'
1474
1477
  );
1475
1478
  }
1476
- if (!baseUrl && process.env.NODE_ENV === "production") {
1477
- console.warn(
1478
- "[router] baseUrl was not provided and VERCEL_URL is not set. Falling back to localhost. Pass baseUrl in RouterConfig for non-Vercel deployments."
1479
+ if (config.protocols && config.protocols.length === 0) {
1480
+ throw new Error(
1481
+ "RouterConfig.protocols cannot be empty. Omit the field to use default ['x402'] or specify protocols explicitly."
1479
1482
  );
1480
1483
  }
1481
- const resolvedBaseUrl = (baseUrl ?? `http://localhost:${process.env.PORT ?? 3e3}`).replace(
1482
- /\/+$/,
1483
- ""
1484
- );
1484
+ const resolvedBaseUrl = config.baseUrl.replace(/\/+$/, "");
1485
1485
  let x402ConfigError;
1486
1486
  let mppConfigError;
1487
1487
  if ((!config.protocols || config.protocols.includes("x402")) && !config.payeeAddress) {
package/dist/index.d.cts CHANGED
@@ -236,12 +236,12 @@ interface RouterConfig {
236
236
  payeeAddress: string;
237
237
  /**
238
238
  * Origin URL (e.g. `https://myapp.com`).
239
- * Used for discovery URLs, OpenAPI servers, and MPP realm.
239
+ * Used for 402 challenge realm, discovery URLs, OpenAPI servers, and MPP memo indexing.
240
240
  *
241
- * Auto-detected on Vercel via `VERCEL_URL`. Falls back to `localhost:PORT` in dev.
242
- * Only needed for non-Vercel production deployments.
241
+ * **Required.** No auto-detection the realm is load-bearing for payment matching,
242
+ * so it must be explicitly set by the consuming app.
243
243
  */
244
- baseUrl?: string;
244
+ baseUrl: string;
245
245
  network?: string;
246
246
  facilitatorUrl?: string;
247
247
  plugin?: RouterPlugin;
package/dist/index.d.ts CHANGED
@@ -236,12 +236,12 @@ interface RouterConfig {
236
236
  payeeAddress: string;
237
237
  /**
238
238
  * Origin URL (e.g. `https://myapp.com`).
239
- * Used for discovery URLs, OpenAPI servers, and MPP realm.
239
+ * Used for 402 challenge realm, discovery URLs, OpenAPI servers, and MPP memo indexing.
240
240
  *
241
- * Auto-detected on Vercel via `VERCEL_URL`. Falls back to `localhost:PORT` in dev.
242
- * Only needed for non-Vercel production deployments.
241
+ * **Required.** No auto-detection the realm is load-bearing for payment matching,
242
+ * so it must be explicitly set by the consuming app.
243
243
  */
244
- baseUrl?: string;
244
+ baseUrl: string;
245
245
  network?: string;
246
246
  facilitatorUrl?: string;
247
247
  plugin?: RouterPlugin;
package/dist/index.js CHANGED
@@ -332,6 +332,7 @@ function resolveMaxPrice(pricing) {
332
332
 
333
333
  // src/orchestrate.ts
334
334
  import { Credential } from "mppx";
335
+ import { isAddress, getAddress } from "viem";
335
336
 
336
337
  // src/protocols/x402.ts
337
338
  async function buildX402Challenge(server, routeEntry, request, price, payeeAddress, network, extensions) {
@@ -834,13 +835,16 @@ function createRequestHandler(routeEntry, handler, deps) {
834
835
  return await build402(request, routeEntry, deps, meta, pluginCtx);
835
836
  }
836
837
  const credential = Credential.fromRequest(request);
837
- const wallet = (credential?.source ?? "").toLowerCase();
838
+ const rawSource = credential?.source ?? "";
839
+ const didParts = rawSource.split(":");
840
+ const lastPart = didParts[didParts.length - 1];
841
+ const wallet = (isAddress(lastPart) ? getAddress(lastPart) : rawSource).toLowerCase();
838
842
  pluginCtx.setVerifiedWallet(wallet);
839
843
  firePluginHook(deps.plugin, "onPaymentVerified", pluginCtx, {
840
844
  protocol: "mpp",
841
845
  payer: wallet,
842
846
  amount: price,
843
- network: "tempo:42431"
847
+ network: "tempo:4217"
844
848
  });
845
849
  const { response, rawResult } = await invoke(
846
850
  request,
@@ -1430,21 +1434,17 @@ function createRouter(config) {
1430
1434
  const registry = new RouteRegistry();
1431
1435
  const nonceStore = config.siwx?.nonceStore ?? new MemoryNonceStore();
1432
1436
  const network = config.network ?? "eip155:8453";
1433
- const baseUrl = config.baseUrl ?? (typeof globalThis.process !== "undefined" && process.env.VERCEL_URL ? `https://${process.env.VERCEL_URL}` : void 0);
1434
- if (config.protocols && config.protocols.length === 0) {
1437
+ if (!config.baseUrl) {
1435
1438
  throw new Error(
1436
- "RouterConfig.protocols cannot be empty. Omit the field to use default ['x402'] or specify protocols explicitly."
1439
+ '[router] baseUrl is required in RouterConfig. Set it to your production domain (e.g., "https://api.example.com"). The realm is used for payment matching and must be correct.'
1437
1440
  );
1438
1441
  }
1439
- if (!baseUrl && process.env.NODE_ENV === "production") {
1440
- console.warn(
1441
- "[router] baseUrl was not provided and VERCEL_URL is not set. Falling back to localhost. Pass baseUrl in RouterConfig for non-Vercel deployments."
1442
+ if (config.protocols && config.protocols.length === 0) {
1443
+ throw new Error(
1444
+ "RouterConfig.protocols cannot be empty. Omit the field to use default ['x402'] or specify protocols explicitly."
1442
1445
  );
1443
1446
  }
1444
- const resolvedBaseUrl = (baseUrl ?? `http://localhost:${process.env.PORT ?? 3e3}`).replace(
1445
- /\/+$/,
1446
- ""
1447
- );
1447
+ const resolvedBaseUrl = config.baseUrl.replace(/\/+$/, "");
1448
1448
  let x402ConfigError;
1449
1449
  let mppConfigError;
1450
1450
  if ((!config.protocols || config.protocols.includes("x402")) && !config.payeeAddress) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentcash/router",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
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": {