@cryptonly/x402 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,62 +12,24 @@ Accept x402 payments in Node.js, with Cryptonly as the facilitator.
12
12
 
13
13
  ---
14
14
 
15
- Cryptonly verifies and settles each payment, and pays the network fee. Payments go straight to your wallet. There are two ways to use this package:
15
+ Cryptonly verifies and settles each payment, and pays the network fee. Payments go straight to your wallet.
16
16
 
17
- - **Prices in the dashboard.** `cryptonlyPaymentMiddleware` for Express loads your prices from the Cryptonly dashboard. A price change needs no deploy.
18
- - **Prices in your code.** `CryptonlyFacilitatorClient` plugs into the stock `@x402/express`, `@x402/hono` or `@x402/next` middleware.
17
+ Pick the package for your framework. Each one loads your prices from the Cryptonly dashboard, so a price change needs no deploy:
19
18
 
20
- You need a Cryptonly API key with the `x402.verify` and `x402.settle` scopes. The [quickstart](https://docs.cryptonly.net/guides/x402/quickstart/) covers getting one.
21
-
22
- ## Prices in the dashboard
23
-
24
- ```bash
25
- npm install @cryptonly/x402 @x402/core @x402/express @x402/evm express
26
- ```
27
-
28
- ```ts
29
- import express from 'express';
30
- import { cryptonlyPaymentMiddleware } from '@cryptonly/x402/express';
31
-
32
- const app = express();
33
- app.get('/health', (_req, res) => res.send('ok')); // free routes go first
34
-
35
- const payments = cryptonlyPaymentMiddleware({ apiKey: process.env.CRYPTONLY_API_KEY! });
36
- app.use(payments);
37
-
38
- // Priced in the dashboard as GET /weather/:city
39
- app.get('/weather/:city', (req, res) => {
40
- res.json({ city: req.params.city, temperatureC: 21 });
41
- });
42
-
43
- await payments.ready(); // fails at startup if the prices can't load
44
- app.listen(4021);
45
- ```
19
+ | Framework | Package |
20
+ | --- | --- |
21
+ | Express | [`@cryptonly/x402-express`](https://www.npmjs.com/package/@cryptonly/x402-express) |
22
+ | Fastify | [`@cryptonly/x402-fastify`](https://www.npmjs.com/package/@cryptonly/x402-fastify) |
23
+ | NestJS (Express or Fastify platform) | [`@cryptonly/x402-nestjs`](https://www.npmjs.com/package/@cryptonly/x402-nestjs) |
46
24
 
47
- The middleware reloads your prices every minute. It fails closed, so a paid route is never served for free:
25
+ This package, `@cryptonly/x402`, is what they share: the facilitator client and the dashboard price loader. Use it directly for prices in your code, or for another framework.
48
26
 
49
- - Until the first load succeeds, every request through it gets `503` with `Retry-After`. This happens with a bad key, an inactive account or no payout wallet.
50
- - If a later reload fails, it keeps the last good prices and logs a warning.
51
-
52
- | Option | Default | |
53
- | --- | --- | --- |
54
- | `apiKey` | required | Your Cryptonly API key. |
55
- | `sandbox` | `false` | Use the sandbox. |
56
- | `baseUrl` | production | Another API origin. Takes precedence over `sandbox`. |
57
- | `refreshIntervalMs` | `60000` | How often to reload prices. `0` turns it off. |
58
- | `retryAfterMs` | `5000` | After a failed first load, how long to answer `503` before the next try. |
59
- | `schemes` | `[new ExactEvmScheme()]` | Schemes for Base. |
60
- | `svmSchemes` | `[new ExactSvmScheme()]` if `@x402/svm` is installed | Schemes for Solana. |
61
- | `paywallConfig` | — | Passed to the stock `paymentMiddleware`. |
62
- | `logger` | `console` | Gets reload failures and skipped routes. |
63
- | `createMiddleware` | stock `paymentMiddleware` | Builds the inner middleware, for example to add hooks. |
64
-
65
- The middleware also has `ready()`, `refresh()`, `routes()` and `close()`.
66
-
67
- Using another framework? Build the routes with `fetchX402Config()` and `routesFromConfig()`, and pass them to its stock x402 middleware.
27
+ You need a Cryptonly API key with the `x402.verify` and `x402.settle` scopes. The [quickstart](https://docs.cryptonly.net/guides/x402/quickstart/) covers getting one.
68
28
 
69
29
  ## Prices in your code
70
30
 
31
+ `CryptonlyFacilitatorClient` plugs into the stock `@x402/express`, `@x402/fastify`, `@x402/hono` or `@x402/next` middleware.
32
+
71
33
  ```bash
72
34
  npm install @cryptonly/x402 @x402/core @x402/express @x402/evm
73
35
  ```
@@ -92,11 +54,27 @@ app.use(
92
54
  );
93
55
  ```
94
56
 
95
- `CryptonlyFacilitatorClient` takes `apiKey`, `sandbox` and `baseUrl`, as above. `payTo` must be a wallet you added in the dashboard.
57
+ `CryptonlyFacilitatorClient` takes `apiKey`, `sandbox` and `baseUrl`. `payTo` must be a wallet you added in the dashboard. On Solana, register `ExactSvmScheme` from `@x402/svm/exact/server` for `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`.
58
+
59
+ ## Prices in the dashboard, another framework
96
60
 
97
- ## Solana
61
+ - `fetchX402Config()` and `routesFromConfig()` turn your dashboard prices into stock `@x402/core` routes for any x402 middleware.
62
+ - `createX402RouteSource()` adds what the framework packages do on top: one load, a refresh every minute, and the last good routes kept when a refresh fails.
98
63
 
99
- Install `@x402/svm` and `@solana/kit`, and add a Solana payout wallet in the dashboard. With prices in your code, register `ExactSvmScheme` from `@x402/svm/exact/server` for `solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp`.
64
+ ```ts
65
+ import { createResourceServer, createX402RouteSource } from '@cryptonly/x402';
66
+ import { x402HTTPResourceServer } from '@x402/core/server';
67
+
68
+ const source = createX402RouteSource({ apiKey: process.env.CRYPTONLY_API_KEY! }, (routes, config) =>
69
+ new x402HTTPResourceServer(
70
+ createResourceServer(config, source.facilitator, source.schemes, source.svmSchemes),
71
+ routes,
72
+ ),
73
+ );
74
+
75
+ await source.ready(); // rejects if the prices can't load
76
+ const httpServer = source.current()!.value; // rebuilt only when the prices change
77
+ ```
100
78
 
101
79
  ## Sandbox
102
80
 
package/dist/index.d.ts CHANGED
@@ -1,6 +1,8 @@
1
1
  export { CryptonlyFacilitatorClient, resolveMerchantApiOrigin, } from './client.js';
2
2
  export type { CryptonlyFacilitatorConfig } from './client.js';
3
- export { X402ConfigError, assertPayableConfig, fetchX402Config, loadX402Extensions, parseX402Config, routeKey, routesFromConfig, } from './config.js';
3
+ export { X402ConfigError, assertPayableConfig, fetchX402Config, isSolanaNetwork, loadX402Extensions, parseX402Config, routeKey, routesFromConfig, } from './config.js';
4
4
  export type { FetchX402ConfigOptions, RoutesFromConfigOptions, X402AccountStatus, X402Config, X402ConfigAsset, X402ConfigErrorCode, X402ConfigResource, X402ExtensionsModule, } from './config.js';
5
5
  export { MERCHANT_API_BASE_URL, MERCHANT_API_KEY_HEADER, SANDBOX_MERCHANT_API_BASE_URL, } from './constants.js';
6
+ export { X402_CONFIG_UNAVAILABLE, X402_LOG_PREFIX, createResourceServer, createX402RouteSource, defaultEvmSchemes, defaultSvmSchemes, describeError, solanaNetworksOf, } from './route-source.js';
7
+ export type { X402Logger, X402RouteSet, X402RouteSetBuilder, X402RouteSource, X402RouteSourceOptions, } from './route-source.js';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,QAAQ,EACR,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,qBAAqB,EACrB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,UAAU,EACV,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,sBAAsB,GACvB,MAAM,mBAAmB,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SANDBOX_MERCHANT_API_BASE_URL = exports.MERCHANT_API_KEY_HEADER = exports.MERCHANT_API_BASE_URL = exports.routesFromConfig = exports.routeKey = exports.parseX402Config = exports.loadX402Extensions = exports.fetchX402Config = exports.assertPayableConfig = exports.X402ConfigError = exports.resolveMerchantApiOrigin = exports.CryptonlyFacilitatorClient = void 0;
3
+ exports.solanaNetworksOf = exports.describeError = exports.defaultSvmSchemes = exports.defaultEvmSchemes = exports.createX402RouteSource = exports.createResourceServer = exports.X402_LOG_PREFIX = exports.X402_CONFIG_UNAVAILABLE = exports.SANDBOX_MERCHANT_API_BASE_URL = exports.MERCHANT_API_KEY_HEADER = exports.MERCHANT_API_BASE_URL = exports.routesFromConfig = exports.routeKey = exports.parseX402Config = exports.loadX402Extensions = exports.isSolanaNetwork = exports.fetchX402Config = exports.assertPayableConfig = exports.X402ConfigError = exports.resolveMerchantApiOrigin = exports.CryptonlyFacilitatorClient = void 0;
4
4
  var client_js_1 = require("./client.js");
5
5
  Object.defineProperty(exports, "CryptonlyFacilitatorClient", { enumerable: true, get: function () { return client_js_1.CryptonlyFacilitatorClient; } });
6
6
  Object.defineProperty(exports, "resolveMerchantApiOrigin", { enumerable: true, get: function () { return client_js_1.resolveMerchantApiOrigin; } });
@@ -8,6 +8,7 @@ var config_js_1 = require("./config.js");
8
8
  Object.defineProperty(exports, "X402ConfigError", { enumerable: true, get: function () { return config_js_1.X402ConfigError; } });
9
9
  Object.defineProperty(exports, "assertPayableConfig", { enumerable: true, get: function () { return config_js_1.assertPayableConfig; } });
10
10
  Object.defineProperty(exports, "fetchX402Config", { enumerable: true, get: function () { return config_js_1.fetchX402Config; } });
11
+ Object.defineProperty(exports, "isSolanaNetwork", { enumerable: true, get: function () { return config_js_1.isSolanaNetwork; } });
11
12
  Object.defineProperty(exports, "loadX402Extensions", { enumerable: true, get: function () { return config_js_1.loadX402Extensions; } });
12
13
  Object.defineProperty(exports, "parseX402Config", { enumerable: true, get: function () { return config_js_1.parseX402Config; } });
13
14
  Object.defineProperty(exports, "routeKey", { enumerable: true, get: function () { return config_js_1.routeKey; } });
@@ -16,4 +17,13 @@ var constants_js_1 = require("./constants.js");
16
17
  Object.defineProperty(exports, "MERCHANT_API_BASE_URL", { enumerable: true, get: function () { return constants_js_1.MERCHANT_API_BASE_URL; } });
17
18
  Object.defineProperty(exports, "MERCHANT_API_KEY_HEADER", { enumerable: true, get: function () { return constants_js_1.MERCHANT_API_KEY_HEADER; } });
18
19
  Object.defineProperty(exports, "SANDBOX_MERCHANT_API_BASE_URL", { enumerable: true, get: function () { return constants_js_1.SANDBOX_MERCHANT_API_BASE_URL; } });
20
+ var route_source_js_1 = require("./route-source.js");
21
+ Object.defineProperty(exports, "X402_CONFIG_UNAVAILABLE", { enumerable: true, get: function () { return route_source_js_1.X402_CONFIG_UNAVAILABLE; } });
22
+ Object.defineProperty(exports, "X402_LOG_PREFIX", { enumerable: true, get: function () { return route_source_js_1.X402_LOG_PREFIX; } });
23
+ Object.defineProperty(exports, "createResourceServer", { enumerable: true, get: function () { return route_source_js_1.createResourceServer; } });
24
+ Object.defineProperty(exports, "createX402RouteSource", { enumerable: true, get: function () { return route_source_js_1.createX402RouteSource; } });
25
+ Object.defineProperty(exports, "defaultEvmSchemes", { enumerable: true, get: function () { return route_source_js_1.defaultEvmSchemes; } });
26
+ Object.defineProperty(exports, "defaultSvmSchemes", { enumerable: true, get: function () { return route_source_js_1.defaultSvmSchemes; } });
27
+ Object.defineProperty(exports, "describeError", { enumerable: true, get: function () { return route_source_js_1.describeError; } });
28
+ Object.defineProperty(exports, "solanaNetworksOf", { enumerable: true, get: function () { return route_source_js_1.solanaNetworksOf; } });
19
29
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAGqB;AAFnB,uHAAA,0BAA0B,OAAA;AAC1B,qHAAA,wBAAwB,OAAA;AAG1B,yCAQqB;AAPnB,4GAAA,eAAe,OAAA;AACf,gHAAA,mBAAmB,OAAA;AACnB,4GAAA,eAAe,OAAA;AACf,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,qGAAA,QAAQ,OAAA;AACR,6GAAA,gBAAgB,OAAA;AAYlB,+CAIwB;AAHtB,qHAAA,qBAAqB,OAAA;AACrB,uHAAA,uBAAuB,OAAA;AACvB,6HAAA,6BAA6B,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAGqB;AAFnB,uHAAA,0BAA0B,OAAA;AAC1B,qHAAA,wBAAwB,OAAA;AAG1B,yCASqB;AARnB,4GAAA,eAAe,OAAA;AACf,gHAAA,mBAAmB,OAAA;AACnB,4GAAA,eAAe,OAAA;AACf,4GAAA,eAAe,OAAA;AACf,+GAAA,kBAAkB,OAAA;AAClB,4GAAA,eAAe,OAAA;AACf,qGAAA,QAAQ,OAAA;AACR,6GAAA,gBAAgB,OAAA;AAYlB,+CAIwB;AAHtB,qHAAA,qBAAqB,OAAA;AACrB,uHAAA,uBAAuB,OAAA;AACvB,6HAAA,6BAA6B,OAAA;AAE/B,qDAS2B;AARzB,0HAAA,uBAAuB,OAAA;AACvB,kHAAA,eAAe,OAAA;AACf,uHAAA,oBAAoB,OAAA;AACpB,wHAAA,qBAAqB,OAAA;AACrB,oHAAA,iBAAiB,OAAA;AACjB,oHAAA,iBAAiB,OAAA;AACjB,gHAAA,aAAa,OAAA;AACb,mHAAA,gBAAgB,OAAA"}
@@ -0,0 +1,105 @@
1
+ import { x402ResourceServer, type RoutesConfig } from '@x402/core/server';
2
+ import type { SchemeNetworkServer } from '@x402/core/types';
3
+ import { CryptonlyFacilitatorClient, type CryptonlyFacilitatorConfig } from './client.js';
4
+ import { type X402Config, type X402ExtensionsModule } from './config.js';
5
+ /** Logger used for refresh failures and skipped resources. */
6
+ export type X402Logger = Pick<Console, 'info' | 'warn' | 'error'>;
7
+ /** Options shared by every framework adapter. */
8
+ export type X402RouteSourceOptions = CryptonlyFacilitatorConfig & {
9
+ /**
10
+ * How often to reload `GET /x402/config`. Defaults to 60 s; `0` turns
11
+ * refreshing off.
12
+ */
13
+ refreshIntervalMs?: number;
14
+ /**
15
+ * Scheme servers registered on the account's EVM network. Defaults to
16
+ * `[new ExactEvmScheme()]` from `@x402/evm`. Resources with another scheme
17
+ * are skipped.
18
+ */
19
+ schemes?: readonly SchemeNetworkServer[];
20
+ /**
21
+ * Scheme servers registered on the account's Solana networks. Defaults
22
+ * to `[new ExactSvmScheme()]` from `@x402/svm` when it is installed, and
23
+ * to none otherwise (Solana resources are then skipped).
24
+ */
25
+ svmSchemes?: readonly SchemeNetworkServer[];
26
+ /** `fetch` for `GET /x402/config`. Defaults to the global `fetch`. */
27
+ fetch?: typeof fetch;
28
+ /**
29
+ * After a failed first load, how long requests answer 503 before the
30
+ * next attempt. Defaults to 5 s.
31
+ */
32
+ retryAfterMs?: number;
33
+ /** Defaults to `console`. */
34
+ logger?: X402Logger;
35
+ /** `@x402/extensions` override; `null` leaves extensions out. */
36
+ extensions?: X402ExtensionsModule | null;
37
+ };
38
+ /** One loaded configuration, its routes and what the adapter built for them. */
39
+ export type X402RouteSet<T> = {
40
+ config: X402Config;
41
+ routes: RoutesConfig;
42
+ /** Identity of the routes: equal keys mean nothing to rebuild. */
43
+ key: string;
44
+ /** What the adapter's `build` returned for these routes. */
45
+ value: T;
46
+ };
47
+ /** The dashboard routes, kept fresh. See {@link createX402RouteSource}. */
48
+ export type X402RouteSource<T> = {
49
+ readonly facilitator: CryptonlyFacilitatorClient;
50
+ /** Scheme servers in use on the EVM network. */
51
+ readonly schemes: readonly SchemeNetworkServer[];
52
+ /** Scheme servers in use on the Solana networks. */
53
+ readonly svmSchemes: readonly SchemeNetworkServer[];
54
+ /** For `Retry-After` while the configuration is unavailable. */
55
+ readonly retryAfterMs: number;
56
+ readonly logger: X402Logger;
57
+ /** The route set in use, or `undefined` before the first successful load. */
58
+ current(): X402RouteSet<T> | undefined;
59
+ /**
60
+ * Loads the configuration now (if not loaded yet) and starts refreshing.
61
+ * Rejects when the first load fails; within `retryAfterMs` of a failure
62
+ * it rejects again without a new attempt.
63
+ */
64
+ ready(): Promise<void>;
65
+ /** Reloads the configuration now. Resolves `true` when the routes changed. */
66
+ refresh(): Promise<boolean>;
67
+ /** Stops refreshing. The last routes stay in use. */
68
+ close(): void;
69
+ };
70
+ /** Builds what an adapter serves for one set of routes. Throwing keeps the last set. */
71
+ export type X402RouteSetBuilder<T> = (routes: RoutesConfig, config: X402Config) => T;
72
+ /** Body of the `503` answered while the configuration is unavailable. */
73
+ export declare const X402_CONFIG_UNAVAILABLE: {
74
+ readonly error: "x402_config_unavailable";
75
+ readonly message: "Payment configuration is unavailable; retry shortly.";
76
+ };
77
+ /** Prefix of every log line the packages write. */
78
+ export declare const X402_LOG_PREFIX = "[@cryptonly/x402]";
79
+ /**
80
+ * Loads the paid routes from the Cryptonly dashboard (`GET /x402/config`)
81
+ * and refreshes them every minute. The framework adapters share it.
82
+ *
83
+ * - The configuration loads on {@link X402RouteSource.ready}, once.
84
+ * - Each refresh calls `build` only when the routes changed. A failed
85
+ * refresh, or a `build` that throws, keeps the last good set.
86
+ */
87
+ export declare function createX402RouteSource<T>(options: X402RouteSourceOptions, build: X402RouteSetBuilder<T>): X402RouteSource<T>;
88
+ /**
89
+ * A fresh `x402ResourceServer` on the facilitator, with the EVM schemes
90
+ * registered on the account's network and the SVM schemes on each of its
91
+ * Solana networks.
92
+ *
93
+ * Build one per route set: `initialize()` on a shared one would clear its
94
+ * facilitator data under requests still in flight.
95
+ */
96
+ export declare function createResourceServer(config: X402Config, facilitator: CryptonlyFacilitatorClient, schemes: readonly SchemeNetworkServer[], svmSchemes: readonly SchemeNetworkServer[]): x402ResourceServer;
97
+ /** The Solana networks an account accepts payments on. */
98
+ export declare function solanaNetworksOf(config: X402Config): X402Config['network'][];
99
+ /** `[new ExactEvmScheme()]` from `@x402/evm`. Throws when it is not installed. */
100
+ export declare function defaultEvmSchemes(): SchemeNetworkServer[];
101
+ /** `[new ExactSvmScheme()]` from `@x402/svm` when installed (optional peer), else none. */
102
+ export declare function defaultSvmSchemes(): SchemeNetworkServer[];
103
+ /** An error's message, for log lines. */
104
+ export declare function describeError(error: unknown): string;
105
+ //# sourceMappingURL=route-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-source.d.ts","sourceRoot":"","sources":["../src/route-source.ts"],"names":[],"mappings":"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"}
@@ -1,81 +1,36 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.routesFromConfig = exports.fetchX402Config = exports.stockPaymentMiddleware = void 0;
4
- exports.cryptonlyPaymentMiddleware = cryptonlyPaymentMiddleware;
5
- const server_1 = require("@x402/evm/exact/server");
6
- const express_1 = require("@x402/express");
3
+ exports.X402_LOG_PREFIX = exports.X402_CONFIG_UNAVAILABLE = void 0;
4
+ exports.createX402RouteSource = createX402RouteSource;
5
+ exports.createResourceServer = createResourceServer;
6
+ exports.solanaNetworksOf = solanaNetworksOf;
7
+ exports.defaultEvmSchemes = defaultEvmSchemes;
8
+ exports.defaultSvmSchemes = defaultSvmSchemes;
9
+ exports.describeError = describeError;
10
+ const server_1 = require("@x402/core/server");
7
11
  const client_js_1 = require("./client.js");
8
12
  const config_js_1 = require("./config.js");
13
+ /** Body of the `503` answered while the configuration is unavailable. */
14
+ exports.X402_CONFIG_UNAVAILABLE = {
15
+ error: 'x402_config_unavailable',
16
+ message: 'Payment configuration is unavailable; retry shortly.',
17
+ };
18
+ /** Prefix of every log line the packages write. */
19
+ exports.X402_LOG_PREFIX = '[@cryptonly/x402]';
9
20
  const DEFAULT_REFRESH_INTERVAL_MS = 60_000;
10
21
  const DEFAULT_RETRY_AFTER_MS = 5_000;
11
- const LOG_PREFIX = '[@cryptonly/x402]';
12
- /** The default {@link InnerMiddlewareFactory}: stock `@x402/express`. */
13
- const stockPaymentMiddleware = (routes, { config, facilitator, schemes, svmSchemes, paywallConfig }) => {
14
- // A fresh resource server per route set: `initialize()` on a shared one
15
- // would clear its facilitator data under requests still in flight.
16
- const server = new express_1.x402ResourceServer(facilitator);
17
- for (const scheme of schemes) {
18
- server.register(config.network, scheme);
19
- }
20
- for (const network of solanaNetworksOf(config)) {
21
- for (const scheme of svmSchemes) {
22
- server.register(network, scheme);
23
- }
24
- }
25
- return (0, express_1.paymentMiddleware)(routes, server, paywallConfig);
26
- };
27
- exports.stockPaymentMiddleware = stockPaymentMiddleware;
28
- function solanaNetworksOf(config) {
29
- const networks = new Set();
30
- for (const entry of config.networks ?? []) {
31
- if ((0, config_js_1.isSolanaNetwork)(entry.network))
32
- networks.add(entry.network);
33
- }
34
- for (const asset of config.assets) {
35
- if (asset.network && (0, config_js_1.isSolanaNetwork)(asset.network))
36
- networks.add(asset.network);
37
- }
38
- return [...networks];
39
- }
40
- let svmModule;
41
- /** `@x402/svm`'s exact server scheme when installed (optional peer). */
42
- function defaultSvmSchemes() {
43
- if (svmModule === undefined) {
44
- try {
45
- // eslint-disable-next-line @typescript-eslint/no-require-imports
46
- svmModule = require('@x402/svm/exact/server');
47
- }
48
- catch {
49
- svmModule = null;
50
- }
51
- }
52
- return svmModule ? [new svmModule.ExactSvmScheme()] : [];
53
- }
54
22
  /**
55
- * Express middleware whose paid routes and prices come from the Cryptonly
56
- * dashboard (`GET /x402/config`), refreshed every minute, so a price change
57
- * reaches production without a deploy.
58
- *
59
- * - The configuration loads on the first request (or on `ready()`), once.
60
- * - Each refresh rebuilds the stock `@x402/express` middleware only when the
61
- * routes changed. A failed refresh keeps the last good routes.
62
- * - Until a first load succeeds, every request through it answers 503
63
- * (fail closed): paid endpoints are never served for free. Mount it after
64
- * health checks and other free routes.
23
+ * Loads the paid routes from the Cryptonly dashboard (`GET /x402/config`)
24
+ * and refreshes them every minute. The framework adapters share it.
65
25
  *
66
- * @example
67
- * ```ts
68
- * import { cryptonlyPaymentMiddleware } from '@cryptonly/x402/express';
69
- *
70
- * app.use(cryptonlyPaymentMiddleware({ apiKey: process.env.CRYPTONLY_API_KEY! }));
71
- * app.get('/weather', (req, res) => res.json({ temperatureC: 21 }));
72
- * ```
26
+ * - The configuration loads on {@link X402RouteSource.ready}, once.
27
+ * - Each refresh calls `build` only when the routes changed. A failed
28
+ * refresh, or a `build` that throws, keeps the last good set.
73
29
  */
74
- function cryptonlyPaymentMiddleware(options) {
30
+ function createX402RouteSource(options, build) {
75
31
  const facilitator = new client_js_1.CryptonlyFacilitatorClient(options);
76
- const schemes = options.schemes ?? [new server_1.ExactEvmScheme()];
32
+ const schemes = options.schemes ?? defaultEvmSchemes();
77
33
  const svmSchemes = options.svmSchemes ?? defaultSvmSchemes();
78
- const createMiddleware = options.createMiddleware ?? exports.stockPaymentMiddleware;
79
34
  const logger = options.logger ?? console;
80
35
  const refreshIntervalMs = options.refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS;
81
36
  const retryAfterMs = options.retryAfterMs ?? DEFAULT_RETRY_AFTER_MS;
@@ -115,18 +70,12 @@ function cryptonlyPaymentMiddleware(options) {
115
70
  if (current?.key === key)
116
71
  return false;
117
72
  for (const line of skipped)
118
- logger.warn(`${LOG_PREFIX} skipped ${line}`);
119
- const handler = createMiddleware(routes, {
120
- config,
121
- facilitator,
122
- schemes,
123
- svmSchemes,
124
- ...(options.paywallConfig ? { paywallConfig: options.paywallConfig } : {}),
125
- });
73
+ logger.warn(`${exports.X402_LOG_PREFIX} skipped ${line}`);
74
+ const value = build(routes, config);
126
75
  const previous = current;
127
- current = { key, routes, handler };
76
+ current = { config, routes, key, value };
128
77
  if (previous) {
129
- logger.info(`${LOG_PREFIX} x402 routes updated: ${Object.keys(routes).join(', ') || '(none)'}`);
78
+ logger.info(`${exports.X402_LOG_PREFIX} x402 routes updated: ${Object.keys(routes).join(', ') || '(none)'}`);
130
79
  }
131
80
  return true;
132
81
  }
@@ -145,8 +94,8 @@ function cryptonlyPaymentMiddleware(options) {
145
94
  timer = setInterval(() => {
146
95
  refresh().catch((error) => {
147
96
  logger.warn(current
148
- ? `${LOG_PREFIX} config refresh failed; keeping the last routes: ${describe(error)}`
149
- : `${LOG_PREFIX} config load failed: ${describe(error)}`);
97
+ ? `${exports.X402_LOG_PREFIX} config refresh failed; keeping the last routes: ${describeError(error)}`
98
+ : `${exports.X402_LOG_PREFIX} config load failed: ${describeError(error)}`);
150
99
  });
151
100
  }, refreshIntervalMs);
152
101
  timer.unref?.();
@@ -165,49 +114,98 @@ function cryptonlyPaymentMiddleware(options) {
165
114
  firstLoad = undefined;
166
115
  lastFailureAt = Date.now();
167
116
  lastFailure = error;
168
- logger.error(`${LOG_PREFIX} x402 config unavailable: ${describe(error)}`);
117
+ logger.error(`${exports.X402_LOG_PREFIX} x402 config unavailable: ${describeError(error)}`);
169
118
  throw error;
170
119
  });
171
120
  }
172
121
  return firstLoad;
173
122
  }
174
- const middleware = async (req, res, next) => {
175
- if (!current) {
176
- try {
177
- await ready();
178
- }
179
- catch {
180
- if (!res.headersSent) {
181
- res.setHeader('Retry-After', String(Math.ceil(retryAfterMs / 1000)));
182
- res.status(503).json({
183
- error: 'x402_config_unavailable',
184
- message: 'Payment configuration is unavailable; retry shortly.',
185
- });
186
- }
187
- return;
188
- }
189
- }
190
- await current.handler(req, res, next);
191
- };
192
- return Object.assign(middleware, {
123
+ return {
124
+ facilitator,
125
+ schemes,
126
+ svmSchemes,
127
+ retryAfterMs,
128
+ logger,
129
+ current: () => current,
193
130
  ready,
194
131
  refresh: () => {
195
132
  startRefreshing();
196
133
  return refresh();
197
134
  },
198
- routes: () => current?.routes,
199
135
  close: () => {
200
136
  closed = true;
201
137
  if (timer)
202
138
  clearInterval(timer);
203
139
  timer = undefined;
204
140
  },
205
- });
141
+ };
142
+ }
143
+ /**
144
+ * A fresh `x402ResourceServer` on the facilitator, with the EVM schemes
145
+ * registered on the account's network and the SVM schemes on each of its
146
+ * Solana networks.
147
+ *
148
+ * Build one per route set: `initialize()` on a shared one would clear its
149
+ * facilitator data under requests still in flight.
150
+ */
151
+ function createResourceServer(config, facilitator, schemes, svmSchemes) {
152
+ const server = new server_1.x402ResourceServer(facilitator);
153
+ for (const scheme of schemes) {
154
+ server.register(config.network, scheme);
155
+ }
156
+ for (const network of solanaNetworksOf(config)) {
157
+ for (const scheme of svmSchemes) {
158
+ server.register(network, scheme);
159
+ }
160
+ }
161
+ return server;
162
+ }
163
+ /** The Solana networks an account accepts payments on. */
164
+ function solanaNetworksOf(config) {
165
+ const networks = new Set();
166
+ for (const entry of config.networks ?? []) {
167
+ if ((0, config_js_1.isSolanaNetwork)(entry.network))
168
+ networks.add(entry.network);
169
+ }
170
+ for (const asset of config.assets) {
171
+ if (asset.network && (0, config_js_1.isSolanaNetwork)(asset.network))
172
+ networks.add(asset.network);
173
+ }
174
+ return [...networks];
175
+ }
176
+ let evmModule;
177
+ let svmModule;
178
+ /** `[new ExactEvmScheme()]` from `@x402/evm`. Throws when it is not installed. */
179
+ function defaultEvmSchemes() {
180
+ if (evmModule === undefined) {
181
+ try {
182
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
183
+ evmModule = require('@x402/evm/exact/server');
184
+ }
185
+ catch {
186
+ evmModule = null;
187
+ }
188
+ }
189
+ if (!evmModule) {
190
+ throw new TypeError(`${exports.X402_LOG_PREFIX} @x402/evm is not installed; install it or pass \`schemes\``);
191
+ }
192
+ return [new evmModule.ExactEvmScheme()];
193
+ }
194
+ /** `[new ExactSvmScheme()]` from `@x402/svm` when installed (optional peer), else none. */
195
+ function defaultSvmSchemes() {
196
+ if (svmModule === undefined) {
197
+ try {
198
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
199
+ svmModule = require('@x402/svm/exact/server');
200
+ }
201
+ catch {
202
+ svmModule = null;
203
+ }
204
+ }
205
+ return svmModule ? [new svmModule.ExactSvmScheme()] : [];
206
206
  }
207
- function describe(error) {
207
+ /** An error's message, for log lines. */
208
+ function describeError(error) {
208
209
  return error instanceof Error ? error.message : String(error);
209
210
  }
210
- var config_js_2 = require("./config.js");
211
- Object.defineProperty(exports, "fetchX402Config", { enumerable: true, get: function () { return config_js_2.fetchX402Config; } });
212
- Object.defineProperty(exports, "routesFromConfig", { enumerable: true, get: function () { return config_js_2.routesFromConfig; } });
213
- //# sourceMappingURL=express.js.map
211
+ //# sourceMappingURL=route-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-source.js","sourceRoot":"","sources":["../src/route-source.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cryptonly/x402",
3
- "version": "0.4.1",
4
- "description": "Cryptonly facilitator client and dashboard-configured payment middleware for the x402 protocol.",
3
+ "version": "0.5.0",
4
+ "description": "Cryptonly x402 facilitator client and dashboard price loader. Framework adapters: @cryptonly/x402-express, @cryptonly/x402-fastify, @cryptonly/x402-nestjs.",
5
5
  "license": "MIT",
6
6
  "private": false,
7
7
  "type": "commonjs",
@@ -12,9 +12,9 @@
12
12
  "repository": {
13
13
  "type": "git",
14
14
  "url": "git+https://github.com/cryptonly-net/x402.git",
15
- "directory": "typescript"
15
+ "directory": "typescript/packages/x402"
16
16
  },
17
- "homepage": "https://github.com/cryptonly-net/x402#readme",
17
+ "homepage": "https://github.com/cryptonly-net/x402/tree/main/typescript/packages/x402#readme",
18
18
  "bugs": {
19
19
  "url": "https://github.com/cryptonly-net/x402/issues"
20
20
  },
@@ -24,9 +24,7 @@
24
24
  "facilitator",
25
25
  "payments",
26
26
  "client",
27
- "typescript",
28
- "express",
29
- "middleware"
27
+ "typescript"
30
28
  ],
31
29
  "main": "./dist/index.js",
32
30
  "types": "./dist/index.d.ts",
@@ -37,30 +35,17 @@
37
35
  "require": "./dist/index.js",
38
36
  "default": "./dist/index.js"
39
37
  },
40
- "./express": {
41
- "types": "./dist/express.d.ts",
42
- "import": "./dist/express.js",
43
- "require": "./dist/express.js",
44
- "default": "./dist/express.js"
45
- },
46
38
  "./package.json": "./package.json"
47
39
  },
