@lunora/x402 1.0.0-alpha.7 → 1.0.0-alpha.70
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/LICENSE.md +18 -0
- package/README.md +22 -2
- package/dist/charge/index.d.mts +81 -21
- package/dist/charge/index.d.ts +81 -21
- package/dist/charge/index.mjs +1 -1
- package/dist/index.d.mts +2 -3
- package/dist/index.d.ts +2 -3
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/DEFAULT_ALLOWED_ASSETS-Bda-nP2p.mjs +1 -0
- package/dist/packem_shared/DEFAULT_FACILITATOR_URL-CPJNUMvi.mjs +1 -0
- package/dist/packem_shared/EVM_NETWORKS-C5yyzK27.mjs +1 -0
- package/dist/packem_shared/createChargeMiddleware-CURPSr23.mjs +1 -0
- package/dist/packem_shared/createFacilitatorClient-piLSnKs5.mjs +1 -0
- package/dist/packem_shared/createPayFetch-yWtKD0NN.mjs +1 -0
- package/dist/packem_shared/createProcedureChargeGate-Ki_K8dQE.mjs +1 -0
- package/dist/packem_shared/{config.d-B-NYmHgG.d.ts → index.d-C1PlJUJL.d.mts} +142 -13
- package/dist/packem_shared/{config.d-B-NYmHgG.d.mts → index.d-C1PlJUJL.d.ts} +142 -13
- package/dist/packem_shared/optional-peer-BBhVxozi.mjs +1 -0
- package/dist/packem_shared/registerWallet-DvCt0Q7M.mjs +1 -0
- package/dist/packem_shared/toPaymentEventRow-DTXuTDh0.mjs +1 -0
- package/dist/packem_shared/withX402-CXFSHtTo.mjs +1 -0
- package/dist/pay/index.d.mts +9 -9
- package/dist/pay/index.d.ts +9 -9
- package/dist/pay/index.mjs +1 -1
- package/package.json +21 -9
- package/dist/packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs +0 -1
- package/dist/packem_shared/DEFAULT_STABLECOIN_DECIMALS-dzQLLL1Z.mjs +0 -1
- package/dist/packem_shared/EVM_NETWORKS-XOms9Rtk.mjs +0 -1
- package/dist/packem_shared/createChargeMiddleware-MQhSA6Wt.mjs +0 -1
- package/dist/packem_shared/createFacilitatorClient-Dj4Ll9xQ.mjs +0 -1
- package/dist/packem_shared/createPayFetch-C4UrAY7P.mjs +0 -1
- package/dist/packem_shared/createProcedureChargeGate-Cfm5mD2y.mjs +0 -1
- package/dist/packem_shared/registerWallet-Cu4qF5tj.mjs +0 -1
- package/dist/packem_shared/toPaymentEventRow-D_kRVcb3.mjs +0 -1
- package/dist/packem_shared/withX402-D10895ct.mjs +0 -1
package/LICENSE.md
CHANGED
|
@@ -108,4 +108,22 @@ specific language governing permissions and limitations under the License.
|
|
|
108
108
|
<!-- /DEPENDENCIES -->
|
|
109
109
|
|
|
110
110
|
<!-- TYPE_DEPENDENCIES -->
|
|
111
|
+
|
|
112
|
+
# Licenses of bundled types
|
|
113
|
+
The published @lunora/x402 artifact additionally contains code with the following licenses:
|
|
114
|
+
Apache-2.0
|
|
115
|
+
|
|
116
|
+
# Bundled types:
|
|
117
|
+
## @x402/evm
|
|
118
|
+
License: Apache-2.0
|
|
119
|
+
By: x402 Foundation
|
|
120
|
+
Repository: https://github.com/x402-foundation/x402
|
|
121
|
+
|
|
122
|
+
---------------------------------------
|
|
123
|
+
|
|
124
|
+
## @x402/svm
|
|
125
|
+
License: Apache-2.0
|
|
126
|
+
By: x402 Foundation
|
|
127
|
+
Repository: https://github.com/x402-foundation/x402
|
|
128
|
+
|
|
111
129
|
<!-- /TYPE_DEPENDENCIES -->
|
package/README.md
CHANGED
|
@@ -25,6 +25,24 @@ The root export (`@lunora/x402`) carries only the shared config/types
|
|
|
25
25
|
(`.x402({ price })`), and MCP tools behind a USDC price; the **pay** rail signs and
|
|
26
26
|
retries `402` challenges under a mandatory spend policy.
|
|
27
27
|
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
The chain toolchains are **optional peers**, so an EVM-only deployment never
|
|
31
|
+
installs Solana's (heavy) toolchain and vice versa. Install the pair your
|
|
32
|
+
network family needs alongside the package:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @lunora/x402 # protocol core only
|
|
36
|
+
pnpm add @x402/evm viem # + EVM networks (Base, Arbitrum, …)
|
|
37
|
+
pnpm add @x402/svm @solana/kit # + Solana networks
|
|
38
|
+
pnpm add @coinbase/cdp-sdk # + CDP-managed custody (EVM)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Missing a peer fails with an `ENV_INVALID` error naming exactly what to install.
|
|
42
|
+
Note that TypeScript needs the same peers present to resolve the pay rail's
|
|
43
|
+
signer types (`ClientSvmSigner` resolves through `@solana/kit`); with neither
|
|
44
|
+
family installed, compile the package's declarations under `skipLibCheck`.
|
|
45
|
+
|
|
28
46
|
## Networks & custody
|
|
29
47
|
|
|
30
48
|
- **EVM** (Base, Arbitrum, Ethereum, Polygon, …) is signed via [`@x402/evm`](https://npmjs.com/package/@x402/evm) + [viem](https://viem.sh); pass a raw CAIP-2 id for chains without a friendly alias.
|
|
@@ -52,8 +70,10 @@ The pay rail's `signer` config selects wallet custody:
|
|
|
52
70
|
## Safety
|
|
53
71
|
|
|
54
72
|
The **pay** rail spends real money autonomously. It is `ActionCtx`-only and
|
|
55
|
-
fail-closed: every payment is bounded by a spend policy (
|
|
56
|
-
|
|
73
|
+
fail-closed: every payment is bounded by a spend policy (`maxPerCall`, a ceiling
|
|
74
|
+
on a single payment, and `maxPerRun`, a ceiling on cumulative spend across the
|
|
75
|
+
wallet's lifetime — the ctx, for `ctx.x402`; there is no windowed cap) and may
|
|
76
|
+
require confirmation. The `policy` field is required, so you cannot
|
|
57
77
|
wire a signer without one; an unbounded policy is refused at runtime (fail-closed)
|
|
58
78
|
before any signer is resolved.
|
|
59
79
|
|
package/dist/charge/index.d.mts
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
import { F as FacilitatorConfig,
|
|
2
|
-
export { type
|
|
1
|
+
import { F as FacilitatorConfig, q as X402ChargeConfig, h as X402Price } from "../packem_shared/index.d-C1PlJUJL.mjs";
|
|
2
|
+
export { type b as Caip2, c as DEFAULT_FACILITATOR_URL,
|
|
3
|
+
/**
|
|
4
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
5
|
+
*
|
|
6
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
7
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
8
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
9
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
10
|
+
*
|
|
11
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
12
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
13
|
+
*/
|
|
14
|
+
type E as EvmAddress, type P as PaymentEventRow, type g as X402Network, type s as X402Receipt, type v as X402ReceiptSink,
|
|
15
|
+
/**
|
|
16
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
17
|
+
*
|
|
18
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
19
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
20
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
21
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
22
|
+
*
|
|
23
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
24
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
25
|
+
*/
|
|
26
|
+
type w as X402Recipient, n as isEvmNetwork, o as isSvmNetwork, p as resolveFacilitatorUrl, t as toCaip2, x as toPaymentEventRow, y as toReceipt } from "../packem_shared/index.d-C1PlJUJL.mjs";
|
|
3
27
|
import { HTTPFacilitatorClient } from '@x402/core/server';
|
|
4
28
|
import { RouteConfig } from '@x402/core/http';
|
|
5
|
-
import '@x402/evm';
|
|
6
|
-
import '@x402/svm';
|
|
7
29
|
import '@x402/core/client';
|
|
8
30
|
import '@x402/core/types';
|
|
31
|
+
import '@solana/accounts';
|
|
9
32
|
/**
|
|
10
33
|
* Build an `@x402/core` facilitator client from Lunora's {@link FacilitatorConfig}.
|
|
11
34
|
*
|
|
@@ -41,7 +64,7 @@ interface ChargeHandlerDeps {
|
|
|
41
64
|
/**
|
|
42
65
|
* Keep background work (the receipt sink) alive past the response — the
|
|
43
66
|
* request's `ctx.waitUntil`. Absent on paths with no platform execution
|
|
44
|
-
* context reaching the middleware (e.g.
|
|
67
|
+
* context reaching the middleware (e.g. a non-Workers test).
|
|
45
68
|
*/
|
|
46
69
|
readonly waitUntil?: (promise: Promise<unknown>) => void;
|
|
47
70
|
}
|
|
@@ -69,21 +92,22 @@ type ChargeRouteOverrides = Pick<RouteConfig, "description" | "resource">;
|
|
|
69
92
|
interface ChargeMiddlewareOptions {
|
|
70
93
|
/**
|
|
71
94
|
* Settle the verified payment **before** dispatching `runHandler`, instead
|
|
72
|
-
* of after.
|
|
73
|
-
*
|
|
74
|
-
* never
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
95
|
+
* of after. **Default `true`** — a settlement failure then means the handler
|
|
96
|
+
* never runs at all, so its side effects (writes, LLM calls, mail, push) can
|
|
97
|
+
* never happen unpaid. This matters because `verifyPayment` only checks the
|
|
98
|
+
* signed intent, NOT solvency: an underfunded or facilitator-refused payment
|
|
99
|
+
* passes verify and fails at `/settle`. Once settlement succeeds the payment
|
|
100
|
+
* is final (on-chain) — a handler failure after that point is a normal
|
|
101
|
+
* application error, not a payment to unwind: there is nothing left to
|
|
102
|
+
* cancel, so it is not caught here and simply propagates.
|
|
79
103
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
104
|
+
* Set `false` for settle-after: the handler's response is passed to
|
|
105
|
+
* settlement as transport context (`responseHeaders` — read by some schemes
|
|
106
|
+
* for settlement overrides), and a handler throw releases the
|
|
107
|
+
* verified-but-unsettled payment via `cancellationDispatcher.cancel`.
|
|
108
|
+
* Settlement can still FAIL after the handler already ran on this path, so a
|
|
109
|
+
* handler gated this way MUST be idempotent or compensatable — opt in only
|
|
110
|
+
* when you need the response as settlement context and can accept that.
|
|
87
111
|
*/
|
|
88
112
|
readonly settleBeforeHandler?: boolean;
|
|
89
113
|
}
|
|
@@ -131,9 +155,45 @@ type X402ProcedureChargeGate = (request: Request, spec: X402ProcedureSpec, dispa
|
|
|
131
155
|
* function's price + `resource`), since `createChargeMiddleware` fetches
|
|
132
156
|
* facilitator support on first use. A failed init is not cached, so a transient
|
|
133
157
|
* facilitator outage retries on the next request. Settlement runs before
|
|
134
|
-
* `dispatch` (`settleBeforeHandler
|
|
158
|
+
* `dispatch` (the `settleBeforeHandler` default) since `dispatch` commits the
|
|
135
159
|
* procedure's real mutation — see `createChargeMiddleware`'s `ChargeMiddlewareOptions`.
|
|
136
160
|
* @experimental
|
|
137
161
|
*/
|
|
138
162
|
declare const createProcedureChargeGate: (config: X402ProcedureChargeConfig) => X402ProcedureChargeGate;
|
|
139
|
-
export { type ChargeHandler, type ChargeHandlerDeps, type ChargeMiddleware, type ChargeMiddlewareOptions, type ChargeRouteOverrides,
|
|
163
|
+
export { type ChargeHandler, type ChargeHandlerDeps, type ChargeMiddleware, type ChargeMiddlewareOptions, type ChargeRouteOverrides,
|
|
164
|
+
/**
|
|
165
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
166
|
+
*
|
|
167
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
168
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
169
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
170
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
171
|
+
*
|
|
172
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
173
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
174
|
+
*/
|
|
175
|
+
type FacilitatorConfig, type HttpActionHandler,
|
|
176
|
+
/**
|
|
177
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
178
|
+
*
|
|
179
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
180
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
181
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
182
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
183
|
+
*
|
|
184
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
185
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
186
|
+
*/
|
|
187
|
+
type X402ChargeConfig,
|
|
188
|
+
/**
|
|
189
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
190
|
+
*
|
|
191
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
192
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
193
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
194
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
195
|
+
*
|
|
196
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
197
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
198
|
+
*/
|
|
199
|
+
type X402Price, type X402ProcedureChargeConfig, type X402ProcedureChargeGate, type X402ProcedureSpec, createChargeMiddleware, createFacilitatorClient, createProcedureChargeGate, withX402 };
|
package/dist/charge/index.d.ts
CHANGED
|
@@ -1,11 +1,34 @@
|
|
|
1
|
-
import { F as FacilitatorConfig,
|
|
2
|
-
export { type
|
|
1
|
+
import { F as FacilitatorConfig, q as X402ChargeConfig, h as X402Price } from "../packem_shared/index.d-C1PlJUJL.js";
|
|
2
|
+
export { type b as Caip2, c as DEFAULT_FACILITATOR_URL,
|
|
3
|
+
/**
|
|
4
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
5
|
+
*
|
|
6
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
7
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
8
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
9
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
10
|
+
*
|
|
11
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
12
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
13
|
+
*/
|
|
14
|
+
type E as EvmAddress, type P as PaymentEventRow, type g as X402Network, type s as X402Receipt, type v as X402ReceiptSink,
|
|
15
|
+
/**
|
|
16
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
17
|
+
*
|
|
18
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
19
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
20
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
21
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
22
|
+
*
|
|
23
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
24
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
25
|
+
*/
|
|
26
|
+
type w as X402Recipient, n as isEvmNetwork, o as isSvmNetwork, p as resolveFacilitatorUrl, t as toCaip2, x as toPaymentEventRow, y as toReceipt } from "../packem_shared/index.d-C1PlJUJL.js";
|
|
3
27
|
import { HTTPFacilitatorClient } from '@x402/core/server';
|
|
4
28
|
import { RouteConfig } from '@x402/core/http';
|
|
5
|
-
import '@x402/evm';
|
|
6
|
-
import '@x402/svm';
|
|
7
29
|
import '@x402/core/client';
|
|
8
30
|
import '@x402/core/types';
|
|
31
|
+
import '@solana/accounts';
|
|
9
32
|
/**
|
|
10
33
|
* Build an `@x402/core` facilitator client from Lunora's {@link FacilitatorConfig}.
|
|
11
34
|
*
|
|
@@ -41,7 +64,7 @@ interface ChargeHandlerDeps {
|
|
|
41
64
|
/**
|
|
42
65
|
* Keep background work (the receipt sink) alive past the response — the
|
|
43
66
|
* request's `ctx.waitUntil`. Absent on paths with no platform execution
|
|
44
|
-
* context reaching the middleware (e.g.
|
|
67
|
+
* context reaching the middleware (e.g. a non-Workers test).
|
|
45
68
|
*/
|
|
46
69
|
readonly waitUntil?: (promise: Promise<unknown>) => void;
|
|
47
70
|
}
|
|
@@ -69,21 +92,22 @@ type ChargeRouteOverrides = Pick<RouteConfig, "description" | "resource">;
|
|
|
69
92
|
interface ChargeMiddlewareOptions {
|
|
70
93
|
/**
|
|
71
94
|
* Settle the verified payment **before** dispatching `runHandler`, instead
|
|
72
|
-
* of after.
|
|
73
|
-
*
|
|
74
|
-
* never
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
95
|
+
* of after. **Default `true`** — a settlement failure then means the handler
|
|
96
|
+
* never runs at all, so its side effects (writes, LLM calls, mail, push) can
|
|
97
|
+
* never happen unpaid. This matters because `verifyPayment` only checks the
|
|
98
|
+
* signed intent, NOT solvency: an underfunded or facilitator-refused payment
|
|
99
|
+
* passes verify and fails at `/settle`. Once settlement succeeds the payment
|
|
100
|
+
* is final (on-chain) — a handler failure after that point is a normal
|
|
101
|
+
* application error, not a payment to unwind: there is nothing left to
|
|
102
|
+
* cancel, so it is not caught here and simply propagates.
|
|
79
103
|
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
104
|
+
* Set `false` for settle-after: the handler's response is passed to
|
|
105
|
+
* settlement as transport context (`responseHeaders` — read by some schemes
|
|
106
|
+
* for settlement overrides), and a handler throw releases the
|
|
107
|
+
* verified-but-unsettled payment via `cancellationDispatcher.cancel`.
|
|
108
|
+
* Settlement can still FAIL after the handler already ran on this path, so a
|
|
109
|
+
* handler gated this way MUST be idempotent or compensatable — opt in only
|
|
110
|
+
* when you need the response as settlement context and can accept that.
|
|
87
111
|
*/
|
|
88
112
|
readonly settleBeforeHandler?: boolean;
|
|
89
113
|
}
|
|
@@ -131,9 +155,45 @@ type X402ProcedureChargeGate = (request: Request, spec: X402ProcedureSpec, dispa
|
|
|
131
155
|
* function's price + `resource`), since `createChargeMiddleware` fetches
|
|
132
156
|
* facilitator support on first use. A failed init is not cached, so a transient
|
|
133
157
|
* facilitator outage retries on the next request. Settlement runs before
|
|
134
|
-
* `dispatch` (`settleBeforeHandler
|
|
158
|
+
* `dispatch` (the `settleBeforeHandler` default) since `dispatch` commits the
|
|
135
159
|
* procedure's real mutation — see `createChargeMiddleware`'s `ChargeMiddlewareOptions`.
|
|
136
160
|
* @experimental
|
|
137
161
|
*/
|
|
138
162
|
declare const createProcedureChargeGate: (config: X402ProcedureChargeConfig) => X402ProcedureChargeGate;
|
|
139
|
-
export { type ChargeHandler, type ChargeHandlerDeps, type ChargeMiddleware, type ChargeMiddlewareOptions, type ChargeRouteOverrides,
|
|
163
|
+
export { type ChargeHandler, type ChargeHandlerDeps, type ChargeMiddleware, type ChargeMiddlewareOptions, type ChargeRouteOverrides,
|
|
164
|
+
/**
|
|
165
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
166
|
+
*
|
|
167
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
168
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
169
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
170
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
171
|
+
*
|
|
172
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
173
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
174
|
+
*/
|
|
175
|
+
type FacilitatorConfig, type HttpActionHandler,
|
|
176
|
+
/**
|
|
177
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
178
|
+
*
|
|
179
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
180
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
181
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
182
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
183
|
+
*
|
|
184
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
185
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
186
|
+
*/
|
|
187
|
+
type X402ChargeConfig,
|
|
188
|
+
/**
|
|
189
|
+
* `@lunora/x402/charge` — the charge rail (server side).
|
|
190
|
+
*
|
|
191
|
+
* A Lunora deployment gates a resource (an HTTP-action route, a procedure, or
|
|
192
|
+
* an MCP tool) behind a USDC price: it returns `402 Payment Required` with a
|
|
193
|
+
* `PAYMENT-REQUIRED` header, verifies the client's `X-PAYMENT` payload (via a
|
|
194
|
+
* facilitator), runs the handler, settles, and attaches `X-PAYMENT-RESPONSE`.
|
|
195
|
+
*
|
|
196
|
+
* `withX402` gates a Lunora HTTP action; `createChargeMiddleware` is the
|
|
197
|
+
* framework-agnostic core for other surfaces (procedures, MCP tools).
|
|
198
|
+
*/
|
|
199
|
+
type X402Price, type X402ProcedureChargeConfig, type X402ProcedureChargeGate, type X402ProcedureSpec, createChargeMiddleware, createFacilitatorClient, createProcedureChargeGate, withX402 };
|
package/dist/charge/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as o}from"../packem_shared/DEFAULT_FACILITATOR_URL-
|
|
1
|
+
import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as o}from"../packem_shared/DEFAULT_FACILITATOR_URL-CPJNUMvi.mjs";import{createFacilitatorClient as i}from"../packem_shared/createFacilitatorClient-piLSnKs5.mjs";import{isEvmNetwork as p,isSvmNetwork as c,toCaip2 as f}from"../packem_shared/EVM_NETWORKS-C5yyzK27.mjs";import{withX402 as l}from"../packem_shared/withX402-CXFSHtTo.mjs";import{createChargeMiddleware as C}from"../packem_shared/createChargeMiddleware-CURPSr23.mjs";import{createProcedureChargeGate as F}from"../packem_shared/createProcedureChargeGate-Ki_K8dQE.mjs";import{toPaymentEventRow as d,toReceipt as h}from"../packem_shared/toPaymentEventRow-DTXuTDh0.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,6 +1,5 @@
|
|
|
1
|
-
export { type
|
|
2
|
-
import '@x402/evm';
|
|
3
|
-
import '@x402/svm';
|
|
1
|
+
export { type b as Caip2, c as DEFAULT_FACILITATOR_URL, z as EVM_NETWORKS, type E as EvmAddress, type F as FacilitatorConfig, type B as FriendlyNetwork, N as NETWORK_TO_CAIP2, G as SVM_NETWORKS, type f as X402CdpSignerConfig, type q as X402ChargeConfig, type g as X402Network, type X as X402PayConfig, type h as X402Price, type s as X402Receipt, type v as X402ReceiptSink, type w as X402Recipient, type i as X402SignerConfig, n as isEvmNetwork, o as isSvmNetwork, p as resolveFacilitatorUrl, t as toCaip2 } from "./packem_shared/index.d-C1PlJUJL.mjs";
|
|
4
2
|
import '@x402/core/http';
|
|
5
3
|
import '@x402/core/client';
|
|
6
4
|
import '@x402/core/types';
|
|
5
|
+
import '@solana/accounts';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export { type
|
|
2
|
-
import '@x402/evm';
|
|
3
|
-
import '@x402/svm';
|
|
1
|
+
export { type b as Caip2, c as DEFAULT_FACILITATOR_URL, z as EVM_NETWORKS, type E as EvmAddress, type F as FacilitatorConfig, type B as FriendlyNetwork, N as NETWORK_TO_CAIP2, G as SVM_NETWORKS, type f as X402CdpSignerConfig, type q as X402ChargeConfig, type g as X402Network, type X as X402PayConfig, type h as X402Price, type s as X402Receipt, type v as X402ReceiptSink, type w as X402Recipient, type i as X402SignerConfig, n as isEvmNetwork, o as isSvmNetwork, p as resolveFacilitatorUrl, t as toCaip2 } from "./packem_shared/index.d-C1PlJUJL.js";
|
|
4
2
|
import '@x402/core/http';
|
|
5
3
|
import '@x402/core/client';
|
|
6
4
|
import '@x402/core/types';
|
|
5
|
+
import '@solana/accounts';
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as T}from"./packem_shared/DEFAULT_FACILITATOR_URL-
|
|
1
|
+
import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as T}from"./packem_shared/DEFAULT_FACILITATOR_URL-CPJNUMvi.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-C5yyzK27.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 l}from"@lunora/errors";import{toCaip2 as f}from"./EVM_NETWORKS-C5yyzK27.mjs";const v=/^\d+(?:\.\d+)?$/,u=(e,t)=>t.startsWith("eip155:")?e.toLowerCase():e,p=(e,t)=>`${t}|${u(e,t)}`,h=/^\d+$/,w=e=>h.test(e)?BigInt(e):void 0,S=6,x=[{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"}],C=()=>{let e=0n;return{add:t=>{e+=t},release:t=>{e=e>t?e-t:0n},get spentAtomic(){return e}}},E=(e,t=S)=>{if(!Number.isInteger(t)||t<0)throw new l("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(!v.test(s))throw new l("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)},b=e=>{if(e.decimals!==void 0)throw new l("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??x;if(t.length===0)throw new l("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 l("BAD_REQUEST",`x402 policy: allowedAssets[${s.asset}].decimals must be a non-negative integer, got ${String(s.decimals)}.`);const o=f(s.network),r=p(s.asset,o),a=n.get(r);if(a!==void 0&&a.decimals!==s.decimals)throw new l("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},g=(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,E(e,s));return n},R=e=>{const t=b(e),n=g(e.maxPerCall,t),s=e.allowedNetworks?.map(r=>f(r)),{allowedRecipients:o}=e;return(r,a)=>a.filter(i=>{const c=t.get(p(i.asset,i.network));if(c===void 0)return!1;const d=w(i.amount);if(d===void 0)return!1;const m=n.get(c.decimals);if(m!==void 0&&d>m||s!==void 0&&!s.includes(i.network))return!1;if(o!==void 0){const A=u(i.payTo,i.network);return o.some(y=>u(y,i.network)===A)}return!0})},P=(e,t)=>{const n=b(e),s=g(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 c=w(a.amount);if(c===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 d=s.get(i.decimals);if(d!==void 0&&t.spentAtomic+c>d)return{abort:!0,reason:`x402 policy: this payment (${a.amount}) would exceed the per-run cap (already spent ${t.spentAtomic.toString()}, cap ${d.toString()}, in atomic base units).`};t.add(c);try{return e.onPaymentRequired!==void 0&&await e.onPaymentRequired(a)!==!0?(t.release(c),{abort:!0,reason:"x402 policy: payment was declined by onPaymentRequired."}):void 0}catch(m){throw t.release(c),m}}},$=e=>t=>{const n=w(t.selectedRequirements.amount);return n!==void 0&&e.release(n),Promise.resolve()},T=e=>{if(!(e.maxPerCall!==void 0||e.maxPerRun!==void 0||e.onPaymentRequired!==void 0))throw new l("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{x as DEFAULT_ALLOWED_ASSETS,S as DEFAULT_STABLECOIN_DECIMALS,T as assertBoundedPolicy,P as buildPaymentGuard,R as buildSpendPolicy,C as createSpendState,$ as releaseSpendOnFailure,E as usdToAtomic};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o="https://x402.org/facilitator",r=t=>t?.url??o;export{o as DEFAULT_FACILITATOR_URL,r as resolveFacilitatorUrl};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s={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"},i=["arbitrum","arbitrum-sepolia","base","base-sepolia","ethereum","polygon"],t=["solana","solana-devnet"],o=a=>{const e=s[a];if(e!==void 0)return e;if(a.includes(":"))return a;throw new Error(`Unknown x402 network "${a}". Use a friendly name (${i.join(", ")}, ${t.join(", ")}) or a raw CAIP-2 id.`)},n=a=>o(a).startsWith("eip155:"),r=a=>o(a).startsWith("solana:");export{i as EVM_NETWORKS,s as NETWORK_TO_CAIP2,t as SVM_NETWORKS,n as isEvmNetwork,r as isSvmNetwork,o as toCaip2};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{x402HTTPResourceServer as E}from"@x402/core/http";import{toCaip2 as x,isEvmNetwork as P}from"./EVM_NETWORKS-C5yyzK27.mjs";import{toReceipt as S}from"./toPaymentEventRow-DTXuTDh0.mjs";import{createFacilitatorClient as H}from"./createFacilitatorClient-piLSnKs5.mjs";import{i as R}from"./optional-peer-BBhVxozi.mjs";const T=async e=>{const{x402ResourceServer:r}=await import("@x402/core/server"),t=new r(H(e.facilitator)),s=x(e.network);if(P(e.network)){const{registerExactEvmScheme:a}=await R(()=>import("@x402/evm/exact/server"),"x402 charge: EVM networks need the optional @x402/evm + viem peers — install them, or configure an SVM network.");a(t,{networks:[s]})}else{const{registerExactSvmScheme:a}=await R(()=>import("@x402/svm/exact/server"),"x402 charge: SVM networks need the optional @x402/svm + @solana/kit peers — install them, or configure an EVM network.");a(t,{networks:[s]})}return t},A="X-PAYMENT",M=e=>{const r=Object.create(null);for(const[t,s]of e)r[t]=s;return r},g=(e,r,t,s)=>{if(e!==void 0)try{const a=Promise.resolve(e(S(r,{resource:t,ts:Date.now()}))).catch(()=>{});s?.(a)}catch{}},b=e=>{const r=P(e.network),t=r?e.recipient.evm:e.recipient.svm;if(t===void 0||t.length===0)throw new Error(`x402 charge on "${e.network}" needs recipient.${r?"evm":"svm"} set.`);return t},U=e=>({accepts:{network:x(e.network),payTo:b(e),price:e.price,scheme:"exact"}}),j=(e,r)=>({getAcceptHeader:()=>e.headers.get("accept")??"",getHeader:t=>e.headers.get(t)??void 0,getMethod:()=>e.method,getPath:()=>r.pathname,getQueryParam:t=>{const s=r.searchParams.getAll(t);if(s.length!==0)return s.length===1?s[0]:s},getQueryParams:()=>{const t=Object.create(null);for(const s of new Set(r.searchParams.keys())){const a=r.searchParams.getAll(s),[i,...w]=a;i!==void 0&&(t[s]=w.length>0?a:i)}return t},getUrl:()=>e.url,getUserAgent:()=>e.headers.get("user-agent")??""}),u=e=>{const r=new Headers(e.headers),{body:t}=e;return t==null?new Response(void 0,{headers:r,status:e.status}):typeof t=="string"?(e.isHtml&&!r.has("content-type")&&r.set("content-type","text/html; charset=utf-8"),new Response(t,{headers:r,status:e.status})):Response.json(t,{headers:r,status:e.status})},k=(e,r)=>{const t=new Headers(e.headers);for(const[s,a]of Object.entries(r))t.set(s,a);return new Response(e.body,{headers:t,status:e.status,statusText:e.statusText})},B=async(e,r,t)=>{const s=await T(e),a=new E(s,{...U(e),...r});await a.initialize();const i=t?.settleBeforeHandler??!0;return{handle:async(c,p,y)=>{const v=new URL(c.url),h={adapter:j(c,v),method:c.method,path:v.pathname,paymentHeader:c.headers.get(A)??void 0},n=await a.processHTTPRequest(h);if(n.type==="no-payment-required")return p();if(n.type==="payment-error")return u(n.response);const f=r?.resource??c.url;if(i){const o=await a.processSettlement(n.paymentPayload,n.paymentRequirements,n.declaredExtensions,{request:h});if(!o.success)return u(o.response);g(e.onReceipt,o,f,y?.waitUntil);const d=await p();return k(d,o.headers)}let m;try{m=await p()}catch(o){try{await n.cancellationDispatcher.cancel({error:o,reason:"handler_threw"})}catch(d){console.error("x402 charge: failed to cancel payment after the handler threw",d)}throw o}const l=await a.processSettlement(n.paymentPayload,n.paymentRequirements,n.declaredExtensions,{request:h,responseHeaders:M(m.headers)});return l.success?(g(e.onReceipt,l,f,y?.waitUntil),k(m,l.headers)):u(l.response)}}};export{U as buildRoute,B as createChargeMiddleware,j as createRequestAdapter,g as reportReceipt,b as resolvePayTo,u as toResponse,k as withHeaders};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{HTTPFacilitatorClient as o}from"@x402/core/server";import{resolveFacilitatorUrl as a}from"./DEFAULT_FACILITATOR_URL-CPJNUMvi.mjs";const l=e=>{const t=a(e);if(e?.headers===void 0)return new o({url:t});const r={...e.headers};return new o({createAuthHeaders:()=>Promise.resolve({settle:r,supported:r,verify:r}),url:t})};export{l as createFacilitatorClient};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{x402Client as l}from"@x402/core/client";import{wrapFetchWithPayment as c}from"@x402/fetch";import{assertBoundedPolicy as s,buildSpendPolicy as p,buildPaymentGuard as y,releaseSpendOnFailure as m,createSpendState as d}from"./DEFAULT_ALLOWED_ASSETS-Bda-nP2p.mjs";import{registerWallet as P}from"./registerWallet-DvCt0Q7M.mjs";const S=async(t,r)=>{s(t.policy);const o=d(),a=p(t.policy),n=y(t.policy,o),i=m(o),e=new l;return await P(e,t,r),e.registerPolicy(a),e.onBeforePaymentCreation(n),e.onPaymentCreationFailure(i),c(r.fetch??globalThis.fetch,e)};export{S as createPayFetch};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createChargeMiddleware as a}from"./createChargeMiddleware-CURPSr23.mjs";const d=(e,r,i,n)=>{const c=e.get(r);if(c!==void 0)return c;const t=i().catch(o=>{throw e.get(r)===t&&e.delete(r),o});return e.set(r,t),t},u=e=>{const r=new Map;return async(i,n,c,t)=>(await d(r,n.functionPath,async()=>a({...e,price:n.price},{resource:n.functionPath}))).handle(i,c,t)};export{u as createProcedureChargeGate};
|
|
@@ -1,8 +1,69 @@
|
|
|
1
|
-
import { ClientEvmSigner } from '@x402/evm';
|
|
2
|
-
import { ClientSvmSigner } from '@x402/svm';
|
|
3
1
|
import { ProcessSettleSuccessResponse } from '@x402/core/http';
|
|
4
2
|
import { BeforePaymentCreationHook, PaymentPolicy, OnPaymentCreationFailureHook } from '@x402/core/client';
|
|
5
3
|
import { PaymentRequirements } from '@x402/core/types';
|
|
4
|
+
import { TransactionSigner } from '@solana/accounts';
|
|
5
|
+
/**
|
|
6
|
+
* ClientEvmSigner - Used by x402 clients to sign payment authorizations.
|
|
7
|
+
*
|
|
8
|
+
* Typically a viem LocalAccount:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const account = privateKeyToAccount('0x...');
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Or composed via `toClientEvmSigner(account, publicClient)`.
|
|
14
|
+
*/
|
|
15
|
+
type ClientEvmSigner = {
|
|
16
|
+
readonly address: `0x${string}`;
|
|
17
|
+
signTypedData(message: {
|
|
18
|
+
domain: Record<string, unknown>;
|
|
19
|
+
types: Record<string, unknown>;
|
|
20
|
+
primaryType: string;
|
|
21
|
+
message: Record<string, unknown>;
|
|
22
|
+
}): Promise<`0x${string}`>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional on-chain reads.
|
|
25
|
+
* Required only for extension enrichment (EIP-2612 / ERC-20 approval).
|
|
26
|
+
*/
|
|
27
|
+
readContract?(args: {
|
|
28
|
+
address: `0x${string}`;
|
|
29
|
+
abi: readonly unknown[];
|
|
30
|
+
functionName: string;
|
|
31
|
+
args?: readonly unknown[];
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Optional: Signs a raw EIP-1559 transaction without broadcasting.
|
|
35
|
+
* Required for ERC-20 approval gas sponsoring when the token lacks EIP-2612.
|
|
36
|
+
*/
|
|
37
|
+
signTransaction?(args: {
|
|
38
|
+
to: `0x${string}`;
|
|
39
|
+
data: `0x${string}`;
|
|
40
|
+
nonce: number;
|
|
41
|
+
gas: bigint;
|
|
42
|
+
maxFeePerGas: bigint;
|
|
43
|
+
maxPriorityFeePerGas: bigint;
|
|
44
|
+
chainId: number;
|
|
45
|
+
}): Promise<`0x${string}`>;
|
|
46
|
+
/**
|
|
47
|
+
* Optional: Gets the current transaction count (nonce) for an address.
|
|
48
|
+
* Required for ERC-20 approval gas sponsoring.
|
|
49
|
+
*/
|
|
50
|
+
getTransactionCount?(args: {
|
|
51
|
+
address: `0x${string}`;
|
|
52
|
+
}): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* Optional: Estimates current gas fees per gas.
|
|
55
|
+
* Required for ERC-20 approval gas sponsoring.
|
|
56
|
+
*/
|
|
57
|
+
estimateFeesPerGas?(): Promise<{
|
|
58
|
+
maxFeePerGas: bigint;
|
|
59
|
+
maxPriorityFeePerGas: bigint;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Client-side signer for creating and signing Solana transactions
|
|
64
|
+
* This is a wrapper around TransactionSigner from @solana/kit
|
|
65
|
+
*/
|
|
66
|
+
type ClientSvmSigner = TransactionSigner;
|
|
6
67
|
/**
|
|
7
68
|
* A normalised record of one settled x402 payment. The settled `amount` is kept
|
|
8
69
|
* as its exact on-chain atomic-unit string (USDC has 6 decimals) — never coerced
|
|
@@ -160,12 +221,48 @@ declare const isEvmNetwork: (network: X402Network) => boolean;
|
|
|
160
221
|
*/
|
|
161
222
|
declare const isSvmNetwork: (network: X402Network) => boolean;
|
|
162
223
|
/**
|
|
163
|
-
* USDC
|
|
164
|
-
*
|
|
165
|
-
*
|
|
224
|
+
* USDC uses 6 decimals, so a USD price converts to atomic base units at `10 ** 6`.
|
|
225
|
+
* This is only the *default* for the standalone {@link usdToAtomic} helper —
|
|
226
|
+
* a spend policy never assumes it, and scales each requirement by the decimals of
|
|
227
|
+
* the asset it actually names (see {@link SpendPolicy.allowedAssets}).
|
|
166
228
|
* @experimental
|
|
167
229
|
*/
|
|
168
230
|
declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
231
|
+
/**
|
|
232
|
+
* A stablecoin an agent wallet may pay in, and the decimals its atomic amounts are
|
|
233
|
+
* denominated in.
|
|
234
|
+
*
|
|
235
|
+
* `decimals` is required and explicit: a 402 server names the token contract to
|
|
236
|
+
* transfer, and the same atomic amount means a wildly different sum in a 6-decimal
|
|
237
|
+
* versus an 18-decimal token. Assuming a decimal count is how a tiny USD cap comes
|
|
238
|
+
* to authorise a large transfer, so the caller states it per asset. Note
|
|
239
|
+
* `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
|
|
240
|
+
* (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
|
|
241
|
+
* @experimental
|
|
242
|
+
*/
|
|
243
|
+
interface AllowedAsset {
|
|
244
|
+
/** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
|
|
245
|
+
readonly asset: string;
|
|
246
|
+
/** Atomic base-unit decimals for this asset. Used to scale the USD caps — must match the token on chain. */
|
|
247
|
+
readonly decimals: number;
|
|
248
|
+
/** The network this asset lives on. Friendly names are resolved to CAIP-2. */
|
|
249
|
+
readonly network: X402Network;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* The assets a policy allows when it doesn't name its own — the canonical
|
|
253
|
+
* 6-decimal, dollar-pegged USDC on each network Lunora has a friendly alias for.
|
|
254
|
+
*
|
|
255
|
+
* Deliberately a small hand-mirrored table rather than `@x402/evm`'s
|
|
256
|
+
* `DEFAULT_STABLECOINS`: that registry mixes 6- and 18-decimal assets, and importing
|
|
257
|
+
* it would pull viem into every bundle that touches a policy (the scheme modules are
|
|
258
|
+
* dynamically imported for exactly that reason — see `wallet.ts`). Addresses verified
|
|
259
|
+
* against `@x402/evm` `DEFAULT_STABLECOINS` and `@x402/svm` `USDC_*_ADDRESS` at 2.19.0.
|
|
260
|
+
*
|
|
261
|
+
* `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
|
|
262
|
+
* paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
|
|
263
|
+
* @experimental
|
|
264
|
+
*/
|
|
265
|
+
declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
|
|
169
266
|
/**
|
|
170
267
|
* Spend limits and approval gates for an agent wallet. At least one bound must be
|
|
171
268
|
* set — see {@link assertBoundedPolicy} — or the pay rail refuses to build.
|
|
@@ -175,11 +272,30 @@ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
|
175
272
|
* @experimental
|
|
176
273
|
*/
|
|
177
274
|
interface SpendPolicy {
|
|
275
|
+
/**
|
|
276
|
+
* Asset allowlist, each entry carrying its own `decimals` (defaults to
|
|
277
|
+
* {@link DEFAULT_ALLOWED_ASSETS} — canonical USDC per friendly network).
|
|
278
|
+
*
|
|
279
|
+
* This is a **security gate, not a convenience**: the server picks which token
|
|
280
|
+
* contract gets transferred, so a policy that only caps a USD amount caps nothing
|
|
281
|
+
* until the asset behind that amount is pinned. A requirement naming an asset
|
|
282
|
+
* outside this list is refused, and the USD caps are scaled by the matched entry's
|
|
283
|
+
* `decimals` — never by an assumed decimal count.
|
|
284
|
+
*
|
|
285
|
+
* Every entry must be dollar-pegged: the caps are USD, and the per-run ledger sums
|
|
286
|
+
* atomic units across payments, so a non-$1 asset silently mis-prices both.
|
|
287
|
+
*/
|
|
288
|
+
readonly allowedAssets?: ReadonlyArray<AllowedAsset>;
|
|
178
289
|
/** Network allowlist. When set, only these networks may be paid on. */
|
|
179
290
|
readonly allowedNetworks?: ReadonlyArray<X402Network>;
|
|
180
291
|
/** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
|
|
181
292
|
readonly allowedRecipients?: ReadonlyArray<string>;
|
|
182
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated One policy-wide decimal count can't describe the assets a server may
|
|
295
|
+
* name, and guessing it is what let a small USD cap authorise a large transfer.
|
|
296
|
+
* Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
|
|
297
|
+
* its own `decimals` instead.
|
|
298
|
+
*/
|
|
183
299
|
readonly decimals?: number;
|
|
184
300
|
/** Hard ceiling on a single payment, in USD. */
|
|
185
301
|
readonly maxPerCall?: X402Price;
|
|
@@ -220,8 +336,16 @@ declare const createSpendState: () => SpendState;
|
|
|
220
336
|
declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
|
|
221
337
|
/**
|
|
222
338
|
* A `PaymentPolicy` that narrows the server's offered requirements to those a
|
|
223
|
-
* bounded wallet may pay: within the per-call cap
|
|
224
|
-
*
|
|
339
|
+
* bounded wallet may pay: in an allowed asset, within the per-call cap *for that
|
|
340
|
+
* asset's decimals*, to an allowed recipient, on an allowed network. An empty result
|
|
341
|
+
* means the client cannot pay — fail-closed.
|
|
342
|
+
*
|
|
343
|
+
* The asset check comes first and is what makes the amount check mean anything. The
|
|
344
|
+
* server chooses the token contract the scheme will sign a transfer against, and
|
|
345
|
+
* `amount` is in that token's atomic base units — so comparing it against a USD cap
|
|
346
|
+
* converted at an assumed decimal count mis-prices any asset that doesn't match the
|
|
347
|
+
* assumption. Pinning the asset (and taking its decimals from the policy, not the
|
|
348
|
+
* requirement) closes that.
|
|
225
349
|
* @experimental
|
|
226
350
|
*/
|
|
227
351
|
declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
@@ -239,6 +363,10 @@ declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
|
239
363
|
* hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
|
|
240
364
|
* later fails. The reservation is intentionally *not* released on success — a
|
|
241
365
|
* committed payment stays counted.
|
|
366
|
+
*
|
|
367
|
+
* The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
|
|
368
|
+
* the two are registered on separate client seams, and a guard that assumed the
|
|
369
|
+
* filter ran would be one wiring change away from signing an unpinned asset.
|
|
242
370
|
* @experimental
|
|
243
371
|
*/
|
|
244
372
|
declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
|
|
@@ -257,10 +385,11 @@ declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFai
|
|
|
257
385
|
* money on an agent's behalf with unlimited spend authority is never the intent,
|
|
258
386
|
* so this fails loudly rather than defaulting to unbounded.
|
|
259
387
|
*
|
|
260
|
-
* `allowedNetworks` / `allowedRecipients` narrow *where* a payment
|
|
261
|
-
*
|
|
262
|
-
* unlimited spend to any recipient it permits. Only `maxPerCall`,
|
|
263
|
-
* a dynamic `onPaymentRequired` gate actually bound spend, so only
|
|
388
|
+
* `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
|
|
389
|
+
* can go and *in what*, but none caps *how much* — a policy with only allowlists still
|
|
390
|
+
* authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
|
|
391
|
+
* `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
|
|
392
|
+
* those count here.
|
|
264
393
|
* @experimental
|
|
265
394
|
*/
|
|
266
395
|
declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
|
|
@@ -401,4 +530,4 @@ type X402SignerConfig = X402CdpSignerConfig | {
|
|
|
401
530
|
* @experimental
|
|
402
531
|
*/
|
|
403
532
|
declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
|
|
404
|
-
export {
|
|
533
|
+
export { AllowedAsset as A, FriendlyNetwork as B, type ClientEvmSigner as C, DEFAULT_ALLOWED_ASSETS as D, EvmAddress as E, type FacilitatorConfig as F, SVM_NETWORKS as G, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, type SpendPolicy as S, X402PayConfig as X, ClientSvmSigner as a, Caip2 as b, type DEFAULT_FACILITATOR_URL as c, type DEFAULT_STABLECOIN_DECIMALS as d, type SpendState as e, type X402CdpSignerConfig as f, type X402Network as g, X402Price as h, X402SignerConfig as i, assertBoundedPolicy as j, buildPaymentGuard as k, buildSpendPolicy as l, createSpendState as m, isEvmNetwork as n, isSvmNetwork as o, resolveFacilitatorUrl as p, X402ChargeConfig as q, releaseSpendOnFailure as r, X402Receipt as s, toCaip2 as t, usdToAtomic as u, X402ReceiptSink as v, X402Recipient as w, toPaymentEventRow as x, toReceipt as y, EVM_NETWORKS as z };
|
|
@@ -1,8 +1,69 @@
|
|
|
1
|
-
import { ClientEvmSigner } from '@x402/evm';
|
|
2
|
-
import { ClientSvmSigner } from '@x402/svm';
|
|
3
1
|
import { ProcessSettleSuccessResponse } from '@x402/core/http';
|
|
4
2
|
import { BeforePaymentCreationHook, PaymentPolicy, OnPaymentCreationFailureHook } from '@x402/core/client';
|
|
5
3
|
import { PaymentRequirements } from '@x402/core/types';
|
|
4
|
+
import { TransactionSigner } from '@solana/accounts';
|
|
5
|
+
/**
|
|
6
|
+
* ClientEvmSigner - Used by x402 clients to sign payment authorizations.
|
|
7
|
+
*
|
|
8
|
+
* Typically a viem LocalAccount:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const account = privateKeyToAccount('0x...');
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* Or composed via `toClientEvmSigner(account, publicClient)`.
|
|
14
|
+
*/
|
|
15
|
+
type ClientEvmSigner = {
|
|
16
|
+
readonly address: `0x${string}`;
|
|
17
|
+
signTypedData(message: {
|
|
18
|
+
domain: Record<string, unknown>;
|
|
19
|
+
types: Record<string, unknown>;
|
|
20
|
+
primaryType: string;
|
|
21
|
+
message: Record<string, unknown>;
|
|
22
|
+
}): Promise<`0x${string}`>;
|
|
23
|
+
/**
|
|
24
|
+
* Optional on-chain reads.
|
|
25
|
+
* Required only for extension enrichment (EIP-2612 / ERC-20 approval).
|
|
26
|
+
*/
|
|
27
|
+
readContract?(args: {
|
|
28
|
+
address: `0x${string}`;
|
|
29
|
+
abi: readonly unknown[];
|
|
30
|
+
functionName: string;
|
|
31
|
+
args?: readonly unknown[];
|
|
32
|
+
}): Promise<unknown>;
|
|
33
|
+
/**
|
|
34
|
+
* Optional: Signs a raw EIP-1559 transaction without broadcasting.
|
|
35
|
+
* Required for ERC-20 approval gas sponsoring when the token lacks EIP-2612.
|
|
36
|
+
*/
|
|
37
|
+
signTransaction?(args: {
|
|
38
|
+
to: `0x${string}`;
|
|
39
|
+
data: `0x${string}`;
|
|
40
|
+
nonce: number;
|
|
41
|
+
gas: bigint;
|
|
42
|
+
maxFeePerGas: bigint;
|
|
43
|
+
maxPriorityFeePerGas: bigint;
|
|
44
|
+
chainId: number;
|
|
45
|
+
}): Promise<`0x${string}`>;
|
|
46
|
+
/**
|
|
47
|
+
* Optional: Gets the current transaction count (nonce) for an address.
|
|
48
|
+
* Required for ERC-20 approval gas sponsoring.
|
|
49
|
+
*/
|
|
50
|
+
getTransactionCount?(args: {
|
|
51
|
+
address: `0x${string}`;
|
|
52
|
+
}): Promise<number>;
|
|
53
|
+
/**
|
|
54
|
+
* Optional: Estimates current gas fees per gas.
|
|
55
|
+
* Required for ERC-20 approval gas sponsoring.
|
|
56
|
+
*/
|
|
57
|
+
estimateFeesPerGas?(): Promise<{
|
|
58
|
+
maxFeePerGas: bigint;
|
|
59
|
+
maxPriorityFeePerGas: bigint;
|
|
60
|
+
}>;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Client-side signer for creating and signing Solana transactions
|
|
64
|
+
* This is a wrapper around TransactionSigner from @solana/kit
|
|
65
|
+
*/
|
|
66
|
+
type ClientSvmSigner = TransactionSigner;
|
|
6
67
|
/**
|
|
7
68
|
* A normalised record of one settled x402 payment. The settled `amount` is kept
|
|
8
69
|
* as its exact on-chain atomic-unit string (USDC has 6 decimals) — never coerced
|
|
@@ -160,12 +221,48 @@ declare const isEvmNetwork: (network: X402Network) => boolean;
|
|
|
160
221
|
*/
|
|
161
222
|
declare const isSvmNetwork: (network: X402Network) => boolean;
|
|
162
223
|
/**
|
|
163
|
-
* USDC
|
|
164
|
-
*
|
|
165
|
-
*
|
|
224
|
+
* USDC uses 6 decimals, so a USD price converts to atomic base units at `10 ** 6`.
|
|
225
|
+
* This is only the *default* for the standalone {@link usdToAtomic} helper —
|
|
226
|
+
* a spend policy never assumes it, and scales each requirement by the decimals of
|
|
227
|
+
* the asset it actually names (see {@link SpendPolicy.allowedAssets}).
|
|
166
228
|
* @experimental
|
|
167
229
|
*/
|
|
168
230
|
declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
231
|
+
/**
|
|
232
|
+
* A stablecoin an agent wallet may pay in, and the decimals its atomic amounts are
|
|
233
|
+
* denominated in.
|
|
234
|
+
*
|
|
235
|
+
* `decimals` is required and explicit: a 402 server names the token contract to
|
|
236
|
+
* transfer, and the same atomic amount means a wildly different sum in a 6-decimal
|
|
237
|
+
* versus an 18-decimal token. Assuming a decimal count is how a tiny USD cap comes
|
|
238
|
+
* to authorise a large transfer, so the caller states it per asset. Note
|
|
239
|
+
* `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
|
|
240
|
+
* (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
|
|
241
|
+
* @experimental
|
|
242
|
+
*/
|
|
243
|
+
interface AllowedAsset {
|
|
244
|
+
/** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
|
|
245
|
+
readonly asset: string;
|
|
246
|
+
/** Atomic base-unit decimals for this asset. Used to scale the USD caps — must match the token on chain. */
|
|
247
|
+
readonly decimals: number;
|
|
248
|
+
/** The network this asset lives on. Friendly names are resolved to CAIP-2. */
|
|
249
|
+
readonly network: X402Network;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* The assets a policy allows when it doesn't name its own — the canonical
|
|
253
|
+
* 6-decimal, dollar-pegged USDC on each network Lunora has a friendly alias for.
|
|
254
|
+
*
|
|
255
|
+
* Deliberately a small hand-mirrored table rather than `@x402/evm`'s
|
|
256
|
+
* `DEFAULT_STABLECOINS`: that registry mixes 6- and 18-decimal assets, and importing
|
|
257
|
+
* it would pull viem into every bundle that touches a policy (the scheme modules are
|
|
258
|
+
* dynamically imported for exactly that reason — see `wallet.ts`). Addresses verified
|
|
259
|
+
* against `@x402/evm` `DEFAULT_STABLECOINS` and `@x402/svm` `USDC_*_ADDRESS` at 2.19.0.
|
|
260
|
+
*
|
|
261
|
+
* `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
|
|
262
|
+
* paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
|
|
263
|
+
* @experimental
|
|
264
|
+
*/
|
|
265
|
+
declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
|
|
169
266
|
/**
|
|
170
267
|
* Spend limits and approval gates for an agent wallet. At least one bound must be
|
|
171
268
|
* set — see {@link assertBoundedPolicy} — or the pay rail refuses to build.
|
|
@@ -175,11 +272,30 @@ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
|
175
272
|
* @experimental
|
|
176
273
|
*/
|
|
177
274
|
interface SpendPolicy {
|
|
275
|
+
/**
|
|
276
|
+
* Asset allowlist, each entry carrying its own `decimals` (defaults to
|
|
277
|
+
* {@link DEFAULT_ALLOWED_ASSETS} — canonical USDC per friendly network).
|
|
278
|
+
*
|
|
279
|
+
* This is a **security gate, not a convenience**: the server picks which token
|
|
280
|
+
* contract gets transferred, so a policy that only caps a USD amount caps nothing
|
|
281
|
+
* until the asset behind that amount is pinned. A requirement naming an asset
|
|
282
|
+
* outside this list is refused, and the USD caps are scaled by the matched entry's
|
|
283
|
+
* `decimals` — never by an assumed decimal count.
|
|
284
|
+
*
|
|
285
|
+
* Every entry must be dollar-pegged: the caps are USD, and the per-run ledger sums
|
|
286
|
+
* atomic units across payments, so a non-$1 asset silently mis-prices both.
|
|
287
|
+
*/
|
|
288
|
+
readonly allowedAssets?: ReadonlyArray<AllowedAsset>;
|
|
178
289
|
/** Network allowlist. When set, only these networks may be paid on. */
|
|
179
290
|
readonly allowedNetworks?: ReadonlyArray<X402Network>;
|
|
180
291
|
/** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
|
|
181
292
|
readonly allowedRecipients?: ReadonlyArray<string>;
|
|
182
|
-
/**
|
|
293
|
+
/**
|
|
294
|
+
* @deprecated One policy-wide decimal count can't describe the assets a server may
|
|
295
|
+
* name, and guessing it is what let a small USD cap authorise a large transfer.
|
|
296
|
+
* Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
|
|
297
|
+
* its own `decimals` instead.
|
|
298
|
+
*/
|
|
183
299
|
readonly decimals?: number;
|
|
184
300
|
/** Hard ceiling on a single payment, in USD. */
|
|
185
301
|
readonly maxPerCall?: X402Price;
|
|
@@ -220,8 +336,16 @@ declare const createSpendState: () => SpendState;
|
|
|
220
336
|
declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
|
|
221
337
|
/**
|
|
222
338
|
* A `PaymentPolicy` that narrows the server's offered requirements to those a
|
|
223
|
-
* bounded wallet may pay: within the per-call cap
|
|
224
|
-
*
|
|
339
|
+
* bounded wallet may pay: in an allowed asset, within the per-call cap *for that
|
|
340
|
+
* asset's decimals*, to an allowed recipient, on an allowed network. An empty result
|
|
341
|
+
* means the client cannot pay — fail-closed.
|
|
342
|
+
*
|
|
343
|
+
* The asset check comes first and is what makes the amount check mean anything. The
|
|
344
|
+
* server chooses the token contract the scheme will sign a transfer against, and
|
|
345
|
+
* `amount` is in that token's atomic base units — so comparing it against a USD cap
|
|
346
|
+
* converted at an assumed decimal count mis-prices any asset that doesn't match the
|
|
347
|
+
* assumption. Pinning the asset (and taking its decimals from the policy, not the
|
|
348
|
+
* requirement) closes that.
|
|
225
349
|
* @experimental
|
|
226
350
|
*/
|
|
227
351
|
declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
@@ -239,6 +363,10 @@ declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
|
239
363
|
* hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
|
|
240
364
|
* later fails. The reservation is intentionally *not* released on success — a
|
|
241
365
|
* committed payment stays counted.
|
|
366
|
+
*
|
|
367
|
+
* The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
|
|
368
|
+
* the two are registered on separate client seams, and a guard that assumed the
|
|
369
|
+
* filter ran would be one wiring change away from signing an unpinned asset.
|
|
242
370
|
* @experimental
|
|
243
371
|
*/
|
|
244
372
|
declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
|
|
@@ -257,10 +385,11 @@ declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFai
|
|
|
257
385
|
* money on an agent's behalf with unlimited spend authority is never the intent,
|
|
258
386
|
* so this fails loudly rather than defaulting to unbounded.
|
|
259
387
|
*
|
|
260
|
-
* `allowedNetworks` / `allowedRecipients` narrow *where* a payment
|
|
261
|
-
*
|
|
262
|
-
* unlimited spend to any recipient it permits. Only `maxPerCall`,
|
|
263
|
-
* a dynamic `onPaymentRequired` gate actually bound spend, so only
|
|
388
|
+
* `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
|
|
389
|
+
* can go and *in what*, but none caps *how much* — a policy with only allowlists still
|
|
390
|
+
* authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
|
|
391
|
+
* `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
|
|
392
|
+
* those count here.
|
|
264
393
|
* @experimental
|
|
265
394
|
*/
|
|
266
395
|
declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
|
|
@@ -401,4 +530,4 @@ type X402SignerConfig = X402CdpSignerConfig | {
|
|
|
401
530
|
* @experimental
|
|
402
531
|
*/
|
|
403
532
|
declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
|
|
404
|
-
export {
|
|
533
|
+
export { AllowedAsset as A, FriendlyNetwork as B, type ClientEvmSigner as C, DEFAULT_ALLOWED_ASSETS as D, EvmAddress as E, type FacilitatorConfig as F, SVM_NETWORKS as G, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, type SpendPolicy as S, X402PayConfig as X, ClientSvmSigner as a, Caip2 as b, type DEFAULT_FACILITATOR_URL as c, type DEFAULT_STABLECOIN_DECIMALS as d, type SpendState as e, type X402CdpSignerConfig as f, type X402Network as g, X402Price as h, X402SignerConfig as i, assertBoundedPolicy as j, buildPaymentGuard as k, buildSpendPolicy as l, createSpendState as m, isEvmNetwork as n, isSvmNetwork as o, resolveFacilitatorUrl as p, X402ChargeConfig as q, releaseSpendOnFailure as r, X402Receipt as s, toCaip2 as t, usdToAtomic as u, X402ReceiptSink as v, X402Recipient as w, toPaymentEventRow as x, toReceipt as y, EVM_NETWORKS as z };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as u}from"@lunora/errors";const a=new Set(["ERR_MODULE_NOT_FOUND","MODULE_NOT_FOUND"]),i=/cannot find (?:module|package)|module not found|failed to resolve (?:module|import)/i,s=(t,o=3)=>{if(typeof t!="object"||t===null||o<0)return!1;const{cause:e,code:r,message:n}=t;return typeof r=="string"&&a.has(r)||typeof n=="string"&&i.test(n)?!0:s(e,o-1)},f=async(t,o)=>{try{return await t()}catch(e){throw s(e)?new u("ENV_INVALID",o,{cause:e}):e}};export{f as i};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as n}from"@lunora/errors";import{toCaip2 as p,isEvmNetwork as w}from"./EVM_NETWORKS-C5yyzK27.mjs";import{i as l}from"./optional-peer-BBhVxozi.mjs";const d=/^0x[0-9a-fA-F]{64}$/,y=async(t,e)=>{const a=await t(e);if(a===void 0||a.length===0)throw new n("ENV_INVALID",`x402 pay: secret "${e}" is not set — the agent wallet has no key to sign with.`);return a},m=(t,e)=>{const a=t.address.startsWith("0x");if(e&&!a)throw new n("ENV_INVALID",`x402 pay: the supplied signer address "${t.address}" is not an EVM (0x…) address, but the network is EVM.`);if(!e&&a)throw new n("ENV_INVALID",`x402 pay: the supplied signer address "${t.address}" is an EVM (0x…) address, but the network is Solana.`)},h=async(t,e)=>{const{CdpClient:a}=await l(()=>import("@coinbase/cdp-sdk"),'x402 pay: CDP-managed custody needs the optional @coinbase/cdp-sdk peer — install it, or use "raw-key"/"signer" custody instead.'),[c,s,r]=await Promise.all([y(e,t.apiKeyIdSecretName??"CDP_API_KEY_ID"),y(e,t.apiKeySecretName??"CDP_API_KEY_SECRET"),y(e,t.walletSecretName??"CDP_WALLET_SECRET")]);return new a({apiKeyId:c,apiKeySecret:s,walletSecret:r}).evm.getOrCreateAccount({name:t.account})},u=async t=>{const e=t.startsWith("0x")?t:`0x${t}`;if(!d.test(e))throw new n("ENV_INVALID","x402 pay: the EVM wallet key must be a 32-byte hex private key (64 hex chars, optional 0x prefix).");const{privateKeyToAccount:a}=await l(()=>import("viem/accounts"),'x402 pay: raw-key EVM custody needs the optional viem peer — install it, or use "cdp"/"signer" custody instead.');return a(e)},E=async t=>{const e=t.trim(),{createKeyPairSignerFromBytes:a,createKeyPairSignerFromPrivateKeyBytes:c,getBase58Encoder:s}=await l(()=>import("@solana/kit"),'x402 pay: raw-key Solana custody needs the optional @solana/kit peer — install it, or pass a pre-built signer via "signer" custody instead.');let r;if(e.startsWith("[")){let o;try{o=JSON.parse(e)}catch{throw new n("ENV_INVALID","x402 pay: the Solana wallet key looks like a JSON byte array but is not valid JSON.")}if(!Array.isArray(o)||o.some(i=>typeof i!="number"))throw new n("ENV_INVALID","x402 pay: the Solana wallet key JSON must be an array of byte values.");r=Uint8Array.from(o)}else try{r=Uint8Array.from(s().encode(e))}catch{throw new n("ENV_INVALID","x402 pay: the Solana wallet key must be a base58 secret key or a JSON byte array.")}if(r.length===64)return a(r);if(r.length===32)return c(r);throw new n("ENV_INVALID",`x402 pay: the Solana wallet key must decode to 32 or 64 bytes (got ${String(r.length)}). Provide a base58 secret key or a JSON byte array.`)},x=async(t,e,a)=>{const c=p(e.network),{signer:s}=e,r=w(e.network);let o;if(s.type==="signer")m(s.signer,r),o=s.signer;else if(s.type==="cdp"){if(!r)throw new n("NOT_IMPLEMENTED",`x402 pay: CDP-managed Solana custody (account "${s.account}") is not wired — a CDP Solana account is not a @solana/kit signer. Build a @solana/kit signer around it and pass it via the { type: "signer" } escape hatch, or use "raw-key".`);o=await h(s,a.getSecret)}else{const i=await y(a.getSecret,s.secretName);o=r?await u(i):await E(i)}if(r){const{registerExactEvmScheme:i}=await l(()=>import("@x402/evm/exact/client"),"x402 pay: EVM networks need the optional @x402/evm + viem peers — install them, or configure an SVM network.");i(t,{networks:[c],signer:o})}else{const{registerExactSvmScheme:i}=await l(()=>import("@x402/svm/exact/client"),"x402 pay: SVM networks need the optional @x402/svm + @solana/kit peers — install them, or configure an EVM network.");i(t,{networks:[c],signer:o})}};export{x as registerWallet,u as resolveEvmAccount,E as resolveSvmSigner};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=(r,o)=>({amount:r.amount??r.requirements.amount,asset:r.requirements.asset,from:r.payer,network:r.network,resource:o.resource,to:r.requirements.payTo,ts:o.ts,tx:r.transaction}),s=r=>({processedAt:r.ts,provider:"x402",providerEventId:r.tx,type:"x402.settled"});export{s as toPaymentEventRow,e as toReceipt};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createChargeMiddleware as w}from"./createChargeMiddleware-CURPSr23.mjs";const h=(o,r)=>{let t;return async(n,a)=>{t??=w(o).catch(i=>{throw t=void 0,i});const d=await t,e=n,c=typeof e.waitUntil=="function"?{waitUntil:i=>{e.waitUntil?.(i)}}:void 0;return d.handle(a,()=>r(n,a),c)}};export{h as withX402};
|
package/dist/pay/index.d.mts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { type
|
|
1
|
+
import { X as X402PayConfig, C as ClientEvmSigner, a as ClientSvmSigner } from "../packem_shared/index.d-C1PlJUJL.mjs";
|
|
2
|
+
export { type A as AllowedAsset, type b as Caip2, D as DEFAULT_ALLOWED_ASSETS, c as DEFAULT_FACILITATOR_URL, d as DEFAULT_STABLECOIN_DECIMALS, type S as SpendPolicy, type e as SpendState, type f as X402CdpSignerConfig, type g as X402Network, type h as X402Price, type i as X402SignerConfig, j as assertBoundedPolicy, k as buildPaymentGuard, l as buildSpendPolicy, m as createSpendState, n as isEvmNetwork, o as isSvmNetwork, r as releaseSpendOnFailure, p as resolveFacilitatorUrl, t as toCaip2, u as usdToAtomic } from "../packem_shared/index.d-C1PlJUJL.mjs";
|
|
3
3
|
import { x402Client } from '@x402/core/client';
|
|
4
|
-
import { ClientSvmSigner } from '@x402/svm';
|
|
5
|
-
import { PrivateKeyAccount } from 'viem/accounts';
|
|
6
|
-
import '@x402/evm';
|
|
7
4
|
import '@x402/core/http';
|
|
8
5
|
import '@x402/core/types';
|
|
6
|
+
import '@solana/accounts';
|
|
9
7
|
/** Reads a secret by name; resolves `undefined` when unset. */
|
|
10
8
|
type GetSecret = (name: string) => Promise<string | undefined> | string | undefined;
|
|
11
9
|
/**
|
|
@@ -17,12 +15,14 @@ interface WalletDeps {
|
|
|
17
15
|
readonly getSecret: GetSecret;
|
|
18
16
|
}
|
|
19
17
|
/**
|
|
20
|
-
* Resolve a
|
|
21
|
-
* or without the `0x` prefix.
|
|
22
|
-
* (`address` + `signTypedData`)
|
|
18
|
+
* Resolve a signer from a raw private key (a viem `LocalAccount` under the hood).
|
|
19
|
+
* The key may be given with or without the `0x` prefix. Typed as the structural
|
|
20
|
+
* `ClientEvmSigner` (`address` + `signTypedData`) rather than viem's own
|
|
21
|
+
* `PrivateKeyAccount` so the published declarations don't require the optional
|
|
22
|
+
* viem peer to type-check.
|
|
23
23
|
* @experimental
|
|
24
24
|
*/
|
|
25
|
-
declare const resolveEvmAccount: (privateKey: string) => Promise<
|
|
25
|
+
declare const resolveEvmAccount: (privateKey: string) => Promise<ClientEvmSigner>;
|
|
26
26
|
/**
|
|
27
27
|
* Resolve a `@solana/kit` `KeyPairSigner` from a raw Solana secret key. The secret
|
|
28
28
|
* may be given as a JSON byte array (`[12,34,…]`, the `solana-keygen` keyfile
|
package/dist/pay/index.d.ts
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { type
|
|
1
|
+
import { X as X402PayConfig, C as ClientEvmSigner, a as ClientSvmSigner } from "../packem_shared/index.d-C1PlJUJL.js";
|
|
2
|
+
export { type A as AllowedAsset, type b as Caip2, D as DEFAULT_ALLOWED_ASSETS, c as DEFAULT_FACILITATOR_URL, d as DEFAULT_STABLECOIN_DECIMALS, type S as SpendPolicy, type e as SpendState, type f as X402CdpSignerConfig, type g as X402Network, type h as X402Price, type i as X402SignerConfig, j as assertBoundedPolicy, k as buildPaymentGuard, l as buildSpendPolicy, m as createSpendState, n as isEvmNetwork, o as isSvmNetwork, r as releaseSpendOnFailure, p as resolveFacilitatorUrl, t as toCaip2, u as usdToAtomic } from "../packem_shared/index.d-C1PlJUJL.js";
|
|
3
3
|
import { x402Client } from '@x402/core/client';
|
|
4
|
-
import { ClientSvmSigner } from '@x402/svm';
|
|
5
|
-
import { PrivateKeyAccount } from 'viem/accounts';
|
|
6
|
-
import '@x402/evm';
|
|
7
4
|
import '@x402/core/http';
|
|
8
5
|
import '@x402/core/types';
|
|
6
|
+
import '@solana/accounts';
|
|
9
7
|
/** Reads a secret by name; resolves `undefined` when unset. */
|
|
10
8
|
type GetSecret = (name: string) => Promise<string | undefined> | string | undefined;
|
|
11
9
|
/**
|
|
@@ -17,12 +15,14 @@ interface WalletDeps {
|
|
|
17
15
|
readonly getSecret: GetSecret;
|
|
18
16
|
}
|
|
19
17
|
/**
|
|
20
|
-
* Resolve a
|
|
21
|
-
* or without the `0x` prefix.
|
|
22
|
-
* (`address` + `signTypedData`)
|
|
18
|
+
* Resolve a signer from a raw private key (a viem `LocalAccount` under the hood).
|
|
19
|
+
* The key may be given with or without the `0x` prefix. Typed as the structural
|
|
20
|
+
* `ClientEvmSigner` (`address` + `signTypedData`) rather than viem's own
|
|
21
|
+
* `PrivateKeyAccount` so the published declarations don't require the optional
|
|
22
|
+
* viem peer to type-check.
|
|
23
23
|
* @experimental
|
|
24
24
|
*/
|
|
25
|
-
declare const resolveEvmAccount: (privateKey: string) => Promise<
|
|
25
|
+
declare const resolveEvmAccount: (privateKey: string) => Promise<ClientEvmSigner>;
|
|
26
26
|
/**
|
|
27
27
|
* Resolve a `@solana/kit` `KeyPairSigner` from a raw Solana secret key. The secret
|
|
28
28
|
* may be given as a JSON byte array (`[12,34,…]`, the `solana-keygen` keyfile
|
package/dist/pay/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createPayFetch as c}from"../packem_shared/createPayFetch-
|
|
1
|
+
import{createPayFetch as c}from"../packem_shared/createPayFetch-yWtKD0NN.mjs";import{DEFAULT_FACILITATOR_URL as f,resolveFacilitatorUrl as p}from"../packem_shared/DEFAULT_FACILITATOR_URL-CPJNUMvi.mjs";import{isEvmNetwork as d,isSvmNetwork as y,toCaip2 as E}from"../packem_shared/EVM_NETWORKS-C5yyzK27.mjs";import{DEFAULT_ALLOWED_ASSETS as T,DEFAULT_STABLECOIN_DECIMALS as v,assertBoundedPolicy as F,buildPaymentGuard as P,buildSpendPolicy as h,createSpendState as _,releaseSpendOnFailure as x,usdToAtomic as D}from"../packem_shared/DEFAULT_ALLOWED_ASSETS-Bda-nP2p.mjs";import{registerWallet as w,resolveEvmAccount as C,resolveSvmSigner as I}from"../packem_shared/registerWallet-DvCt0Q7M.mjs";const i=async(e,t)=>({fetch:await c(e,t)}),m=(e,t)=>{let r;return{fetch:async(o,a)=>(r??=i(e,t),(await r).fetch(o,a))}};export{T as DEFAULT_ALLOWED_ASSETS,f as DEFAULT_FACILITATOR_URL,v as DEFAULT_STABLECOIN_DECIMALS,F as assertBoundedPolicy,P as buildPaymentGuard,h as buildSpendPolicy,c as createPayFetch,_ as createSpendState,i as createX402Pay,d as isEvmNetwork,y as isSvmNetwork,m as lazyX402Pay,w as registerWallet,x as releaseSpendOnFailure,C as resolveEvmAccount,p as resolveFacilitatorUrl,I as resolveSvmSigner,E as toCaip2,D as usdToAtomic};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/x402",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.70",
|
|
4
4
|
"description": "Agentic payments (x402) for Lunora: charge agents per request (charge rail) and let your agents pay x402-gated resources (pay rail)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -52,17 +52,17 @@
|
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
56
|
-
"@
|
|
57
|
-
"@x402/
|
|
58
|
-
"@x402/evm": "2.19.0",
|
|
59
|
-
"@x402/fetch": "2.19.0",
|
|
60
|
-
"@x402/svm": "2.19.0",
|
|
61
|
-
"viem": "2.55.8"
|
|
55
|
+
"@lunora/errors": "1.0.0-alpha.37",
|
|
56
|
+
"@x402/core": "2.25.0",
|
|
57
|
+
"@x402/fetch": "2.25.0"
|
|
62
58
|
},
|
|
63
59
|
"peerDependencies": {
|
|
64
60
|
"@coinbase/cdp-sdk": ">=1.0.0",
|
|
65
|
-
"@coinbase/x402": ">=2.0.0"
|
|
61
|
+
"@coinbase/x402": ">=2.0.0",
|
|
62
|
+
"@solana/kit": ">=7.0.0",
|
|
63
|
+
"@x402/evm": ">=2.0.0",
|
|
64
|
+
"@x402/svm": ">=2.0.0",
|
|
65
|
+
"viem": ">=2.0.0"
|
|
66
66
|
},
|
|
67
67
|
"peerDependenciesMeta": {
|
|
68
68
|
"@coinbase/cdp-sdk": {
|
|
@@ -70,6 +70,18 @@
|
|
|
70
70
|
},
|
|
71
71
|
"@coinbase/x402": {
|
|
72
72
|
"optional": true
|
|
73
|
+
},
|
|
74
|
+
"@solana/kit": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"@x402/evm": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"@x402/svm": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"viem": {
|
|
84
|
+
"optional": true
|
|
73
85
|
}
|
|
74
86
|
},
|
|
75
87
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const r="https://x402.org/facilitator",o=t=>t?.url??r;export{r as DEFAULT_FACILITATOR_URL,o as resolveFacilitatorUrl};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as l}from"@lunora/errors";import{toCaip2 as w}from"./EVM_NETWORKS-XOms9Rtk.mjs";const y=/^\d+(?:\.\d+)?$/,u=(e,t)=>t.startsWith("eip155:")?e.toLowerCase():e,d=6,R=()=>{let e=0n;return{add:t=>{e+=t},release:t=>{e=e>t?e-t:0n},get spentAtomic(){return e}}},m=(e,t=d)=>{if(!Number.isInteger(t)||t<0)throw new l("BAD_REQUEST",`x402 policy: decimals must be a non-negative integer, got ${String(t)}.`);const n=(typeof e=="number"?e.toString():e).trim(),o=n.startsWith("$")?n.slice(1):n;if(!y.test(o))throw new l("BAD_REQUEST",`x402 policy: "${String(e)}" is not a valid USD amount (use a plain decimal like "0.01").`);const[a="0",r=""]=o.split("."),i=r.slice(0,t).padEnd(t,"0");return BigInt(a)*10n**BigInt(t)+BigInt(i===""?"0":i)},v=e=>{const t=e.decimals??d,n=e.maxPerCall===void 0?void 0:m(e.maxPerCall,t),o=e.allowedNetworks?.map(r=>w(r)),{allowedRecipients:a}=e;return(r,i)=>i.filter(s=>{if(n!==void 0&&BigInt(s.amount)>n||o!==void 0&&!o.includes(s.network))return!1;if(a!==void 0){const c=u(s.payTo,s.network);return a.some(p=>u(p,s.network)===c)}return!0})},x=(e,t)=>{const n=e.decimals??d,o=e.maxPerRun===void 0?void 0:m(e.maxPerRun,n);return async a=>{const r=a.selectedRequirements,i=BigInt(r.amount);if(o!==void 0&&t.spentAtomic+i>o)return{abort:!0,reason:`x402 policy: this payment (${r.amount}) would exceed the per-run cap (already spent ${t.spentAtomic.toString()}, cap ${o.toString()}, in atomic base units).`};if(t.add(i),e.onPaymentRequired!==void 0&&!await e.onPaymentRequired(r))return t.release(i),{abort:!0,reason:"x402 policy: payment was declined by onPaymentRequired."}}},S=e=>t=>(e.release(BigInt(t.selectedRequirements.amount)),Promise.resolve()),f=e=>{if(!(e.maxPerCall!==void 0||e.maxPerRun!==void 0||e.onPaymentRequired!==void 0))throw new l("FORBIDDEN","x402 pay: refusing to build a wallet with an unbounded spend policy. Set at least one of maxPerCall, maxPerRun, or onPaymentRequired (allowedNetworks/allowedRecipients narrow but do not bound spend).")};export{d as DEFAULT_STABLECOIN_DECIMALS,f as assertBoundedPolicy,x as buildPaymentGuard,v as buildSpendPolicy,R as createSpendState,S as releaseSpendOnFailure,m as usdToAtomic};
|
|
@@ -1 +0,0 @@
|
|
|
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};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{x402HTTPResourceServer as P}from"@x402/core/http";import{toCaip2 as v,isEvmNetwork as x}from"./EVM_NETWORKS-XOms9Rtk.mjs";import{toReceipt as H}from"./toPaymentEventRow-D_kRVcb3.mjs";import{createFacilitatorClient as k}from"./createFacilitatorClient-Dj4Ll9xQ.mjs";const T=async e=>{const{x402ResourceServer:r}=await import("@x402/core/server"),t=new r(k(e.facilitator)),s=v(e.network);if(x(e.network)){const{registerExactEvmScheme:a}=await import("@x402/evm/exact/server");a(t,{networks:[s]})}else{const{registerExactSvmScheme:a}=await import("@x402/svm/exact/server");a(t,{networks:[s]})}return t},S="X-PAYMENT",E=e=>{const r=Object.create(null);for(const[t,s]of e)r[t]=s;return r},g=(e,r,t,s)=>{if(e!==void 0)try{const a=Promise.resolve(e(H(r,{resource:t,ts:Date.now()}))).catch(()=>{});s?.(a)}catch{}},b=e=>{const r=x(e.network),t=r?e.recipient.evm:e.recipient.svm;if(t===void 0||t.length===0)throw new Error(`x402 charge on "${e.network}" needs recipient.${r?"evm":"svm"} set.`);return t},q=e=>({accepts:{network:v(e.network),payTo:b(e),price:e.price,scheme:"exact"}}),A=(e,r)=>({getAcceptHeader:()=>e.headers.get("accept")??"",getHeader:t=>e.headers.get(t)??void 0,getMethod:()=>e.method,getPath:()=>r.pathname,getQueryParam:t=>{const s=r.searchParams.getAll(t);if(s.length!==0)return s.length===1?s[0]:s},getQueryParams:()=>{const t=Object.create(null);for(const s of new Set(r.searchParams.keys())){const a=r.searchParams.getAll(s),[i,...o]=a;i!==void 0&&(t[s]=o.length>0?a:i)}return t},getUrl:()=>e.url,getUserAgent:()=>e.headers.get("user-agent")??""}),m=e=>{const r=new Headers(e.headers),{body:t}=e;return t==null?new Response(void 0,{headers:r,status:e.status}):typeof t=="string"?(e.isHtml&&!r.has("content-type")&&r.set("content-type","text/html; charset=utf-8"),new Response(t,{headers:r,status:e.status})):Response.json(t,{headers:r,status:e.status})},R=(e,r)=>{const t=new Headers(e.headers);for(const[s,a]of Object.entries(r))t.set(s,a);return new Response(e.body,{headers:t,status:e.status,statusText:e.statusText})},O=async(e,r,t)=>{const s=await T(e),a=new P(s,{...q(e),...r});await a.initialize();const i=t?.settleBeforeHandler??!1;return{handle:async(o,h,w)=>{const y=new URL(o.url),l={adapter:A(o,y),method:o.method,path:y.pathname,paymentHeader:o.headers.get(S)??void 0},n=await a.processHTTPRequest(l);if(n.type==="no-payment-required")return h();if(n.type==="payment-error")return m(n.response);const f=r?.resource??o.url;if(i){const c=await a.processSettlement(n.paymentPayload,n.paymentRequirements,n.declaredExtensions,{request:l});if(!c.success)return m(c.response);g(e.onReceipt,c,f,w?.waitUntil);const d=await h();return R(d,c.headers)}let u;try{u=await h()}catch(c){try{await n.cancellationDispatcher.cancel({error:c,reason:"handler_threw"})}catch(d){console.error("x402 charge: failed to cancel payment after the handler threw",d)}throw c}const p=await a.processSettlement(n.paymentPayload,n.paymentRequirements,n.declaredExtensions,{request:l,responseHeaders:E(u.headers)});return p.success?(g(e.onReceipt,p,f,w?.waitUntil),R(u,p.headers)):m(p.response)}}};export{q as buildRoute,O as createChargeMiddleware,A as createRequestAdapter,g as reportReceipt,b as resolvePayTo,m as toResponse,R as withHeaders};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{HTTPFacilitatorClient as o}from"@x402/core/server";import{resolveFacilitatorUrl as i}from"./DEFAULT_FACILITATOR_URL-lUtljfJI.mjs";const s=r=>{const t=i(r);if(r?.headers===void 0)return new o({url:t});const e={...r.headers};return new o({createAuthHeaders:()=>Promise.resolve({settle:e,supported:e,verify:e}),url:t})};export{s as createFacilitatorClient};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{x402Client as i}from"@x402/core/client";import{wrapFetchWithPayment as a}from"@x402/fetch";import{assertBoundedPolicy as n,buildSpendPolicy as c,buildPaymentGuard as l,releaseSpendOnFailure as m,createSpendState as p}from"./DEFAULT_STABLECOIN_DECIMALS-dzQLLL1Z.mjs";import{registerWallet as y}from"./registerWallet-Cu4qF5tj.mjs";const u=async(r,t)=>{n(r.policy);const e=new i;await y(e,r,t);const o=p();return e.registerPolicy(c(r.policy)),e.onBeforePaymentCreation(l(r.policy,o)),e.onPaymentCreationFailure(m(o)),a(t.fetch??globalThis.fetch,e)};export{u as createPayFetch};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createChargeMiddleware as h}from"./createChargeMiddleware-MQhSA6Wt.mjs";const d=a=>{const r=new Map;return async(n,e,c,o)=>{let t=r.get(e.functionPath);return t===void 0&&(t=h({...a,price:e.price},{resource:e.functionPath},{settleBeforeHandler:!0}).catch(i=>{throw r.delete(e.functionPath),i}),r.set(e.functionPath,t)),(await t).handle(n,c,o)}};export{d as createProcedureChargeGate};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as i}from"@lunora/errors";import{toCaip2 as l,isEvmNetwork as w}from"./EVM_NETWORKS-XOms9Rtk.mjs";const p=/^0x[0-9a-fA-F]{64}$/,y=async(t,e)=>{const a=await t(e);if(a===void 0||a.length===0)throw new i("ENV_INVALID",`x402 pay: secret "${e}" is not set — the agent wallet has no key to sign with.`);return a},d=(t,e)=>{const a=t.address.startsWith("0x");if(e&&!a)throw new i("ENV_INVALID",`x402 pay: the supplied signer address "${t.address}" is not an EVM (0x…) address, but the network is EVM.`);if(!e&&a)throw new i("ENV_INVALID",`x402 pay: the supplied signer address "${t.address}" is an EVM (0x…) address, but the network is Solana.`)},h=async(t,e)=>{let a;try{a=await import("@coinbase/cdp-sdk")}catch{throw new i("ENV_INVALID",'x402 pay: CDP-managed custody needs the optional @coinbase/cdp-sdk peer — install it, or use "raw-key"/"signer" custody instead.')}const[c,s,r]=await Promise.all([y(e,t.apiKeyIdSecretName??"CDP_API_KEY_ID"),y(e,t.apiKeySecretName??"CDP_API_KEY_SECRET"),y(e,t.walletSecretName??"CDP_WALLET_SECRET")]);return new a.CdpClient({apiKeyId:c,apiKeySecret:s,walletSecret:r}).evm.getOrCreateAccount({name:t.account})},m=async t=>{const e=t.startsWith("0x")?t:`0x${t}`;if(!p.test(e))throw new i("ENV_INVALID","x402 pay: the EVM wallet key must be a 32-byte hex private key (64 hex chars, optional 0x prefix).");const{privateKeyToAccount:a}=await import("viem/accounts");return a(e)},g=async t=>{const e=t.trim(),{createKeyPairSignerFromBytes:a,createKeyPairSignerFromPrivateKeyBytes:c,getBase58Encoder:s}=await import("@solana/kit");let r;if(e.startsWith("[")){let n;try{n=JSON.parse(e)}catch{throw new i("ENV_INVALID","x402 pay: the Solana wallet key looks like a JSON byte array but is not valid JSON.")}if(!Array.isArray(n)||n.some(o=>typeof o!="number"))throw new i("ENV_INVALID","x402 pay: the Solana wallet key JSON must be an array of byte values.");r=Uint8Array.from(n)}else try{r=Uint8Array.from(s().encode(e))}catch{throw new i("ENV_INVALID","x402 pay: the Solana wallet key must be a base58 secret key or a JSON byte array.")}if(r.length===64)return a(r);if(r.length===32)return c(r);throw new i("ENV_INVALID",`x402 pay: the Solana wallet key must decode to 32 or 64 bytes (got ${String(r.length)}). Provide a base58 secret key or a JSON byte array.`)},E=async(t,e,a)=>{const c=l(e.network),{signer:s}=e,r=w(e.network);let n;if(s.type==="signer")d(s.signer,r),n=s.signer;else if(s.type==="cdp"){if(!r)throw new i("NOT_IMPLEMENTED",`x402 pay: CDP-managed Solana custody (account "${s.account}") is not wired — a CDP Solana account is not a @solana/kit signer. Build a @solana/kit signer around it and pass it via the { type: "signer" } escape hatch, or use "raw-key".`);n=await h(s,a.getSecret)}else{const o=await y(a.getSecret,s.secretName);n=r?await m(o):await g(o)}if(r){const{registerExactEvmScheme:o}=await import("@x402/evm/exact/client");o(t,{networks:[c],signer:n})}else{const{registerExactSvmScheme:o}=await import("@x402/svm/exact/client");o(t,{networks:[c],signer:n})}};export{E as registerWallet,m as resolveEvmAccount,g as resolveSvmSigner};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const r=(t,e)=>({amount:t.amount??t.requirements.amount,asset:t.requirements.asset,from:t.payer,network:t.network,resource:e.resource,to:t.requirements.payTo,ts:e.ts,tx:t.transaction}),o=t=>({processedAt:t.ts,provider:"x402",providerEventId:t.tx,type:"x402.settled"});export{o as toPaymentEventRow,r as toReceipt};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{createChargeMiddleware as h}from"./createChargeMiddleware-MQhSA6Wt.mjs";const d=(t,a)=>{let e;return async(o,r)=>(e??=h(t).catch(c=>{throw e=void 0,c}),(await e).handle(r,()=>a(o,r)))};export{d as withX402};
|