@agentcash/router 0.6.8 → 0.7.1

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.d.cts CHANGED
@@ -3,6 +3,29 @@ import { ZodType } from 'zod';
3
3
  import { PaymentRequirements, PaymentRequired, SettleResponse } from '@x402/core/types';
4
4
  export { S as SIWX_ERROR_MESSAGES, a as SiwxErrorCode } from './siwx-BMlja_nt.cjs';
5
5
 
6
+ interface EntitlementStore {
7
+ has(route: string, wallet: string): Promise<boolean>;
8
+ grant(route: string, wallet: string): Promise<void>;
9
+ }
10
+ /**
11
+ * In-memory SIWX entitlement store.
12
+ *
13
+ * Suitable for development and tests. Not durable across server restarts.
14
+ */
15
+ declare class MemoryEntitlementStore implements EntitlementStore {
16
+ private readonly routeToWallets;
17
+ has(route: string, wallet: string): Promise<boolean>;
18
+ grant(route: string, wallet: string): Promise<void>;
19
+ }
20
+ interface RedisEntitlementStoreOptions {
21
+ /** Key prefix. Default: 'siwx:entitlement:' */
22
+ prefix?: string;
23
+ }
24
+ /**
25
+ * Redis-backed entitlement store for paid+SIWX acceleration.
26
+ */
27
+ declare function createRedisEntitlementStore(client: unknown, options?: RedisEntitlementStoreOptions): EntitlementStore;
28
+
6
29
  /**
7
30
  * SIWX challenge expiry in milliseconds.
8
31
  * Currently not configurable per-route — this is a known limitation.
@@ -162,6 +185,26 @@ interface X402Server {
162
185
  }
163
186
  type ProtocolType = 'x402' | 'mpp';
164
187
  type AuthMode = 'paid' | 'siwx' | 'apiKey' | 'unprotected';
188
+ type RouteMethod = 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';
189
+ interface RouteDefinition<K extends string = string> {
190
+ /**
191
+ * Public API path segment (without `/api/` prefix).
192
+ * Example: `flightaware/airports/id/flights/arrivals`
193
+ */
194
+ path: K;
195
+ /**
196
+ * Internal route ID for pricing maps / analytics. Defaults to `path`.
197
+ *
198
+ * In `strictRoutes` mode, custom keys are disallowed to prevent discovery
199
+ * drift between internal IDs and advertised paths.
200
+ */
201
+ key?: string;
202
+ /**
203
+ * Optional explicit method. If omitted, defaults to builder behavior
204
+ * (`POST`, or `GET` when `.query()` is used).
205
+ */
206
+ method?: RouteMethod;
207
+ }
165
208
  interface TierConfig {
166
209
  price: string;
167
210
  label?: string;
@@ -216,6 +259,11 @@ interface ProviderQuotaEvent {
216
259
  interface RouteEntry {
217
260
  key: string;
218
261
  authMode: AuthMode;
262
+ /**
263
+ * Enables SIWX acceleration on paid routes.
264
+ * When true, valid SIWX proofs can bypass repeat payment if entitlement exists.
265
+ */
266
+ siwxEnabled?: boolean;
219
267
  pricing?: PricingConfig;
220
268
  protocols: ProtocolType[];
221
269
  bodySchema?: ZodType;
@@ -223,7 +271,7 @@ interface RouteEntry {
223
271
  outputSchema?: ZodType;
224
272
  description?: string;
225
273
  path?: string;
226
- method: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';
274
+ method: RouteMethod;
227
275
  maxPrice?: string;
228
276
  minPrice?: string;
229
277
  payTo?: string | ((request: Request) => string | Promise<string>);
@@ -247,6 +295,7 @@ interface RouterConfig {
247
295
  plugin?: RouterPlugin;
248
296
  siwx?: {
249
297
  nonceStore?: NonceStore;
298
+ entitlementStore?: EntitlementStore;
250
299
  };
251
300
  prices?: Record<string, string>;
252
301
  mpp?: {
@@ -270,6 +319,16 @@ interface RouterConfig {
270
319
  * })
271
320
  */
272
321
  protocols?: ProtocolType[];
322
+ /**
323
+ * Enforce explicit, path-first route definitions.
324
+ *
325
+ * When enabled:
326
+ * - `.route('key')` is rejected; use `.route({ path })`.
327
+ * - custom `key` differing from `path` is rejected.
328
+ *
329
+ * This prevents discovery/openapi drift caused by shorthand internal keys.
330
+ */
331
+ strictRoutes?: boolean;
273
332
  }
274
333
 
275
334
  declare class RouteRegistry {
@@ -286,6 +345,15 @@ interface WellKnownOptions {
286
345
  description?: string;
287
346
  instructions?: string | (() => string | Promise<string>);
288
347
  ownershipProofs?: string[];
348
+ /**
349
+ * Whether to include explicit HTTP method prefixes in `resources`.
350
+ * - `off`: always emit plain URLs.
351
+ * - `non-default`: emit `METHOD url` for PUT/PATCH/DELETE routes.
352
+ * - `always`: emit `METHOD url` for all routes.
353
+ *
354
+ * @default 'non-default'
355
+ */
356
+ methodHints?: 'off' | 'non-default' | 'always';
289
357
  }
290
358
 
291
359
  interface OpenAPIOptions {
@@ -297,6 +365,8 @@ interface OpenAPIOptions {
297
365
  name?: string;
298
366
  url?: string;
299
367
  };
368
+ llmsTxtUrl?: string;
369
+ ownershipProofs?: string[];
300
370
  }
301
371
 
302
372
  interface OrchestrateDeps {
@@ -306,6 +376,7 @@ interface OrchestrateDeps {
306
376
  mppInitError?: string;
307
377
  plugin?: RouterPlugin;
308
378
  nonceStore: NonceStore;
379
+ entitlementStore: EntitlementStore;
309
380
  payeeAddress: string;
310
381
  network: string;
311
382
  mppx?: {
@@ -329,6 +400,7 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, HasAuth extend
329
400
  /** @internal */ readonly _deps: OrchestrateDeps;
330
401
  /** @internal */ _authMode: AuthMode | null;
331
402
  /** @internal */ _pricing: PricingConfig | undefined;
403
+ /** @internal */ _siwxEnabled: boolean;
332
404
  /** @internal */ _protocols: ProtocolType[];
333
405
  /** @internal */ _maxPrice: string | undefined;
334
406
  /** @internal */ _minPrice: string | undefined;
@@ -357,7 +429,7 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, HasAuth extend
357
429
  }>;
358
430
  default?: string;
359
431
  }, options?: PaidOptions): RouteBuilder<TBody, TQuery, True, True, HasBody>;
360
- siwx(): HasAuth extends true ? never : RouteBuilder<TBody, TQuery, True, False, HasBody>;
432
+ siwx(): RouteBuilder<TBody, TQuery, True, False, HasBody>;
361
433
  apiKey(resolver: (key: string) => unknown | Promise<unknown>): RouteBuilder<TBody, TQuery, True, NeedsBody, HasBody>;
362
434
  unprotected(): RouteBuilder<TBody, TQuery, True, False, HasBody>;
363
435
  provider(name: string, config?: ProviderConfig): this;
@@ -404,7 +476,7 @@ interface MonitorEntry {
404
476
  critical?: number;
405
477
  }
406
478
  interface ServiceRouter<TPriceKeys extends string = never> {
407
- route<K extends string>(key: K): [K] extends [TPriceKeys] ? RouteBuilder<undefined, undefined, true, false, false> : RouteBuilder<undefined, undefined, false, false, false>;
479
+ route<K extends string>(keyOrDefinition: K | RouteDefinition<K>): [K] extends [TPriceKeys] ? RouteBuilder<undefined, undefined, true, false, false> : RouteBuilder<undefined, undefined, false, false, false>;
408
480
  wellKnown(options?: WellKnownOptions): (request: NextRequest) => Promise<NextResponse>;
409
481
  openapi(options: OpenAPIOptions): (request: NextRequest) => Promise<NextResponse>;
410
482
  monitors(): MonitorEntry[];
@@ -414,4 +486,4 @@ declare function createRouter<const P extends Record<string, string> = Record<ne
414
486
  prices?: P;
415
487
  }): ServiceRouter<Extract<keyof P, string>>;
416
488
 
417
- export { type AlertEvent, type AlertFn, type AlertLevel, type AuthEvent, 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 RedisNonceStoreOptions, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, SIWX_CHALLENGE_EXPIRY_MS, type ServiceRouter, type SettlementEvent, type TierConfig, type X402Server, consolePlugin, createRedisNonceStore, createRouter };
489
+ export { type AlertEvent, type AlertFn, type AlertLevel, type AuthEvent, type AuthMode, type EntitlementStore, type ErrorEvent, type HandlerContext, HttpError, MemoryEntitlementStore, 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 RedisEntitlementStoreOptions, type RedisNonceStoreOptions, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, SIWX_CHALLENGE_EXPIRY_MS, type ServiceRouter, type SettlementEvent, type TierConfig, type X402Server, consolePlugin, createRedisEntitlementStore, createRedisNonceStore, createRouter };
package/dist/index.d.ts CHANGED
@@ -3,6 +3,29 @@ import { ZodType } from 'zod';
3
3
  import { PaymentRequirements, PaymentRequired, SettleResponse } from '@x402/core/types';
4
4
  export { S as SIWX_ERROR_MESSAGES, a as SiwxErrorCode } from './siwx-BMlja_nt.js';
5
5
 
6
+ interface EntitlementStore {
7
+ has(route: string, wallet: string): Promise<boolean>;
8
+ grant(route: string, wallet: string): Promise<void>;
9
+ }
10
+ /**
11
+ * In-memory SIWX entitlement store.
12
+ *
13
+ * Suitable for development and tests. Not durable across server restarts.
14
+ */
15
+ declare class MemoryEntitlementStore implements EntitlementStore {
16
+ private readonly routeToWallets;
17
+ has(route: string, wallet: string): Promise<boolean>;
18
+ grant(route: string, wallet: string): Promise<void>;
19
+ }
20
+ interface RedisEntitlementStoreOptions {
21
+ /** Key prefix. Default: 'siwx:entitlement:' */
22
+ prefix?: string;
23
+ }
24
+ /**
25
+ * Redis-backed entitlement store for paid+SIWX acceleration.
26
+ */
27
+ declare function createRedisEntitlementStore(client: unknown, options?: RedisEntitlementStoreOptions): EntitlementStore;
28
+
6
29
  /**
7
30
  * SIWX challenge expiry in milliseconds.
8
31
  * Currently not configurable per-route — this is a known limitation.
@@ -162,6 +185,26 @@ interface X402Server {
162
185
  }
163
186
  type ProtocolType = 'x402' | 'mpp';
164
187
  type AuthMode = 'paid' | 'siwx' | 'apiKey' | 'unprotected';
188
+ type RouteMethod = 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';
189
+ interface RouteDefinition<K extends string = string> {
190
+ /**
191
+ * Public API path segment (without `/api/` prefix).
192
+ * Example: `flightaware/airports/id/flights/arrivals`
193
+ */
194
+ path: K;
195
+ /**
196
+ * Internal route ID for pricing maps / analytics. Defaults to `path`.
197
+ *
198
+ * In `strictRoutes` mode, custom keys are disallowed to prevent discovery
199
+ * drift between internal IDs and advertised paths.
200
+ */
201
+ key?: string;
202
+ /**
203
+ * Optional explicit method. If omitted, defaults to builder behavior
204
+ * (`POST`, or `GET` when `.query()` is used).
205
+ */
206
+ method?: RouteMethod;
207
+ }
165
208
  interface TierConfig {
166
209
  price: string;
167
210
  label?: string;
@@ -216,6 +259,11 @@ interface ProviderQuotaEvent {
216
259
  interface RouteEntry {
217
260
  key: string;
218
261
  authMode: AuthMode;
262
+ /**
263
+ * Enables SIWX acceleration on paid routes.
264
+ * When true, valid SIWX proofs can bypass repeat payment if entitlement exists.
265
+ */
266
+ siwxEnabled?: boolean;
219
267
  pricing?: PricingConfig;
220
268
  protocols: ProtocolType[];
221
269
  bodySchema?: ZodType;
@@ -223,7 +271,7 @@ interface RouteEntry {
223
271
  outputSchema?: ZodType;
224
272
  description?: string;
225
273
  path?: string;
226
- method: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH';
274
+ method: RouteMethod;
227
275
  maxPrice?: string;
228
276
  minPrice?: string;
229
277
  payTo?: string | ((request: Request) => string | Promise<string>);
@@ -247,6 +295,7 @@ interface RouterConfig {
247
295
  plugin?: RouterPlugin;
248
296
  siwx?: {
249
297
  nonceStore?: NonceStore;
298
+ entitlementStore?: EntitlementStore;
250
299
  };
251
300
  prices?: Record<string, string>;
252
301
  mpp?: {
@@ -270,6 +319,16 @@ interface RouterConfig {
270
319
  * })
271
320
  */
272
321
  protocols?: ProtocolType[];
322
+ /**
323
+ * Enforce explicit, path-first route definitions.
324
+ *
325
+ * When enabled:
326
+ * - `.route('key')` is rejected; use `.route({ path })`.
327
+ * - custom `key` differing from `path` is rejected.
328
+ *
329
+ * This prevents discovery/openapi drift caused by shorthand internal keys.
330
+ */
331
+ strictRoutes?: boolean;
273
332
  }
274
333
 
275
334
  declare class RouteRegistry {
@@ -286,6 +345,15 @@ interface WellKnownOptions {
286
345
  description?: string;
287
346
  instructions?: string | (() => string | Promise<string>);
288
347
  ownershipProofs?: string[];
348
+ /**
349
+ * Whether to include explicit HTTP method prefixes in `resources`.
350
+ * - `off`: always emit plain URLs.
351
+ * - `non-default`: emit `METHOD url` for PUT/PATCH/DELETE routes.
352
+ * - `always`: emit `METHOD url` for all routes.
353
+ *
354
+ * @default 'non-default'
355
+ */
356
+ methodHints?: 'off' | 'non-default' | 'always';
289
357
  }
290
358
 
291
359
  interface OpenAPIOptions {
@@ -297,6 +365,8 @@ interface OpenAPIOptions {
297
365
  name?: string;
298
366
  url?: string;
299
367
  };
368
+ llmsTxtUrl?: string;
369
+ ownershipProofs?: string[];
300
370
  }
301
371
 
302
372
  interface OrchestrateDeps {
@@ -306,6 +376,7 @@ interface OrchestrateDeps {
306
376
  mppInitError?: string;
307
377
  plugin?: RouterPlugin;
308
378
  nonceStore: NonceStore;
379
+ entitlementStore: EntitlementStore;
309
380
  payeeAddress: string;
310
381
  network: string;
311
382
  mppx?: {
@@ -329,6 +400,7 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, HasAuth extend
329
400
  /** @internal */ readonly _deps: OrchestrateDeps;
330
401
  /** @internal */ _authMode: AuthMode | null;
331
402
  /** @internal */ _pricing: PricingConfig | undefined;
403
+ /** @internal */ _siwxEnabled: boolean;
332
404
  /** @internal */ _protocols: ProtocolType[];
333
405
  /** @internal */ _maxPrice: string | undefined;
334
406
  /** @internal */ _minPrice: string | undefined;
@@ -357,7 +429,7 @@ declare class RouteBuilder<TBody = undefined, TQuery = undefined, HasAuth extend
357
429
  }>;
358
430
  default?: string;
359
431
  }, options?: PaidOptions): RouteBuilder<TBody, TQuery, True, True, HasBody>;
360
- siwx(): HasAuth extends true ? never : RouteBuilder<TBody, TQuery, True, False, HasBody>;
432
+ siwx(): RouteBuilder<TBody, TQuery, True, False, HasBody>;
361
433
  apiKey(resolver: (key: string) => unknown | Promise<unknown>): RouteBuilder<TBody, TQuery, True, NeedsBody, HasBody>;
362
434
  unprotected(): RouteBuilder<TBody, TQuery, True, False, HasBody>;
363
435
  provider(name: string, config?: ProviderConfig): this;
@@ -404,7 +476,7 @@ interface MonitorEntry {
404
476
  critical?: number;
405
477
  }
406
478
  interface ServiceRouter<TPriceKeys extends string = never> {
407
- route<K extends string>(key: K): [K] extends [TPriceKeys] ? RouteBuilder<undefined, undefined, true, false, false> : RouteBuilder<undefined, undefined, false, false, false>;
479
+ route<K extends string>(keyOrDefinition: K | RouteDefinition<K>): [K] extends [TPriceKeys] ? RouteBuilder<undefined, undefined, true, false, false> : RouteBuilder<undefined, undefined, false, false, false>;
408
480
  wellKnown(options?: WellKnownOptions): (request: NextRequest) => Promise<NextResponse>;
409
481
  openapi(options: OpenAPIOptions): (request: NextRequest) => Promise<NextResponse>;
410
482
  monitors(): MonitorEntry[];
@@ -414,4 +486,4 @@ declare function createRouter<const P extends Record<string, string> = Record<ne
414
486
  prices?: P;
415
487
  }): ServiceRouter<Extract<keyof P, string>>;
416
488
 
417
- export { type AlertEvent, type AlertFn, type AlertLevel, type AuthEvent, 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 RedisNonceStoreOptions, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, SIWX_CHALLENGE_EXPIRY_MS, type ServiceRouter, type SettlementEvent, type TierConfig, type X402Server, consolePlugin, createRedisNonceStore, createRouter };
489
+ export { type AlertEvent, type AlertFn, type AlertLevel, type AuthEvent, type AuthMode, type EntitlementStore, type ErrorEvent, type HandlerContext, HttpError, MemoryEntitlementStore, 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 RedisEntitlementStoreOptions, type RedisNonceStoreOptions, type RequestMeta, type ResponseMeta, RouteBuilder, type RouteEntry, RouteRegistry, type RouterConfig, type RouterPlugin, SIWX_CHALLENGE_EXPIRY_MS, type ServiceRouter, type SettlementEvent, type TierConfig, type X402Server, consolePlugin, createRedisEntitlementStore, createRedisNonceStore, createRouter };