@lunora/x402 1.0.0-alpha.12 → 1.0.0-alpha.14
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/dist/charge/index.d.mts +2 -2
- package/dist/charge/index.d.ts +2 -2
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/packem_shared/DEFAULT_ALLOWED_ASSETS-BIIP_mdG.mjs +1 -0
- package/dist/packem_shared/{config.d-B-NYmHgG.d.mts → config.d-Dki_2r9a.d.mts} +79 -11
- package/dist/packem_shared/{config.d-B-NYmHgG.d.ts → config.d-Dki_2r9a.d.ts} +79 -11
- package/dist/packem_shared/createPayFetch-B6A51xPI.mjs +1 -0
- package/dist/pay/index.d.mts +2 -2
- package/dist/pay/index.d.ts +2 -2
- package/dist/pay/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/packem_shared/DEFAULT_STABLECOIN_DECIMALS-gY9zXmGa.mjs +0 -1
- package/dist/packem_shared/createPayFetch-CDZJaS13.mjs +0 -1
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';
|
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';
|
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';
|
|
@@ -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};
|
|
@@ -160,12 +160,48 @@ declare const isEvmNetwork: (network: X402Network) => boolean;
|
|
|
160
160
|
*/
|
|
161
161
|
declare const isSvmNetwork: (network: X402Network) => boolean;
|
|
162
162
|
/**
|
|
163
|
-
* USDC
|
|
164
|
-
*
|
|
165
|
-
*
|
|
163
|
+
* USDC uses 6 decimals, so a USD price converts to atomic base units at `10 ** 6`.
|
|
164
|
+
* This is only the *default* for the standalone {@link usdToAtomic} helper —
|
|
165
|
+
* a spend policy never assumes it, and scales each requirement by the decimals of
|
|
166
|
+
* the asset it actually names (see {@link SpendPolicy.allowedAssets}).
|
|
166
167
|
* @experimental
|
|
167
168
|
*/
|
|
168
169
|
declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
170
|
+
/**
|
|
171
|
+
* A stablecoin an agent wallet may pay in, and the decimals its atomic amounts are
|
|
172
|
+
* denominated in.
|
|
173
|
+
*
|
|
174
|
+
* `decimals` is required and explicit: a 402 server names the token contract to
|
|
175
|
+
* transfer, and the same atomic amount means a wildly different sum in a 6-decimal
|
|
176
|
+
* versus an 18-decimal token. Assuming a decimal count is how a tiny USD cap comes
|
|
177
|
+
* to authorise a large transfer, so the caller states it per asset. Note
|
|
178
|
+
* `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
|
|
179
|
+
* (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
|
|
180
|
+
* @experimental
|
|
181
|
+
*/
|
|
182
|
+
interface AllowedAsset {
|
|
183
|
+
/** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
|
|
184
|
+
readonly asset: string;
|
|
185
|
+
/** Atomic base-unit decimals for this asset. Used to scale the USD caps — must match the token on chain. */
|
|
186
|
+
readonly decimals: number;
|
|
187
|
+
/** The network this asset lives on. Friendly names are resolved to CAIP-2. */
|
|
188
|
+
readonly network: X402Network;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The assets a policy allows when it doesn't name its own — the canonical
|
|
192
|
+
* 6-decimal, dollar-pegged USDC on each network Lunora has a friendly alias for.
|
|
193
|
+
*
|
|
194
|
+
* Deliberately a small hand-mirrored table rather than `@x402/evm`'s
|
|
195
|
+
* `DEFAULT_STABLECOINS`: that registry mixes 6- and 18-decimal assets, and importing
|
|
196
|
+
* it would pull viem into every bundle that touches a policy (the scheme modules are
|
|
197
|
+
* dynamically imported for exactly that reason — see `wallet.ts`). Addresses verified
|
|
198
|
+
* against `@x402/evm` `DEFAULT_STABLECOINS` and `@x402/svm` `USDC_*_ADDRESS` at 2.19.0.
|
|
199
|
+
*
|
|
200
|
+
* `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
|
|
201
|
+
* paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
|
|
202
|
+
* @experimental
|
|
203
|
+
*/
|
|
204
|
+
declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
|
|
169
205
|
/**
|
|
170
206
|
* Spend limits and approval gates for an agent wallet. At least one bound must be
|
|
171
207
|
* set — see {@link assertBoundedPolicy} — or the pay rail refuses to build.
|
|
@@ -175,11 +211,30 @@ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
|
175
211
|
* @experimental
|
|
176
212
|
*/
|
|
177
213
|
interface SpendPolicy {
|
|
214
|
+
/**
|
|
215
|
+
* Asset allowlist, each entry carrying its own `decimals` (defaults to
|
|
216
|
+
* {@link DEFAULT_ALLOWED_ASSETS} — canonical USDC per friendly network).
|
|
217
|
+
*
|
|
218
|
+
* This is a **security gate, not a convenience**: the server picks which token
|
|
219
|
+
* contract gets transferred, so a policy that only caps a USD amount caps nothing
|
|
220
|
+
* until the asset behind that amount is pinned. A requirement naming an asset
|
|
221
|
+
* outside this list is refused, and the USD caps are scaled by the matched entry's
|
|
222
|
+
* `decimals` — never by an assumed decimal count.
|
|
223
|
+
*
|
|
224
|
+
* Every entry must be dollar-pegged: the caps are USD, and the per-run ledger sums
|
|
225
|
+
* atomic units across payments, so a non-$1 asset silently mis-prices both.
|
|
226
|
+
*/
|
|
227
|
+
readonly allowedAssets?: ReadonlyArray<AllowedAsset>;
|
|
178
228
|
/** Network allowlist. When set, only these networks may be paid on. */
|
|
179
229
|
readonly allowedNetworks?: ReadonlyArray<X402Network>;
|
|
180
230
|
/** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
|
|
181
231
|
readonly allowedRecipients?: ReadonlyArray<string>;
|
|
182
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* @deprecated One policy-wide decimal count can't describe the assets a server may
|
|
234
|
+
* name, and guessing it is what let a small USD cap authorise a large transfer.
|
|
235
|
+
* Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
|
|
236
|
+
* its own `decimals` instead.
|
|
237
|
+
*/
|
|
183
238
|
readonly decimals?: number;
|
|
184
239
|
/** Hard ceiling on a single payment, in USD. */
|
|
185
240
|
readonly maxPerCall?: X402Price;
|
|
@@ -220,8 +275,16 @@ declare const createSpendState: () => SpendState;
|
|
|
220
275
|
declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
|
|
221
276
|
/**
|
|
222
277
|
* A `PaymentPolicy` that narrows the server's offered requirements to those a
|
|
223
|
-
* bounded wallet may pay: within the per-call cap
|
|
224
|
-
*
|
|
278
|
+
* bounded wallet may pay: in an allowed asset, within the per-call cap *for that
|
|
279
|
+
* asset's decimals*, to an allowed recipient, on an allowed network. An empty result
|
|
280
|
+
* means the client cannot pay — fail-closed.
|
|
281
|
+
*
|
|
282
|
+
* The asset check comes first and is what makes the amount check mean anything. The
|
|
283
|
+
* server chooses the token contract the scheme will sign a transfer against, and
|
|
284
|
+
* `amount` is in that token's atomic base units — so comparing it against a USD cap
|
|
285
|
+
* converted at an assumed decimal count mis-prices any asset that doesn't match the
|
|
286
|
+
* assumption. Pinning the asset (and taking its decimals from the policy, not the
|
|
287
|
+
* requirement) closes that.
|
|
225
288
|
* @experimental
|
|
226
289
|
*/
|
|
227
290
|
declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
@@ -239,6 +302,10 @@ declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
|
239
302
|
* hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
|
|
240
303
|
* later fails. The reservation is intentionally *not* released on success — a
|
|
241
304
|
* committed payment stays counted.
|
|
305
|
+
*
|
|
306
|
+
* The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
|
|
307
|
+
* the two are registered on separate client seams, and a guard that assumed the
|
|
308
|
+
* filter ran would be one wiring change away from signing an unpinned asset.
|
|
242
309
|
* @experimental
|
|
243
310
|
*/
|
|
244
311
|
declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
|
|
@@ -257,10 +324,11 @@ declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFai
|
|
|
257
324
|
* money on an agent's behalf with unlimited spend authority is never the intent,
|
|
258
325
|
* so this fails loudly rather than defaulting to unbounded.
|
|
259
326
|
*
|
|
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
|
|
327
|
+
* `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
|
|
328
|
+
* can go and *in what*, but none caps *how much* — a policy with only allowlists still
|
|
329
|
+
* authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
|
|
330
|
+
* `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
|
|
331
|
+
* those count here.
|
|
264
332
|
* @experimental
|
|
265
333
|
*/
|
|
266
334
|
declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
|
|
@@ -401,4 +469,4 @@ type X402SignerConfig = X402CdpSignerConfig | {
|
|
|
401
469
|
* @experimental
|
|
402
470
|
*/
|
|
403
471
|
declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
|
|
404
|
-
export { Caip2 as C, DEFAULT_FACILITATOR_URL as D, EVM_NETWORKS as E, FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, SVM_NETWORKS as S, X402CdpSignerConfig as X, EvmAddress as a, FriendlyNetwork as b, X402ChargeConfig as c, X402Network as d, X402PayConfig as e, X402Price as f, X402Receipt as g, X402ReceiptSink as h, X402Recipient as i, X402SignerConfig as j, isEvmNetwork as k, isSvmNetwork as l,
|
|
472
|
+
export { AllowedAsset as A, Caip2 as C, DEFAULT_FACILITATOR_URL as D, EVM_NETWORKS as E, FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, SVM_NETWORKS as S, X402CdpSignerConfig as X, EvmAddress as a, FriendlyNetwork as b, X402ChargeConfig as c, X402Network as d, X402PayConfig as e, X402Price as f, X402Receipt as g, X402ReceiptSink as h, X402Recipient as i, X402SignerConfig as j, isEvmNetwork as k, isSvmNetwork as l, DEFAULT_ALLOWED_ASSETS as m, DEFAULT_STABLECOIN_DECIMALS as n, SpendPolicy as o, SpendState as p, assertBoundedPolicy as q, resolveFacilitatorUrl as r, buildPaymentGuard as s, toCaip2 as t, buildSpendPolicy as u, createSpendState as v, releaseSpendOnFailure as w, usdToAtomic as x, toPaymentEventRow as y, toReceipt as z };
|
|
@@ -160,12 +160,48 @@ declare const isEvmNetwork: (network: X402Network) => boolean;
|
|
|
160
160
|
*/
|
|
161
161
|
declare const isSvmNetwork: (network: X402Network) => boolean;
|
|
162
162
|
/**
|
|
163
|
-
* USDC
|
|
164
|
-
*
|
|
165
|
-
*
|
|
163
|
+
* USDC uses 6 decimals, so a USD price converts to atomic base units at `10 ** 6`.
|
|
164
|
+
* This is only the *default* for the standalone {@link usdToAtomic} helper —
|
|
165
|
+
* a spend policy never assumes it, and scales each requirement by the decimals of
|
|
166
|
+
* the asset it actually names (see {@link SpendPolicy.allowedAssets}).
|
|
166
167
|
* @experimental
|
|
167
168
|
*/
|
|
168
169
|
declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
170
|
+
/**
|
|
171
|
+
* A stablecoin an agent wallet may pay in, and the decimals its atomic amounts are
|
|
172
|
+
* denominated in.
|
|
173
|
+
*
|
|
174
|
+
* `decimals` is required and explicit: a 402 server names the token contract to
|
|
175
|
+
* transfer, and the same atomic amount means a wildly different sum in a 6-decimal
|
|
176
|
+
* versus an 18-decimal token. Assuming a decimal count is how a tiny USD cap comes
|
|
177
|
+
* to authorise a large transfer, so the caller states it per asset. Note
|
|
178
|
+
* `@x402/evm`'s own `DEFAULT_STABLECOINS` registry is *not* uniformly 6-decimal
|
|
179
|
+
* (MegaUSD and Mezo USD are 18), which is exactly why it can't be trusted as a gate.
|
|
180
|
+
* @experimental
|
|
181
|
+
*/
|
|
182
|
+
interface AllowedAsset {
|
|
183
|
+
/** Token contract (EVM) or mint (SVM) address. Matched case-insensitively on EVM, exactly on SVM. */
|
|
184
|
+
readonly asset: string;
|
|
185
|
+
/** Atomic base-unit decimals for this asset. Used to scale the USD caps — must match the token on chain. */
|
|
186
|
+
readonly decimals: number;
|
|
187
|
+
/** The network this asset lives on. Friendly names are resolved to CAIP-2. */
|
|
188
|
+
readonly network: X402Network;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* The assets a policy allows when it doesn't name its own — the canonical
|
|
192
|
+
* 6-decimal, dollar-pegged USDC on each network Lunora has a friendly alias for.
|
|
193
|
+
*
|
|
194
|
+
* Deliberately a small hand-mirrored table rather than `@x402/evm`'s
|
|
195
|
+
* `DEFAULT_STABLECOINS`: that registry mixes 6- and 18-decimal assets, and importing
|
|
196
|
+
* it would pull viem into every bundle that touches a policy (the scheme modules are
|
|
197
|
+
* dynamically imported for exactly that reason — see `wallet.ts`). Addresses verified
|
|
198
|
+
* against `@x402/evm` `DEFAULT_STABLECOINS` and `@x402/svm` `USDC_*_ADDRESS` at 2.19.0.
|
|
199
|
+
*
|
|
200
|
+
* `ethereum` (`eip155:1`) is absent — the SDK ships no default stablecoin for it, so
|
|
201
|
+
* paying there needs an explicit {@link SpendPolicy.allowedAssets} entry.
|
|
202
|
+
* @experimental
|
|
203
|
+
*/
|
|
204
|
+
declare const DEFAULT_ALLOWED_ASSETS: ReadonlyArray<AllowedAsset>;
|
|
169
205
|
/**
|
|
170
206
|
* Spend limits and approval gates for an agent wallet. At least one bound must be
|
|
171
207
|
* set — see {@link assertBoundedPolicy} — or the pay rail refuses to build.
|
|
@@ -175,11 +211,30 @@ declare const DEFAULT_STABLECOIN_DECIMALS = 6;
|
|
|
175
211
|
* @experimental
|
|
176
212
|
*/
|
|
177
213
|
interface SpendPolicy {
|
|
214
|
+
/**
|
|
215
|
+
* Asset allowlist, each entry carrying its own `decimals` (defaults to
|
|
216
|
+
* {@link DEFAULT_ALLOWED_ASSETS} — canonical USDC per friendly network).
|
|
217
|
+
*
|
|
218
|
+
* This is a **security gate, not a convenience**: the server picks which token
|
|
219
|
+
* contract gets transferred, so a policy that only caps a USD amount caps nothing
|
|
220
|
+
* until the asset behind that amount is pinned. A requirement naming an asset
|
|
221
|
+
* outside this list is refused, and the USD caps are scaled by the matched entry's
|
|
222
|
+
* `decimals` — never by an assumed decimal count.
|
|
223
|
+
*
|
|
224
|
+
* Every entry must be dollar-pegged: the caps are USD, and the per-run ledger sums
|
|
225
|
+
* atomic units across payments, so a non-$1 asset silently mis-prices both.
|
|
226
|
+
*/
|
|
227
|
+
readonly allowedAssets?: ReadonlyArray<AllowedAsset>;
|
|
178
228
|
/** Network allowlist. When set, only these networks may be paid on. */
|
|
179
229
|
readonly allowedNetworks?: ReadonlyArray<X402Network>;
|
|
180
230
|
/** Recipient allowlist. When set, only these `payTo` addresses may be paid. */
|
|
181
231
|
readonly allowedRecipients?: ReadonlyArray<string>;
|
|
182
|
-
/**
|
|
232
|
+
/**
|
|
233
|
+
* @deprecated One policy-wide decimal count can't describe the assets a server may
|
|
234
|
+
* name, and guessing it is what let a small USD cap authorise a large transfer.
|
|
235
|
+
* Setting this now throws — put the asset in {@link SpendPolicy.allowedAssets} with
|
|
236
|
+
* its own `decimals` instead.
|
|
237
|
+
*/
|
|
183
238
|
readonly decimals?: number;
|
|
184
239
|
/** Hard ceiling on a single payment, in USD. */
|
|
185
240
|
readonly maxPerCall?: X402Price;
|
|
@@ -220,8 +275,16 @@ declare const createSpendState: () => SpendState;
|
|
|
220
275
|
declare const usdToAtomic: (usd: X402Price, decimals?: number) => bigint;
|
|
221
276
|
/**
|
|
222
277
|
* A `PaymentPolicy` that narrows the server's offered requirements to those a
|
|
223
|
-
* bounded wallet may pay: within the per-call cap
|
|
224
|
-
*
|
|
278
|
+
* bounded wallet may pay: in an allowed asset, within the per-call cap *for that
|
|
279
|
+
* asset's decimals*, to an allowed recipient, on an allowed network. An empty result
|
|
280
|
+
* means the client cannot pay — fail-closed.
|
|
281
|
+
*
|
|
282
|
+
* The asset check comes first and is what makes the amount check mean anything. The
|
|
283
|
+
* server chooses the token contract the scheme will sign a transfer against, and
|
|
284
|
+
* `amount` is in that token's atomic base units — so comparing it against a USD cap
|
|
285
|
+
* converted at an assumed decimal count mis-prices any asset that doesn't match the
|
|
286
|
+
* assumption. Pinning the asset (and taking its decimals from the policy, not the
|
|
287
|
+
* requirement) closes that.
|
|
225
288
|
* @experimental
|
|
226
289
|
*/
|
|
227
290
|
declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
@@ -239,6 +302,10 @@ declare const buildSpendPolicy: (policy: SpendPolicy) => PaymentPolicy;
|
|
|
239
302
|
* hook returns; {@link releaseSpendOnFailure} releases it if the signature itself
|
|
240
303
|
* later fails. The reservation is intentionally *not* released on success — a
|
|
241
304
|
* committed payment stays counted.
|
|
305
|
+
*
|
|
306
|
+
* The asset is re-checked here rather than trusted from {@link buildSpendPolicy}:
|
|
307
|
+
* the two are registered on separate client seams, and a guard that assumed the
|
|
308
|
+
* filter ran would be one wiring change away from signing an unpinned asset.
|
|
242
309
|
* @experimental
|
|
243
310
|
*/
|
|
244
311
|
declare const buildPaymentGuard: (policy: SpendPolicy, state: SpendState) => BeforePaymentCreationHook;
|
|
@@ -257,10 +324,11 @@ declare const releaseSpendOnFailure: (state: SpendState) => OnPaymentCreationFai
|
|
|
257
324
|
* money on an agent's behalf with unlimited spend authority is never the intent,
|
|
258
325
|
* so this fails loudly rather than defaulting to unbounded.
|
|
259
326
|
*
|
|
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
|
|
327
|
+
* `allowedNetworks` / `allowedRecipients` / `allowedAssets` narrow *where* a payment
|
|
328
|
+
* can go and *in what*, but none caps *how much* — a policy with only allowlists still
|
|
329
|
+
* authorises unlimited spend to any recipient it permits. Only `maxPerCall`,
|
|
330
|
+
* `maxPerRun`, or a dynamic `onPaymentRequired` gate actually bound spend, so only
|
|
331
|
+
* those count here.
|
|
264
332
|
* @experimental
|
|
265
333
|
*/
|
|
266
334
|
declare const assertBoundedPolicy: (policy: SpendPolicy) => void;
|
|
@@ -401,4 +469,4 @@ type X402SignerConfig = X402CdpSignerConfig | {
|
|
|
401
469
|
* @experimental
|
|
402
470
|
*/
|
|
403
471
|
declare const resolveFacilitatorUrl: (facilitator?: FacilitatorConfig) => string;
|
|
404
|
-
export { Caip2 as C, DEFAULT_FACILITATOR_URL as D, EVM_NETWORKS as E, FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, SVM_NETWORKS as S, X402CdpSignerConfig as X, EvmAddress as a, FriendlyNetwork as b, X402ChargeConfig as c, X402Network as d, X402PayConfig as e, X402Price as f, X402Receipt as g, X402ReceiptSink as h, X402Recipient as i, X402SignerConfig as j, isEvmNetwork as k, isSvmNetwork as l,
|
|
472
|
+
export { AllowedAsset as A, Caip2 as C, DEFAULT_FACILITATOR_URL as D, EVM_NETWORKS as E, FacilitatorConfig as F, NETWORK_TO_CAIP2 as N, PaymentEventRow as P, SVM_NETWORKS as S, X402CdpSignerConfig as X, EvmAddress as a, FriendlyNetwork as b, X402ChargeConfig as c, X402Network as d, X402PayConfig as e, X402Price as f, X402Receipt as g, X402ReceiptSink as h, X402Recipient as i, X402SignerConfig as j, isEvmNetwork as k, isSvmNetwork as l, DEFAULT_ALLOWED_ASSETS as m, DEFAULT_STABLECOIN_DECIMALS as n, SpendPolicy as o, SpendState as p, assertBoundedPolicy as q, resolveFacilitatorUrl as r, buildPaymentGuard as s, toCaip2 as t, buildSpendPolicy as u, createSpendState as v, releaseSpendOnFailure as w, usdToAtomic as x, toPaymentEventRow as y, toReceipt as z };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{x402Client as l}from"@x402/core/client";import{wrapFetchWithPayment as c}from"@x402/fetch";import{assertBoundedPolicy as m,buildSpendPolicy as p,buildPaymentGuard as y,releaseSpendOnFailure as s,createSpendState as d}from"./DEFAULT_ALLOWED_ASSETS-BIIP_mdG.mjs";import{registerWallet as P}from"./registerWallet-Cu4qF5tj.mjs";const S=async(r,t)=>{m(r.policy);const i=d(),o=p(r.policy),a=y(r.policy,i),n=s(i),e=new l;return await P(e,r,t),e.registerPolicy(o),e.onBeforePaymentCreation(a),e.onPaymentCreationFailure(n),c(t.fetch??globalThis.fetch,e)};export{S as createPayFetch};
|
package/dist/pay/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { e as X402PayConfig } from "../packem_shared/config.d-
|
|
2
|
-
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL,
|
|
1
|
+
import { e as X402PayConfig } from "../packem_shared/config.d-Dki_2r9a.mjs";
|
|
2
|
+
export { type A as AllowedAsset, type C as Caip2, m as DEFAULT_ALLOWED_ASSETS, D as DEFAULT_FACILITATOR_URL, n as DEFAULT_STABLECOIN_DECIMALS, type o as SpendPolicy, type p as SpendState, type X as X402CdpSignerConfig, type d as X402Network, type f as X402Price, type j as X402SignerConfig, q as assertBoundedPolicy, s as buildPaymentGuard, u as buildSpendPolicy, v as createSpendState, k as isEvmNetwork, l as isSvmNetwork, w as releaseSpendOnFailure, r as resolveFacilitatorUrl, t as toCaip2, x as usdToAtomic } from "../packem_shared/config.d-Dki_2r9a.mjs";
|
|
3
3
|
import { x402Client } from '@x402/core/client';
|
|
4
4
|
import { ClientSvmSigner } from '@x402/svm';
|
|
5
5
|
import { PrivateKeyAccount } from 'viem/accounts';
|
package/dist/pay/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { e as X402PayConfig } from "../packem_shared/config.d-
|
|
2
|
-
export { type C as Caip2, D as DEFAULT_FACILITATOR_URL,
|
|
1
|
+
import { e as X402PayConfig } from "../packem_shared/config.d-Dki_2r9a.js";
|
|
2
|
+
export { type A as AllowedAsset, type C as Caip2, m as DEFAULT_ALLOWED_ASSETS, D as DEFAULT_FACILITATOR_URL, n as DEFAULT_STABLECOIN_DECIMALS, type o as SpendPolicy, type p as SpendState, type X as X402CdpSignerConfig, type d as X402Network, type f as X402Price, type j as X402SignerConfig, q as assertBoundedPolicy, s as buildPaymentGuard, u as buildSpendPolicy, v as createSpendState, k as isEvmNetwork, l as isSvmNetwork, w as releaseSpendOnFailure, r as resolveFacilitatorUrl, t as toCaip2, x as usdToAtomic } from "../packem_shared/config.d-Dki_2r9a.js";
|
|
3
3
|
import { x402Client } from '@x402/core/client';
|
|
4
4
|
import { ClientSvmSigner } from '@x402/svm';
|
|
5
5
|
import { PrivateKeyAccount } from 'viem/accounts';
|
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-B6A51xPI.mjs";import{DEFAULT_FACILITATOR_URL as S,resolveFacilitatorUrl as A}from"../packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs";import{isEvmNetwork as d,isSvmNetwork as y,toCaip2 as E}from"../packem_shared/EVM_NETWORKS-XOms9Rtk.mjs";import{DEFAULT_ALLOWED_ASSETS as f,DEFAULT_STABLECOIN_DECIMALS as u,assertBoundedPolicy as T,buildPaymentGuard as v,buildSpendPolicy as F,createSpendState as P,releaseSpendOnFailure as _,usdToAtomic as x}from"../packem_shared/DEFAULT_ALLOWED_ASSETS-BIIP_mdG.mjs";import{registerWallet as U,resolveEvmAccount as h,resolveSvmSigner as w}from"../packem_shared/registerWallet-Cu4qF5tj.mjs";const i=async(e,r)=>({fetch:await c(e,r)}),s=(e,r)=>{let t;return{fetch:async(o,a)=>(t??=i(e,r),(await t).fetch(o,a))}};export{f as DEFAULT_ALLOWED_ASSETS,S as DEFAULT_FACILITATOR_URL,u as DEFAULT_STABLECOIN_DECIMALS,T as assertBoundedPolicy,v as buildPaymentGuard,F as buildSpendPolicy,c as createPayFetch,P as createSpendState,i as createX402Pay,d as isEvmNetwork,y as isSvmNetwork,s as lazyX402Pay,U as registerWallet,_ as releaseSpendOnFailure,h as resolveEvmAccount,A as resolveFacilitatorUrl,w as resolveSvmSigner,E as toCaip2,x 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.14",
|
|
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",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as s}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,l=6,v=()=>{let e=0n;return{add:t=>{e+=t},release:t=>{e=e>t?e-t:0n},get spentAtomic(){return e}}},m=(e,t=l)=>{if(!Number.isInteger(t)||t<0)throw new s("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 s("BAD_REQUEST",`x402 policy: "${String(e)}" is not a valid USD amount (use a plain decimal like "0.01").`);const[d="0",i=""]=o.split("."),r=i.slice(0,t).padEnd(t,"0");return BigInt(d)*10n**BigInt(t)+BigInt(r===""?"0":r)},R=e=>{const t=e.decimals??l,n=e.maxPerCall===void 0?void 0:m(e.maxPerCall,t),o=e.allowedNetworks?.map(i=>w(i)),{allowedRecipients:d}=e;return(i,r)=>r.filter(a=>{if(n!==void 0&&BigInt(a.amount)>n||o!==void 0&&!o.includes(a.network))return!1;if(d!==void 0){const c=u(a.payTo,a.network);return d.some(p=>u(p,a.network)===c)}return!0})},x=(e,t)=>{const n=e.decimals??l,o=e.maxPerRun===void 0?void 0:m(e.maxPerRun,n);return async d=>{const i=d.selectedRequirements,r=BigInt(i.amount);if(o!==void 0&&t.spentAtomic+r>o)return{abort:!0,reason:`x402 policy: this payment (${i.amount}) would exceed the per-run cap (already spent ${t.spentAtomic.toString()}, cap ${o.toString()}, in atomic base units).`};t.add(r);try{return e.onPaymentRequired!==void 0&&!await e.onPaymentRequired(i)?(t.release(r),{abort:!0,reason:"x402 policy: payment was declined by onPaymentRequired."}):void 0}catch(a){throw t.release(r),a}}},S=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 s("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{l as DEFAULT_STABLECOIN_DECIMALS,b as assertBoundedPolicy,x as buildPaymentGuard,R as buildSpendPolicy,v as createSpendState,S as releaseSpendOnFailure,m as usdToAtomic};
|
|
@@ -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-gY9zXmGa.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};
|