@cryptonly/x402-nestjs 0.0.0-stage → 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
@@ -1,3 +1,134 @@
1
- # Temporary Holding Version
1
+ <img src="https://raw.githubusercontent.com/cryptonly-net/.github/main/profile/assets/header-banner.svg" alt="Cryptonly" width="100%" />
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <div align="center">
4
+
5
+ # Cryptonly x402 for NestJS
6
+
7
+ Accept x402 payments in NestJS, with Cryptonly as the facilitator.
8
+
9
+ [Website](https://cryptonly.net) · [Documentation](https://docs.cryptonly.net/guides/x402/) · [Contact](https://cryptonly.net/contact/)
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ Cryptonly verifies and settles each payment, and pays the network fee. Payments go straight to your wallet. Mark a handler with `@X402()` and its price comes from the Cryptonly dashboard, so a price change needs no deploy. Works on the Express and the Fastify platform.
16
+
17
+ 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.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install @cryptonly/x402-nestjs @x402/core @x402/evm
23
+ ```
24
+
25
+ ## Use
26
+
27
+ Register the module once:
28
+
29
+ ```ts
30
+ import { Module } from '@nestjs/common';
31
+ import { X402Module } from '@cryptonly/x402-nestjs';
32
+
33
+ @Module({
34
+ imports: [X402Module.forRoot({ apiKey: process.env.CRYPTONLY_API_KEY!, isGlobal: true })],
35
+ controllers: [WeatherController],
36
+ })
37
+ export class AppModule {}
38
+ ```
39
+
40
+ Then mark the paid handlers:
41
+
42
+ ```ts
43
+ import { Controller, Get, Param } from '@nestjs/common';
44
+ import { X402, X402Payment, type X402VerifiedPayment } from '@cryptonly/x402-nestjs';
45
+
46
+ @Controller('weather')
47
+ export class WeatherController {
48
+ @X402() // priced in the dashboard as GET /weather/:city
49
+ @Get(':city')
50
+ get(@Param('city') city: string, @X402Payment() payment: X402VerifiedPayment) {
51
+ return { city, temperatureC: 21, paidBy: payment.payer };
52
+ }
53
+ }
54
+ ```
55
+
56
+ With `@nestjs/config`, use `forRootAsync`:
57
+
58
+ ```ts
59
+ X402Module.forRootAsync({
60
+ isGlobal: true,
61
+ imports: [ConfigModule],
62
+ inject: [ConfigService],
63
+ useFactory: (config: ConfigService) => ({ apiKey: config.getOrThrow('CRYPTONLY_API_KEY') }),
64
+ });
65
+ ```
66
+
67
+ ## How it works
68
+
69
+ - **Only `@X402()` routes are paid.** Put it on a handler, or on a controller to cover all its handlers. A route without it is served for free, even if the dashboard prices it.
70
+ - **Price in the dashboard.** The handler's method and path must match a dashboard endpoint. Price the full public path, including any `setGlobalPrefix()` or version prefix.
71
+ - **Fails closed.**
72
+ - An `@X402()` route the dashboard doesn't price answers `503` (`x402_route_unpriced`).
73
+ - Until the prices first load, paid routes answer `503` with `Retry-After`.
74
+ - At startup, and on each price change, the module logs a warning for each mismatch between the dashboard and the handlers.
75
+ - **Order.** Guards run first, then the payment check, then pipes and the handler. A request your auth guard rejects is never asked to pay.
76
+ - **Charging.** The payment is verified before the handler and settled after it returns. An exception, including a `ValidationPipe` error, cancels it, so the buyer isn't charged.
77
+ - **`@X402Payment()`** gives the verified payment: `payer`, `network`, `amount`, `asset`, `payTo`. It is verified but not yet settled.
78
+
79
+ ## Price in code
80
+
81
+ Pass a stock `@x402/core` route config to `@X402()`. That route then needs no dashboard price:
82
+
83
+ ```ts
84
+ @X402({
85
+ accepts: { scheme: 'exact', price: '$0.01', network: 'eip155:8453', payTo: process.env.PAY_TO! },
86
+ description: 'Current weather',
87
+ })
88
+ @Get('now')
89
+ now() {
90
+ return { temperatureC: 21 };
91
+ }
92
+ ```
93
+
94
+ `payTo` must be a wallet you added in the dashboard.
95
+
96
+ ## Options
97
+
98
+ | Option | Default | |
99
+ | --- | --- | --- |
100
+ | `apiKey` | required | Your Cryptonly API key. |
101
+ | `sandbox` | `false` | Use the sandbox. |
102
+ | `baseUrl` | production | Another API origin. Takes precedence over `sandbox`. |
103
+ | `refreshIntervalMs` | `60000` | How often to reload prices. `0` turns it off. |
104
+ | `retryAfterMs` | `5000` | After a failed first load, how long to answer `503` before the next try. |
105
+ | `schemes` | `[new ExactEvmScheme()]` | Schemes for Base. |
106
+ | `svmSchemes` | `[new ExactSvmScheme()]` if `@x402/svm` is installed | Schemes for Solana. |
107
+ | `logger` | Nest `Logger` | Gets reload failures and skipped routes. |
108
+ | `waitForConfig` | `false` | Load the prices during bootstrap, so a bad key fails startup. When `false`, they load on the first paid request. |
109
+ | `isGlobal` | `false` | Make the module global, so any module's controllers can use `@X402()`. |
110
+
111
+ Inject `X402Service` for `ready()`, `refresh()`, `routes()` and the `facilitator` client.
112
+
113
+ ## Not supported
114
+
115
+ - Handlers that take `@Res()` without `passthrough: true`: the payment can't be settled before the response is sent.
116
+ - The HTML paywall for browsers. Paid routes answer `402` with JSON, for x402 clients.
117
+
118
+ ## Solana
119
+
120
+ Install `@x402/svm` and `@solana/kit`, and add a Solana payout wallet in the dashboard. Solana prices then work with no other change.
121
+
122
+ ## Sandbox
123
+
124
+ Pass `sandbox: true` and use a key from your [sandbox account](https://docs.cryptonly.net/guides/sandbox-environment/). The sandbox settles on Base Sepolia (`eip155:84532`) and Solana Devnet.
125
+
126
+ ## Learn more
127
+
128
+ - [x402 quickstart](https://docs.cryptonly.net/guides/x402/quickstart/)
129
+ - [Discovery](https://docs.cryptonly.net/guides/x402/discovery/): list your endpoints for AI agents
130
+ - [Reference](https://docs.cryptonly.net/guides/x402/reference/): key scopes, limits and reason codes
131
+
132
+ ## License
133
+
134
+ [MIT](https://github.com/cryptonly-net/x402/blob/main/LICENSE)
@@ -0,0 +1,36 @@
1
+ import type { RouteConfig } from '@x402/core/server';
2
+ import type { PaymentPayload, PaymentRequirements } from '@x402/core/types';
3
+ /** What {@link X402} stores on a handler or controller. */
4
+ export type X402RouteMetadata = {
5
+ /** The price in code; without it the price comes from the dashboard. */
6
+ route?: RouteConfig;
7
+ };
8
+ /**
9
+ * Requires an x402 payment for a handler, or for every handler of a
10
+ * controller.
11
+ *
12
+ * - `@X402()`: the price comes from the dashboard resource with the same
13
+ * method and path. A route the dashboard doesn't price answers 503.
14
+ * - `@X402({ accepts: { scheme, price, network, payTo } })`: the price is
15
+ * in code, as a stock `@x402/core` `RouteConfig`.
16
+ *
17
+ * The payment is verified before the handler runs and settled after it
18
+ * succeeds. An exception, including a validation error, cancels it.
19
+ */
20
+ export declare function X402(route?: RouteConfig): ClassDecorator & MethodDecorator;
21
+ /** The payment of a request, as verified before the handler. Not yet settled. */
22
+ export type X402VerifiedPayment = {
23
+ /** The paying wallet, as the facilitator verified it. */
24
+ payer?: string;
25
+ scheme: string;
26
+ network: string;
27
+ /** Atomic units of {@link asset}. */
28
+ amount: string;
29
+ asset: string;
30
+ payTo: string;
31
+ payload: PaymentPayload;
32
+ requirements: PaymentRequirements;
33
+ };
34
+ /** Injects the {@link X402VerifiedPayment} of the request into an `@X402()` handler. */
35
+ export declare const X402Payment: (...dataOrPipes: unknown[]) => ParameterDecorator;
36
+ //# sourceMappingURL=decorators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAI5E,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,wEAAwE;IACxE,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,EAAE,WAAW,GAAG,cAAc,GAAG,eAAe,CAK1E;AAED,iFAAiF;AACjF,MAAM,MAAM,mBAAmB,GAAG;IAChC,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,cAAc,CAAC;IACxB,YAAY,EAAE,mBAAmB,CAAC;CACnC,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,WAAW,mDAGvB,CAAC"}
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.X402Payment = void 0;
4
+ exports.X402 = X402;
5
+ const common_1 = require("@nestjs/common");
6
+ const x402_options_js_1 = require("./x402.options.js");
7
+ const x402_interceptor_js_1 = require("./x402.interceptor.js");
8
+ /**
9
+ * Requires an x402 payment for a handler, or for every handler of a
10
+ * controller.
11
+ *
12
+ * - `@X402()`: the price comes from the dashboard resource with the same
13
+ * method and path. A route the dashboard doesn't price answers 503.
14
+ * - `@X402({ accepts: { scheme, price, network, payTo } })`: the price is
15
+ * in code, as a stock `@x402/core` `RouteConfig`.
16
+ *
17
+ * The payment is verified before the handler runs and settled after it
18
+ * succeeds. An exception, including a validation error, cancels it.
19
+ */
20
+ function X402(route) {
21
+ return (0, common_1.applyDecorators)((0, common_1.SetMetadata)(x402_options_js_1.X402_ROUTE_METADATA, { route }), (0, common_1.UseInterceptors)(x402_interceptor_js_1.X402Interceptor));
22
+ }
23
+ /** Injects the {@link X402VerifiedPayment} of the request into an `@X402()` handler. */
24
+ exports.X402Payment = (0, common_1.createParamDecorator)((_data, context) => context.switchToHttp().getRequest()[x402_options_js_1.X402_PAYMENT]);
25
+ //# sourceMappingURL=decorators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decorators.js","sourceRoot":"","sources":["../src/decorators.ts"],"names":[],"mappings":";;;AA8BA,oBAKC;AAnCD,2CAMwB;AAGxB,uDAAsE;AACtE,+DAAwD;AAQxD;;;;;;;;;;;GAWG;AACH,SAAgB,IAAI,CAAC,KAAmB;IACtC,OAAO,IAAA,wBAAe,EACpB,IAAA,oBAAW,EAAC,qCAAmB,EAAE,EAAE,KAAK,EAA8B,CAAC,EACvE,IAAA,wBAAe,EAAC,qCAAe,CAAC,CACjC,CAAC;AACJ,CAAC;AAgBD,wFAAwF;AAC3E,QAAA,WAAW,GAAG,IAAA,6BAAoB,EAC7C,CAAC,KAAc,EAAE,OAAyB,EAAmC,EAAE,CAC7E,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC,8BAAY,CAAC,CACpD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { HttpException } from '@nestjs/common';
2
+ /**
3
+ * Thrown for a request that needs payment, or whose payment failed. The
4
+ * `PAYMENT-REQUIRED` header is already on the response, so the default
5
+ * exception filter, or yours, sends it with this body and status.
6
+ */
7
+ export declare class X402PaymentRequiredException extends HttpException {
8
+ constructor(body?: unknown, status?: number);
9
+ }
10
+ //# sourceMappingURL=exceptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.d.ts","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAc,MAAM,gBAAgB,CAAC;AAE3D;;;;GAIG;AACH,qBAAa,4BAA6B,SAAQ,aAAa;gBACjD,IAAI,GAAE,OAAY,EAAE,MAAM,GAAE,MAAoC;CAG7E"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.X402PaymentRequiredException = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ /**
6
+ * Thrown for a request that needs payment, or whose payment failed. The
7
+ * `PAYMENT-REQUIRED` header is already on the response, so the default
8
+ * exception filter, or yours, sends it with this body and status.
9
+ */
10
+ class X402PaymentRequiredException extends common_1.HttpException {
11
+ constructor(body = {}, status = common_1.HttpStatus.PAYMENT_REQUIRED) {
12
+ super((body ?? {}), status);
13
+ }
14
+ }
15
+ exports.X402PaymentRequiredException = X402PaymentRequiredException;
16
+ //# sourceMappingURL=exceptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../src/exceptions.ts"],"names":[],"mappings":";;;AAAA,2CAA2D;AAE3D;;;;GAIG;AACH,MAAa,4BAA6B,SAAQ,sBAAa;IAC7D,YAAY,OAAgB,EAAE,EAAE,SAAiB,mBAAU,CAAC,gBAAgB;QAC1E,KAAK,CAAC,CAAC,IAAI,IAAI,EAAE,CAA4B,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;CACF;AAJD,oEAIC"}
@@ -0,0 +1,11 @@
1
+ export { X402, X402Payment } from './decorators.js';
2
+ export type { X402RouteMetadata, X402VerifiedPayment } from './decorators.js';
3
+ export { X402PaymentRequiredException } from './exceptions.js';
4
+ export { X402Interceptor } from './x402.interceptor.js';
5
+ export { X402Module } from './x402.module.js';
6
+ export { X402_MODULE_OPTIONS, X402_PAYMENT, X402_ROUTE_METADATA, } from './x402.options.js';
7
+ export type { X402ModuleOptions } from './x402.options.js';
8
+ export { X402Service } from './x402.service.js';
9
+ export { fetchX402Config, routesFromConfig } from '@cryptonly/x402';
10
+ export type { X402Config } from '@cryptonly/x402';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACpD,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.routesFromConfig = exports.fetchX402Config = exports.X402Service = exports.X402_ROUTE_METADATA = exports.X402_PAYMENT = exports.X402_MODULE_OPTIONS = exports.X402Module = exports.X402Interceptor = exports.X402PaymentRequiredException = exports.X402Payment = exports.X402 = void 0;
4
+ var decorators_js_1 = require("./decorators.js");
5
+ Object.defineProperty(exports, "X402", { enumerable: true, get: function () { return decorators_js_1.X402; } });
6
+ Object.defineProperty(exports, "X402Payment", { enumerable: true, get: function () { return decorators_js_1.X402Payment; } });
7
+ var exceptions_js_1 = require("./exceptions.js");
8
+ Object.defineProperty(exports, "X402PaymentRequiredException", { enumerable: true, get: function () { return exceptions_js_1.X402PaymentRequiredException; } });
9
+ var x402_interceptor_js_1 = require("./x402.interceptor.js");
10
+ Object.defineProperty(exports, "X402Interceptor", { enumerable: true, get: function () { return x402_interceptor_js_1.X402Interceptor; } });
11
+ var x402_module_js_1 = require("./x402.module.js");
12
+ Object.defineProperty(exports, "X402Module", { enumerable: true, get: function () { return x402_module_js_1.X402Module; } });
13
+ var x402_options_js_1 = require("./x402.options.js");
14
+ Object.defineProperty(exports, "X402_MODULE_OPTIONS", { enumerable: true, get: function () { return x402_options_js_1.X402_MODULE_OPTIONS; } });
15
+ Object.defineProperty(exports, "X402_PAYMENT", { enumerable: true, get: function () { return x402_options_js_1.X402_PAYMENT; } });
16
+ Object.defineProperty(exports, "X402_ROUTE_METADATA", { enumerable: true, get: function () { return x402_options_js_1.X402_ROUTE_METADATA; } });
17
+ var x402_service_js_1 = require("./x402.service.js");
18
+ Object.defineProperty(exports, "X402Service", { enumerable: true, get: function () { return x402_service_js_1.X402Service; } });
19
+ var x402_1 = require("@cryptonly/x402");
20
+ Object.defineProperty(exports, "fetchX402Config", { enumerable: true, get: function () { return x402_1.fetchX402Config; } });
21
+ Object.defineProperty(exports, "routesFromConfig", { enumerable: true, get: function () { return x402_1.routesFromConfig; } });
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAoD;AAA3C,qGAAA,IAAI,OAAA;AAAE,4GAAA,WAAW,OAAA;AAE1B,iDAA+D;AAAtD,6HAAA,4BAA4B,OAAA;AACrC,6DAAwD;AAA/C,sHAAA,eAAe,OAAA;AACxB,mDAA8C;AAArC,4GAAA,UAAU,OAAA;AACnB,qDAI2B;AAHzB,sHAAA,mBAAmB,OAAA;AACnB,+GAAA,YAAY,OAAA;AACZ,sHAAA,mBAAmB,OAAA;AAGrB,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AACpB,wCAAoE;AAA3D,uGAAA,eAAe,OAAA;AAAE,wGAAA,gBAAgB,OAAA"}
@@ -0,0 +1,45 @@
1
+ import type { HTTPAdapter, HTTPRequestContext } from '@x402/core/server';
2
+ /** What the Express and Fastify request objects have in common. */
3
+ export type PlatformRequest = {
4
+ method: string;
5
+ url: string;
6
+ headers: Record<string, string | string[] | undefined>;
7
+ query?: unknown;
8
+ body?: unknown;
9
+ protocol?: string;
10
+ /** Express only. */
11
+ path?: string;
12
+ /** Express only. */
13
+ originalUrl?: string;
14
+ };
15
+ /** What the Express response and the Fastify reply have in common. */
16
+ export type PlatformResponse = {
17
+ statusCode: number;
18
+ header(name: string, value: string): unknown;
19
+ getHeader(name: string): unknown;
20
+ getHeaders(): Record<string, unknown>;
21
+ removeHeader(name: string): unknown;
22
+ };
23
+ /** `@x402/core`'s view of a request on either Nest platform. */
24
+ export declare class NestRequestAdapter implements HTTPAdapter {
25
+ private readonly req;
26
+ constructor(req: PlatformRequest);
27
+ getHeader(name: string): string | undefined;
28
+ getMethod(): string;
29
+ getPath(): string;
30
+ getUrl(): string;
31
+ getAcceptHeader(): string;
32
+ getUserAgent(): string;
33
+ getQueryParams(): Record<string, string | string[]>;
34
+ getQueryParam(name: string): string | string[] | undefined;
35
+ getBody(): unknown;
36
+ }
37
+ /** The `@x402/core` request context of a Nest request. */
38
+ export declare function requestContextOf(req: PlatformRequest): HTTPRequestContext;
39
+ /** Sets each header on the response. */
40
+ export declare function setHeaders(res: PlatformResponse, headers: Record<string, string>): void;
41
+ /** The response's headers as strings. */
42
+ export declare function headersOf(res: PlatformResponse): Record<string, string>;
43
+ /** A header's value as a string, or `null` when unset. */
44
+ export declare function headerOf(res: PlatformResponse, name: string): string | null;
45
+ //# sourceMappingURL=request-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-adapter.d.ts","sourceRoot":"","sources":["../src/request-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEzE,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACvD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,sEAAsE;AACtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IAC7C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC,CAAC;AAEF,gEAAgE;AAChE,qBAAa,kBAAmB,YAAW,WAAW;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBAAH,GAAG,EAAE,eAAe;IAEjD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAK3C,SAAS,IAAI,MAAM;IAInB,OAAO,IAAI,MAAM;IAIjB,MAAM,IAAI,MAAM;IAKhB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;IAItB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAInD,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS;IAI1D,OAAO,IAAI,OAAO;CAGnB;AAED,0DAA0D;AAC1D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,GAAG,kBAAkB,CAgBzE;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAEvF;AAED,yCAAyC;AACzC,wBAAgB,SAAS,CAAC,GAAG,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMvE;AAED,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG3E"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NestRequestAdapter = void 0;
4
+ exports.requestContextOf = requestContextOf;
5
+ exports.setHeaders = setHeaders;
6
+ exports.headersOf = headersOf;
7
+ exports.headerOf = headerOf;
8
+ /** `@x402/core`'s view of a request on either Nest platform. */
9
+ class NestRequestAdapter {
10
+ req;
11
+ constructor(req) {
12
+ this.req = req;
13
+ }
14
+ getHeader(name) {
15
+ const value = this.req.headers[name.toLowerCase()];
16
+ return Array.isArray(value) ? value[0] : value;
17
+ }
18
+ getMethod() {
19
+ return this.req.method;
20
+ }
21
+ getPath() {
22
+ return this.req.path ?? this.req.url.split('?')[0];
23
+ }
24
+ getUrl() {
25
+ const protocol = this.req.protocol ?? 'http';
26
+ return `${protocol}://${this.getHeader('host') ?? ''}${this.req.originalUrl ?? this.req.url}`;
27
+ }
28
+ getAcceptHeader() {
29
+ return this.getHeader('accept') ?? '';
30
+ }
31
+ getUserAgent() {
32
+ return this.getHeader('user-agent') ?? '';
33
+ }
34
+ getQueryParams() {
35
+ return (this.req.query ?? {});
36
+ }
37
+ getQueryParam(name) {
38
+ return this.getQueryParams()[name];
39
+ }
40
+ getBody() {
41
+ return this.req.body;
42
+ }
43
+ }
44
+ exports.NestRequestAdapter = NestRequestAdapter;
45
+ /** The `@x402/core` request context of a Nest request. */
46
+ function requestContextOf(req) {
47
+ const adapter = new NestRequestAdapter(req);
48
+ const path = adapter.getPath();
49
+ let decodedPath = path;
50
+ try {
51
+ decodedPath = decodeURIComponent(path);
52
+ }
53
+ catch {
54
+ // Keep the raw path; route matching then fails closed.
55
+ }
56
+ return {
57
+ adapter,
58
+ path,
59
+ decodedPath,
60
+ method: req.method,
61
+ paymentHeader: adapter.getHeader('payment-signature') ?? adapter.getHeader('x-payment'),
62
+ };
63
+ }
64
+ /** Sets each header on the response. */
65
+ function setHeaders(res, headers) {
66
+ for (const [name, value] of Object.entries(headers))
67
+ res.header(name, String(value));
68
+ }
69
+ /** The response's headers as strings. */
70
+ function headersOf(res) {
71
+ const headers = {};
72
+ for (const [name, value] of Object.entries(res.getHeaders())) {
73
+ if (value != null)
74
+ headers[name] = String(value);
75
+ }
76
+ return headers;
77
+ }
78
+ /** A header's value as a string, or `null` when unset. */
79
+ function headerOf(res, name) {
80
+ const value = res.getHeader(name);
81
+ return value == null ? null : String(value);
82
+ }
83
+ //# sourceMappingURL=request-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-adapter.js","sourceRoot":"","sources":["../src/request-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type CallHandler, type ExecutionContext, type NestInterceptor } from '@nestjs/common';
2
+ import { Reflector } from '@nestjs/core';
3
+ import { type Observable } from 'rxjs';
4
+ import { X402Service } from './x402.service.js';
5
+ /**
6
+ * Gates an `@X402()` handler: verifies the payment before the handler and
7
+ * settles it after the handler succeeds. Added by {@link X402}; it does
8
+ * nothing on handlers without it.
9
+ */
10
+ export declare class X402Interceptor implements NestInterceptor {
11
+ private readonly x402;
12
+ private readonly reflector;
13
+ constructor(x402: X402Service, reflector: Reflector);
14
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
15
+ private verify;
16
+ private settleAfter;
17
+ private settle;
18
+ private cancel;
19
+ private facilitatorFailure;
20
+ }
21
+ //# sourceMappingURL=x402.interceptor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.interceptor.d.ts","sourceRoot":"","sources":["../src/x402.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAUzC,OAAO,EAA0C,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAY/E,OAAO,EAAE,WAAW,EAAuB,MAAM,mBAAmB,CAAC;AAWrE;;;;GAIG;AACH,qBACa,eAAgB,YAAW,eAAe;IAEnD,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,SAAS;IAGvC,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC;YAgB9D,MAAM;IA0DpB,OAAO,CAAC,WAAW;YAsBL,MAAM;YAqCN,MAAM;IAsBpB,OAAO,CAAC,kBAAkB;CAQ3B"}
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.X402Interceptor = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const core_1 = require("@nestjs/core");
15
+ const server_1 = require("@x402/core/server");
16
+ const x402_1 = require("@cryptonly/x402");
17
+ const rxjs_1 = require("rxjs");
18
+ const exceptions_js_1 = require("./exceptions.js");
19
+ const request_adapter_js_1 = require("./request-adapter.js");
20
+ const x402_options_js_1 = require("./x402.options.js");
21
+ const x402_service_js_1 = require("./x402.service.js");
22
+ /**
23
+ * Gates an `@X402()` handler: verifies the payment before the handler and
24
+ * settles it after the handler succeeds. Added by {@link X402}; it does
25
+ * nothing on handlers without it.
26
+ */
27
+ let X402Interceptor = class X402Interceptor {
28
+ x402;
29
+ reflector;
30
+ constructor(x402, reflector) {
31
+ this.x402 = x402;
32
+ this.reflector = reflector;
33
+ }
34
+ intercept(context, next) {
35
+ if (context.getType() !== 'http')
36
+ return next.handle();
37
+ const meta = this.reflector.getAllAndOverride(x402_options_js_1.X402_ROUTE_METADATA, [context.getHandler(), context.getClass()]);
38
+ if (!meta)
39
+ return next.handle();
40
+ const http = context.switchToHttp();
41
+ const req = http.getRequest();
42
+ const res = http.getResponse();
43
+ return (0, rxjs_1.from)(this.verify(context, meta, req, res)).pipe((0, rxjs_1.mergeMap)((pending) => (pending ? this.settleAfter(pending, res, next) : next.handle())));
44
+ }
45
+ async verify(context, meta, req, res) {
46
+ let server;
47
+ if (meta.route) {
48
+ server = this.x402.inCodeServer(context.getHandler(), meta.route);
49
+ }
50
+ else {
51
+ server = await this.x402.dashboardServer();
52
+ if (!server) {
53
+ res.header('Retry-After', String(Math.ceil(this.x402.retryAfterMs / 1000)));
54
+ throw new common_1.ServiceUnavailableException(x402_1.X402_CONFIG_UNAVAILABLE);
55
+ }
56
+ }
57
+ const request = (0, request_adapter_js_1.requestContextOf)(req);
58
+ if (!server.httpServer.requiresPayment(request)) {
59
+ // Fail closed: a paid handler is never served for free.
60
+ this.x402.warnUnpriced(request.method, request.path);
61
+ throw new common_1.ServiceUnavailableException({
62
+ error: 'x402_route_unpriced',
63
+ message: 'This endpoint has no price yet; retry later.',
64
+ });
65
+ }
66
+ let result;
67
+ try {
68
+ await server.prepare();
69
+ result = await server.httpServer.processHTTPRequest(request);
70
+ }
71
+ catch (error) {
72
+ throw this.facilitatorFailure(error);
73
+ }
74
+ switch (result.type) {
75
+ case 'no-payment-required':
76
+ return undefined;
77
+ case 'payment-error':
78
+ (0, request_adapter_js_1.setHeaders)(res, result.response.headers);
79
+ throw new exceptions_js_1.X402PaymentRequiredException(result.response.body, result.response.status);
80
+ case 'payment-verified': {
81
+ const { paymentPayload, paymentRequirements } = result;
82
+ req[x402_options_js_1.X402_PAYMENT] = {
83
+ payer: server.payerOf(paymentPayload) ?? payerFromPayload(paymentPayload.payload),
84
+ scheme: paymentRequirements.scheme,
85
+ network: paymentRequirements.network,
86
+ amount: paymentRequirements.amount,
87
+ asset: paymentRequirements.asset,
88
+ payTo: paymentRequirements.payTo,
89
+ payload: paymentPayload,
90
+ requirements: paymentRequirements,
91
+ };
92
+ return { server, request, result };
93
+ }
94
+ }
95
+ }
96
+ settleAfter(pending, res, next) {
97
+ let settled = false;
98
+ return next.handle().pipe(
99
+ // Exceptions from pipes (validation) and the handler: no charge.
100
+ (0, rxjs_1.catchError)((error) => (0, rxjs_1.from)(this.cancel(pending, res, { reason: 'handler_threw', error })).pipe((0, rxjs_1.mergeMap)(() => (0, rxjs_1.throwError)(() => error)))), (0, rxjs_1.mergeMap)(async (body) => {
101
+ if (settled)
102
+ return body;
103
+ settled = true;
104
+ await this.settle(pending, res, body);
105
+ return body;
106
+ }));
107
+ }
108
+ async settle(pending, res, body) {
109
+ const { server, request, result } = pending;
110
+ // Set when a handler with `@Res({ passthrough: true })` chose an error status.
111
+ if (res.statusCode >= 400) {
112
+ await this.cancel(pending, res, { reason: 'handler_failed', responseStatus: res.statusCode });
113
+ return;
114
+ }
115
+ try {
116
+ const settlement = await server.httpServer.processSettlement(result.paymentPayload, result.paymentRequirements, result.declaredExtensions, { request, responseBody: bodyBuffer(body), responseHeaders: (0, request_adapter_js_1.headersOf)(res) }, undefined, result.beforeHandlerSettlement);
117
+ res.removeHeader(server_1.SETTLEMENT_OVERRIDES_HEADER);
118
+ if (!settlement.success) {
119
+ (0, request_adapter_js_1.setHeaders)(res, settlement.response.headers);
120
+ throw new exceptions_js_1.X402PaymentRequiredException(settlement.response.body, settlement.response.status);
121
+ }
122
+ (0, request_adapter_js_1.setHeaders)(res, settlement.headers);
123
+ res.header('Cache-Control', (0, server_1.withPrivateCacheControl)((0, request_adapter_js_1.headerOf)(res, 'Cache-Control')));
124
+ }
125
+ catch (error) {
126
+ res.removeHeader(server_1.SETTLEMENT_OVERRIDES_HEADER);
127
+ if (error instanceof common_1.HttpException)
128
+ throw error;
129
+ if (error instanceof server_1.FacilitatorResponseError) {
130
+ throw new common_1.BadGatewayException({ error: error.message });
131
+ }
132
+ this.x402.logger.error(`${x402_1.X402_LOG_PREFIX} settlement failed: ${(0, x402_1.describeError)(error)}`);
133
+ throw new exceptions_js_1.X402PaymentRequiredException({});
134
+ }
135
+ }
136
+ async cancel(pending, res, options) {
137
+ const { server, result } = pending;
138
+ try {
139
+ const canceled = await result.cancellationDispatcher.cancel(options);
140
+ res.removeHeader(server_1.SETTLEMENT_OVERRIDES_HEADER);
141
+ const headers = server.httpServer.createFailurePathSettlementHeaders(canceled, result.beforeHandlerSettlement, result.paymentPayload, (0, request_adapter_js_1.headerOf)(res, 'Cache-Control'));
142
+ if (headers)
143
+ (0, request_adapter_js_1.setHeaders)(res, headers);
144
+ }
145
+ catch (error) {
146
+ // The handler's own error is the one to answer with.
147
+ this.x402.logger.error(`${x402_1.X402_LOG_PREFIX} cancelling a payment failed: ${(0, x402_1.describeError)(error)}`);
148
+ }
149
+ }
150
+ facilitatorFailure(error) {
151
+ if (error instanceof common_1.HttpException)
152
+ return error;
153
+ if (error instanceof server_1.FacilitatorResponseError) {
154
+ return new common_1.BadGatewayException({ error: error.message });
155
+ }
156
+ this.x402.logger.error(`${x402_1.X402_LOG_PREFIX} payment processing failed: ${(0, x402_1.describeError)(error)}`);
157
+ return new common_1.InternalServerErrorException();
158
+ }
159
+ };
160
+ exports.X402Interceptor = X402Interceptor;
161
+ exports.X402Interceptor = X402Interceptor = __decorate([
162
+ (0, common_1.Injectable)(),
163
+ __metadata("design:paramtypes", [x402_service_js_1.X402Service,
164
+ core_1.Reflector])
165
+ ], X402Interceptor);
166
+ /** The handler's result as the bytes the settlement sees. */
167
+ function bodyBuffer(body) {
168
+ if (body === undefined || body === null || body instanceof common_1.StreamableFile) {
169
+ return Buffer.alloc(0);
170
+ }
171
+ if (Buffer.isBuffer(body))
172
+ return body;
173
+ return Buffer.from(typeof body === 'string' ? body : JSON.stringify(body));
174
+ }
175
+ /** The `from` of an EVM authorization or Permit2 payload, when the facilitator gave no payer. */
176
+ function payerFromPayload(payload) {
177
+ const authorization = payload.authorization;
178
+ const permit2 = payload.permit2Authorization;
179
+ const from = authorization?.from ?? permit2?.from;
180
+ return typeof from === 'string' ? from : undefined;
181
+ }
182
+ //# sourceMappingURL=x402.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.interceptor.js","sourceRoot":"","sources":["../src/x402.interceptor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { X402ConfigurableModule } from './x402.options.js';
2
+ /**
3
+ * x402 payments with Cryptonly as the facilitator. Register it once, then
4
+ * mark paid handlers with `@X402()`.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * @Module({
9
+ * imports: [
10
+ * X402Module.forRoot({ apiKey: process.env.CRYPTONLY_API_KEY!, isGlobal: true }),
11
+ * ],
12
+ * })
13
+ * export class AppModule {}
14
+ * ```
15
+ */
16
+ export declare class X402Module extends X402ConfigurableModule {
17
+ }
18
+ //# sourceMappingURL=x402.module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.module.d.ts","sourceRoot":"","sources":["../src/x402.module.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAG3D;;;;;;;;;;;;;GAaG;AACH,qBAKa,UAAW,SAAQ,sBAAsB;CAAG"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.X402Module = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const core_1 = require("@nestjs/core");
12
+ const x402_interceptor_js_1 = require("./x402.interceptor.js");
13
+ const x402_options_js_1 = require("./x402.options.js");
14
+ const x402_service_js_1 = require("./x402.service.js");
15
+ /**
16
+ * x402 payments with Cryptonly as the facilitator. Register it once, then
17
+ * mark paid handlers with `@X402()`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * @Module({
22
+ * imports: [
23
+ * X402Module.forRoot({ apiKey: process.env.CRYPTONLY_API_KEY!, isGlobal: true }),
24
+ * ],
25
+ * })
26
+ * export class AppModule {}
27
+ * ```
28
+ */
29
+ let X402Module = class X402Module extends x402_options_js_1.X402ConfigurableModule {
30
+ };
31
+ exports.X402Module = X402Module;
32
+ exports.X402Module = X402Module = __decorate([
33
+ (0, common_1.Module)({
34
+ imports: [core_1.DiscoveryModule],
35
+ providers: [x402_service_js_1.X402Service, x402_interceptor_js_1.X402Interceptor],
36
+ exports: [x402_service_js_1.X402Service, x402_interceptor_js_1.X402Interceptor],
37
+ })
38
+ ], X402Module);
39
+ //# sourceMappingURL=x402.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.module.js","sourceRoot":"","sources":["../src/x402.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,uCAA+C;AAC/C,+DAAwD;AACxD,uDAA2D;AAC3D,uDAAgD;AAEhD;;;;;;;;;;;;;GAaG;AAMI,IAAM,UAAU,GAAhB,MAAM,UAAW,SAAQ,wCAAsB;CAAG,CAAA;AAA5C,gCAAU;qBAAV,UAAU;IALtB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,sBAAe,CAAC;QAC1B,SAAS,EAAE,CAAC,6BAAW,EAAE,qCAAe,CAAC;QACzC,OAAO,EAAE,CAAC,6BAAW,EAAE,qCAAe,CAAC;KACxC,CAAC;GACW,UAAU,CAAkC"}
@@ -0,0 +1,37 @@
1
+ import type { X402RouteSourceOptions } from '@cryptonly/x402';
2
+ /** Options for `X402Module.forRoot()` and `forRootAsync()`. */
3
+ export type X402ModuleOptions = X402RouteSourceOptions & {
4
+ /**
5
+ * Await the dashboard configuration during application bootstrap, so a bad
6
+ * key or an inactive account fails startup. Defaults to `false`: it loads
7
+ * on the first paid request, which answers 503 until it does.
8
+ */
9
+ waitForConfig?: boolean;
10
+ };
11
+ export declare const X402ConfigurableModule: import("@nestjs/common").ConfigurableModuleCls<X402ModuleOptions, "forRoot", "create", {
12
+ isGlobal: boolean;
13
+ }>, X402_MODULE_OPTIONS: string | symbol, X402_OPTIONS_TYPE: import("@cryptonly/x402").CryptonlyFacilitatorConfig & {
14
+ refreshIntervalMs?: number;
15
+ schemes?: readonly import("@x402/core/types").SchemeNetworkServer[];
16
+ svmSchemes?: readonly import("@x402/core/types").SchemeNetworkServer[];
17
+ fetch?: typeof fetch;
18
+ retryAfterMs?: number;
19
+ logger?: import("@cryptonly/x402").X402Logger;
20
+ extensions?: import("@cryptonly/x402").X402ExtensionsModule | null;
21
+ } & {
22
+ /**
23
+ * Await the dashboard configuration during application bootstrap, so a bad
24
+ * key or an inactive account fails startup. Defaults to `false`: it loads
25
+ * on the first paid request, which answers 503 until it does.
26
+ */
27
+ waitForConfig?: boolean;
28
+ } & Partial<{
29
+ isGlobal: boolean;
30
+ }>, X402_ASYNC_OPTIONS_TYPE: import("@nestjs/common").ConfigurableModuleAsyncOptions<X402ModuleOptions, "create"> & Partial<{
31
+ isGlobal: boolean;
32
+ }>;
33
+ /** Metadata key of {@link X402} on handlers and controllers. */
34
+ export declare const X402_ROUTE_METADATA = "cryptonly:x402:route";
35
+ /** Where the interceptor puts the verified payment on the request. */
36
+ export declare const X402_PAYMENT: unique symbol;
37
+ //# sourceMappingURL=x402.options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.options.d.ts","sourceRoot":"","sources":["../src/x402.options.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAE9D,+DAA+D;AAC/D,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,GAAG;IACvD;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MACoB,sBAAsB;;IACzB,mBAAmB,mBAC3B,iBAAiB;;;;;;;;;IAX/B;;;;OAIG;oBACa,OAAO;;;IAOH,uBAAuB;;EAOnC,CAAC;AAEX,gEAAgE;AAChE,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,sEAAsE;AACtE,eAAO,MAAM,YAAY,eAAuC,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var _a;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.X402_PAYMENT = exports.X402_ROUTE_METADATA = exports.X402_ASYNC_OPTIONS_TYPE = exports.X402_OPTIONS_TYPE = exports.X402_MODULE_OPTIONS = exports.X402ConfigurableModule = void 0;
5
+ const common_1 = require("@nestjs/common");
6
+ _a = new common_1.ConfigurableModuleBuilder()
7
+ .setClassMethodName('forRoot')
8
+ .setExtras({ isGlobal: false }, (definition, extras) => ({
9
+ ...definition,
10
+ global: extras.isGlobal,
11
+ }))
12
+ .build(), exports.X402ConfigurableModule = _a.ConfigurableModuleClass, exports.X402_MODULE_OPTIONS = _a.MODULE_OPTIONS_TOKEN, exports.X402_OPTIONS_TYPE = _a.OPTIONS_TYPE, exports.X402_ASYNC_OPTIONS_TYPE = _a.ASYNC_OPTIONS_TYPE;
13
+ /** Metadata key of {@link X402} on handlers and controllers. */
14
+ exports.X402_ROUTE_METADATA = 'cryptonly:x402:route';
15
+ /** Where the interceptor puts the verified payment on the request. */
16
+ exports.X402_PAYMENT = Symbol.for('cryptonly.x402.payment');
17
+ //# sourceMappingURL=x402.options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.options.js","sourceRoot":"","sources":["../src/x402.options.ts"],"names":[],"mappings":";;;;AAAA,2CAA2D;AAa9C,KAKT,IAAI,kCAAyB,EAAqB;KACnD,kBAAkB,CAAC,SAAS,CAAC;KAC7B,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACvD,GAAG,UAAU;IACb,MAAM,EAAE,MAAM,CAAC,QAAQ;CACxB,CAAC,CAAC;KACF,KAAK,EAAE,EAViB,8BAAsB,+BACzB,2BAAmB,4BAC3B,yBAAiB,oBACX,+BAAuB,yBAOlC;AAEX,gEAAgE;AACnD,QAAA,mBAAmB,GAAG,sBAAsB,CAAC;AAE1D,sEAAsE;AACzD,QAAA,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { type OnApplicationBootstrap, type OnModuleDestroy } from '@nestjs/common';
2
+ import { DiscoveryService, MetadataScanner, Reflector } from '@nestjs/core';
3
+ import { x402HTTPResourceServer, type RouteConfig, type RoutesConfig } from '@x402/core/server';
4
+ import { type CryptonlyFacilitatorClient, type X402Logger } from '@cryptonly/x402';
5
+ import { type X402ModuleOptions } from './x402.options.js';
6
+ /** A resource server ready to process requests for one set of routes. */
7
+ export type PreparedServer = {
8
+ readonly httpServer: x402HTTPResourceServer;
9
+ /** Syncs the facilitator's `/supported` once, and the bazaar extension. */
10
+ prepare(): Promise<void>;
11
+ /** The payer the facilitator verified for a payment payload. */
12
+ payerOf(payload: object): string | undefined;
13
+ };
14
+ /**
15
+ * The dashboard routes of the account, kept fresh, and the resource servers
16
+ * that `@X402()` handlers are paid through.
17
+ */
18
+ export declare class X402Service implements OnApplicationBootstrap, OnModuleDestroy {
19
+ private readonly options;
20
+ private readonly discovery;
21
+ private readonly scanner;
22
+ private readonly reflector;
23
+ readonly logger: X402Logger;
24
+ private readonly source;
25
+ private readonly inCode;
26
+ private decorated;
27
+ private readonly warned;
28
+ constructor(options: X402ModuleOptions, discovery: DiscoveryService, scanner: MetadataScanner, reflector: Reflector);
29
+ /** The facilitator client, for calls of your own (`/verify`, `/settle`, discovery). */
30
+ get facilitator(): CryptonlyFacilitatorClient;
31
+ /** For `Retry-After` while the configuration is unavailable. */
32
+ get retryAfterMs(): number;
33
+ /**
34
+ * Loads the dashboard configuration now (if not loaded yet) and starts
35
+ * refreshing. Rejects when the first load fails.
36
+ */
37
+ ready(): Promise<void>;
38
+ /** Reloads the configuration now. Resolves `true` when the routes changed. */
39
+ refresh(): Promise<boolean>;
40
+ /** The dashboard routes in use, or `undefined` before the first successful load. */
41
+ routes(): RoutesConfig | undefined;
42
+ onApplicationBootstrap(): Promise<void>;
43
+ onModuleDestroy(): void;
44
+ /** The server for dashboard-priced routes, or `undefined` while the configuration is unavailable. */
45
+ dashboardServer(): Promise<PreparedServer | undefined>;
46
+ /** The server for a handler priced in code, built on first use. */
47
+ inCodeServer(handler: object, route: RouteConfig): PreparedServer;
48
+ /** Logs, once per route, that a dashboard-priced handler has no dashboard price. */
49
+ warnUnpriced(method: string, path: string): void;
50
+ private prepared;
51
+ /** The `@X402()` handlers, with their controller and method paths. */
52
+ private discoverDecorated;
53
+ /**
54
+ * Warns about mismatches between the dashboard and the `@X402()` handlers.
55
+ * A handler's path matches a dashboard path that ends with it, so a global
56
+ * prefix or a version segment is allowed for.
57
+ */
58
+ private checkRoutes;
59
+ private warnOnce;
60
+ }
61
+ //# sourceMappingURL=x402.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.service.d.ts","sourceRoot":"","sources":["../src/x402.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC5E,OAAO,EAEL,sBAAsB,EAEtB,KAAK,WAAW,EAChB,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAKL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EAEhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAA4C,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAErG,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;IAC5C,2EAA2E;IAC3E,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,gEAAgE;IAChE,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC9C,CAAC;AAuBF;;;GAGG;AACH,qBACa,WAAY,YAAW,sBAAsB,EAAE,eAAe;IAQ1C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACrD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAV5B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkC;IACzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;gBAGI,OAAO,EAAE,iBAAiB,EACvD,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,SAAS;IAyBvC,uFAAuF;IACvF,IAAI,WAAW,IAAI,0BAA0B,CAE5C;IAED,gEAAgE;IAChE,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,8EAA8E;IAC9E,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAI3B,oFAAoF;IACpF,MAAM,IAAI,YAAY,GAAG,SAAS;IAI5B,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAS7C,eAAe,IAAI,IAAI;IAIvB,qGAAqG;IAC/F,eAAe,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC;IAW5D,mEAAmE;IACnE,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,cAAc;IAejE,oFAAoF;IACpF,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAOhD,OAAO,CAAC,QAAQ;IA0BhB,sEAAsE;IACtE,OAAO,CAAC,iBAAiB;IA2BzB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,QAAQ;CAKjB"}
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.X402Service = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const constants_1 = require("@nestjs/common/constants");
18
+ const core_1 = require("@nestjs/core");
19
+ const server_1 = require("@x402/core/server");
20
+ const x402_1 = require("@cryptonly/x402");
21
+ const x402_options_js_1 = require("./x402.options.js");
22
+ let bazaarModule;
23
+ function loadBazaar() {
24
+ if (bazaarModule === undefined) {
25
+ try {
26
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
27
+ bazaarModule = require('@x402/extensions/bazaar');
28
+ }
29
+ catch {
30
+ bazaarModule = null;
31
+ }
32
+ }
33
+ return bazaarModule;
34
+ }
35
+ /**
36
+ * The dashboard routes of the account, kept fresh, and the resource servers
37
+ * that `@X402()` handlers are paid through.
38
+ */
39
+ let X402Service = class X402Service {
40
+ options;
41
+ discovery;
42
+ scanner;
43
+ reflector;
44
+ logger;
45
+ source;
46
+ inCode = new Map();
47
+ decorated;
48
+ warned = new Set();
49
+ constructor(options, discovery, scanner, reflector) {
50
+ this.options = options;
51
+ this.discovery = discovery;
52
+ this.scanner = scanner;
53
+ this.reflector = reflector;
54
+ const nest = new common_1.Logger('X402');
55
+ this.logger = options.logger ?? {
56
+ info: (message) => nest.log(message),
57
+ warn: (message) => nest.warn(message),
58
+ error: (message) => nest.error(message),
59
+ };
60
+ this.source = (0, x402_1.createX402RouteSource)({ ...options, logger: this.logger }, (routes, config) => {
61
+ const server = this.prepared((0, x402_1.createResourceServer)(config, this.source.facilitator, this.source.schemes, this.source.svmSchemes), routes);
62
+ // Sync `/supported` in the background, as the stock middleware does.
63
+ server.prepare().catch(() => { });
64
+ this.checkRoutes(routes);
65
+ return server;
66
+ });
67
+ }
68
+ /** The facilitator client, for calls of your own (`/verify`, `/settle`, discovery). */
69
+ get facilitator() {
70
+ return this.source.facilitator;
71
+ }
72
+ /** For `Retry-After` while the configuration is unavailable. */
73
+ get retryAfterMs() {
74
+ return this.source.retryAfterMs;
75
+ }
76
+ /**
77
+ * Loads the dashboard configuration now (if not loaded yet) and starts
78
+ * refreshing. Rejects when the first load fails.
79
+ */
80
+ ready() {
81
+ return this.source.ready();
82
+ }
83
+ /** Reloads the configuration now. Resolves `true` when the routes changed. */
84
+ refresh() {
85
+ return this.source.refresh();
86
+ }
87
+ /** The dashboard routes in use, or `undefined` before the first successful load. */
88
+ routes() {
89
+ return this.source.current()?.routes;
90
+ }
91
+ async onApplicationBootstrap() {
92
+ this.decorated = this.discoverDecorated();
93
+ if (this.options.waitForConfig && this.decorated.some((route) => !route.priceInCode)) {
94
+ await this.source.ready();
95
+ }
96
+ const current = this.source.current();
97
+ if (current)
98
+ this.checkRoutes(current.routes);
99
+ }
100
+ onModuleDestroy() {
101
+ this.source.close();
102
+ }
103
+ /** The server for dashboard-priced routes, or `undefined` while the configuration is unavailable. */
104
+ async dashboardServer() {
105
+ if (!this.source.current()) {
106
+ try {
107
+ await this.source.ready();
108
+ }
109
+ catch {
110
+ return undefined;
111
+ }
112
+ }
113
+ return this.source.current()?.value;
114
+ }
115
+ /** The server for a handler priced in code, built on first use. */
116
+ inCodeServer(handler, route) {
117
+ let server = this.inCode.get(handler);
118
+ if (!server) {
119
+ const resourceServer = new server_1.x402ResourceServer(this.source.facilitator);
120
+ const accepts = Array.isArray(route.accepts) ? route.accepts : [route.accepts];
121
+ for (const network of new Set(accepts.map((option) => option.network))) {
122
+ const schemes = (0, x402_1.isSolanaNetwork)(network) ? this.source.svmSchemes : this.source.schemes;
123
+ for (const scheme of schemes)
124
+ resourceServer.register(network, scheme);
125
+ }
126
+ server = this.prepared(resourceServer, route);
127
+ this.inCode.set(handler, server);
128
+ }
129
+ return server;
130
+ }
131
+ /** Logs, once per route, that a dashboard-priced handler has no dashboard price. */
132
+ warnUnpriced(method, path) {
133
+ this.warnOnce(`${x402_1.X402_LOG_PREFIX} @X402() on ${method} ${path} has no dashboard price; ` +
134
+ 'it answers 503 until one is added');
135
+ }
136
+ prepared(resourceServer, routes) {
137
+ const httpServer = new server_1.x402HTTPResourceServer(resourceServer, routes);
138
+ const payers = new WeakMap();
139
+ resourceServer.onAfterVerify(async ({ paymentPayload, result }) => {
140
+ if (result.payer)
141
+ payers.set(paymentPayload, result.payer);
142
+ });
143
+ let initialized;
144
+ const prepare = () => {
145
+ initialized ??= (async () => {
146
+ await httpServer.initialize();
147
+ if (!(0, server_1.checkIfBazaarNeeded)(routes))
148
+ return;
149
+ const bazaar = loadBazaar();
150
+ if (!bazaar)
151
+ return;
152
+ if (!resourceServer.hasExtension('bazaar')) {
153
+ resourceServer.registerExtension(bazaar.bazaarResourceServerExtension);
154
+ }
155
+ bazaar.validateBazaarRouteExtensions(routes);
156
+ })().catch((error) => {
157
+ initialized = undefined;
158
+ throw error;
159
+ });
160
+ return initialized;
161
+ };
162
+ return { httpServer, prepare, payerOf: (payload) => payers.get(payload) };
163
+ }
164
+ /** The `@X402()` handlers, with their controller and method paths. */
165
+ discoverDecorated() {
166
+ const routes = [];
167
+ for (const wrapper of this.discovery.getControllers()) {
168
+ const { instance, metatype } = wrapper;
169
+ if (!instance || !metatype)
170
+ continue;
171
+ const prototype = Object.getPrototypeOf(instance);
172
+ const controllerPaths = asArray(Reflect.getMetadata(constants_1.PATH_METADATA, metatype) ?? '/');
173
+ for (const name of this.scanner.getAllMethodNames(prototype)) {
174
+ const handler = prototype[name];
175
+ const meta = this.reflector.getAllAndOverride(x402_options_js_1.X402_ROUTE_METADATA, [handler, metatype]);
176
+ const methodPath = Reflect.getMetadata(constants_1.PATH_METADATA, handler);
177
+ if (!meta || methodPath === undefined)
178
+ continue;
179
+ const requestMethod = Reflect.getMetadata(constants_1.METHOD_METADATA, handler);
180
+ const method = requestMethod === common_1.RequestMethod.ALL ? '*' : common_1.RequestMethod[requestMethod];
181
+ for (const controllerPath of controllerPaths) {
182
+ for (const path of asArray(methodPath)) {
183
+ routes.push({ method, path: joinPath(controllerPath, path), priceInCode: !!meta.route });
184
+ }
185
+ }
186
+ }
187
+ }
188
+ return routes;
189
+ }
190
+ /**
191
+ * Warns about mismatches between the dashboard and the `@X402()` handlers.
192
+ * A handler's path matches a dashboard path that ends with it, so a global
193
+ * prefix or a version segment is allowed for.
194
+ */
195
+ checkRoutes(routes) {
196
+ if (!this.decorated)
197
+ return;
198
+ const dashboard = Object.keys(routes).map(parseRouteKey);
199
+ const decorated = this.decorated.filter((route) => !route.priceInCode);
200
+ const serves = (handler, priced) => (handler.method === '*' || priced.method === '*' || handler.method === priced.method) &&
201
+ endsWithSegments(priced.path, handler.path);
202
+ for (const priced of dashboard) {
203
+ if (!decorated.some((handler) => serves(handler, priced))) {
204
+ this.warnOnce(`${x402_1.X402_LOG_PREFIX} the dashboard prices ${priced.method} ${priced.path}, ` +
205
+ 'but no @X402() handler serves it: this app serves it for free');
206
+ }
207
+ }
208
+ for (const handler of decorated) {
209
+ if (!dashboard.some((priced) => serves(handler, priced))) {
210
+ this.warnUnpriced(handler.method, handler.path);
211
+ }
212
+ }
213
+ }
214
+ warnOnce(message) {
215
+ if (this.warned.has(message))
216
+ return;
217
+ this.warned.add(message);
218
+ this.logger.warn(message);
219
+ }
220
+ };
221
+ exports.X402Service = X402Service;
222
+ exports.X402Service = X402Service = __decorate([
223
+ (0, common_1.Injectable)(),
224
+ __param(0, (0, common_1.Inject)(x402_options_js_1.X402_MODULE_OPTIONS)),
225
+ __metadata("design:paramtypes", [Object, core_1.DiscoveryService,
226
+ core_1.MetadataScanner,
227
+ core_1.Reflector])
228
+ ], X402Service);
229
+ function asArray(value) {
230
+ return Array.isArray(value) ? value : [value];
231
+ }
232
+ function segments(path) {
233
+ return path.split('/').filter(Boolean);
234
+ }
235
+ function joinPath(...parts) {
236
+ return `/${parts.flatMap(segments).join('/')}`;
237
+ }
238
+ /** `GET /a/b` → `{ GET, /a/b }`; a bare path matches any method. */
239
+ function parseRouteKey(key) {
240
+ const [first, ...rest] = key.trim().split(/\s+/);
241
+ return rest.length > 0
242
+ ? { method: first.toUpperCase(), path: joinPath(rest.join(' ')), priceInCode: false }
243
+ : { method: '*', path: joinPath(first), priceInCode: false };
244
+ }
245
+ function endsWithSegments(path, suffix) {
246
+ const whole = segments(path);
247
+ const tail = segments(suffix);
248
+ if (tail.length > whole.length)
249
+ return false;
250
+ const offset = whole.length - tail.length;
251
+ return tail.every((segment, index) => {
252
+ const other = whole[offset + index];
253
+ // `:param` in either path matches any one segment.
254
+ return segment === other || segment.startsWith(':') || other.startsWith(':');
255
+ });
256
+ }
257
+ //# sourceMappingURL=x402.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x402.service.js","sourceRoot":"","sources":["../src/x402.service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,90 @@
1
1
  {
2
2
  "name": "@cryptonly/x402-nestjs",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.5.0",
4
+ "description": "NestJS module and decorators for x402 payments with Cryptonly as the facilitator. Works on the Express and Fastify platforms.",
5
+ "license": "MIT",
6
+ "private": false,
7
+ "type": "commonjs",
8
+ "sideEffects": false,
9
+ "engines": {
10
+ "node": ">=18"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/cryptonly-net/x402.git",
15
+ "directory": "typescript/packages/x402-nestjs"
16
+ },
17
+ "homepage": "https://github.com/cryptonly-net/x402/tree/main/typescript/packages/x402-nestjs#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/cryptonly-net/x402/issues"
20
+ },
21
+ "keywords": [
22
+ "cryptonly",
23
+ "x402",
24
+ "facilitator",
25
+ "payments",
26
+ "nestjs",
27
+ "nest",
28
+ "decorators"
29
+ ],
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js",
36
+ "require": "./dist/index.js",
37
+ "default": "./dist/index.js"
38
+ },
39
+ "./package.json": "./package.json"
40
+ },
41
+ "files": [
42
+ "dist"
43
+ ],
44
+ "scripts": {
45
+ "build": "tsc -p tsconfig.build.json",
46
+ "clean": "rm -rf dist",
47
+ "prepublishOnly": "npm run build",
48
+ "test": "jest",
49
+ "typecheck": "tsc -p tsconfig.json"
50
+ },
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "dependencies": {
55
+ "@cryptonly/x402": "0.5.0"
56
+ },
57
+ "peerDependencies": {
58
+ "@nestjs/common": "^10 || ^11",
59
+ "@nestjs/core": "^10 || ^11",
60
+ "@x402/core": "^2",
61
+ "@x402/evm": "^2",
62
+ "@x402/extensions": "^2",
63
+ "@x402/svm": "^2",
64
+ "reflect-metadata": "^0.1.13 || ^0.2",
65
+ "rxjs": "^7"
66
+ },
67
+ "peerDependenciesMeta": {
68
+ "@x402/extensions": {
69
+ "optional": true
70
+ },
71
+ "@x402/svm": {
72
+ "optional": true
73
+ }
74
+ },
75
+ "devDependencies": {
76
+ "@x402/core": "^2.28.0",
77
+ "@x402/evm": "^2.28.0",
78
+ "@x402/extensions": "^2.28.0",
79
+ "@x402/svm": "^2.28.0",
80
+ "@nestjs/common": "11.1.11",
81
+ "@nestjs/core": "11.1.11",
82
+ "@nestjs/platform-express": "11.1.11",
83
+ "@nestjs/platform-fastify": "11.1.11",
84
+ "@nestjs/config": "^4.0.2",
85
+ "class-validator": "^0.14.2",
86
+ "class-transformer": "^0.5.1",
87
+ "reflect-metadata": "0.2.2",
88
+ "rxjs": "7.8.2"
89
+ }
90
+ }