48
- "typesVersions": {
49
- "*": {
50
- "express": [
51
- "./dist/express.d.ts"
52
- ]
53
- }
54
- },
55
40
  "files": [
56
41
  "dist"
57
42
  ],
58
43
  "scripts": {
59
44
  "build": "tsc -p tsconfig.build.json",
60
45
  "clean": "rm -rf dist",
61
- "prepare": "npm run build",
62
46
  "prepublishOnly": "npm run build",
63
- "test": "jest"
47
+ "test": "jest",
48
+ "typecheck": "tsc -p tsconfig.json"
64
49
  },
65
50
  "publishConfig": {
66
51
  "access": "public"
@@ -68,40 +53,24 @@
68
53
  "peerDependencies": {
69
54
  "@x402/core": "^2",
70
55
  "@x402/evm": "^2",
71
- "@x402/express": "^2",
72
56
  "@x402/extensions": "^2",
73
- "@x402/svm": "^2",
74
- "express": "^4 || ^5"
57
+ "@x402/svm": "^2"
75
58
  },
76
59
  "peerDependenciesMeta": {
77
60
  "@x402/evm": {
78
61
  "optional": true
79
62
  },
80
- "@x402/express": {
81
- "optional": true
82
- },
83
63
  "@x402/extensions": {
84
64
  "optional": true
85
65
  },
86
- "express": {
87
- "optional": true
88
- },
89
66
  "@x402/svm": {
90
67
  "optional": true
91
68
  }
92
69
  },
93
70
  "devDependencies": {
94
- "@types/express": "^5.0.6",
95
- "@types/jest": "^29.5.14",
96
- "@types/node": "^22.20.5",
97
71
  "@x402/core": "^2.28.0",
98
72
  "@x402/evm": "^2.28.0",
99
- "@x402/express": "^2.28.0",
100
73
  "@x402/extensions": "^2.28.0",
101
- "@x402/svm": "^2.28.0",
102
- "express": "^5.3.0",
103
- "jest": "^29.7.0",
104
- "ts-jest": "^29.2.0",
105
- "typescript": "^5.9.3"
74
+ "@x402/svm": "^2.28.0"
106
75
  }
107
76
  }
