@lunora/x402 1.0.0-alpha.31 → 1.0.0-alpha.32

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.
@@ -69,21 +69,22 @@ type ChargeRouteOverrides = Pick<RouteConfig, "description" | "resource">;
69
69
  interface ChargeMiddlewareOptions {
70
70
  /**
71
71
  * Settle the verified payment **before** dispatching `runHandler`, instead
72
- * of after. Use this for a mutation/procedure gate: a settlement failure
73
- * then means the handler never runs at all, so a paid mutation's writes can
74
- * never be committed without payment (the free-execution gap X402-04
75
- * closes). Once settlement succeeds the payment is final (on-chain) — a
76
- * handler failure after that point is a normal application error, not a
77
- * payment to unwind: there is nothing left to cancel, so it is not caught
78
- * here and simply propagates.
72
+ * of after. **Default `true`** a settlement failure then means the handler
73
+ * never runs at all, so its side effects (writes, LLM calls, mail, push) can
74
+ * never happen unpaid. This matters because `verifyPayment` only checks the
75
+ * signed intent, NOT solvency: an underfunded or facilitator-refused payment
76
+ * passes verify and fails at `/settle`. Once settlement succeeds the payment
77
+ * is final (on-chain) a handler failure after that point is a normal
78
+ * application error, not a payment to unwind: there is nothing left to
79
+ * cancel, so it is not caught here and simply propagates.
79
80
  *
80
- * Default `false` (settle-after, the historical behaviour): the handler's
81
- * response is passed to settlement as transport context (`responseHeaders`
82
- * — read by some schemes for settlement overrides), and a handler throw
83
- * still releases the verified-but-unsettled payment via
84
- * `cancellationDispatcher.cancel`. Because settlement can still fail after
85
- * the handler already ran on this path, `.x402()` handlers gated this way
86
- * MUST be idempotent or compensatable see the `@lunora/x402` charge docs.
81
+ * Set `false` for settle-after: the handler's response is passed to
82
+ * settlement as transport context (`responseHeaders` — read by some schemes
83
+ * for settlement overrides), and a handler throw releases the
84
+ * verified-but-unsettled payment via `cancellationDispatcher.cancel`.
85
+ * Settlement can still FAIL after the handler already ran on this path, so a
86
+ * handler gated this way MUST be idempotent or compensatable opt in only
87
+ * when you need the response as settlement context and can accept that.
87
88
  */
88
89
  readonly settleBeforeHandler?: boolean;
89
90
  }
