@lunora/x402 1.0.0-alpha.2 → 1.0.0-alpha.20
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 +2 -0
- package/dist/charge/index.d.mts +110 -47
- package/dist/charge/index.d.ts +110 -47
- package/dist/charge/index.mjs +1 -7
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -2
- package/dist/packem_shared/DEFAULT_ALLOWED_ASSETS-BIIP_mdG.mjs +1 -0
- package/dist/packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs +1 -0
- package/dist/packem_shared/EVM_NETWORKS-XOms9Rtk.mjs +1 -0
- package/dist/packem_shared/config.d-Dki_2r9a.d.mts +472 -0
- package/dist/packem_shared/config.d-Dki_2r9a.d.ts +472 -0
- package/dist/packem_shared/createChargeMiddleware-MQhSA6Wt.mjs +1 -0
- package/dist/packem_shared/createFacilitatorClient-Dj4Ll9xQ.mjs +1 -0
- package/dist/packem_shared/createPayFetch-B6A51xPI.mjs +1 -0
- package/dist/packem_shared/createProcedureChargeGate-Cfm5mD2y.mjs +1 -0
- package/dist/packem_shared/registerWallet-Cu4qF5tj.mjs +1 -0
- package/dist/packem_shared/toPaymentEventRow-D_kRVcb3.mjs +1 -0
- package/dist/packem_shared/withX402-D10895ct.mjs +1 -0
- package/dist/pay/index.d.mts +61 -43
- package/dist/pay/index.d.ts +61 -43
- package/dist/pay/index.mjs +1 -21
- package/package.json +8 -8
- package/dist/packem_shared/DEFAULT_FACILITATOR_URL-Cbz6kIqa.mjs +0 -4
- package/dist/packem_shared/DEFAULT_STABLECOIN_DECIMALS-CSu5b5lD.mjs +0 -85
- package/dist/packem_shared/EVM_NETWORKS-BhnYWUQ4.mjs +0 -26
- package/dist/packem_shared/config.d-CddwCiBm.d.mts +0 -325
- package/dist/packem_shared/config.d-CddwCiBm.d.ts +0 -325
- package/dist/packem_shared/createChargeMiddleware-BJkYJeFf.mjs +0 -148
- package/dist/packem_shared/createFacilitatorClient-rXHBnCZm.mjs +0 -16
- package/dist/packem_shared/createPayFetch-O2vkvM1v.mjs +0 -17
- package/dist/packem_shared/createProcedureChargeGate-CV8ITlQP.mjs +0 -19
- package/dist/packem_shared/registerWallet-I4pVwq65.mjs +0 -109
- package/dist/packem_shared/toPaymentEventRow-DW4O9N7Y.mjs +0 -22
- package/dist/packem_shared/withX402-rUq0voT8.mjs +0 -15
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @lunora/x402
|
|
2
2
|
|
|
3
|
+
> **Experimental** — this package is outside the Lunora 1.0 stability promise: its API may change in any release, without a major version bump.
|
|
4
|
+
|
|
3
5
|
> Agentic payments over the [x402](https://x402.org) protocol for [Lunora](https://lunora.sh).
|
|
4
6
|
|
|
5
7
|
x402 turns HTTP `402 Payment Required` into a machine-payable rail: no accounts,
|
package/dist/charge/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FacilitatorConfig, c as X402ChargeConfig, f as X402Price } from "../packem_shared/config.d-
|
|
2
|
-
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, type a as EvmAddress, type P as PaymentEventRow, type d as X402Network, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2,
|
|
1
|
+
import { F as FacilitatorConfig, c as X402ChargeConfig, f as X402Price } from "../packem_shared/config.d-Dki_2r9a.mjs";
|
|
2
|
+
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, type a as EvmAddress, type P as PaymentEventRow, type d as X402Network, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2, y as toPaymentEventRow, z as toReceipt } from "../packem_shared/config.d-Dki_2r9a.mjs";
|
|
3
3
|
import { HTTPFacilitatorClient } from '@x402/core/server';
|
|
4
4
|
import { RouteConfig } from '@x402/core/http';
|
|
5
5
|
import '@x402/evm';
|
|
@@ -7,51 +7,106 @@ import '@x402/svm';
|
|
|
7
7
|
import '@x402/core/client';
|
|
8
8
|
import '@x402/core/types';
|
|
9
9
|
/**
|
|
10
|
-
* Build an `@x402/core` facilitator client from Lunora's {@link FacilitatorConfig}.
|
|
11
|
-
*
|
|
12
|
-
* `config.headers` (e.g. a CDP bearer token) are applied to every facilitator
|
|
13
|
-
* call — `@x402/core` splits auth per endpoint (`verify` / `settle` /
|
|
14
|
-
* `supported`), so the same header map is handed to each. With no config the
|
|
15
|
-
* client points at the public {@link resolveFacilitatorUrl default} and sends no
|
|
16
|
-
* auth headers.
|
|
17
|
-
|
|
10
|
+
* Build an `@x402/core` facilitator client from Lunora's {@link FacilitatorConfig}.
|
|
11
|
+
*
|
|
12
|
+
* `config.headers` (e.g. a CDP bearer token) are applied to every facilitator
|
|
13
|
+
* call — `@x402/core` splits auth per endpoint (`verify` / `settle` /
|
|
14
|
+
* `supported`), so the same header map is handed to each. With no config the
|
|
15
|
+
* client points at the public {@link resolveFacilitatorUrl default} and sends no
|
|
16
|
+
* auth headers.
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
18
19
|
declare const createFacilitatorClient: (config?: FacilitatorConfig) => HTTPFacilitatorClient;
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A handler shaped like a Lunora HTTP action: `(context, request) => Response`.
|
|
22
|
+
* @experimental
|
|
23
|
+
*/
|
|
20
24
|
type HttpActionHandler<Context> = (context: Context, request: Request) => Promise<Response> | Response;
|
|
21
25
|
/**
|
|
22
|
-
* Gate `handler` behind an x402 paywall described by `config`. Returns a handler
|
|
23
|
-
* of the same shape, ready to pass to `httpAction`.
|
|
24
|
-
|
|
26
|
+
* Gate `handler` behind an x402 paywall described by `config`. Returns a handler
|
|
27
|
+
* of the same shape, ready to pass to `httpAction`.
|
|
28
|
+
* @experimental
|
|
29
|
+
*/
|
|
25
30
|
declare const withX402: <Context>(config: X402ChargeConfig, handler: HttpActionHandler<Context>) => HttpActionHandler<Context>;
|
|
26
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Runs the protected resource handler, producing the Response to gate.
|
|
33
|
+
* @experimental
|
|
34
|
+
*/
|
|
27
35
|
type ChargeHandler = () => Promise<Response> | Response;
|
|
28
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Per-request platform seams `handle` can use, beyond the request/handler pair.
|
|
38
|
+
* @experimental
|
|
39
|
+
*/
|
|
40
|
+
interface ChargeHandlerDeps {
|
|
41
|
+
/**
|
|
42
|
+
* Keep background work (the receipt sink) alive past the response — the
|
|
43
|
+
* request's `ctx.waitUntil`. Absent on paths with no platform execution
|
|
44
|
+
* context reaching the middleware (e.g. today's HTTP-action rail).
|
|
45
|
+
*/
|
|
46
|
+
readonly waitUntil?: (promise: Promise<unknown>) => void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A prepared, initialised paywall. Build once (it fetches facilitator support), reuse per request.
|
|
50
|
+
* @experimental
|
|
51
|
+
*/
|
|
29
52
|
interface ChargeMiddleware {
|
|
30
53
|
/** Gate `request`: challenge / verify / settle around `runHandler`. */
|
|
31
|
-
handle: (request: Request, runHandler: ChargeHandler) => Promise<Response>;
|
|
54
|
+
handle: (request: Request, runHandler: ChargeHandler, deps?: ChargeHandlerDeps) => Promise<Response>;
|
|
32
55
|
}
|
|
33
56
|
/**
|
|
34
|
-
* Route metadata a caller can layer onto the generated catch-all route. The
|
|
35
|
-
* procedure gate sets `resource` to the `functionPath` so the x402 challenge
|
|
36
|
-
* names the paid function (x402 core falls back to the request URL otherwise —
|
|
37
|
-
* every RPC POSTs to the same `/_lunora/rpc`, so the URL can't tell two paid
|
|
38
|
-
* procedures apart).
|
|
39
|
-
|
|
57
|
+
* Route metadata a caller can layer onto the generated catch-all route. The
|
|
58
|
+
* procedure gate sets `resource` to the `functionPath` so the x402 challenge
|
|
59
|
+
* names the paid function (x402 core falls back to the request URL otherwise —
|
|
60
|
+
* every RPC POSTs to the same `/_lunora/rpc`, so the URL can't tell two paid
|
|
61
|
+
* procedures apart).
|
|
62
|
+
* @experimental
|
|
63
|
+
*/
|
|
40
64
|
type ChargeRouteOverrides = Pick<RouteConfig, "description" | "resource">;
|
|
41
65
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
66
|
+
* Behaviour knobs for {@link createChargeMiddleware} beyond route metadata.
|
|
67
|
+
* @experimental
|
|
68
|
+
*/
|
|
69
|
+
interface ChargeMiddlewareOptions {
|
|
70
|
+
/**
|
|
71
|
+
* Settle the verified payment **before** dispatching `runHandler`, instead
|
|
72
|
+
* of after. Use this for a mutation/procedure gate: a settlement failure
|
|
73
|
+
* then means the handler never runs at all, so a paid mutation's writes can
|
|
74
|
+
* never be committed without payment (the free-execution gap X402-04
|
|
75
|
+
* closes). Once settlement succeeds the payment is final (on-chain) — a
|
|
76
|
+
* handler failure after that point is a normal application error, not a
|
|
77
|
+
* payment to unwind: there is nothing left to cancel, so it is not caught
|
|
78
|
+
* here and simply propagates.
|
|
79
|
+
*
|
|
80
|
+
* Default `false` (settle-after, the historical behaviour): the handler's
|
|
81
|
+
* response is passed to settlement as transport context (`responseHeaders`
|
|
82
|
+
* — read by some schemes for settlement overrides), and a handler throw
|
|
83
|
+
* still releases the verified-but-unsettled payment via
|
|
84
|
+
* `cancellationDispatcher.cancel`. Because settlement can still fail after
|
|
85
|
+
* the handler already ran on this path, `.x402()` handlers gated this way
|
|
86
|
+
* MUST be idempotent or compensatable — see the `@lunora/x402` charge docs.
|
|
87
|
+
*/
|
|
88
|
+
readonly settleBeforeHandler?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Build and initialise a {@link ChargeMiddleware} for `config`. Fetches
|
|
92
|
+
* facilitator support once (via `initialize()`), so call this once per config
|
|
93
|
+
* and reuse the result across requests. `routeOverrides` layers extra route
|
|
94
|
+
* metadata (e.g. `resource`) onto the generated catch-all route; `options`
|
|
95
|
+
* controls settlement ordering (see {@link ChargeMiddlewareOptions}).
|
|
96
|
+
* @experimental
|
|
97
|
+
*/
|
|
98
|
+
declare const createChargeMiddleware: (config: X402ChargeConfig, routeOverrides?: ChargeRouteOverrides, options?: ChargeMiddlewareOptions) => Promise<ChargeMiddleware>;
|
|
48
99
|
/**
|
|
49
|
-
* Charge config for the procedure gate: the worker-level settlement vocabulary
|
|
50
|
-
* (network, recipient, facilitator) minus `price` — price is per-procedure and
|
|
51
|
-
* arrives with each {@link X402ProcedureSpec}.
|
|
52
|
-
|
|
100
|
+
* Charge config for the procedure gate: the worker-level settlement vocabulary
|
|
101
|
+
* (network, recipient, facilitator) minus `price` — price is per-procedure and
|
|
102
|
+
* arrives with each {@link X402ProcedureSpec}.
|
|
103
|
+
* @experimental
|
|
104
|
+
*/
|
|
53
105
|
type X402ProcedureChargeConfig = Omit<X402ChargeConfig, "price">;
|
|
54
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* The per-RPC charge spec the runtime passes the gate for each paid dispatch.
|
|
108
|
+
* @experimental
|
|
109
|
+
*/
|
|
55
110
|
interface X402ProcedureSpec {
|
|
56
111
|
/** The `file:function` id of the paid procedure; becomes the x402 challenge `resource`. */
|
|
57
112
|
readonly functionPath: string;
|
|
@@ -59,18 +114,26 @@ interface X402ProcedureSpec {
|
|
|
59
114
|
readonly price: X402Price;
|
|
60
115
|
}
|
|
61
116
|
/**
|
|
62
|
-
* Gate one paid RPC. Returns a real `402` + `PAYMENT-REQUIRED` challenge when the
|
|
63
|
-
* request is unpaid, or the dispatched response (with `X-PAYMENT-RESPONSE`
|
|
64
|
-
* attached) once the client's `X-PAYMENT` is verified and settled. `dispatch`
|
|
65
|
-
* runs the actual shard forward —
|
|
66
|
-
|
|
67
|
-
|
|
117
|
+
* Gate one paid RPC. Returns a real `402` + `PAYMENT-REQUIRED` challenge when the
|
|
118
|
+
* request is unpaid, or the dispatched response (with `X-PAYMENT-RESPONSE`
|
|
119
|
+
* attached) once the client's `X-PAYMENT` is verified and settled. `dispatch`
|
|
120
|
+
* runs the actual shard forward — settlement happens **before** `dispatch` is
|
|
121
|
+
* invoked (settle-first), so a settlement failure means the shard forward
|
|
122
|
+
* (the mutation's commit) never runs at all — no committed-but-unpaid write is
|
|
123
|
+
* possible. `deps.waitUntil`, when supplied (the request's `ctx.waitUntil`),
|
|
124
|
+
* keeps the opt-in receipt sink alive past the response.
|
|
125
|
+
* @experimental
|
|
126
|
+
*/
|
|
127
|
+
type X402ProcedureChargeGate = (request: Request, spec: X402ProcedureSpec, dispatch: () => Promise<Response>, deps?: ChargeHandlerDeps) => Promise<Response>;
|
|
68
128
|
/**
|
|
69
|
-
* Build the injectable procedure charge gate for `config`. One initialised
|
|
70
|
-
* {@link ChargeMiddleware} is memoised per `functionPath` (each bakes that
|
|
71
|
-
* function's price + `resource`), since `createChargeMiddleware` fetches
|
|
72
|
-
* facilitator support on first use. A failed init is not cached, so a transient
|
|
73
|
-
* facilitator outage retries on the next request.
|
|
74
|
-
|
|
129
|
+
* Build the injectable procedure charge gate for `config`. One initialised
|
|
130
|
+
* {@link ChargeMiddleware} is memoised per `functionPath` (each bakes that
|
|
131
|
+
* function's price + `resource`), since `createChargeMiddleware` fetches
|
|
132
|
+
* facilitator support on first use. A failed init is not cached, so a transient
|
|
133
|
+
* facilitator outage retries on the next request. Settlement runs before
|
|
134
|
+
* `dispatch` (`settleBeforeHandler: true`) since `dispatch` commits the
|
|
135
|
+
* procedure's real mutation — see `createChargeMiddleware`'s `ChargeMiddlewareOptions`.
|
|
136
|
+
* @experimental
|
|
137
|
+
*/
|
|
75
138
|
declare const createProcedureChargeGate: (config: X402ProcedureChargeConfig) => X402ProcedureChargeGate;
|
|
76
|
-
export { type ChargeHandler, type ChargeMiddleware, type ChargeRouteOverrides, type FacilitatorConfig, type HttpActionHandler, type X402ChargeConfig, type X402Price, type X402ProcedureChargeConfig, type X402ProcedureChargeGate, type X402ProcedureSpec, createChargeMiddleware, createFacilitatorClient, createProcedureChargeGate, withX402 };
|
|
139
|
+
export { type ChargeHandler, type ChargeHandlerDeps, type ChargeMiddleware, type ChargeMiddlewareOptions, type ChargeRouteOverrides, type FacilitatorConfig, type HttpActionHandler, type X402ChargeConfig, type X402Price, type X402ProcedureChargeConfig, type X402ProcedureChargeGate, type X402ProcedureSpec, createChargeMiddleware, createFacilitatorClient, createProcedureChargeGate, withX402 };
|
package/dist/charge/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { F as FacilitatorConfig, c as X402ChargeConfig, f as X402Price } from "../packem_shared/config.d-
|
|
2
|
-
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, type a as EvmAddress, type P as PaymentEventRow, type d as X402Network, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2,
|
|
1
|
+
import { F as FacilitatorConfig, c as X402ChargeConfig, f as X402Price } from "../packem_shared/config.d-Dki_2r9a.js";
|
|
2
|
+
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, type a as EvmAddress, type P as PaymentEventRow, type d as X402Network, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2, y as toPaymentEventRow, z as toReceipt } from "../packem_shared/config.d-Dki_2r9a.js";
|
|
3
3
|
import { HTTPFacilitatorClient } from '@x402/core/server';
|
|
4
4
|
import { RouteConfig } from '@x402/core/http';
|
|
5
5
|
import '@x402/evm';
|
|
@@ -7,51 +7,106 @@ import '@x402/svm';
|
|
|
7
7
|
import '@x402/core/client';
|
|
8
8
|
import '@x402/core/types';
|
|
9
9
|
/**
|
|
10
|
-
* Build an `@x402/core` facilitator client from Lunora's {@link FacilitatorConfig}.
|
|
11
|
-
*
|
|
12
|
-
* `config.headers` (e.g. a CDP bearer token) are applied to every facilitator
|
|
13
|
-
* call — `@x402/core` splits auth per endpoint (`verify` / `settle` /
|
|
14
|
-
* `supported`), so the same header map is handed to each. With no config the
|
|
15
|
-
* client points at the public {@link resolveFacilitatorUrl default} and sends no
|
|
16
|
-
* auth headers.
|
|
17
|
-
|
|
10
|
+
* Build an `@x402/core` facilitator client from Lunora's {@link FacilitatorConfig}.
|
|
11
|
+
*
|
|
12
|
+
* `config.headers` (e.g. a CDP bearer token) are applied to every facilitator
|
|
13
|
+
* call — `@x402/core` splits auth per endpoint (`verify` / `settle` /
|
|
14
|
+
* `supported`), so the same header map is handed to each. With no config the
|
|
15
|
+
* client points at the public {@link resolveFacilitatorUrl default} and sends no
|
|
16
|
+
* auth headers.
|
|
17
|
+
* @experimental
|
|
18
|
+
*/
|
|
18
19
|
declare const createFacilitatorClient: (config?: FacilitatorConfig) => HTTPFacilitatorClient;
|
|
19
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A handler shaped like a Lunora HTTP action: `(context, request) => Response`.
|
|
22
|
+
* @experimental
|
|
23
|
+
*/
|
|
20
24
|
type HttpActionHandler<Context> = (context: Context, request: Request) => Promise<Response> | Response;
|
|
21
25
|
/**
|
|
22
|
-
* Gate `handler` behind an x402 paywall described by `config`. Returns a handler
|
|
23
|
-
* of the same shape, ready to pass to `httpAction`.
|
|
24
|
-
|
|
26
|
+
* Gate `handler` behind an x402 paywall described by `config`. Returns a handler
|
|
27
|
+
* of the same shape, ready to pass to `httpAction`.
|
|
28
|
+
* @experimental
|
|
29
|
+
*/
|
|
25
30
|
declare const withX402: <Context>(config: X402ChargeConfig, handler: HttpActionHandler<Context>) => HttpActionHandler<Context>;
|
|
26
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Runs the protected resource handler, producing the Response to gate.
|
|
33
|
+
* @experimental
|
|
34
|
+
*/
|
|
27
35
|
type ChargeHandler = () => Promise<Response> | Response;
|
|
28
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Per-request platform seams `handle` can use, beyond the request/handler pair.
|
|
38
|
+
* @experimental
|
|
39
|
+
*/
|
|
40
|
+
interface ChargeHandlerDeps {
|
|
41
|
+
/**
|
|
42
|
+
* Keep background work (the receipt sink) alive past the response — the
|
|
43
|
+
* request's `ctx.waitUntil`. Absent on paths with no platform execution
|
|
44
|
+
* context reaching the middleware (e.g. today's HTTP-action rail).
|
|
45
|
+
*/
|
|
46
|
+
readonly waitUntil?: (promise: Promise<unknown>) => void;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A prepared, initialised paywall. Build once (it fetches facilitator support), reuse per request.
|
|
50
|
+
* @experimental
|
|
51
|
+
*/
|
|
29
52
|
interface ChargeMiddleware {
|
|
30
53
|
/** Gate `request`: challenge / verify / settle around `runHandler`. */
|
|
31
|
-
handle: (request: Request, runHandler: ChargeHandler) => Promise<Response>;
|
|
54
|
+
handle: (request: Request, runHandler: ChargeHandler, deps?: ChargeHandlerDeps) => Promise<Response>;
|
|
32
55
|
}
|
|
33
56
|
/**
|
|
34
|
-
* Route metadata a caller can layer onto the generated catch-all route. The
|
|
35
|
-
* procedure gate sets `resource` to the `functionPath` so the x402 challenge
|
|
36
|
-
* names the paid function (x402 core falls back to the request URL otherwise —
|
|
37
|
-
* every RPC POSTs to the same `/_lunora/rpc`, so the URL can't tell two paid
|
|
38
|
-
* procedures apart).
|
|
39
|
-
|
|
57
|
+
* Route metadata a caller can layer onto the generated catch-all route. The
|
|
58
|
+
* procedure gate sets `resource` to the `functionPath` so the x402 challenge
|
|
59
|
+
* names the paid function (x402 core falls back to the request URL otherwise —
|
|
60
|
+
* every RPC POSTs to the same `/_lunora/rpc`, so the URL can't tell two paid
|
|
61
|
+
* procedures apart).
|
|
62
|
+
* @experimental
|
|
63
|
+
*/
|
|
40
64
|
type ChargeRouteOverrides = Pick<RouteConfig, "description" | "resource">;
|
|
41
65
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
66
|
+
* Behaviour knobs for {@link createChargeMiddleware} beyond route metadata.
|
|
67
|
+
* @experimental
|
|
68
|
+
*/
|
|
69
|
+
interface ChargeMiddlewareOptions {
|
|
70
|
+
/**
|
|
71
|
+
* Settle the verified payment **before** dispatching `runHandler`, instead
|
|
72
|
+
* of after. Use this for a mutation/procedure gate: a settlement failure
|
|
73
|
+
* then means the handler never runs at all, so a paid mutation's writes can
|
|
74
|
+
* never be committed without payment (the free-execution gap X402-04
|
|
75
|
+
* closes). Once settlement succeeds the payment is final (on-chain) — a
|
|
76
|
+
* handler failure after that point is a normal application error, not a
|
|
77
|
+
* payment to unwind: there is nothing left to cancel, so it is not caught
|
|
78
|
+
* here and simply propagates.
|
|
79
|
+
*
|
|
80
|
+
* Default `false` (settle-after, the historical behaviour): the handler's
|
|
81
|
+
* response is passed to settlement as transport context (`responseHeaders`
|
|
82
|
+
* — read by some schemes for settlement overrides), and a handler throw
|
|
83
|
+
* still releases the verified-but-unsettled payment via
|
|
84
|
+
* `cancellationDispatcher.cancel`. Because settlement can still fail after
|
|
85
|
+
* the handler already ran on this path, `.x402()` handlers gated this way
|
|
86
|
+
* MUST be idempotent or compensatable — see the `@lunora/x402` charge docs.
|
|
87
|
+
*/
|
|
88
|
+
readonly settleBeforeHandler?: boolean;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Build and initialise a {@link ChargeMiddleware} for `config`. Fetches
|
|
92
|
+
* facilitator support once (via `initialize()`), so call this once per config
|
|
93
|
+
* and reuse the result across requests. `routeOverrides` layers extra route
|
|
94
|
+
* metadata (e.g. `resource`) onto the generated catch-all route; `options`
|
|
95
|
+
* controls settlement ordering (see {@link ChargeMiddlewareOptions}).
|
|
96
|
+
* @experimental
|
|
97
|
+
*/
|
|
98
|
+
declare const createChargeMiddleware: (config: X402ChargeConfig, routeOverrides?: ChargeRouteOverrides, options?: ChargeMiddlewareOptions) => Promise<ChargeMiddleware>;
|
|
48
99
|
/**
|
|
49
|
-
* Charge config for the procedure gate: the worker-level settlement vocabulary
|
|
50
|
-
* (network, recipient, facilitator) minus `price` — price is per-procedure and
|
|
51
|
-
* arrives with each {@link X402ProcedureSpec}.
|
|
52
|
-
|
|
100
|
+
* Charge config for the procedure gate: the worker-level settlement vocabulary
|
|
101
|
+
* (network, recipient, facilitator) minus `price` — price is per-procedure and
|
|
102
|
+
* arrives with each {@link X402ProcedureSpec}.
|
|
103
|
+
* @experimental
|
|
104
|
+
*/
|
|
53
105
|
type X402ProcedureChargeConfig = Omit<X402ChargeConfig, "price">;
|
|
54
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* The per-RPC charge spec the runtime passes the gate for each paid dispatch.
|
|
108
|
+
* @experimental
|
|
109
|
+
*/
|
|
55
110
|
interface X402ProcedureSpec {
|
|
56
111
|
/** The `file:function` id of the paid procedure; becomes the x402 challenge `resource`. */
|
|
57
112
|
readonly functionPath: string;
|
|
@@ -59,18 +114,26 @@ interface X402ProcedureSpec {
|
|
|
59
114
|
readonly price: X402Price;
|
|
60
115
|
}
|
|
61
116
|
/**
|
|
62
|
-
* Gate one paid RPC. Returns a real `402` + `PAYMENT-REQUIRED` challenge when the
|
|
63
|
-
* request is unpaid, or the dispatched response (with `X-PAYMENT-RESPONSE`
|
|
64
|
-
* attached) once the client's `X-PAYMENT` is verified and settled. `dispatch`
|
|
65
|
-
* runs the actual shard forward —
|
|
66
|
-
|
|
67
|
-
|
|
117
|
+
* Gate one paid RPC. Returns a real `402` + `PAYMENT-REQUIRED` challenge when the
|
|
118
|
+
* request is unpaid, or the dispatched response (with `X-PAYMENT-RESPONSE`
|
|
119
|
+
* attached) once the client's `X-PAYMENT` is verified and settled. `dispatch`
|
|
120
|
+
* runs the actual shard forward — settlement happens **before** `dispatch` is
|
|
121
|
+
* invoked (settle-first), so a settlement failure means the shard forward
|
|
122
|
+
* (the mutation's commit) never runs at all — no committed-but-unpaid write is
|
|
123
|
+
* possible. `deps.waitUntil`, when supplied (the request's `ctx.waitUntil`),
|
|
124
|
+
* keeps the opt-in receipt sink alive past the response.
|
|
125
|
+
* @experimental
|
|
126
|
+
*/
|
|
127
|
+
type X402ProcedureChargeGate = (request: Request, spec: X402ProcedureSpec, dispatch: () => Promise<Response>, deps?: ChargeHandlerDeps) => Promise<Response>;
|
|
68
128
|
/**
|
|
69
|
-
* Build the injectable procedure charge gate for `config`. One initialised
|
|
70
|
-
* {@link ChargeMiddleware} is memoised per `functionPath` (each bakes that
|
|
71
|
-
* function's price + `resource`), since `createChargeMiddleware` fetches
|
|
72
|
-
* facilitator support on first use. A failed init is not cached, so a transient
|
|
73
|
-
* facilitator outage retries on the next request.
|
|
74
|
-
|
|
129
|
+
* Build the injectable procedure charge gate for `config`. One initialised
|
|
130
|
+
* {@link ChargeMiddleware} is memoised per `functionPath` (each bakes that
|
|
131
|
+
* function's price + `resource`), since `createChargeMiddleware` fetches
|
|
132
|
+
* facilitator support on first use. A failed init is not cached, so a transient
|
|
133
|
+
* facilitator outage retries on the next request. Settlement runs before
|
|
134
|
+
* `dispatch` (`settleBeforeHandler: true`) since `dispatch` commits the
|
|
135
|
+
* procedure's real mutation — see `createChargeMiddleware`'s `ChargeMiddlewareOptions`.
|
|
136
|
+
* @experimental
|
|
137
|
+
*/
|
|
75
138
|
declare const createProcedureChargeGate: (config: X402ProcedureChargeConfig) => X402ProcedureChargeGate;
|
|
76
|
-
export { type ChargeHandler, type ChargeMiddleware, type ChargeRouteOverrides, type FacilitatorConfig, type HttpActionHandler, type X402ChargeConfig, type X402Price, type X402ProcedureChargeConfig, type X402ProcedureChargeGate, type X402ProcedureSpec, createChargeMiddleware, createFacilitatorClient, createProcedureChargeGate, withX402 };
|
|
139
|
+
export { type ChargeHandler, type ChargeHandlerDeps, type ChargeMiddleware, type ChargeMiddlewareOptions, type ChargeRouteOverrides, type FacilitatorConfig, type HttpActionHandler, type X402ChargeConfig, type X402Price, type X402ProcedureChargeConfig, type X402ProcedureChargeGate, type X402ProcedureSpec, createChargeMiddleware, createFacilitatorClient, createProcedureChargeGate, withX402 };
|
package/dist/charge/index.mjs
CHANGED
|
@@ -1,7 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { createFacilitatorClient } from '../packem_shared/createFacilitatorClient-rXHBnCZm.mjs';
|
|
3
|
-
export { isEvmNetwork, isSvmNetwork, toCaip2 } from '../packem_shared/EVM_NETWORKS-BhnYWUQ4.mjs';
|
|
4
|
-
export { withX402 } from '../packem_shared/withX402-rUq0voT8.mjs';
|
|
5
|
-
export { createChargeMiddleware } from '../packem_shared/createChargeMiddleware-BJkYJeFf.mjs';
|
|
6
|
-
export { createProcedureChargeGate } from '../packem_shared/createProcedureChargeGate-CV8ITlQP.mjs';
|
|
7
|
-
export { toPaymentEventRow, toReceipt } from '../packem_shared/toPaymentEventRow-DW4O9N7Y.mjs';
|
|
1
|
+
import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as o}from"../packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs";import{createFacilitatorClient as i}from"../packem_shared/createFacilitatorClient-Dj4Ll9xQ.mjs";import{isEvmNetwork as p,isSvmNetwork as c,toCaip2 as f}from"../packem_shared/EVM_NETWORKS-XOms9Rtk.mjs";import{withX402 as l}from"../packem_shared/withX402-D10895ct.mjs";import{createChargeMiddleware as C}from"../packem_shared/createChargeMiddleware-MQhSA6Wt.mjs";import{createProcedureChargeGate as F}from"../packem_shared/createProcedureChargeGate-Cfm5mD2y.mjs";import{toPaymentEventRow as d,toReceipt as h}from"../packem_shared/toPaymentEventRow-D_kRVcb3.mjs";export{t as DEFAULT_FACILITATOR_URL,C as createChargeMiddleware,i as createFacilitatorClient,F as createProcedureChargeGate,p as isEvmNetwork,c as isSvmNetwork,o as resolveFacilitatorUrl,f as toCaip2,d as toPaymentEventRow,h as toReceipt,l as withX402};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, E as EVM_NETWORKS, type a as EvmAddress, type F as FacilitatorConfig, type b as FriendlyNetwork, N as NETWORK_TO_CAIP2, S as SVM_NETWORKS, type X as X402CdpSignerConfig, type c as X402ChargeConfig, type d as X402Network, type e as X402PayConfig, type f as X402Price, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, type j as X402SignerConfig, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2 } from "./packem_shared/config.d-
|
|
1
|
+
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, E as EVM_NETWORKS, type a as EvmAddress, type F as FacilitatorConfig, type b as FriendlyNetwork, N as NETWORK_TO_CAIP2, S as SVM_NETWORKS, type X as X402CdpSignerConfig, type c as X402ChargeConfig, type d as X402Network, type e as X402PayConfig, type f as X402Price, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, type j as X402SignerConfig, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2 } from "./packem_shared/config.d-Dki_2r9a.mjs";
|
|
2
2
|
import '@x402/evm';
|
|
3
3
|
import '@x402/svm';
|
|
4
4
|
import '@x402/core/http';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, E as EVM_NETWORKS, type a as EvmAddress, type F as FacilitatorConfig, type b as FriendlyNetwork, N as NETWORK_TO_CAIP2, S as SVM_NETWORKS, type X as X402CdpSignerConfig, type c as X402ChargeConfig, type d as X402Network, type e as X402PayConfig, type f as X402Price, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, type j as X402SignerConfig, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2 } from "./packem_shared/config.d-
|
|
1
|
+
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL, E as EVM_NETWORKS, type a as EvmAddress, type F as FacilitatorConfig, type b as FriendlyNetwork, N as NETWORK_TO_CAIP2, S as SVM_NETWORKS, type X as X402CdpSignerConfig, type c as X402ChargeConfig, type d as X402Network, type e as X402PayConfig, type f as X402Price, type g as X402Receipt, type h as X402ReceiptSink, type i as X402Recipient, type j as X402SignerConfig, k as isEvmNetwork, l as isSvmNetwork, r as resolveFacilitatorUrl, t as toCaip2 } from "./packem_shared/config.d-Dki_2r9a.js";
|
|
2
2
|
import '@x402/evm';
|
|
3
3
|
import '@x402/svm';
|
|
4
4
|
import '@x402/core/http';
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { EVM_NETWORKS, NETWORK_TO_CAIP2, SVM_NETWORKS, isEvmNetwork, isSvmNetwork, toCaip2 } from './packem_shared/EVM_NETWORKS-BhnYWUQ4.mjs';
|
|
1
|
+
import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as T}from"./packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs";import{EVM_NETWORKS as E,NETWORK_TO_CAIP2 as _,SVM_NETWORKS as i,isEvmNetwork as N,isSvmNetwork as O,toCaip2 as R}from"./packem_shared/EVM_NETWORKS-XOms9Rtk.mjs";export{t as DEFAULT_FACILITATOR_URL,E as EVM_NETWORKS,_ as NETWORK_TO_CAIP2,i as SVM_NETWORKS,N as isEvmNetwork,O as isSvmNetwork,T as resolveFacilitatorUrl,R as toCaip2};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as d}from"@lunora/errors";import{toCaip2 as w}from"./EVM_NETWORKS-XOms9Rtk.mjs";const E=/^\d+(?:\.\d+)?$/,u=(e,t)=>t.startsWith("eip155:")?e.toLowerCase():e,p=(e,t)=>`${t}|${u(e,t)}`,S=/^\d+$/,f=e=>S.test(e)?BigInt(e):void 0,A=6,v=[{asset:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",decimals:6,network:"base"},{asset:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",decimals:6,network:"base-sepolia"},{asset:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",decimals:6,network:"polygon"},{asset:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",decimals:6,network:"arbitrum"},{asset:"0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",decimals:6,network:"arbitrum-sepolia"},{asset:"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",decimals:6,network:"solana"},{asset:"4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",decimals:6,network:"solana-devnet"}],R=()=>{let e=0n;return{add:t=>{e+=t},release:t=>{e=e>t?e-t:0n},get spentAtomic(){return e}}},x=(e,t=A)=>{if(!Number.isInteger(t)||t<0)throw new d("BAD_REQUEST",`x402 policy: decimals must be a non-negative integer, got ${String(t)}.`);const n=(typeof e=="number"?e.toString():e).trim(),s=n.startsWith("$")?n.slice(1):n;if(!E.test(s))throw new d("BAD_REQUEST",`x402 policy: "${String(e)}" is not a valid USD amount (use a plain decimal like "0.01").`);const[o="0",r=""]=s.split("."),a=r.slice(0,t).padEnd(t,"0");return BigInt(o)*10n**BigInt(t)+BigInt(a===""?"0":a)},g=e=>{if(e.decimals!==void 0)throw new d("BAD_REQUEST","x402 policy: `decimals` is no longer supported — a single policy-wide decimal count can't describe the assets a server may name. List the asset in `allowedAssets` with its own `decimals` instead.");const t=e.allowedAssets??v;if(t.length===0)throw new d("BAD_REQUEST","x402 policy: `allowedAssets` is empty, so no payment could ever be made. Omit it to accept the default USDC assets, or list at least one asset.");const n=new Map;for(const s of t){if(!Number.isInteger(s.decimals)||s.decimals<0)throw new d("BAD_REQUEST",`x402 policy: allowedAssets[${s.asset}].decimals must be a non-negative integer, got ${String(s.decimals)}.`);const o=w(s.network),r=p(s.asset,o),a=n.get(r);if(a!==void 0&&a.decimals!==s.decimals)throw new d("BAD_REQUEST",`x402 policy: allowedAssets lists ${s.asset} on ${o} twice with different decimals (${String(a.decimals)} and ${String(s.decimals)}). One asset cannot have two precisions.`);n.set(r,{...s,network:o})}return n},y=(e,t)=>{const n=new Map;if(e===void 0)return n;for(const{decimals:s}of t.values())n.has(s)||n.set(s,x(e,s));return n},$=e=>{const t=g(e),n=y(e.maxPerCall,t),s=e.allowedNetworks?.map(r=>w(r)),{allowedRecipients:o}=e;return(r,a)=>a.filter(i=>{const l=t.get(p(i.asset,i.network));if(l===void 0)return!1;const c=f(i.amount);if(c===void 0)return!1;const m=n.get(l.decimals);if(m!==void 0&&c>m||s!==void 0&&!s.includes(i.network))return!1;if(o!==void 0){const b=u(i.payTo,i.network);return o.some(h=>u(h,i.network)===b)}return!0})},C=(e,t)=>{const n=g(e),s=y(e.maxPerRun,n);let o;return async r=>{const a=r.selectedRequirements,i=n.get(p(a.asset,a.network));if(i===void 0)return{abort:!0,reason:`x402 policy: asset ${a.asset} on ${a.network} is not in this wallet's allowed assets, so its amount cannot be priced against the caps.`};if(o===void 0)o=i.decimals;else if(o!==i.decimals)return{abort:!0,reason:`x402 policy: this payment is in a ${String(i.decimals)}-decimal asset but the run's spend is tracked in ${String(o)}-decimal units. One wallet cannot mix asset precisions under a single per-run cap.`};const l=f(a.amount);if(l===void 0)return{abort:!0,reason:`x402 policy: this payment's amount (${a.amount}) is not a canonical atomic quantity, so it cannot be checked against the caps.`};const c=s.get(i.decimals);if(c!==void 0&&t.spentAtomic+l>c)return{abort:!0,reason:`x402 policy: this payment (${a.amount}) would exceed the per-run cap (already spent ${t.spentAtomic.toString()}, cap ${c.toString()}, in atomic base units).`};t.add(l);try{return e.onPaymentRequired!==void 0&&!await e.onPaymentRequired(a)?(t.release(l),{abort:!0,reason:"x402 policy: payment was declined by onPaymentRequired."}):void 0}catch(m){throw t.release(l),m}}},P=e=>t=>(e.release(BigInt(t.selectedRequirements.amount)),Promise.resolve()),B=e=>{if(!(e.maxPerCall!==void 0||e.maxPerRun!==void 0||e.onPaymentRequired!==void 0))throw new d("FORBIDDEN","x402 pay: refusing to build a wallet with an unbounded spend policy. Set at least one of maxPerCall, maxPerRun, or onPaymentRequired (allowedNetworks/allowedRecipients/allowedAssets narrow but do not bound spend).")};export{v as DEFAULT_ALLOWED_ASSETS,A as DEFAULT_STABLECOIN_DECIMALS,B as assertBoundedPolicy,C as buildPaymentGuard,$ as buildSpendPolicy,R as createSpendState,P as releaseSpendOnFailure,x as usdToAtomic};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const r="https://x402.org/facilitator",o=t=>t?.url??r;export{r as DEFAULT_FACILITATOR_URL,o as resolveFacilitatorUrl};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const i={arbitrum:"eip155:42161","arbitrum-sepolia":"eip155:421614",base:"eip155:8453","base-sepolia":"eip155:84532",ethereum:"eip155:1",polygon:"eip155:137",solana:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","solana-devnet":"solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1"},r=["arbitrum","arbitrum-sepolia","base","base-sepolia","ethereum","polygon"],s=["solana","solana-devnet"],o=a=>{const e=i[a];if(e!==void 0)return e;if(a.includes(":"))return a;throw new Error(`Unknown x402 network "${a}". Use a friendly name (${r.join(", ")}, ${s.join(", ")}) or a raw CAIP-2 id.`)},t=a=>o(a).startsWith("eip155:"),n=a=>o(a).startsWith("solana:");export{r as EVM_NETWORKS,i as NETWORK_TO_CAIP2,s as SVM_NETWORKS,t as isEvmNetwork,n as isSvmNetwork,o as toCaip2};
|