@cryptonly/x402-express 0.0.0-stage → 0.6.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 +87 -2
- package/dist/index.d.ts +73 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -0
- package/package.json +84 -4
package/README.md
CHANGED
|
@@ -1,3 +1,88 @@
|
|
|
1
|
-
|
|
1
|
+
<img src="https://raw.githubusercontent.com/cryptonly-net/.github/main/profile/assets/header-banner.svg" alt="Cryptonly" width="100%" />
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
# Cryptonly x402 for Express
|
|
6
|
+
|
|
7
|
+
Accept x402 payments in Express, 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. Your prices live in the Cryptonly dashboard, so a price change needs no deploy.
|
|
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-express @x402/core @x402/express @x402/evm express
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Use
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import express from 'express';
|
|
29
|
+
import { cryptonlyPaymentMiddleware } from '@cryptonly/x402-express';
|
|
30
|
+
|
|
31
|
+
const app = express();
|
|
32
|
+
app.get('/health', (_req, res) => res.send('ok')); // free routes go first
|
|
33
|
+
|
|
34
|
+
const payments = cryptonlyPaymentMiddleware({ apiKey: process.env.CRYPTONLY_API_KEY! });
|
|
35
|
+
app.use(payments);
|
|
36
|
+
|
|
37
|
+
// Priced in the dashboard as GET /weather/:city
|
|
38
|
+
app.get('/weather/:city', (req, res) => {
|
|
39
|
+
res.json({ city: req.params.city, temperatureC: 21 });
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
await payments.ready(); // fails at startup if the prices can't load
|
|
43
|
+
app.listen(4021);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
It reloads your prices every minute and fails closed, so a paid route is never served for free:
|
|
47
|
+
|
|
48
|
+
- 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.
|
|
49
|
+
- If a later reload fails, it keeps the last good prices and logs a warning.
|
|
50
|
+
|
|
51
|
+
The buyer is charged only when the handler succeeds. A `4xx`/`5xx` response or a thrown error cancels the payment.
|
|
52
|
+
|
|
53
|
+
## Options
|
|
54
|
+
|
|
55
|
+
| Option | Default | |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `apiKey` | required | Your Cryptonly API key. |
|
|
58
|
+
| `sandbox` | `false` | Use the sandbox. |
|
|
59
|
+
| `baseUrl` | production | Another API origin. Takes precedence over `sandbox`. |
|
|
60
|
+
| `refreshIntervalMs` | `60000` | How often to reload prices. `0` turns it off. |
|
|
61
|
+
| `retryAfterMs` | `5000` | After a failed first load, how long to answer `503` before the next try. |
|
|
62
|
+
| `schemes` | `[new ExactEvmScheme()]` | Schemes for Base. |
|
|
63
|
+
| `svmSchemes` | `[new ExactSvmScheme()]` if `@x402/svm` is installed | Schemes for Solana. |
|
|
64
|
+
| `logger` | `console` | Gets reload failures and skipped routes. |
|
|
65
|
+
| `paywallConfig` | — | Passed to the stock `paymentMiddleware`. |
|
|
66
|
+
| `createMiddleware` | stock `paymentMiddleware` | Builds the inner middleware, for example to add hooks. |
|
|
67
|
+
|
|
68
|
+
The middleware also has `ready()`, `refresh()`, `routes()` and `close()`.
|
|
69
|
+
|
|
70
|
+
On NestJS, use [`@cryptonly/x402-nestjs`](https://www.npmjs.com/package/@cryptonly/x402-nestjs) for decorators. This middleware also works there, applied with `consumer.apply(payments).forRoutes(...)`.
|
|
71
|
+
|
|
72
|
+
## Solana
|
|
73
|
+
|
|
74
|
+
Install `@x402/svm` and `@solana/kit`, and add a Solana payout wallet in the dashboard. Solana prices then work with no other change.
|
|
75
|
+
|
|
76
|
+
## Sandbox
|
|
77
|
+
|
|
78
|
+
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.
|
|
79
|
+
|
|
80
|
+
## Learn more
|
|
81
|
+
|
|
82
|
+
- [x402 quickstart](https://docs.cryptonly.net/guides/x402/quickstart/)
|
|
83
|
+
- [Discovery](https://docs.cryptonly.net/guides/x402/discovery/): list your endpoints for AI agents
|
|
84
|
+
- [Reference](https://docs.cryptonly.net/guides/x402/reference/): key scopes, limits and reason codes
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
[MIT](https://github.com/cryptonly-net/x402/blob/main/LICENSE)
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from 'express';
|
|
2
|
+
import type { RoutesConfig } from '@x402/core/server';
|
|
3
|
+
import type { SchemeNetworkServer } from '@x402/core/types';
|
|
4
|
+
import { type PaywallConfig } from '@x402/express';
|
|
5
|
+
import { type CryptonlyFacilitatorClient, type X402Config, type X402Logger, type X402RouteSourceOptions } from '@cryptonly/x402';
|
|
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 = X402Logger;
|
|
26
|
+
/** Options for {@link cryptonlyPaymentMiddleware}. */
|
|
27
|
+
export type CryptonlyPaymentMiddlewareOptions = X402RouteSourceOptions & {
|
|
28
|
+
/** Passed to the stock `paymentMiddleware` for the browser paywall. */
|
|
29
|
+
paywallConfig?: PaywallConfig;
|
|
30
|
+
/** Builds the inner middleware. See {@link InnerMiddlewareFactory}. */
|
|
31
|
+
createMiddleware?: InnerMiddlewareFactory;
|
|
32
|
+
};
|
|
33
|
+
/** The middleware returned by {@link cryptonlyPaymentMiddleware}. */
|
|
34
|
+
export type CryptonlyPaymentMiddleware = ((req: Request, res: Response, next: NextFunction) => Promise<void>) & {
|
|
35
|
+
/**
|
|
36
|
+
* Loads the configuration now (if not loaded yet) and starts refreshing.
|
|
37
|
+
* Rejects when the first load fails. Await it before `listen` to fail
|
|
38
|
+
* fast at startup.
|
|
39
|
+
*/
|
|
40
|
+
ready(): Promise<void>;
|
|
41
|
+
/** Reloads the configuration now. Resolves `true` when the routes changed. */
|
|
42
|
+
refresh(): Promise<boolean>;
|
|
43
|
+
/** The routes in use, or `undefined` before the first successful load. */
|
|
44
|
+
routes(): RoutesConfig | undefined;
|
|
45
|
+
/** Stops refreshing. The last routes stay in use. */
|
|
46
|
+
close(): void;
|
|
47
|
+
};
|
|
48
|
+
/** The default {@link InnerMiddlewareFactory}: stock `@x402/express`. */
|
|
49
|
+
export declare const stockPaymentMiddleware: InnerMiddlewareFactory;
|
|
50
|
+
/**
|
|
51
|
+
* Express middleware whose paid routes and prices come from the Cryptonly
|
|
52
|
+
* dashboard (`GET /x402/config`), refreshed every minute, so a price change
|
|
53
|
+
* reaches production without a deploy.
|
|
54
|
+
*
|
|
55
|
+
* - The configuration loads on the first request (or on `ready()`), once.
|
|
56
|
+
* - Each refresh rebuilds the stock `@x402/express` middleware only when the
|
|
57
|
+
* routes changed. A failed refresh keeps the last good routes.
|
|
58
|
+
* - Until a first load succeeds, every request through it answers 503
|
|
59
|
+
* (fail closed): paid endpoints are never served for free. Mount it after
|
|
60
|
+
* health checks and other free routes.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```ts
|
|
64
|
+
* import { cryptonlyPaymentMiddleware } from '@cryptonly/x402-express';
|
|
65
|
+
*
|
|
66
|
+
* app.use(cryptonlyPaymentMiddleware({ apiKey: process.env.CRYPTONLY_API_KEY! }));
|
|
67
|
+
* app.get('/weather', (req, res) => res.json({ temperatureC: 21 }));
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function cryptonlyPaymentMiddleware(options: CryptonlyPaymentMiddlewareOptions): CryptonlyPaymentMiddleware;
|
|
71
|
+
export { fetchX402Config, routesFromConfig } from '@cryptonly/x402';
|
|
72
|
+
export type { X402Config } from '@cryptonly/x402';
|
|
73
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.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;AACtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAIL,KAAK,0BAA0B,EAC/B,KAAK,UAAU,EACf,KAAK,UAAU,EAEf,KAAK,sBAAsB,EAC5B,MAAM,iBAAiB,CAAC;AAEzB,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,UAAU,CAAC;AAEnD,sDAAsD;AACtD,MAAM,MAAM,iCAAiC,GAAG,sBAAsB,GAAG;IACvE,uEAAuE;IACvE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,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;AAEF,yEAAyE;AACzE,eAAO,MAAM,sBAAsB,EAAE,sBAQlC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,iCAAiC,GACzC,0BAA0B,CAmC5B;AAED,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,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.routesFromConfig = exports.fetchX402Config = exports.stockPaymentMiddleware = void 0;
|
|
4
|
+
exports.cryptonlyPaymentMiddleware = cryptonlyPaymentMiddleware;
|
|
5
|
+
const express_1 = require("@x402/express");
|
|
6
|
+
const x402_1 = require("@cryptonly/x402");
|
|
7
|
+
/** The default {@link InnerMiddlewareFactory}: stock `@x402/express`. */
|
|
8
|
+
const stockPaymentMiddleware = (routes, { config, facilitator, schemes, svmSchemes, paywallConfig }) => (0, express_1.paymentMiddleware)(routes, (0, x402_1.createResourceServer)(config, facilitator, schemes, svmSchemes), paywallConfig);
|
|
9
|
+
exports.stockPaymentMiddleware = stockPaymentMiddleware;
|
|
10
|
+
/**
|
|
11
|
+
* Express middleware whose paid routes and prices come from the Cryptonly
|
|
12
|
+
* dashboard (`GET /x402/config`), refreshed every minute, so a price change
|
|
13
|
+
* reaches production without a deploy.
|
|
14
|
+
*
|
|
15
|
+
* - The configuration loads on the first request (or on `ready()`), once.
|
|
16
|
+
* - Each refresh rebuilds the stock `@x402/express` middleware only when the
|
|
17
|
+
* routes changed. A failed refresh keeps the last good routes.
|
|
18
|
+
* - Until a first load succeeds, every request through it answers 503
|
|
19
|
+
* (fail closed): paid endpoints are never served for free. Mount it after
|
|
20
|
+
* health checks and other free routes.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { cryptonlyPaymentMiddleware } from '@cryptonly/x402-express';
|
|
25
|
+
*
|
|
26
|
+
* app.use(cryptonlyPaymentMiddleware({ apiKey: process.env.CRYPTONLY_API_KEY! }));
|
|
27
|
+
* app.get('/weather', (req, res) => res.json({ temperatureC: 21 }));
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
function cryptonlyPaymentMiddleware(options) {
|
|
31
|
+
const createMiddleware = options.createMiddleware ?? exports.stockPaymentMiddleware;
|
|
32
|
+
const source = (0, x402_1.createX402RouteSource)(options, (routes, config) => createMiddleware(routes, {
|
|
33
|
+
config,
|
|
34
|
+
facilitator: source.facilitator,
|
|
35
|
+
schemes: source.schemes,
|
|
36
|
+
svmSchemes: source.svmSchemes,
|
|
37
|
+
...(options.paywallConfig ? { paywallConfig: options.paywallConfig } : {}),
|
|
38
|
+
}));
|
|
39
|
+
const middleware = async (req, res, next) => {
|
|
40
|
+
if (!source.current()) {
|
|
41
|
+
try {
|
|
42
|
+
await source.ready();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
if (!res.headersSent) {
|
|
46
|
+
res.setHeader('Retry-After', String(Math.ceil(source.retryAfterMs / 1000)));
|
|
47
|
+
res.status(503).json(x402_1.X402_CONFIG_UNAVAILABLE);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
await source.current().value(req, res, next);
|
|
53
|
+
};
|
|
54
|
+
return Object.assign(middleware, {
|
|
55
|
+
ready: source.ready,
|
|
56
|
+
refresh: source.refresh,
|
|
57
|
+
routes: () => source.current()?.routes,
|
|
58
|
+
close: source.close,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
var x402_2 = require("@cryptonly/x402");
|
|
62
|
+
Object.defineProperty(exports, "fetchX402Config", { enumerable: true, get: function () { return x402_2.fetchX402Config; } });
|
|
63
|
+
Object.defineProperty(exports, "routesFromConfig", { enumerable: true, get: function () { return x402_2.routesFromConfig; } });
|
|
64
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAyGA,gEAqCC;AA3ID,2CAAsE;AACtE,0CASyB;AA6DzB,yEAAyE;AAClE,MAAM,sBAAsB,GAA2B,CAC5D,MAAM,EACN,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,EAC3D,EAAE,CACF,IAAA,2BAAiB,EACf,MAAM,EACN,IAAA,2BAAoB,EAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,CAAC,EAC9D,aAAa,CACd,CAAC;AARS,QAAA,sBAAsB,0BAQ/B;AAEJ;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,0BAA0B,CACxC,OAA0C;IAE1C,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,8BAAsB,CAAC;IAC5E,MAAM,MAAM,GAAuC,IAAA,4BAAqB,EACtE,OAAO,EACP,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CACjB,gBAAgB,CAAC,MAAM,EAAE;QACvB,MAAM;QACN,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC,CACL,CAAC;IAEF,MAAM,UAAU,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QAC3E,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;oBACrB,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;oBAC5E,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,8BAAuB,CAAC,CAAC;gBAChD,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;QACD,MAAM,MAAM,CAAC,OAAO,EAAG,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;IAChD,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE;QAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,MAAM;QACtC,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC,CAAC;AACL,CAAC;AAED,wCAAoE;AAA3D,uGAAA,eAAe,OAAA;AAAE,wGAAA,gBAAgB,OAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,86 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cryptonly/x402-express",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.6.0",
|
|
4
|
+
"description": "Express middleware for x402 payments with Cryptonly as the facilitator; prices come from the Cryptonly dashboard.",
|
|
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-express"
|
|
16
|
+
},
|
|
17
|
+
"homepage": "https://github.com/cryptonly-net/x402/tree/main/typescript/packages/x402-express#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/cryptonly-net/x402/issues"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"cryptonly",
|
|
23
|
+
"x402",
|
|
24
|
+
"facilitator",
|
|
25
|
+
"payments",
|
|
26
|
+
"express",
|
|
27
|
+
"middleware"
|
|
28
|
+
],
|
|
29
|
+
"main": "./dist/index.js",
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.js",
|
|
35
|
+
"require": "./dist/index.js",
|
|
36
|
+
"default": "./dist/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./package.json": "./package.json"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsc -p tsconfig.build.json",
|
|
45
|
+
"clean": "rm -rf dist",
|
|
46
|
+
"prepublishOnly": "npm run build",
|
|
47
|
+
"test": "jest",
|
|
48
|
+
"typecheck": "tsc -p tsconfig.json"
|
|
49
|
+
},
|
|
50
|
+
"publishConfig": {
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@cryptonly/x402": "0.6.0"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@x402/core": "^2",
|
|
58
|
+
"@x402/evm": "^2",
|
|
59
|
+
"@x402/express": "^2",
|
|
60
|
+
"@x402/extensions": "^2",
|
|
61
|
+
"@x402/svm": "^2",
|
|
62
|
+
"express": "^4 || ^5"
|
|
63
|
+
},
|
|
64
|
+
"peerDependenciesMeta": {
|
|
65
|
+
"@x402/extensions": {
|
|
66
|
+
"optional": true
|
|
67
|
+
},
|
|
68
|
+
"@x402/svm": {
|
|
69
|
+
"optional": true
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@x402/core": "^2.28.0",
|
|
74
|
+
"@x402/evm": "^2.28.0",
|
|
75
|
+
"@x402/extensions": "^2.28.0",
|
|
76
|
+
"@x402/svm": "^2.28.0",
|
|
77
|
+
"@x402/express": "^2.28.0",
|
|
78
|
+
"@types/express": "^5.0.6",
|
|
79
|
+
"express": "^5.3.0",
|
|
80
|
+
"@nestjs/common": "11.1.11",
|
|
81
|
+
"@nestjs/core": "11.1.11",
|
|
82
|
+
"@nestjs/platform-express": "11.1.11",
|
|
83
|
+
"reflect-metadata": "0.2.2",
|
|
84
|
+
"rxjs": "7.8.2"
|
|
85
|
+
}
|
|
86
|
+
}
|