@@ -131,7 +132,7 @@ type X402ProcedureChargeGate = (request: Request, spec: X402ProcedureSpec, dispa
131
132
  * function's price + `resource`), since `createChargeMiddleware` fetches
132
133
  * facilitator support on first use. A failed init is not cached, so a transient
133
134
  * facilitator outage retries on the next request. Settlement runs before
134
- * `dispatch` (`settleBeforeHandler: true`) since `dispatch` commits the
135
+ * `dispatch` (the `settleBeforeHandler` default) since `dispatch` commits the
135
136
  * procedure's real mutation — see `createChargeMiddleware`'s `ChargeMiddlewareOptions`.
136
137
  * @experimental
137
138
  */
@@ -69,21 +69,22 @@ type ChargeRouteOverrides = Pick<RouteConfig, "description" | "resource">;
69
69
  interface ChargeMiddlewareOptions {
70
70
  /**
71
71
  * Settle the verified payment **before** dispatching `runHandler`, instead
72
- * of after. Use this for a mutation/procedure gate: a settlement failure
73
- * then means the handler never runs at all, so a paid mutation's writes can
74
- * never be committed without payment (the free-execution gap X402-04
75
- * closes). Once settlement succeeds the payment is final (on-chain) — a
76
- * handler failure after that point is a normal application error, not a
77
- * payment to unwind: there is nothing left to cancel, so it is not caught
78
- * here and simply propagates.
72
+ * of after. **Default `true`** a settlement failure then means the handler
73
+ * never runs at all, so its side effects (writes, LLM calls, mail, push) can
74
+ * never happen unpaid. This matters because `verifyPayment` only checks the
75
+ * signed intent, NOT solvency: an underfunded or facilitator-refused payment
76
+ * passes verify and fails at `/settle`. Once settlement succeeds the payment
77
+ * is final (on-chain) a handler failure after that point is a normal
78
+ * application error, not a payment to unwind: there is nothing left to
79
+ * cancel, so it is not caught here and simply propagates.
79
80
  *
80
- * Default `false` (settle-after, the historical behaviour): the handler's
81
- * response is passed to settlement as transport context (`responseHeaders`
82
- * — read by some schemes for settlement overrides), and a handler throw
83
- * still releases the verified-but-unsettled payment via
84
- * `cancellationDispatcher.cancel`. Because settlement can still fail after
85
- * the handler already ran on this path, `.x402()` handlers gated this way
86
- * MUST be idempotent or compensatable see the `@lunora/x402` charge docs.
81
+ * Set `false` for settle-after: the handler's response is passed to
82
+ * settlement as transport context (`responseHeaders` — read by some schemes
83
+ * for settlement overrides), and a handler throw releases the
84
+ * verified-but-unsettled payment via `cancellationDispatcher.cancel`.
85
+ * Settlement can still FAIL after the handler already ran on this path, so a
86
+ * handler gated this way MUST be idempotent or compensatable opt in only
87
+ * when you need the response as settlement context and can accept that.
87
88
  */
88
89
  readonly settleBeforeHandler?: boolean;
89
90
  }
@@ -131,7 +132,7 @@ type X402ProcedureChargeGate = (request: Request, spec: X402ProcedureSpec, dispa
131
132
  * function's price + `resource`), since `createChargeMiddleware` fetches
132
133
  * facilitator support on first use. A failed init is not cached, so a transient
133
134
  * facilitator outage retries on the next request. Settlement runs before
134
- * `dispatch` (`settleBeforeHandler: true`) since `dispatch` commits the
135
+ * `dispatch` (the `settleBeforeHandler` default) since `dispatch` commits the
135
136
  * procedure's real mutation — see `createChargeMiddleware`'s `ChargeMiddlewareOptions`.
136
137
  * @experimental
137
138
  */
@@ -1 +1 @@
1
- import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as o}from"../packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs";import{createFacilitatorClient as i}from"../packem_shared/createFacilitatorClient-Dj4Ll9xQ.mjs";import{isEvmNetwork as p,isSvmNetwork as c,toCaip2 as f}from"../packem_shared/EVM_NETWORKS-XOms9Rtk.mjs";import{withX402 as l}from"../packem_shared/withX402-D10895ct.mjs";import{createChargeMiddleware as C}from"../packem_shared/createChargeMiddleware-MQhSA6Wt.mjs";import{createProcedureChargeGate as F}from"../packem_shared/createProcedureChargeGate-Cfm5mD2y.mjs";import{toPaymentEventRow as d,toReceipt as h}from"../packem_shared/toPaymentEventRow-D_kRVcb3.mjs";export{t as DEFAULT_FACILITATOR_URL,C as createChargeMiddleware,i as createFacilitatorClient,F as createProcedureChargeGate,p as isEvmNetwork,c as isSvmNetwork,o as resolveFacilitatorUrl,f as toCaip2,d as toPaymentEventRow,h as toReceipt,l as withX402};
1
+ import{DEFAULT_FACILITATOR_URL as t,resolveFacilitatorUrl as o}from"../packem_shared/DEFAULT_FACILITATOR_URL-lUtljfJI.mjs";import{createFacilitatorClient as i}from"../packem_shared/createFacilitatorClient-Dj4Ll9xQ.mjs";import{isEvmNetwork as p,isSvmNetwork as c,toCaip2 as f}from"../packem_shared/EVM_NETWORKS-XOms9Rtk.mjs";import{withX402 as l}from"../packem_shared/withX402-B-JxoON3.mjs";import{createChargeMiddleware as C}from"../packem_shared/createChargeMiddleware-BtNcqDSy.mjs";import{createProcedureChargeGate as F}from"../packem_shared/createProcedureChargeGate-D3N5D-dW.mjs";import{toPaymentEventRow as d,toReceipt as h}from"../packem_shared/toPaymentEventRow-D_kRVcb3.mjs";export{t as DEFAULT_FACILITATOR_URL,C as createChargeMiddleware,i as createFacilitatorClient,F as createProcedureChargeGate,p as isEvmNetwork,c as isSvmNetwork,o as resolveFacilitatorUrl,f as toCaip2,d as toPaymentEventRow,h as toReceipt,l as withX402};
@@ -1 +1 @@
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
+ 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??!0;return{handle:async(o,h,w)=>{const y=new URL(o.url),u={adapter:A(o,y),method:o.method,path:y.pathname,paymentHeader:o.headers.get(S)??void 0},n=await a.processHTTPRequest(u);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:u});if(!c.success)return m(c.response);g(e.onReceipt,c,f,w?.waitUntil);const d=await h();return R(d,c.headers)}let l;try{l=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:u,responseHeaders:E(l.headers)});return p.success?(g(e.onReceipt,p,f,w?.waitUntil),R(l,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};
@@ -0,0 +1 @@
1
+ import{createChargeMiddleware as h}from"./createChargeMiddleware-BtNcqDSy.mjs";const d=a=>{const r=new Map;return async(c,t,n,o)=>{let e=r.get(t.functionPath);return e===void 0&&(e=h({...a,price:t.price},{resource:t.functionPath}).catch(i=>{throw r.delete(t.functionPath),i}),r.set(t.functionPath,e)),(await e).handle(c,n,o)}};export{d as createProcedureChargeGate};
@@ -1 +1 @@
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};
1
+ import{createChargeMiddleware as h}from"./createChargeMiddleware-BtNcqDSy.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};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lunora/x402",
3
- "version": "1.0.0-alpha.31",
3
+ "version": "1.0.0-alpha.32",
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{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};