package/dist/express.d.ts DELETED
@@ -1,100 +0,0 @@
1
- import type { NextFunction, Request, Response } from 'express';
2
- import type { RoutesConfig } from '@x402/core/server';
3
- import { type PaywallConfig, type SchemeNetworkServer } from '@x402/express';
4
- import { CryptonlyFacilitatorClient, type CryptonlyFacilitatorConfig } from './client.js';
5
- import { type X402Config, type X402ExtensionsModule } from './config.js';
6
- /** An Express middleware. */
7
- export type ExpressMiddleware = (req: Request, res: Response, next: NextFunction) => void | Promise<void>;
8
- /** What {@link InnerMiddlewareFactory} gets besides the routes. */
9
- export type InnerMiddlewareContext = {
10
- config: X402Config;
11
- facilitator: CryptonlyFacilitatorClient;
12
- /** Registered on the account's EVM network. */
13
- schemes: readonly SchemeNetworkServer[];
14
- /** Registered on each Solana network of the account. */
15
- svmSchemes: readonly SchemeNetworkServer[];
16
- paywallConfig?: PaywallConfig;
17
- };
18
- /**
19
- * Builds the payment middleware for one set of routes. The default is the
20
- * stock `paymentMiddleware` from `@x402/express` over a fresh
21
- * `x402ResourceServer`; replace it to add hooks, or in tests.
22
- */
23
- export type InnerMiddlewareFactory = (routes: RoutesConfig, context: InnerMiddlewareContext) => ExpressMiddleware;
24
- /** Logger used for refresh failures and skipped resources. */
25
- export type CryptonlyMiddlewareLogger = Pick<Console, 'info' | 'warn' | 'error'>;
26
- /** Options for {@link cryptonlyPaymentMiddleware}. */
27
- export type CryptonlyPaymentMiddlewareOptions = CryptonlyFacilitatorConfig & {
28
- /**
29
- * How often to reload `GET /x402/config`. Defaults to 60 s; `0` turns
30
- * refreshing off.
31
- */
32
- refreshIntervalMs?: number;
33
- /**
34
- * Scheme servers registered on the account's network. Defaults to
35
- * `[new ExactEvmScheme()]`. Resources with another scheme are skipped.
36
- */
37
- schemes?: readonly SchemeNetworkServer[];
38
- /**
39
- * Scheme servers registered on the account's Solana networks. Defaults
40
- * to `[new ExactSvmScheme()]` from `@x402/svm` when it is installed, and
41
- * to none otherwise (Solana resources are then skipped).
42
- */
43
- svmSchemes?: readonly SchemeNetworkServer[];
44
- /** Passed to the stock `paymentMiddleware` for the browser paywall. */
45
- paywallConfig?: PaywallConfig;
46
- /** `fetch` for `GET /x402/config`. Defaults to the global `fetch`. */
47
- fetch?: typeof fetch;
48
- /**
49
- * After a failed first load, how long requests answer 503 before the
50
- * next attempt. Defaults to 5 s.
51
- */
52
- retryAfterMs?: number;
53
- /** Defaults to `console`. */
54
- logger?: CryptonlyMiddlewareLogger;
55
- /** `@x402/extensions` override; `null` leaves extensions out. */
56
- extensions?: X402ExtensionsModule | null;
57
- /** Builds the inner middleware. See {@link InnerMiddlewareFactory}. */
58
- createMiddleware?: InnerMiddlewareFactory;
59
- };
60
- /** The middleware returned by {@link cryptonlyPaymentMiddleware}. */
61
- export type CryptonlyPaymentMiddleware = ((req: Request, res: Response, next: NextFunction) => Promise<void>) & {
62
- /**
63
- * Loads the configuration now (if not loaded yet) and starts refreshing.
64
- * Rejects when the first load fails. Await it before `listen` to fail
65
- * fast at startup.
66
- */
67
- ready(): Promise<void>;
68
- /** Reloads the configuration now. Resolves `true` when the routes changed. */
69
- refresh(): Promise<boolean>;
70
- /** The routes in use, or `undefined` before the first successful load. */
71
- routes(): RoutesConfig | undefined;
72
- /** Stops refreshing. The last routes stay in use. */
73
- close(): void;
74
- };
75
- /** The default {@link InnerMiddlewareFactory}: stock `@x402/express`. */
76
- export declare const stockPaymentMiddleware: InnerMiddlewareFactory;
77
- /**
78
- * Express middleware whose paid routes and prices come from the Cryptonly
79
- * dashboard (`GET /x402/config`), refreshed every minute, so a price change
80
- * reaches production without a deploy.
81
- *
82
- * - The configuration loads on the first request (or on `ready()`), once.
83
- * - Each refresh rebuilds the stock `@x402/express` middleware only when the
84
- * routes changed. A failed refresh keeps the last good routes.
85
- * - Until a first load succeeds, every request through it answers 503
86
- * (fail closed): paid endpoints are never served for free. Mount it after
87
- * health checks and other free routes.
88
- *
89
- * @example
90
- * ```ts
91
- * import { cryptonlyPaymentMiddleware } from '@cryptonly/x402/express';
92
- *
93
- * app.use(cryptonlyPaymentMiddleware({ apiKey: process.env.CRYPTONLY_API_KEY! }));
94
- * app.get('/weather', (req, res) => res.json({ temperatureC: 21 }));
95
- * ```
96
- */
97
- export declare function cryptonlyPaymentMiddleware(options: CryptonlyPaymentMiddlewareOptions): CryptonlyPaymentMiddleware;
98
- export { fetchX402Config, routesFromConfig } from './config.js';
99
- export type { X402Config } from './config.js';
100
- //# sourceMappingURL=express.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,0BAA0B,EAAE,KAAK,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,oBAAoB,EAC1B,MAAM,aAAa,CAAC;AAErB,6BAA6B;AAC7B,MAAM,MAAM,iBAAiB,GAAG,CAC9B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,KACf,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE1B,mEAAmE;AACnE,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,0BAA0B,CAAC;IACxC,+CAA+C;IAC/C,OAAO,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACxC,wDAAwD;IACxD,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,sBAAsB,KAC5B,iBAAiB,CAAC;AAEvB,8DAA8D;AAC9D,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAEjF,sDAAsD;AACtD,MAAM,MAAM,iCAAiC,GAAG,0BAA0B,GAAG;IAC3E;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IACzC;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C,uEAAuE;IACvE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,sEAAsE;IACtE,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,yBAAyB,CAAC;IACnC,iEAAiE;IACjE,UAAU,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACzC,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;CAC3C,CAAC;AAEF,qEAAqE;AACrE,MAAM,MAAM,0BAA0B,GAAG,CAAC,CACxC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,KACf,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG;IACpB;;;;OAIG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,8EAA8E;IAC9E,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5B,0EAA0E;IAC1E,MAAM,IAAI,YAAY,GAAG,SAAS,CAAC;IACnC,qDAAqD;IACrD,KAAK,IAAI,IAAI,CAAC;CACf,CAAC;AAMF,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,EAAE,sBAgBpC,CAAC;AA6BF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iCAAiC,GACzC,0BAA0B,CA+I5B;AAMD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"express.js","sourceRoot":"","sources":["../src/express.ts"],"names":[],"mappings":"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"}