@dexterai/x402 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -8
- package/dist/adapters/index.d.cts +2 -3
- package/dist/adapters/index.d.ts +2 -3
- package/dist/batch-settlement/index.cjs +1 -1
- package/dist/batch-settlement/index.d.cts +5 -81
- package/dist/batch-settlement/index.d.ts +5 -81
- package/dist/batch-settlement/index.js +1 -1
- package/dist/batch-settlement/seller/index.cjs +1 -0
- package/dist/batch-settlement/seller/index.d.cts +17 -0
- package/dist/batch-settlement/seller/index.d.ts +17 -0
- package/dist/batch-settlement/seller/index.js +1 -0
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +3 -5
- package/dist/client/index.d.ts +3 -5
- package/dist/client/index.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.cts +4 -5
- package/dist/react/index.d.ts +4 -5
- package/dist/react/index.js +1 -1
- package/dist/server/index.cjs +16 -16
- package/dist/server/index.d.cts +20 -30
- package/dist/server/index.d.ts +20 -30
- package/dist/server/index.js +16 -16
- package/dist/{sponsored-access-BEufXQ6c.d.cts → sponsored-access-DC2x5LQ-.d.cts} +12 -2
- package/dist/{sponsored-access-4wVjCYrH.d.ts → sponsored-access-DSgmtjhF.d.ts} +12 -2
- package/dist/types-BBhXpBwI.d.cts +60 -0
- package/dist/types-BIINnfB4.d.ts +142 -0
- package/dist/types-Bbt_SDZE.d.cts +142 -0
- package/dist/types-CwK4mPWV.d.ts +60 -0
- package/dist/{types-HFS_C6RX.d.ts → types-IqnDBsjL.d.cts} +226 -2
- package/dist/{types-B3kS1y_t.d.cts → types-IqnDBsjL.d.ts} +226 -2
- package/package.json +8 -2
- package/dist/types-Bcsi5jQb.d.cts +0 -227
- package/dist/types-Bcsi5jQb.d.ts +0 -227
package/dist/server/index.d.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
import { P as PaymentAccept, V as VerifyResponse,
|
|
2
|
-
export {
|
|
1
|
+
import { P as PaymentAccept, V as VerifyResponse, e as SettleResponse, f as PayToProvider, g as PaymentRequired } from '../types-IqnDBsjL.js';
|
|
2
|
+
export { j as AccessPassClaims, A as AccessPassClientConfig, d as AccessPassInfo, b as AccessPassTier, h as PayToContext, i as PayToProviderDefaults } from '../types-IqnDBsjL.js';
|
|
3
|
+
import * as _x402_evm_batch_settlement_server from '@x402/evm/batch-settlement/server';
|
|
3
4
|
import { Request, RequestHandler } from 'express';
|
|
4
5
|
import { SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
5
6
|
export { SPONSORED_ACCESS_EXTENSION_KEY, SponsoredAccessClientConsent, SponsoredAccessPaymentRequiredInfo, SponsoredAccessSettlementInfo, SponsoredRecommendation } from '@dexterai/x402-ads-types';
|
|
7
|
+
import { B as BatchSettlementSeller } from '../types-CwK4mPWV.js';
|
|
6
8
|
export { b as BASE_MAINNET_NETWORK, D as DEXTER_FACILITATOR_URL, a as SOLANA_MAINNET_NETWORK, c as USDC_BASE, U as USDC_MINT } from '../constants-qU-4U3L-.js';
|
|
9
|
+
import '../types-BIINnfB4.js';
|
|
10
|
+
import '@x402/evm/batch-settlement/client';
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* Facilitator Client
|
|
@@ -210,33 +214,6 @@ interface X402Server {
|
|
|
210
214
|
*/
|
|
211
215
|
declare function createX402Server(config: X402ServerConfig): X402Server;
|
|
212
216
|
|
|
213
|
-
/**
|
|
214
|
-
* Express Middleware for x402 Payments
|
|
215
|
-
*
|
|
216
|
-
* One-liner middleware to protect any Express endpoint with x402 payments.
|
|
217
|
-
* Handles the entire flow: 402 response, payment verification, settlement.
|
|
218
|
-
*
|
|
219
|
-
* @example
|
|
220
|
-
* ```typescript
|
|
221
|
-
* import express from 'express';
|
|
222
|
-
* import { x402Middleware } from '@dexterai/x402/server';
|
|
223
|
-
*
|
|
224
|
-
* const app = express();
|
|
225
|
-
*
|
|
226
|
-
* app.get('/api/protected',
|
|
227
|
-
* x402Middleware({
|
|
228
|
-
* payTo: 'YourSolanaAddress...',
|
|
229
|
-
* amount: '0.01', // $0.01 USD
|
|
230
|
-
* network: 'solana:mainnet',
|
|
231
|
-
* }),
|
|
232
|
-
* (req, res) => {
|
|
233
|
-
* // This only runs after successful payment
|
|
234
|
-
* res.json({ data: 'protected content' });
|
|
235
|
-
* }
|
|
236
|
-
* );
|
|
237
|
-
* ```
|
|
238
|
-
*/
|
|
239
|
-
|
|
240
217
|
/**
|
|
241
218
|
* Middleware configuration
|
|
242
219
|
*/
|
|
@@ -320,6 +297,19 @@ interface X402MiddlewareConfig {
|
|
|
320
297
|
* batching scheme. Default: 'exact'.
|
|
321
298
|
*/
|
|
322
299
|
scheme?: 'exact' | 'batch-settlement';
|
|
300
|
+
/**
|
|
301
|
+
* Batch-settlement seller options. Only used when scheme is
|
|
302
|
+
* 'batch-settlement'. See createBatchSettlementSeller.
|
|
303
|
+
*/
|
|
304
|
+
batchSettlement?: {
|
|
305
|
+
autoSettle?: boolean | {
|
|
306
|
+
claimIntervalSecs?: number;
|
|
307
|
+
settleIntervalSecs?: number;
|
|
308
|
+
refundIntervalSecs?: number;
|
|
309
|
+
};
|
|
310
|
+
channelStore?: _x402_evm_batch_settlement_server.ChannelStorage;
|
|
311
|
+
route?: string;
|
|
312
|
+
};
|
|
323
313
|
/**
|
|
324
314
|
* Enable verbose logging
|
|
325
315
|
*/
|
|
@@ -425,7 +415,7 @@ interface X402Request extends Request {
|
|
|
425
415
|
network: string;
|
|
426
416
|
};
|
|
427
417
|
}
|
|
428
|
-
declare function x402Middleware(config: X402MiddlewareConfig): RequestHandler;
|
|
418
|
+
declare function x402Middleware(config: X402MiddlewareConfig): RequestHandler | BatchSettlementSeller;
|
|
429
419
|
|
|
430
420
|
/**
|
|
431
421
|
* x402 Browser Support Middleware
|
package/dist/server/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var F="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",be="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Pe="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var V="eip155:8453",ee="eip155:84532",te="eip155:42161",re="eip155:137",ne="eip155:10",se="eip155:43114",ie="eip155:56",oe="eip155:1187947933",ae="eip155:324705682",ce="eip155:1";var pe="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var me="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",_e="0x55d398326f99059fF775485246999027B3197955",Te="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",ht={[ie]:Te,[V]:me,[ee]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[te]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[re]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[ne]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[se]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[oe]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ae]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[ce]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},bt={[_e]:{symbol:"USDT",decimals:18},[Te]:{symbol:"USDC",decimals:18}},H=6;var Pt={[ie]:56,[V]:8453,[ee]:84532,[te]:42161,[re]:137,[ne]:10,[se]:43114,[oe]:1187947933,[ae]:324705682,[ce]:1},Tt={[F]:"https://api.dexter.cash/api/solana/rpc",[be]:"https://api.devnet.solana.com",[Pe]:"https://api.testnet.solana.com"},wt={[ie]:"https://bsc-dataseed1.binance.org",[V]:"https://api.dexter.cash/api/base/rpc",[ee]:"https://sepolia.base.org",[te]:"https://arb1.arbitrum.io/rpc",[re]:"https://polygon-rpc.com",[ne]:"https://mainnet.optimism.io",[se]:"https://api.avax.network/ext/bc/C/rpc",[oe]:"https://skale-base.skalenodes.com/v1/base",[ae]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[ce]:"https://eth.llamarpc.com"},B="https://x402.dexter.cash",de=F;function G(e,t){let n=Math.pow(10,t);return Math.floor(e*n).toString()}function we(e){return e.startsWith("solana:")||e==="solana"}function ve(e){if(typeof Buffer<"u")return Buffer.from(e,"utf-8").toString("base64");let t=new TextEncoder().encode(e),n="";for(let r=0;r<t.length;r++)n+=String.fromCharCode(t[r]);return btoa(n)}function Ne(e){if(typeof Buffer<"u")return Buffer.from(e,"base64").toString("utf-8");let t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return new TextDecoder().decode(n)}function W(e){return ve(JSON.stringify(e))}function j(e){return JSON.parse(Ne(e))}function Oe(e){if(e instanceof TypeError)return!0;if(e&&typeof e=="object"&&"status"in e){let t=e.status;return t>=500&&t<600}return!1}var X=class extends Error{status;body;constructor(t,n){super(`HTTP ${t}`),this.status=t,this.body=n}},J=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(t=B,n){this.facilitatorUrl=t.replace(/\/$/,""),this.timeoutMs=n?.timeoutMs??1e4,this.maxRetries=n?.maxRetries??3,this.retryBaseMs=n?.retryBaseMs??500}async fetchWithTimeout(t,n){let r=new AbortController,s=setTimeout(()=>r.abort(),this.timeoutMs);try{return await fetch(t,{...n,signal:r.signal})}finally{clearTimeout(s)}}async fetchWithRetry(t,n){let r;for(let s=0;s<this.maxRetries;s++)try{let c=await this.fetchWithTimeout(t,n);if(!c.ok&&c.status>=500)throw new X(c.status,await c.text());return c}catch(c){if(r=c,s<this.maxRetries-1&&Oe(c)){let l=this.retryBaseMs*Math.pow(2,s);await new Promise(P=>setTimeout(P,l));continue}throw c}throw r}async getSupported(){let t=Date.now();if(this.cachedSupported&&t-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let n=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!n.ok)throw new Error(`Facilitator /supported returned ${n.status}`);return this.cachedSupported=await n.json(),this.cacheTime=t,this.cachedSupported}async getFeePayer(t){let r=(await this.getSupported()).kinds.find(s=>s.x402Version===2&&(s.scheme==="exact"||s.scheme==="exact-approval")&&s.network===t);if(!r)throw new Error(`Facilitator does not support network "${t}" with a recognized scheme`);return r.extra?.feePayer}async getNetworkExtra(t){return(await this.getSupported()).kinds.find(s=>s.x402Version===2&&(s.scheme==="exact"||s.scheme==="exact-approval"||s.scheme==="batch-settlement")&&s.network===t)?.extra}async verifyPayment(t,n){try{let r=j(t),s=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return s.ok?await s.json():{isValid:!1,invalidReason:`facilitator_error_${s.status}`}}catch(r){return{isValid:!1,invalidReason:r instanceof X?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_verify_error"}}}async settlePayment(t,n){try{let r=j(t),s=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return s.ok?{...await s.json(),network:n.network}:{success:!1,network:n.network,errorReason:`facilitator_error_${s.status}`}}catch(r){let s=r instanceof X?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_settle_error";return{success:!1,network:n.network,errorReason:s}}}};function Ae(e){try{let t=j(e);return t?.accepted?.amount??t?.accepted?.maxAmountRequired}catch{return}}function Y(e){let{payTo:t,facilitatorUrl:n=B,network:r=F,asset:s={address:pe,decimals:6},defaultTimeoutSeconds:c=60}=e,l=e.scheme??"exact",P=new J(n),y=null,b=new Map,k=3e4,R=Date.now();function o(a){let i=(a.maxTimeoutSeconds||c)*1e3;if(b.set(a.payTo,{accept:a,expiresAt:Date.now()+i}),Date.now()-R>k){let T=Date.now();for(let[v,_]of b)_.expiresAt<T&&b.delete(v);R=T}}function x(a){let i=b.get(a);if(i){if(i.expiresAt<Date.now()){b.delete(a);return}return i.accept}}async function d(a){return typeof t=="string"?t:t(a||{})}async function f(){if(y||(y=await P.getNetworkExtra(r)),we(r)&&!y?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${r}"`);return{...y?.feePayer?{feePayer:y.feePayer}:{},decimals:y?.decimals??s.decimals,name:y?.name,version:y?.version,...l==="batch-settlement"&&y?.receiverAuthorizer?{receiverAuthorizer:y.receiverAuthorizer}:{}}}async function m(a,i){let{amountAtomic:T,timeoutSeconds:v=c}=i,_=await f(),w={scheme:l,network:r,amount:T,maxAmountRequired:T,asset:s.address,payTo:a,maxTimeoutSeconds:v,extra:_};return o(w),w}async function S(a){let i=await d({amountAtomic:a.amountAtomic,resourceUrl:a.resourceUrl});return m(i,a)}async function p(a){let{resourceUrl:i,description:T,mimeType:v="application/json"}=a,_={url:i,description:T,mimeType:v},w=await S(a);return{x402Version:2,resource:_,accepts:[w],error:"Payment required"}}function g(a){return W(a)}function u(a){return{status:402,headers:{"PAYMENT-REQUIRED":g(a)},body:{}}}async function h(a,i){if(!i){let T=await d({paymentHeader:a});i=x(T),i||(i=await m(T,{amountAtomic:Ae(a)??"0",resourceUrl:""}))}return P.verifyPayment(a,i)}async function E(a,i){if(!i){let T=await d({paymentHeader:a});i=x(T),i||(i=await m(T,{amountAtomic:Ae(a)??"0",resourceUrl:""}))}return P.settlePayment(a,i)}return{buildRequirements:p,encodeRequirements:g,create402Response:u,verifyPayment:h,settlePayment:E,getPaymentAccept:S,network:r,facilitator:P}}var Re=new WeakMap;function Se(e){return Re.get(e)}var Ce={base:"base","base-sepolia":"base_sepolia"},Ie={base:"eip155:8453","base-sepolia":"eip155:84532"};function De(e){let t=typeof e=="string"?{secretKey:e}:e,n=t.network??"base",r=Ce[n]??"base",s=Ie[n]??"eip155:8453",c=t.apiVersion??"2026-01-28.clover",l=null;async function P(){if(l)return l;try{let{default:b}=await import("stripe");return l=new b(t.secretKey,{apiVersion:c,appInfo:{name:"@dexterai/x402",url:"https://dexter.cash/sdk"}}),l}catch{throw new Error('The "stripe" package is required for stripePayTo(). Install it with: npm install stripe')}}let y=async b=>{if(b.paymentHeader){try{let S=JSON.parse(Buffer.from(b.paymentHeader,"base64").toString()),p=S.payload?.authorization?.to;if(p&&typeof p=="string")return p;let g=S.accepted?.payTo;if(g&&typeof g=="string")return g}catch{}throw new Error("Could not extract deposit address from payment header. Ensure the client is sending a valid x402 PAYMENT-SIGNATURE.")}let k=await P(),R=b.amountAtomic?parseInt(b.amountAtomic,10):1e4,o=Math.max(1,Math.round(R/Math.pow(10,H-2))),d=(await k.paymentIntents.create({amount:o,currency:"usd",payment_method_types:["crypto"],payment_method_data:{type:"crypto"},payment_method_options:{crypto:{mode:"custom"}},confirm:!0})).next_action;if(!d?.crypto_collect_deposit_details)throw new Error("Stripe PaymentIntent did not return crypto deposit details. Ensure your Stripe account has crypto payins enabled: https://support.stripe.com/questions/get-started-with-pay-with-crypto");let f=d.crypto_collect_deposit_details,m=f.deposit_addresses?.[r]?.address;if(!m)throw new Error(`No deposit address found for network "${r}". Available networks: ${Object.keys(f.deposit_addresses||{}).join(", ")}`);return m};return y._x402Defaults={network:s,facilitatorUrl:B},Re.set(y,s),y}function Ue(e,t){if(typeof e=="string"||typeof e=="function")return e;if(t in e)return e[t];let r=`${t.split(":")[0]}:*`;if(r in e)return e[r];if("*"in e)return e["*"];throw new Error(`No payTo configured for network "${t}"`)}function Be(e){let{payTo:t,amount:n,asset:r,description:s,resourceUrl:c,mimeType:l,timeoutSeconds:P,verbose:y=!1,getResourceUrl:b,getAmount:k,getDescription:R}=e,o=y?console.log.bind(console,"[x402:middleware]"):()=>{},x=typeof t=="function"?t._x402Defaults:void 0,d=e.facilitatorUrl??x?.facilitatorUrl,f=e.network?Array.isArray(e.network)?e.network:[e.network]:x?.network?[x.network]:[de],m=new Map;for(let p of f){let g=Ue(t,p);if(typeof g=="function"){let u=Se(g);if(u&&p!==u)throw new Error(`stripePayTo is configured for "${u}" but middleware includes network "${p}". Stripe only supports Base deposit addresses. Use a static payTo for other chains.`)}m.set(p,Y({payTo:g,network:p,asset:r,facilitatorUrl:d,defaultTimeoutSeconds:P,scheme:e.scheme}))}let S=m.get(f[0]);return async(p,g,u)=>{try{let h=p.headers["payment-signature"];if(!h){o("No payment signature, returning 402");let _=b?.(p)??c??`${p.protocol}://${p.get("host")}${p.originalUrl}`,w=k?.(p)??n,L=R?.(p)??s,A=r?.decimals??H,O={amountAtomic:G(parseFloat(w),A),resourceUrl:_,description:L,mimeType:l,timeoutSeconds:P},q=[],N=null;for(let[,le]of m)try{let Z=await le.buildRequirements(O);q.push(...Z.accepts),N||(N=Z)}catch(Z){o("Failed to build requirements for a network:",Z)}if(!N||q.length===0){g.status(500).json({error:"Failed to build payment requirements"});return}N={...N,accepts:q};let Q=S.encodeRequirements(N);g.setHeader("PAYMENT-REQUIRED",Q),g.status(402).json({error:"Payment required",accepts:N.accepts,resource:N.resource});return}o("Payment signature received, verifying...");let E=S;try{let w=JSON.parse(Buffer.from(h,"base64").toString())?.accepted?.network;w&&m.has(w)&&(E=m.get(w))}catch{}let a=await E.verifyPayment(h);if(!a.isValid){if(o("Payment verification failed:",a.invalidReason),e.onVerifyFailed)try{await e.onVerifyFailed({reason:a.invalidReason,resourceUrl:`${p.protocol}://${p.get("host")}${p.originalUrl}`})}catch{}g.status(402).json({error:"Payment verification failed",reason:a.invalidReason});return}o("Payment verified, settling...");let i=await E.settlePayment(h);if(!i.success){o("Payment settlement failed:",i.errorReason),g.status(402).json({error:"Payment settlement failed",reason:i.errorReason});return}o("Payment settled:",i.transaction);let T=i.network||f[0];if(e.onSettlement)try{await e.onSettlement({transaction:i.transaction,network:T,payer:a.payer??"",resourceUrl:`${p.protocol}://${p.get("host")}${p.originalUrl}`})}catch{}p.x402={transaction:i.transaction,payer:a.payer??"",network:T};let v={success:!0,transaction:i.transaction,network:T,payer:a.payer??""};if(i.extensions&&(v.extensions=i.extensions),g.setHeader("PAYMENT-RESPONSE",W(v)),e.sponsoredAccess&&i.extensions?.["sponsored-access"]){let _=i.extensions["sponsored-access"],w=_?.info?.recommendations??_?.recommendations;if(w&&w.length>0){if(o("Injecting sponsored-access recommendations into response"),typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.onMatch)try{e.sponsoredAccess.onMatch(w,{transaction:i.transaction,network:T,payer:a.payer??""})}catch{}let L=g.json.bind(g);g.json=function(M){return typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.inject?L(e.sponsoredAccess.inject(M,w)):M&&typeof M=="object"&&!Array.isArray(M)?L({_x402_sponsored:w,...M}):L(M)}}}u()}catch(h){o("Middleware error:",h),g.status(500).json({error:"Payment processing error"})}}}function C(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var $e='<svg width="18" height="18" viewBox="0 0 2000 2000" xmlns="http://www.w3.org/2000/svg"><path d="M1000 2000c554.17 0 1000-445.83 1000-1000S1554.17 0 1000 0 0 445.83 0 1000s445.83 1000 1000 1000z" fill="#2775ca"/><path d="M1275 1158.33c0-145.83-87.5-195.83-262.5-216.66-125-16.67-150-50-150-108.34s41.67-95.83 125-95.83c75 0 116.67 25 137.5 87.5 4.17 12.5 16.67 20.83 29.17 20.83h66.66c16.67 0 29.17-12.5 29.17-29.16v-4.17c-16.67-91.67-91.67-162.5-187.5-170.83v-100c0-16.67-12.5-29.17-33.33-33.34h-62.5c-16.67 0-29.17 12.5-33.34 33.34v95.83c-125 16.67-204.16 100-204.16 204.17 0 137.5 83.33 191.66 258.33 212.5 116.67 20.83 154.17 45.83 154.17 112.5s-58.34 112.5-137.5 112.5c-108.34 0-145.84-45.84-158.34-108.34-4.16-16.66-16.66-25-29.16-25h-70.84c-16.66 0-29.16 12.5-29.16 29.17v4.17c16.66 104.16 83.33 179.16 220.83 200v100c0 16.66 12.5 29.16 33.33 33.33h62.5c16.67 0 29.17-12.5 33.34-33.33v-100c125-20.84 208.33-108.34 208.33-220.84z" fill="#fff"/><path d="M787.5 1595.83c-325-116.66-491.67-479.16-370.83-800 62.5-175 200-308.33 370.83-370.83 16.67-8.33 25-20.83 25-41.67V325c0-16.67-8.33-29.17-25-33.33-4.17 0-12.5 0-16.67 4.16-395.83 125-612.5 545.84-487.5 941.67 75 233.33 254.17 412.5 487.5 487.5 16.67 8.33 33.34 0 37.5-16.67 4.17-4.16 4.17-8.33 4.17-16.66v-58.34c0-12.5-12.5-29.16-25-37.5zM1229.17 295.83c-16.67-8.33-33.34 0-37.5 16.67-4.17 4.17-4.17 8.33-4.17 16.67v58.33c0 16.67 12.5 33.33 25 41.67 325 116.66 491.67 479.16 370.83 800-62.5 175-200 308.33-370.83 370.83-16.67 8.33-25 20.83-25 41.67V1700c0 16.67 8.33 29.17 25 33.33 4.17 0 12.5 0 16.67-4.16 395.83-125 612.5-545.84 487.5-941.67-75-237.5-258.34-416.67-487.5-491.67z" fill="#fff"/></svg>',Le='<svg width="36" height="36" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg"><g><path fill="#F2681A" d="m324.93,313.11c-115.5,0-231,0-350,0l350,0z"/><path fill="#FDFAF5" d="m230.43,50.62c1.1.85 2.19 1.7 3.32 2.57 6.02 4.8 11.77 9.88 17.46 15.07.92.84.92.84 1.86 1.69 1.82 1.69 3.59 3.42 5.35 5.16.61.56 1.22 1.13 1.84 1.71 5.66 5.76 6.18 10.43 6.13 18.3.02 1.16.04 2.32.06 3.52.06 3.83.06 7.65.07 11.48.02 2.68.05 5.35.08 8.03.05 5.6.09 11.21.1 16.81.02 7.15.09 14.31.17 21.46.06 5.53.1 11.05.13 16.58.02 2.64.04 5.27.07 7.91.18 17.58.12 32.82-11.24 47.32-7.35 7.27-16.54 12.06-25.42 17.22-1.97 1.16-3.94 2.33-5.91 3.49-7.16 4.24-14.34 8.44-21.53 12.62-4.8 2.79-9.59 5.6-14.38 8.42-1.25.73-2.5 1.47-3.79 2.23-2.32 1.36-4.64 2.73-6.96 4.1-27.47 16.09-27.47 16.09-42.16 12.93-8.06-2.28-14.94-5.82-22.16-10.02-1.17-.67-2.34-1.34-3.54-2.04-24.55-14.25-43.58-27.03-51.9-55.58-1.07-4.58-1.54-8.92-1.52-13.61.28-9.5.28-9.5-3.3-17.97-1.81-1.49-3.68-2.92-5.59-4.28-9.19-7.06-12.7-20.03-14.18-31.06-.54-5.77-.55-11.56-.6-17.35-.03-1.32-.07-2.63-.1-3.99-.01-1.26-.02-2.53-.03-3.83-.02-1.15-.03-2.29-.05-3.47.72-4.02 1.94-5.36 5.21-7.74 2.89-.53 2.89-.53 6.07-.46 1.71.02 1.71.02 3.46.05 1.19.04 2.37.08 3.59.12 1.2.02 2.41.04 3.65.06 2.97.05 5.93.13 8.9.23.14-1.35.29-2.7.43-4.08.63-5 1.78-9.74 3.14-14.58.22-.79.43-1.59.66-2.4.53-1.92 1.06-3.84 1.6-5.76-1.55-.45-1.55-.45-3.13-.9-9.52-3.52-17.1-10.95-21.37-20.1-3.81-9.26-3.87-20.34-.29-29.68 6.49-13.99 16.36-23.23 30.66-29.01 49.81-17.69 115.79 8.35 155.13 38.85z"/><path fill="#F2671A" d="m142.93,22.62c.86.19 1.73.39 2.62.59 36.12 8.21 68.79 24.98 95.38 50.75 1.02.98 2.03 1.97 3.08 2.98 10.84 10.66 10.84 10.66 11.05 14.62-2.06 3.55-5.44 4.18-9.17 5.3-.79.25-1.59.49-2.41.75-28.13 8.43-60.95 6.37-87.13-7.16-.86-.49-1.71-.97-2.6-1.48-7.37-4.05-12.59-3.36-20.59-1.54-22.76 4-48.47 1.53-68.69-9.74-4.88-3.88-8.23-8.29-10.21-14.22-.93-10.38-.67-18.44 5.83-26.83 19.57-23.38 55.99-20.36 82.83-14z"/><path fill="#F16619" d="m44.93,129.12c27.36-.03 54.72-.05 82.08-.06 12.7-.01 25.41-.01 38.11-.03 11.07-.01 22.14-.02 33.2-.02 5.86 0 11.73-.01 17.59-.01 5.51-.01 11.03-.01 16.54-.01 2.03 0 4.06 0 6.09-.01 2.76-.01 5.52 0 8.28 0 .81 0 1.63-.01 2.47-.01 5.51.02 5.51.02 6.81 1.32.22 3.43.22 3.43 0 7-2.75 2.75-3.42 2.66-7.15 2.82-1.41.07-1.41.07-2.85.14-1.47.05-1.47.05-2.98.11-1.49.07-1.49.07-3 .14-2.45.11-4.9.21-7.35.3-.2 1.3-.4 2.59-.6 3.93-2.57 16.08-5.93 29.89-18.89 40.86-10.35 7.28-21.87 8.49-34.17 7.71-13.11-2.33-22.52-9.19-30.33-19.83-4.49-7.64-4.8-17.05-5.83-25.67-4.24.39-8.47.77-12.83 1.17-.28 1.84-.28 1.84-.56 3.71-2.32 14.39-5.63 23.35-16.95 33.11-2.32 1.67-2.32 1.67-4.65 1.67 4 4.67 9.06 6.59 14.87 8.24 3.79 1.09 3.79 1.09 6.12 3.43-.65 5.31-.65 5.31-2.33 7-8.42-.27-15.13-2.29-22.17-7-1.09-1.21-2.17-2.43-3.25-3.65-2.72-2.81-4.45-3.84-8.36-4.16-1.67-.02-3.34-.02-5.01.01-1.77-.04-3.54-.09-5.3-.15-1.27-.04-1.27-.04-2.56-.08-9.26-.54-17.6-4.56-24.51-10.64-9.58-11.11-11.03-22.56-10.72-36.82.02-1.4.03-2.8.05-4.24.04-3.42.1-6.85.17-10.27z"/><path fill="#F26117" d="m172.68,203.08c7.27.09 13.23 1.97 18.87 6.65 2.88 3.07 3.86 5.12 4.25 9.32-.12 1.01-.24 2.02-.36 3.06-2.55.95-2.55.95-5.83 1.17-3.28-2.84-3.28-2.84-5.83-5.83-.36.58-.71 1.16-1.08 1.75-7.6 11.29-20.06 17.74-33.05 21.09-20.36 3.1-36.81-1.66-53.37-13.73-2.33-2.11-2.33-2.11-4.67-5.61.42-3.45.99-4.49 3.5-7 4.07.37 5.95 2.13 8.75 4.96 9.81 8.93 22.53 11.87 35.51 11.69 11.74-1.05 22.38-5.85 31.57-13.15 2.06-2.45 2.06-2.45 3.5-4.67-1.66.07-1.66.07-3.35.15-3.65-.15-3.65-.15-5.98-2.48.75-6.18 1.46-7.19 7.58-7.36z"/></g></svg>',qe=`
|
|
1
|
+
var q="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Te="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Se="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var z="eip155:8453",ee="eip155:84532",te="eip155:42161",re="eip155:137",ne="eip155:10",se="eip155:43114",oe="eip155:56",ie="eip155:1187947933",ae="eip155:324705682",ce="eip155:1";var pe="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var me="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Be="0x55d398326f99059fF775485246999027B3197955",we="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ut={[oe]:we,[z]:me,[ee]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[te]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[re]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[ne]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[se]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[ie]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ae]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[ce]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Bt={[Be]:{symbol:"USDT",decimals:18},[we]:{symbol:"USDC",decimals:18}},j=6;var $t={[oe]:56,[z]:8453,[ee]:84532,[te]:42161,[re]:137,[ne]:10,[se]:43114,[ie]:1187947933,[ae]:324705682,[ce]:1},Lt={[q]:"https://api.dexter.cash/api/solana/rpc",[Te]:"https://api.devnet.solana.com",[Se]:"https://api.testnet.solana.com"},Ft={[oe]:"https://bsc-dataseed1.binance.org",[z]:"https://api.dexter.cash/api/base/rpc",[ee]:"https://sepolia.base.org",[te]:"https://arb1.arbitrum.io/rpc",[re]:"https://polygon-rpc.com",[ne]:"https://mainnet.optimism.io",[se]:"https://api.avax.network/ext/bc/C/rpc",[ie]:"https://skale-base.skalenodes.com/v1/base",[ae]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[ce]:"https://eth.llamarpc.com"},B="https://x402.dexter.cash",le=q;function V(e,t){let n=Math.pow(10,t);return Math.floor(e*n).toString()}function Re(e){return e.startsWith("solana:")||e==="solana"}function $e(e){if(typeof Buffer<"u")return Buffer.from(e,"utf-8").toString("base64");let t=new TextEncoder().encode(e),n="";for(let r=0;r<t.length;r++)n+=String.fromCharCode(t[r]);return btoa(n)}function Le(e){if(typeof Buffer<"u")return Buffer.from(e,"base64").toString("utf-8");let t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return new TextDecoder().decode(n)}function W(e){return $e(JSON.stringify(e))}function G(e){return JSON.parse(Le(e))}function Fe(e){if(e instanceof TypeError)return!0;if(e&&typeof e=="object"&&"status"in e){let t=e.status;return t>=500&&t<600}return!1}var X=class extends Error{status;body;constructor(t,n){super(`HTTP ${t}`),this.status=t,this.body=n}},J=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(t=B,n){this.facilitatorUrl=t.replace(/\/$/,""),this.timeoutMs=n?.timeoutMs??1e4,this.maxRetries=n?.maxRetries??3,this.retryBaseMs=n?.retryBaseMs??500}async fetchWithTimeout(t,n){let r=new AbortController,s=setTimeout(()=>r.abort(),this.timeoutMs);try{return await fetch(t,{...n,signal:r.signal})}finally{clearTimeout(s)}}async fetchWithRetry(t,n){let r;for(let s=0;s<this.maxRetries;s++)try{let p=await this.fetchWithTimeout(t,n);if(!p.ok&&p.status>=500)throw new X(p.status,await p.text());return p}catch(p){if(r=p,s<this.maxRetries-1&&Fe(p)){let l=this.retryBaseMs*Math.pow(2,s);await new Promise(y=>setTimeout(y,l));continue}throw p}throw r}async getSupported(){let t=Date.now();if(this.cachedSupported&&t-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let n=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!n.ok)throw new Error(`Facilitator /supported returned ${n.status}`);return this.cachedSupported=await n.json(),this.cacheTime=t,this.cachedSupported}async getFeePayer(t){let r=(await this.getSupported()).kinds.find(s=>s.x402Version===2&&(s.scheme==="exact"||s.scheme==="exact-approval")&&s.network===t);if(!r)throw new Error(`Facilitator does not support network "${t}" with a recognized scheme`);return r.extra?.feePayer}async getNetworkExtra(t){return(await this.getSupported()).kinds.find(s=>s.x402Version===2&&(s.scheme==="exact"||s.scheme==="exact-approval"||s.scheme==="batch-settlement")&&s.network===t)?.extra}async verifyPayment(t,n){try{let r=G(t),s=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return s.ok?await s.json():{isValid:!1,invalidReason:`facilitator_error_${s.status}`}}catch(r){return{isValid:!1,invalidReason:r instanceof X?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_verify_error"}}}async settlePayment(t,n){try{let r=G(t),s=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return s.ok?{...await s.json(),network:n.network}:{success:!1,network:n.network,errorReason:`facilitator_error_${s.status}`}}catch(r){let s=r instanceof X?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_settle_error";return{success:!1,network:n.network,errorReason:s}}}};function Ae(e){try{let t=G(e);return t?.accepted?.amount??t?.accepted?.maxAmountRequired}catch{return}}function Y(e){let{payTo:t,facilitatorUrl:n=B,network:r=q,asset:s={address:pe,decimals:6},defaultTimeoutSeconds:p=60}=e,l=e.scheme??"exact",y=new J(n),g=null,h=new Map,S=3e4,c=Date.now();function o(a){let i=(a.maxTimeoutSeconds||p)*1e3;if(h.set(a.payTo,{accept:a,expiresAt:Date.now()+i}),Date.now()-c>S){let w=Date.now();for(let[_,M]of h)M.expiresAt<w&&h.delete(_);c=w}}function f(a){let i=h.get(a);if(i){if(i.expiresAt<Date.now()){h.delete(a);return}return i.accept}}async function m(a){return typeof t=="string"?t:t(a||{})}async function x(){if(g||(g=await y.getNetworkExtra(r)),Re(r)&&!g?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${r}"`);return{...g?.feePayer?{feePayer:g.feePayer}:{},decimals:g?.decimals??s.decimals,name:g?.name,version:g?.version,...l==="batch-settlement"&&g?.receiverAuthorizer?{receiverAuthorizer:g.receiverAuthorizer}:{}}}async function T(a,i){let{amountAtomic:w,timeoutSeconds:_=p}=i,M=await x(),A={scheme:l,network:r,amount:w,maxAmountRequired:w,asset:s.address,payTo:a,maxTimeoutSeconds:_,extra:M};return o(A),A}async function E(a){let i=await m({amountAtomic:a.amountAtomic,resourceUrl:a.resourceUrl});return T(i,a)}async function d(a){let{resourceUrl:i,description:w,mimeType:_="application/json"}=a,M={url:i,description:w,mimeType:_},A=await E(a);return{x402Version:2,resource:M,accepts:[A],error:"Payment required"}}function u(a){return W(a)}function b(a){return{status:402,headers:{"PAYMENT-REQUIRED":u(a)},body:{}}}async function P(a,i){if(!i){let w=await m({paymentHeader:a});i=f(w),i||(i=await T(w,{amountAtomic:Ae(a)??"0",resourceUrl:""}))}return y.verifyPayment(a,i)}async function R(a,i){if(!i){let w=await m({paymentHeader:a});i=f(w),i||(i=await T(w,{amountAtomic:Ae(a)??"0",resourceUrl:""}))}return y.settlePayment(a,i)}return{buildRequirements:d,encodeRequirements:u,create402Response:b,verifyPayment:P,settlePayment:R,getPaymentAccept:E,network:r,facilitator:y}}var Ee=new WeakMap;function ke(e){return Ee.get(e)}var qe={base:"base","base-sepolia":"base_sepolia"},We={base:"eip155:8453","base-sepolia":"eip155:84532"};function Ke(e){let t=typeof e=="string"?{secretKey:e}:e,n=t.network??"base",r=qe[n]??"base",s=We[n]??"eip155:8453",p=t.apiVersion??"2026-01-28.clover",l=null;async function y(){if(l)return l;try{let{default:h}=await import("stripe");return l=new h(t.secretKey,{apiVersion:p,appInfo:{name:"@dexterai/x402",url:"https://dexter.cash/sdk"}}),l}catch{throw new Error('The "stripe" package is required for stripePayTo(). Install it with: npm install stripe')}}let g=async h=>{if(h.paymentHeader){try{let E=JSON.parse(Buffer.from(h.paymentHeader,"base64").toString()),d=E.payload?.authorization?.to;if(d&&typeof d=="string")return d;let u=E.accepted?.payTo;if(u&&typeof u=="string")return u}catch{}throw new Error("Could not extract deposit address from payment header. Ensure the client is sending a valid x402 PAYMENT-SIGNATURE.")}let S=await y(),c=h.amountAtomic?parseInt(h.amountAtomic,10):1e4,o=Math.max(1,Math.round(c/Math.pow(10,j-2))),m=(await S.paymentIntents.create({amount:o,currency:"usd",payment_method_types:["crypto"],payment_method_data:{type:"crypto"},payment_method_options:{crypto:{mode:"custom"}},confirm:!0})).next_action;if(!m?.crypto_collect_deposit_details)throw new Error("Stripe PaymentIntent did not return crypto deposit details. Ensure your Stripe account has crypto payins enabled: https://support.stripe.com/questions/get-started-with-pay-with-crypto");let x=m.crypto_collect_deposit_details,T=x.deposit_addresses?.[r]?.address;if(!T)throw new Error(`No deposit address found for network "${r}". Available networks: ${Object.keys(x.deposit_addresses||{}).join(", ")}`);return T};return g._x402Defaults={network:s,facilitatorUrl:B},Ee.set(g,s),g}import{homedir as Ge}from"os";import{join as Xe}from"path";import{FileChannelStorage as Je}from"@x402/evm/batch-settlement/server";import{HTTPFacilitatorClient as He,x402ResourceServer as ze}from"@x402/core/server";import{x402HTTPResourceServer as je}from"@x402/core/http";import{BatchSettlementEvmScheme as Ve}from"@x402/evm/batch-settlement/server";function ve(e){let t=e.verbose?console.log.bind(console,"[batch-settlement:seller]"):()=>{},n=new He({url:e.facilitatorUrl}),r=new Ve(e.payTo,{storage:e.channelStore}),s=new ze(n).register(e.network,r),p=new je(s,{[e.route]:{accepts:{scheme:"batch-settlement",payTo:e.payTo,price:e.price,network:e.network},description:"batch-settlement protected route",mimeType:"application/json"}}),l=null;function y(){if(l)return l;let c=p.initialize();return c.catch(o=>{l===c&&(l=null),e.verbose?t("resource server initialize() failed:",o):console.error("[batch-settlement:seller] resource server initialize() failed:",o)}),l=c,c}let g=y();function h(c,o){if(c.headersSent)return;for(let[m,x]of Object.entries(o.headers))c.setHeader(m,x);c.status(o.status);let{body:f}=o;f==null?c.end():typeof f=="string"?c.send(f):c.json(f)}return{scheme:r,facilitator:n,handler:async(c,o,f)=>{try{await y();let m=c.get("host")??"",x=`${c.baseUrl??""}${c.path}`||"/",T={getHeader:R=>c.headers[R.toLowerCase()],getMethod:()=>c.method,getPath:()=>x,getUrl:()=>`${c.protocol}://${m}${c.originalUrl}`,getAcceptHeader:()=>c.headers.accept??"",getUserAgent:()=>c.headers["user-agent"]??"",getBody:()=>c.body??{},getQueryParams:()=>c.query,getQueryParam:R=>{let a=c.query[R];if(typeof a=="string"||Array.isArray(a))return a}},E=c.headers["payment-signature"]??c.headers["x-payment"],d={adapter:T,path:x,method:c.method,paymentHeader:E},u=await p.processHTTPRequest(d);if(t("processHTTPRequest ->",u.type),u.type==="no-payment-required"){f();return}if(u.type==="payment-error"){h(o,u.response);return}let b={request:d,responseBody:Buffer.alloc(0)},P=await p.processSettlement(u.paymentPayload,u.paymentRequirements,u.declaredExtensions,b);if(t("processSettlement ->",P.success?"success":`failure:${P.errorReason}`),!P.success){h(o,P.response);return}for(let[R,a]of Object.entries(P.headers))o.headersSent||o.setHeader(R,a);f()}catch(m){t("handler error:",m),o.headersSent||o.status(500).json({error:"Payment processing error"})}},ready:g}}import{formatUnits as Me}from"viem";var _e=6;async function fe(e){let{manager:t,store:n,channelId:r}=e,s=await n.get(r),p=BigInt(s?.chargedCumulativeAmount??"0"),l=BigInt(s?.balance??"0"),y=l>p?l-p:0n,{claims:g,settle:h}=await t.claimAndSettle(),S=await t.refund([r]),c=S.find(o=>o.channel===r)??S[0];return{claimTx:g[0]?.transaction??"",settleTx:h?.transaction??"",refundTx:c?.transaction??"",settledAmount:Me(p,_e),refundedAmount:Me(y,_e)}}async function Ce(e){let t=await e.store.list(),n=[];for(let r of t)try{let s=await fe({manager:e.manager,store:e.store,channelId:r.channelId});n.push({channelId:r.channelId,...s})}catch(s){n.push({channelId:r.channelId,error:s instanceof Error?s.message:String(s)})}return n}function Ne(e){let t=!1,n=async()=>{try{await e.claimAndSettle()}catch(s){e.onError?.(s)}},r=setInterval(()=>{t||n()},e.claimIntervalMs);return typeof r.unref=="function"&&r.unref(),{async stop(){t||(t=!0,clearInterval(r),await n())}}}var Ye="https://x402.dexter.cash",Qe="GET /",Oe=new Set(["eip155:8453","eip155:42161","eip155:137"]);function Ze(e){return e===!1?null:e===void 0||e===!0?3e5:(e.claimIntervalSecs??300)*1e3}function ge(e){if(!Oe.has(e.network))throw new Error(`batch-settlement is not supported on network "${e.network}" \u2014 supported: ${[...Oe].join(", ")}`);let t=e.facilitatorUrl??Ye,n=e.channelStore??new Je({directory:Xe(Ge(),".dexter-x402","seller-channels")}),r=ve({payTo:e.payTo,network:e.network,price:e.price,route:e.route??Qe,facilitatorUrl:t,channelStore:n,verbose:e.verbose}),s=r.scheme.createChannelManager(r.facilitator,e.network),p=async()=>{await s.claimAndSettle()},l=Ze(e.autoSettle),y=null;l!==null&&(y=Ne({claimAndSettle:p,claimIntervalMs:l,onError:c=>console.error("[batch-settlement:seller] auto-loop claim pass failed",c)}));let g=n,h=(c,o,f)=>{r.handler(c,o,f)},S=h;return S.middleware=()=>h,S.closeChannel=c=>fe({manager:s,store:g,channelId:c}),S.closeAll=()=>Ce({manager:s,store:g}),S.stop=async()=>{y&&await y.stop()},S}function et(e,t){if(typeof e=="string"||typeof e=="function")return e;if(t in e)return e[t];let r=`${t.split(":")[0]}:*`;if(r in e)return e[r];if("*"in e)return e["*"];throw new Error(`No payTo configured for network "${t}"`)}function tt(e){if(e.scheme==="batch-settlement"){let d=Array.isArray(e.network)?e.network[0]:e.network;if(!d)throw new Error('x402Middleware: scheme "batch-settlement" requires a network');let u=typeof e.payTo=="string"?e.payTo:void 0;if(!u)throw new Error('x402Middleware: scheme "batch-settlement" requires a string payTo address');return ge({payTo:u,network:d,price:e.amount,facilitatorUrl:e.facilitatorUrl,route:e.batchSettlement?.route,channelStore:e.batchSettlement?.channelStore,autoSettle:e.batchSettlement?.autoSettle,verbose:e.verbose})}let{payTo:t,amount:n,asset:r,description:s,resourceUrl:p,mimeType:l,timeoutSeconds:y,verbose:g=!1,getResourceUrl:h,getAmount:S,getDescription:c}=e,o=g?console.log.bind(console,"[x402:middleware]"):()=>{},f=typeof t=="function"?t._x402Defaults:void 0,m=e.facilitatorUrl??f?.facilitatorUrl,x=e.network?Array.isArray(e.network)?e.network:[e.network]:f?.network?[f.network]:[le],T=new Map;for(let d of x){let u=et(t,d);if(typeof u=="function"){let b=ke(u);if(b&&d!==b)throw new Error(`stripePayTo is configured for "${b}" but middleware includes network "${d}". Stripe only supports Base deposit addresses. Use a static payTo for other chains.`)}T.set(d,Y({payTo:u,network:d,asset:r,facilitatorUrl:m,defaultTimeoutSeconds:y,scheme:e.scheme}))}let E=T.get(x[0]);return async(d,u,b)=>{try{let P=d.headers["payment-signature"];if(!P){o("No payment signature, returning 402");let M=h?.(d)??p??`${d.protocol}://${d.get("host")}${d.originalUrl}`,A=S?.(d)??n,L=c?.(d)??s,k=r?.decimals??j,N={amountAtomic:V(parseFloat(A),k),resourceUrl:M,description:L,mimeType:l,timeoutSeconds:y},F=[],C=null;for(let[,de]of T)try{let Z=await de.buildRequirements(N);F.push(...Z.accepts),C||(C=Z)}catch(Z){o("Failed to build requirements for a network:",Z)}if(!C||F.length===0){u.status(500).json({error:"Failed to build payment requirements"});return}C={...C,accepts:F};let Q=E.encodeRequirements(C);u.setHeader("PAYMENT-REQUIRED",Q),u.status(402).json({error:"Payment required",accepts:C.accepts,resource:C.resource});return}o("Payment signature received, verifying...");let R=E;try{let A=JSON.parse(Buffer.from(P,"base64").toString())?.accepted?.network;A&&T.has(A)&&(R=T.get(A))}catch{}let a=await R.verifyPayment(P);if(!a.isValid){if(o("Payment verification failed:",a.invalidReason),e.onVerifyFailed)try{await e.onVerifyFailed({reason:a.invalidReason,resourceUrl:`${d.protocol}://${d.get("host")}${d.originalUrl}`})}catch{}u.status(402).json({error:"Payment verification failed",reason:a.invalidReason});return}o("Payment verified, settling...");let i=await R.settlePayment(P);if(!i.success){o("Payment settlement failed:",i.errorReason),u.status(402).json({error:"Payment settlement failed",reason:i.errorReason});return}o("Payment settled:",i.transaction);let w=i.network||x[0];if(e.onSettlement)try{await e.onSettlement({transaction:i.transaction,network:w,payer:a.payer??"",resourceUrl:`${d.protocol}://${d.get("host")}${d.originalUrl}`})}catch{}d.x402={transaction:i.transaction,payer:a.payer??"",network:w};let _={success:!0,transaction:i.transaction,network:w,payer:a.payer??""};if(i.extensions&&(_.extensions=i.extensions),u.setHeader("PAYMENT-RESPONSE",W(_)),e.sponsoredAccess&&i.extensions?.["sponsored-access"]){let M=i.extensions["sponsored-access"],A=M?.info?.recommendations??M?.recommendations;if(A&&A.length>0){if(o("Injecting sponsored-access recommendations into response"),typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.onMatch)try{e.sponsoredAccess.onMatch(A,{transaction:i.transaction,network:w,payer:a.payer??""})}catch{}let L=u.json.bind(u);u.json=function(v){return typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.inject?L(e.sponsoredAccess.inject(v,A)):v&&typeof v=="object"&&!Array.isArray(v)?L({_x402_sponsored:A,...v}):L(v)}}}b()}catch(P){o("Middleware error:",P),u.status(500).json({error:"Payment processing error"})}}}function O(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var rt='<svg width="18" height="18" viewBox="0 0 2000 2000" xmlns="http://www.w3.org/2000/svg"><path d="M1000 2000c554.17 0 1000-445.83 1000-1000S1554.17 0 1000 0 0 445.83 0 1000s445.83 1000 1000 1000z" fill="#2775ca"/><path d="M1275 1158.33c0-145.83-87.5-195.83-262.5-216.66-125-16.67-150-50-150-108.34s41.67-95.83 125-95.83c75 0 116.67 25 137.5 87.5 4.17 12.5 16.67 20.83 29.17 20.83h66.66c16.67 0 29.17-12.5 29.17-29.16v-4.17c-16.67-91.67-91.67-162.5-187.5-170.83v-100c0-16.67-12.5-29.17-33.33-33.34h-62.5c-16.67 0-29.17 12.5-33.34 33.34v95.83c-125 16.67-204.16 100-204.16 204.17 0 137.5 83.33 191.66 258.33 212.5 116.67 20.83 154.17 45.83 154.17 112.5s-58.34 112.5-137.5 112.5c-108.34 0-145.84-45.84-158.34-108.34-4.16-16.66-16.66-25-29.16-25h-70.84c-16.66 0-29.16 12.5-29.16 29.17v4.17c16.66 104.16 83.33 179.16 220.83 200v100c0 16.66 12.5 29.16 33.33 33.33h62.5c16.67 0 29.17-12.5 33.34-33.33v-100c125-20.84 208.33-108.34 208.33-220.84z" fill="#fff"/><path d="M787.5 1595.83c-325-116.66-491.67-479.16-370.83-800 62.5-175 200-308.33 370.83-370.83 16.67-8.33 25-20.83 25-41.67V325c0-16.67-8.33-29.17-25-33.33-4.17 0-12.5 0-16.67 4.16-395.83 125-612.5 545.84-487.5 941.67 75 233.33 254.17 412.5 487.5 487.5 16.67 8.33 33.34 0 37.5-16.67 4.17-4.16 4.17-8.33 4.17-16.66v-58.34c0-12.5-12.5-29.16-25-37.5zM1229.17 295.83c-16.67-8.33-33.34 0-37.5 16.67-4.17 4.17-4.17 8.33-4.17 16.67v58.33c0 16.67 12.5 33.33 25 41.67 325 116.66 491.67 479.16 370.83 800-62.5 175-200 308.33-370.83 370.83-16.67 8.33-25 20.83-25 41.67V1700c0 16.67 8.33 29.17 25 33.33 4.17 0 12.5 0 16.67-4.16 395.83-125 612.5-545.84 487.5-941.67-75-237.5-258.34-416.67-487.5-491.67z" fill="#fff"/></svg>',nt='<svg width="36" height="36" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg"><g><path fill="#F2681A" d="m324.93,313.11c-115.5,0-231,0-350,0l350,0z"/><path fill="#FDFAF5" d="m230.43,50.62c1.1.85 2.19 1.7 3.32 2.57 6.02 4.8 11.77 9.88 17.46 15.07.92.84.92.84 1.86 1.69 1.82 1.69 3.59 3.42 5.35 5.16.61.56 1.22 1.13 1.84 1.71 5.66 5.76 6.18 10.43 6.13 18.3.02 1.16.04 2.32.06 3.52.06 3.83.06 7.65.07 11.48.02 2.68.05 5.35.08 8.03.05 5.6.09 11.21.1 16.81.02 7.15.09 14.31.17 21.46.06 5.53.1 11.05.13 16.58.02 2.64.04 5.27.07 7.91.18 17.58.12 32.82-11.24 47.32-7.35 7.27-16.54 12.06-25.42 17.22-1.97 1.16-3.94 2.33-5.91 3.49-7.16 4.24-14.34 8.44-21.53 12.62-4.8 2.79-9.59 5.6-14.38 8.42-1.25.73-2.5 1.47-3.79 2.23-2.32 1.36-4.64 2.73-6.96 4.1-27.47 16.09-27.47 16.09-42.16 12.93-8.06-2.28-14.94-5.82-22.16-10.02-1.17-.67-2.34-1.34-3.54-2.04-24.55-14.25-43.58-27.03-51.9-55.58-1.07-4.58-1.54-8.92-1.52-13.61.28-9.5.28-9.5-3.3-17.97-1.81-1.49-3.68-2.92-5.59-4.28-9.19-7.06-12.7-20.03-14.18-31.06-.54-5.77-.55-11.56-.6-17.35-.03-1.32-.07-2.63-.1-3.99-.01-1.26-.02-2.53-.03-3.83-.02-1.15-.03-2.29-.05-3.47.72-4.02 1.94-5.36 5.21-7.74 2.89-.53 2.89-.53 6.07-.46 1.71.02 1.71.02 3.46.05 1.19.04 2.37.08 3.59.12 1.2.02 2.41.04 3.65.06 2.97.05 5.93.13 8.9.23.14-1.35.29-2.7.43-4.08.63-5 1.78-9.74 3.14-14.58.22-.79.43-1.59.66-2.4.53-1.92 1.06-3.84 1.6-5.76-1.55-.45-1.55-.45-3.13-.9-9.52-3.52-17.1-10.95-21.37-20.1-3.81-9.26-3.87-20.34-.29-29.68 6.49-13.99 16.36-23.23 30.66-29.01 49.81-17.69 115.79 8.35 155.13 38.85z"/><path fill="#F2671A" d="m142.93,22.62c.86.19 1.73.39 2.62.59 36.12 8.21 68.79 24.98 95.38 50.75 1.02.98 2.03 1.97 3.08 2.98 10.84 10.66 10.84 10.66 11.05 14.62-2.06 3.55-5.44 4.18-9.17 5.3-.79.25-1.59.49-2.41.75-28.13 8.43-60.95 6.37-87.13-7.16-.86-.49-1.71-.97-2.6-1.48-7.37-4.05-12.59-3.36-20.59-1.54-22.76 4-48.47 1.53-68.69-9.74-4.88-3.88-8.23-8.29-10.21-14.22-.93-10.38-.67-18.44 5.83-26.83 19.57-23.38 55.99-20.36 82.83-14z"/><path fill="#F16619" d="m44.93,129.12c27.36-.03 54.72-.05 82.08-.06 12.7-.01 25.41-.01 38.11-.03 11.07-.01 22.14-.02 33.2-.02 5.86 0 11.73-.01 17.59-.01 5.51-.01 11.03-.01 16.54-.01 2.03 0 4.06 0 6.09-.01 2.76-.01 5.52 0 8.28 0 .81 0 1.63-.01 2.47-.01 5.51.02 5.51.02 6.81 1.32.22 3.43.22 3.43 0 7-2.75 2.75-3.42 2.66-7.15 2.82-1.41.07-1.41.07-2.85.14-1.47.05-1.47.05-2.98.11-1.49.07-1.49.07-3 .14-2.45.11-4.9.21-7.35.3-.2 1.3-.4 2.59-.6 3.93-2.57 16.08-5.93 29.89-18.89 40.86-10.35 7.28-21.87 8.49-34.17 7.71-13.11-2.33-22.52-9.19-30.33-19.83-4.49-7.64-4.8-17.05-5.83-25.67-4.24.39-8.47.77-12.83 1.17-.28 1.84-.28 1.84-.56 3.71-2.32 14.39-5.63 23.35-16.95 33.11-2.32 1.67-2.32 1.67-4.65 1.67 4 4.67 9.06 6.59 14.87 8.24 3.79 1.09 3.79 1.09 6.12 3.43-.65 5.31-.65 5.31-2.33 7-8.42-.27-15.13-2.29-22.17-7-1.09-1.21-2.17-2.43-3.25-3.65-2.72-2.81-4.45-3.84-8.36-4.16-1.67-.02-3.34-.02-5.01.01-1.77-.04-3.54-.09-5.3-.15-1.27-.04-1.27-.04-2.56-.08-9.26-.54-17.6-4.56-24.51-10.64-9.58-11.11-11.03-22.56-10.72-36.82.02-1.4.03-2.8.05-4.24.04-3.42.1-6.85.17-10.27z"/><path fill="#F26117" d="m172.68,203.08c7.27.09 13.23 1.97 18.87 6.65 2.88 3.07 3.86 5.12 4.25 9.32-.12 1.01-.24 2.02-.36 3.06-2.55.95-2.55.95-5.83 1.17-3.28-2.84-3.28-2.84-5.83-5.83-.36.58-.71 1.16-1.08 1.75-7.6 11.29-20.06 17.74-33.05 21.09-20.36 3.1-36.81-1.66-53.37-13.73-2.33-2.11-2.33-2.11-4.67-5.61.42-3.45.99-4.49 3.5-7 4.07.37 5.95 2.13 8.75 4.96 9.81 8.93 22.53 11.87 35.51 11.69 11.74-1.05 22.38-5.85 31.57-13.15 2.06-2.45 2.06-2.45 3.5-4.67-1.66.07-1.66.07-3.35.15-3.65-.15-3.65-.15-5.98-2.48.75-6.18 1.46-7.19 7.58-7.36z"/></g></svg>',st=`
|
|
2
2
|
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Orbitron:wght@500;700&display=swap');
|
|
3
3
|
*{margin:0;padding:0;box-sizing:border-box}
|
|
4
4
|
body{font-family:'Inter',system-ui,-apple-system,sans-serif;background:#0a0a0a;color:#e2e8f0;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:1rem}
|
|
@@ -20,7 +20,7 @@ h1{font-family:'Orbitron',sans-serif;font-size:1.15rem;font-weight:700;color:#f1
|
|
|
20
20
|
.footer a{color:#525252;text-decoration:none}
|
|
21
21
|
.footer a:hover{color:#737373}
|
|
22
22
|
.sep{width:3px;height:3px;border-radius:50%;background:#333}
|
|
23
|
-
`,
|
|
23
|
+
`,ot=`
|
|
24
24
|
.pay-section{margin:1.25rem 0}
|
|
25
25
|
.pay-btn{display:inline-flex;align-items:center;justify-content:center;gap:.5rem;background:linear-gradient(135deg,#F26B1A,#D13F00);color:#fff;border:none;padding:.65rem 2rem;border-radius:6px;font-family:'Inter',sans-serif;font-size:.95rem;font-weight:600;cursor:pointer;transition:opacity .15s,transform .1s;min-width:180px}
|
|
26
26
|
.pay-btn:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}
|
|
@@ -36,7 +36,7 @@ h1{font-family:'Orbitron',sans-serif;font-size:1.15rem;font-weight:700;color:#f1
|
|
|
36
36
|
.result-box{background:rgba(34,197,94,.06);border:1px solid rgba(34,197,94,.15);border-radius:6px;padding:.75rem;margin-top:.75rem;text-align:left;font-size:.78rem;max-height:200px;overflow:auto}
|
|
37
37
|
.result-box pre{color:#94a3b8;font-family:'SF Mono',Monaco,Consolas,monospace;white-space:pre-wrap;word-break:break-all}
|
|
38
38
|
.no-wallet{font-size:.82rem;color:#737373;margin:1rem 0}
|
|
39
|
-
`,
|
|
39
|
+
`,it=`
|
|
40
40
|
<script type="module">
|
|
41
41
|
// Payment data is embedded in #x402-data attributes
|
|
42
42
|
const dataEl = document.getElementById('x402-data');
|
|
@@ -233,22 +233,22 @@ if (btn) {
|
|
|
233
233
|
});
|
|
234
234
|
}
|
|
235
235
|
</script>
|
|
236
|
-
`;function
|
|
236
|
+
`;function at(e,t,n,r,s,p){let l="?",y="This resource requires payment",g="";try{let c=JSON.parse(Buffer.from(e,"base64").toString()),o=c.accepts?.[0];if(o){let f=o.amount??o.maxAmountRequired??"0",m=o.extra?.decimals||6;l=(Number(f)/Math.pow(10,m)).toFixed(m>4?4:2),g=o.network||""}c.resource?.description&&(y=c.resource.description)}catch{}let h=g.includes("solana")?"Solana":g.includes("eip155")?"Base":"",S=r.showEndpoint?`<div class="endpoint"><code>${O(n)} ${O(t)}</code></div>`:"";return`<!DOCTYPE html>
|
|
237
237
|
<html lang="en">
|
|
238
238
|
<head>
|
|
239
239
|
<meta charset="utf-8">
|
|
240
240
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
241
|
-
<title>${
|
|
242
|
-
<style>${
|
|
241
|
+
<title>${O(r.title)} \u2014 ${O(l)} USDC</title>
|
|
242
|
+
<style>${st}${ot}</style>
|
|
243
243
|
</head>
|
|
244
244
|
<body>
|
|
245
245
|
<div class="card">
|
|
246
|
-
<div class="crest">${
|
|
247
|
-
<h1>${
|
|
248
|
-
<p class="desc">${
|
|
249
|
-
<div class="price">${
|
|
250
|
-
<div class="chain">${
|
|
251
|
-
${
|
|
246
|
+
<div class="crest">${nt}</div>
|
|
247
|
+
<h1>${O(r.title)}</h1>
|
|
248
|
+
<p class="desc">${O(y)}</p>
|
|
249
|
+
<div class="price">${rt}<span id="price-value">${O(l)}</span></div>
|
|
250
|
+
<div class="chain">${O(h)}${h?" network":""}</div>
|
|
251
|
+
${S}
|
|
252
252
|
|
|
253
253
|
<div id="pay-section" class="pay-section" style="display:none">
|
|
254
254
|
<button id="pay-btn" class="pay-btn">Pay ${l}</button>
|
|
@@ -277,10 +277,10 @@ if (btn) {
|
|
|
277
277
|
data-method="${n}"
|
|
278
278
|
data-url="${t}"
|
|
279
279
|
data-rpc="${s}"
|
|
280
|
-
data-body="${
|
|
280
|
+
data-body="${p?Buffer.from(p).toString("base64"):""}"
|
|
281
281
|
></div>
|
|
282
|
-
${
|
|
282
|
+
${it}
|
|
283
283
|
</body>
|
|
284
|
-
</html>`}function ze(e={}){let t={title:e.title??"Payment Required",branding:e.branding??'Powered by <a href="https://docs.dexter.cash/docs/sdk/">Dexter x402</a>',sdkUrl:e.sdkUrl??"https://docs.dexter.cash/docs/sdk/",showEndpoint:e.showEndpoint??!0},n=e.rpcUrl??"https://api.dexter.cash/api/solana/rpc";return(r,s,c)=>{let l=s.json.bind(s);s.json=function(P){if(s.statusCode===402&&r.accepts("html")&&!r.headers["payment-signature"]){let y=s.getHeader("PAYMENT-REQUIRED")||s.getHeader("payment-required");if(y&&typeof y=="string"){let b;if(r.body&&typeof r.body=="object"&&Object.keys(r.body).length>0)try{b=JSON.stringify(r.body)}catch{}let k=Ke(y,r.originalUrl,r.method,t,n,b);return s.setHeader("Content-Security-Policy","default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; connect-src *; img-src data:; frame-ancestors 'none'"),s.setHeader("X-Content-Type-Options","nosniff"),s.status(402).type("html").send(k),s}}return l(P)},c()}}import fe from"crypto";var Ve=/^(\d+)(m|h|d|w)$/;function He(e){let t=e.match(Ve);if(!t)return null;let n=parseInt(t[1],10);switch(t[2]){case"m":return n*60;case"h":return n*3600;case"d":return n*86400;case"w":return n*604800;default:return null}}function Ee(e){return e>=604800&&e%604800===0?`${e/604800} week${e/604800>1?"s":""}`:e>=86400&&e%86400===0?`${e/86400} day${e/86400>1?"s":""}`:e>=3600&&e%3600===0?`${e/3600} hour${e/3600>1?"s":""}`:e>=60&&e%60===0?`${e/60} minute${e/60>1?"s":""}`:`${e} second${e>1?"s":""}`}function Ge(e,t){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify(e)).toString("base64url"),s=fe.createHmac("sha256",t).update(`${n}.${r}`).digest("base64url");return`${n}.${r}.${s}`}function je(e,t){try{let n=e.split(".");if(n.length!==3)return null;let[r,s,c]=n,l=fe.createHmac("sha256",t).update(`${r}.${s}`).digest("base64url");if(c!==l)return null;let P=JSON.parse(Buffer.from(s,"base64url").toString());return P.exp&&Date.now()/1e3>P.exp||P.sub!=="x402-access-pass"?null:P}catch{return null}}function Xe(e){let{payTo:t,network:n=de,asset:r,facilitatorUrl:s,tiers:c,ratePerHour:l,secret:P,issuer:y="x402-access-pass",verbose:b=!1,description:k}=e,R=P??fe.randomBytes(32);if(P||console.warn("[x402:access-pass] No secret provided \u2014 access passes will be invalidated on server restart. Set `secret` for production use."),!c&&!l)throw new Error("x402AccessPass: at least one of `tiers` or `ratePerHour` is required");let o=b?console.log.bind(console,"[x402:access-pass]"):()=>{},x=r?.decimals??H,d=[];if(c){for(let[u,h]of Object.entries(c)){let E=He(u);if(!E){console.warn(`x402AccessPass: skipping tier "${u}" \u2014 unrecognized duration format (use 5m, 1h, 24h, 7d)`);continue}d.push({id:u,label:Ee(E),seconds:E,price:h,priceAtomic:G(parseFloat(h),x)})}d.sort((u,h)=>u.seconds-h.seconds)}let f=Y({payTo:t,network:n,asset:r,facilitatorUrl:s}),m={tiers:d.length>0?d:void 0,ratePerHour:l||void 0,issuer:y},S=W(m);function p(u){if(!l)throw new Error("Custom durations not supported \u2014 no ratePerHour configured");let h=u/3600,E=(parseFloat(l)*h).toFixed(x>4?4:2);return{price:E,priceAtomic:G(parseFloat(E),x)}}function g(u){let h=u.query.tier,E=u.query.duration;if(h){let i=d.find(T=>T.id===h);if(i)return{tier:i.id,seconds:i.seconds,price:i.price,priceAtomic:i.priceAtomic,label:i.label}}if(E){let i=parseInt(E,10);if(i>0&&l){let T=p(i);return{tier:"custom",seconds:i,...T,label:Ee(i)}}}if(d.length>0){let i=d[0];return{tier:i.id,seconds:i.seconds,price:i.price,priceAtomic:i.priceAtomic,label:i.label}}return{tier:"custom",seconds:3600,...p(3600),label:"1 hour"}}return async(u,h,E)=>{try{let a=u.headers.authorization;if(a?.startsWith("Bearer ")){let A=je(a.slice(7),R);if(A)return o("Valid access pass:",A.tier,"| expires:",new Date(A.exp*1e3).toISOString()),u.accessPass={tier:A.tier,duration:A.duration,expiresAt:new Date(A.exp*1e3).toISOString(),payer:A.payer,network:A.network},E();o("Invalid or expired access pass token")}let i=u.headers["payment-signature"];if(i){o("Payment signature received, verifying for pass purchase...");let A=await f.verifyPayment(i);if(!A.isValid){o("Payment verification failed:",A.invalidReason),h.status(402).json({error:"Payment verification failed",reason:A.invalidReason});return}let M=await f.settlePayment(i);if(!M.success){o("Payment settlement failed:",M.errorReason),h.status(402).json({error:"Payment settlement failed",reason:M.errorReason});return}o("Payment settled:",M.transaction);let O=g(u),q=Math.floor(Date.now()/1e3),N={sub:"x402-access-pass",tier:O.tier,duration:O.seconds,iat:q,exp:q+O.seconds,payer:A.payer??"",network:n,iss:y},Q=Ge(N,R);u.x402={transaction:M.transaction,payer:A.payer??"",network:n};let le={success:!0,transaction:M.transaction,network:n,payer:A.payer??""};h.setHeader("PAYMENT-RESPONSE",W(le)),h.setHeader("ACCESS-PASS",Q),h.json({accessPass:{token:Q,tier:O.tier,duration:O.label,durationSeconds:O.seconds,expiresAt:new Date((q+O.seconds)*1e3).toISOString(),usage:"Include on subsequent requests as: Authorization: Bearer <token>"},transaction:M.transaction,payer:A.payer});return}o("No access pass or payment, returning 402");let T=g(u),v=T.priceAtomic,_=`${u.protocol}://${u.get("host")}${u.originalUrl}`,w=await f.buildRequirements({amountAtomic:v,resourceUrl:_,description:k||`Access pass: ${T.label}`,mimeType:"application/json"}),L=f.encodeRequirements(w);h.setHeader("PAYMENT-REQUIRED",L),h.setHeader("X-ACCESS-PASS-TIERS",S),h.status(402).json({error:"Access pass required",message:"Purchase an access pass to unlock unlimited API access for a time window.",accepts:w.accepts,resource:w.resource,accessPass:{tiers:d.length>0?d:void 0,ratePerHour:l||void 0,usage:"Add ?tier=<id> or ?duration=<seconds> to your payment request to choose a pass duration."}})}catch(a){o("Access pass middleware error:",a),h.status(500).json({error:"Payment processing error",message:a instanceof Error?a.message:"Unknown error"})}}}import{createHmac as Je,randomBytes as Ye}from"crypto";var Qe=300;function Ze(e){let t={unitSize:e.unitSize,ratePerUnit:e.ratePerUnit,minUsd:e.minUsd??.01,maxUsd:e.maxUsd??1/0,roundingMode:e.roundingMode??"ceil",decimals:e.decimals??6},{unitSize:n,ratePerUnit:r,minUsd:s,maxUsd:c,roundingMode:l,decimals:P}=t;if(n<=0)throw new Error("unitSize must be positive");if(r<=0)throw new Error("ratePerUnit must be positive");if(s<0)throw new Error("minUsd cannot be negative");if(c<s)throw new Error("maxUsd must be >= minUsd");let y=Ye(32);function b(o,x){let d=JSON.stringify({unitSize:n,ratePerUnit:r,minUsd:s,maxUsd:c===1/0?"none":c,roundingMode:l}),f=`${o}|${d}|${x}`;return Je("sha256",y).update(f).digest("hex").slice(0,16)}function k(o){let x=o.length,d=x/n,f;switch(l){case"ceil":f=Math.ceil(d);break;case"floor":f=Math.floor(d);break;case"round":f=Math.round(d);break}x>0&&f===0&&(f=1);let m=f*r;m=Math.max(s,m),m=Math.min(c,m);let S=Math.pow(10,P),p=Math.floor(m*S).toString(),g=Math.floor(Date.now()/1e3),u=b(o,g),h=`${g}.${u}`;return{amountAtomic:p,usdAmount:m,quoteHash:h,units:f,inputLength:x}}function R(o,x){if(!x)return!1;let d=x.indexOf(".");if(d===-1)return!1;let f=parseInt(x.slice(0,d),10),m=x.slice(d+1);if(isNaN(f)||!m)return!1;let S=Math.floor(Date.now()/1e3)-f;if(S<0||S>Qe)return!1;let p=b(o,f);if(m.length!==p.length)return!1;let g=0;for(let u=0;u<m.length;u++)g|=m.charCodeAt(u)^p.charCodeAt(u);return g===0}return{calculate:k,validateQuote:R,config:t}}function et(e){let t=e.ratePerUnit.toFixed(2),n=e.unitSize.toLocaleString();return`from $${t} per ${n} chars`}import{createHash as ut}from"crypto";var I={usesMaxCompletionTokens:!1,supportsTemperature:!0,supportsTopP:!0,supportsFrequencyPenalty:!0,supportsPresencePenalty:!0,supportsReasoningEffort:!1,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},K={usesMaxCompletionTokens:!0,supportsTemperature:!1,supportsTopP:!1,supportsFrequencyPenalty:!1,supportsPresencePenalty:!1,supportsReasoningEffort:!1,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},$={usesMaxCompletionTokens:!0,supportsTemperature:!1,supportsTopP:!1,supportsFrequencyPenalty:!1,supportsPresencePenalty:!1,supportsReasoningEffort:!0,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},ke={...$,supportsStreaming:!1},D=[{id:"gpt-4o-mini",displayName:"GPT-4o Mini",family:"gpt-4o",tier:"fast",capabilityRank:3,modalities:["text","vision"],apiType:"chat",pricing:{input:.15,output:.6,cached:.075},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:I,deprecated:!1,description:"Fast, affordable small model with vision support"},{id:"gpt-4.1-nano",displayName:"GPT-4.1 Nano",family:"gpt-4.1",tier:"fast",capabilityRank:2,modalities:["text"],apiType:"chat",pricing:{input:.1,output:.4,cached:.025},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:32768,parameters:I,deprecated:!1,description:"Smallest 4.1 model, very fast and cheap"},{id:"gpt-4.1-mini",displayName:"GPT-4.1 Mini",family:"gpt-4.1",tier:"fast",capabilityRank:4,modalities:["text"],apiType:"chat",pricing:{input:.4,output:1.6,cached:.1},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:32768,parameters:I,deprecated:!1,description:"Balanced 4.1 model, good price/performance"},{id:"gpt-5-nano",displayName:"GPT-5 Nano",family:"gpt-5",tier:"fast",capabilityRank:1,modalities:["text"],apiType:"chat",pricing:{input:.05,output:.4,cached:.005},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:K,deprecated:!1,description:"Cheapest GPT-5 variant, extremely fast"},{id:"gpt-5-mini",displayName:"GPT-5 Mini",family:"gpt-5",tier:"fast",capabilityRank:5,modalities:["text"],apiType:"chat",pricing:{input:.25,output:2,cached:.025},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Small but capable GPT-5, great value"},{id:"gpt-4o",displayName:"GPT-4o",family:"gpt-4o",tier:"standard",capabilityRank:5,modalities:["text","vision"],apiType:"chat",pricing:{input:2.5,output:10,cached:1.25},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:I,deprecated:!1,description:"Flagship multimodal model with vision"},{id:"gpt-4.1",displayName:"GPT-4.1",family:"gpt-4.1",tier:"standard",capabilityRank:6,modalities:["text"],apiType:"chat",pricing:{input:2,output:8,cached:.5},contextWindow:1e6,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:I,deprecated:!1,description:"Long context specialist, 1M token window"},{id:"gpt-5",displayName:"GPT-5",family:"gpt-5",tier:"standard",capabilityRank:7,modalities:["text"],apiType:"chat",pricing:{input:1.25,output:10,cached:.125},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Base GPT-5, excellent all-around"},{id:"gpt-5.1",displayName:"GPT-5.1",family:"gpt-5",tier:"standard",capabilityRank:8,modalities:["text"],apiType:"chat",pricing:{input:1.25,output:10,cached:.125},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Improved GPT-5 with better instruction following"},{id:"gpt-5.2",displayName:"GPT-5.2",family:"gpt-5",tier:"standard",capabilityRank:9,modalities:["text"],apiType:"chat",pricing:{input:1.75,output:14,cached:.175},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Latest GPT-5, most capable standard model"},{id:"o1-mini",displayName:"o1 Mini",family:"o1",tier:"reasoning",capabilityRank:3,modalities:["text"],apiType:"chat",pricing:{input:1.1,output:4.4,cached:.55},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:$,deprecated:!1,description:"Fast reasoning model, good for math/code"},{id:"o3-mini",displayName:"o3 Mini",family:"o3",tier:"reasoning",capabilityRank:4,modalities:["text"],apiType:"chat",pricing:{input:1.1,output:4.4,cached:.55},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:$,deprecated:!1,description:"Improved mini reasoner with better efficiency"},{id:"o4-mini",displayName:"o4 Mini",family:"o4",tier:"reasoning",capabilityRank:5,modalities:["text"],apiType:"chat",pricing:{input:1.1,output:4.4,cached:.275},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:$,deprecated:!1,description:"Latest mini reasoner, best reasoning per dollar"},{id:"o3",displayName:"o3",family:"o3",tier:"reasoning",capabilityRank:7,modalities:["text"],apiType:"chat",pricing:{input:2,output:8,cached:.5},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:$,deprecated:!1,description:"Full o3 reasoning model, excellent for complex problems"},{id:"o1",displayName:"o1",family:"o1",tier:"reasoning",capabilityRank:8,modalities:["text"],apiType:"chat",pricing:{input:15,output:60,cached:7.5},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:$,deprecated:!1,description:"Original full reasoning model, very capable"},{id:"gpt-5-pro",displayName:"GPT-5 Pro",family:"gpt-5",tier:"premium",capabilityRank:7,modalities:["text"],apiType:"chat",pricing:{input:15,output:120},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Enhanced GPT-5 for demanding tasks"},{id:"gpt-5.2-pro",displayName:"GPT-5.2 Pro",family:"gpt-5",tier:"premium",capabilityRank:8,modalities:["text"],apiType:"chat",pricing:{input:21,output:168},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Most capable standard model available"},{id:"o3-pro",displayName:"o3 Pro",family:"o3",tier:"premium",capabilityRank:9,modalities:["text"],apiType:"chat",pricing:{input:20,output:80},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:ke,deprecated:!1,description:"Premium o3 with extended thinking time"},{id:"o1-pro",displayName:"o1 Pro",family:"o1",tier:"premium",capabilityRank:10,modalities:["text"],apiType:"chat",pricing:{input:150,output:600},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:ke,deprecated:!1,description:"Most capable reasoning model, extended compute"},{id:"o3-deep-research",displayName:"o3 Deep Research",family:"o3",tier:"specialized",capabilityRank:8,modalities:["text"],apiType:"responses",pricing:{input:10,output:40,cached:2.5},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:{...$,supportsStreaming:!1},deprecated:!1,description:"Extended research sessions with web access"},{id:"o4-mini-deep-research",displayName:"o4 Mini Deep Research",family:"o4",tier:"specialized",capabilityRank:6,modalities:["text"],apiType:"responses",pricing:{input:2,output:8,cached:.5},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:{...$,supportsStreaming:!1},deprecated:!1,description:"Affordable deep research with o4 mini"},{id:"computer-use-preview",displayName:"Computer Use Preview",family:"computer-use",tier:"specialized",capabilityRank:5,modalities:["text","vision"],apiType:"responses",pricing:{input:3,output:12},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:{...I,supportsReasoningEffort:!1},deprecated:!1,description:"Can control computer interfaces via screenshots"},{id:"gpt-realtime",displayName:"GPT Realtime",family:"gpt-realtime",tier:"specialized",capabilityRank:7,modalities:["text","audio","realtime"],apiType:"chat",pricing:{input:4,output:16,cached:.4},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:4096,parameters:{...I,supportsReasoningEffort:!1},deprecated:!1,description:"Real-time audio conversation model"},{id:"gpt-realtime-mini",displayName:"GPT Realtime Mini",family:"gpt-realtime",tier:"specialized",capabilityRank:4,modalities:["text","audio","realtime"],apiType:"chat",pricing:{input:.6,output:2.4,cached:.06},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:4096,parameters:{...I,supportsReasoningEffort:!1},deprecated:!1,description:"Affordable real-time audio model"},{id:"gpt-4o-2024-05-13",displayName:"GPT-4o (May 2024)",family:"gpt-4o",tier:"standard",capabilityRank:4,modalities:["text","vision"],apiType:"chat",pricing:{input:5,output:15},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:4096,parameters:I,deprecated:!0,description:"Original GPT-4o snapshot, use gpt-4o instead"}],ge=new Map(D.map(e=>[e.id,e]));function ye(e){let t=ge.get(e);if(!t)throw new Error(`Unknown model: ${e}. Use getAvailableModelIds() to see valid options.`);return t}function tt(e){return ge.get(e)}function rt(e){return ge.has(e)}function nt(){return D.map(e=>e.id)}function st(e){return D.filter(t=>t.tier===e&&!t.deprecated).sort((t,n)=>t.capabilityRank-n.capabilityRank)}function it(e){return D.filter(t=>t.family===e).sort((t,n)=>t.capabilityRank-n.capabilityRank)}function ot(){let e={fast:1,standard:2,reasoning:3,premium:4,specialized:5};return D.filter(t=>!t.deprecated).sort((t,n)=>{let r=e[t.tier]-e[n.tier];return r!==0?r:t.capabilityRank-n.capabilityRank})}function at(){return D.filter(e=>!e.deprecated&&e.modalities.includes("text")&&!e.modalities.includes("realtime")&&e.apiType!=="responses").sort((e,t)=>{let n={fast:1,standard:2,reasoning:3,premium:4,specialized:5},r=n[e.tier]-n[t.tier];return r!==0?r:e.capabilityRank-t.capabilityRank})}function ct(e="fast"){let t={fast:1,standard:2,reasoning:3,premium:4,specialized:5},n=t[e];return D.filter(s=>!s.deprecated&&t[s.tier]>=n).sort((s,c)=>s.pricing.input-c.pricing.input)[0]}function pt(e,t,n,r=!1){let s=ye(e),c=r&&s.pricing.cached?t/1e6*s.pricing.cached:t/1e6*s.pricing.input,l=n/1e6*s.pricing.output;return c+l}function dt(e){let t=ye(e);return`$${t.pricing.input.toFixed(2)} in / $${t.pricing.output.toFixed(2)} out per 1M tokens`}var xe=Object.fromEntries(D.map(e=>[e.id,{input:e.pricing.input,output:e.pricing.output,cached:e.pricing.cached,maxTokens:e.defaultMaxOutput,tier:e.tier}]));var ue=null;async function lt(){if(ue)return ue;try{return ue=await import("tiktoken"),ue}catch{throw new Error('Token pricing requires the "tiktoken" package. Install with: npm install tiktoken')}}var U=xe,z="gpt-4o-mini";async function mt(e){let t=await lt();try{return t.encoding_for_model(e)}catch{return t.get_encoding("cl100k_base")}}async function he(e,t=z){let n=await mt(t);try{return n.encode(e).length}finally{n.free()}}function Me(e,t,n,r){let s=JSON.stringify({model:t,rate:n,tokens:r});return ut("sha256").update(e+s).digest("hex").slice(0,16)}function ft(e={}){let t=e.model??z,n=U[t],r={input:e.inputRate??n?.input??U[z].input,output:e.outputRate??n?.output??U[z].output,maxTokens:e.maxTokens??n?.maxTokens??4096,tier:e.tier??n?.tier??"custom"},s=e.tokenizer,c={model:t,inputRate:r.input,outputRate:r.output,maxTokens:r.maxTokens,tier:r.tier,tokenizer:s??(o=>he(o,t)),minUsd:e.minUsd??.001,maxUsd:e.maxUsd??50,decimals:e.decimals??6},{minUsd:l,maxUsd:P,decimals:y}=c;async function b(o){return s?s(o):he(o,t)}async function k(o,x){let d=x?`${x}
|
|
284
|
+
</html>`}function ct(e={}){let t={title:e.title??"Payment Required",branding:e.branding??'Powered by <a href="https://docs.dexter.cash/docs/sdk/">Dexter x402</a>',sdkUrl:e.sdkUrl??"https://docs.dexter.cash/docs/sdk/",showEndpoint:e.showEndpoint??!0},n=e.rpcUrl??"https://api.dexter.cash/api/solana/rpc";return(r,s,p)=>{let l=s.json.bind(s);s.json=function(y){if(s.statusCode===402&&r.accepts("html")&&!r.headers["payment-signature"]){let g=s.getHeader("PAYMENT-REQUIRED")||s.getHeader("payment-required");if(g&&typeof g=="string"){let h;if(r.body&&typeof r.body=="object"&&Object.keys(r.body).length>0)try{h=JSON.stringify(r.body)}catch{}let S=at(g,r.originalUrl,r.method,t,n,h);return s.setHeader("Content-Security-Policy","default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; connect-src *; img-src data:; frame-ancestors 'none'"),s.setHeader("X-Content-Type-Options","nosniff"),s.status(402).type("html").send(S),s}}return l(y)},p()}}import ye from"crypto";var pt=/^(\d+)(m|h|d|w)$/;function lt(e){let t=e.match(pt);if(!t)return null;let n=parseInt(t[1],10);switch(t[2]){case"m":return n*60;case"h":return n*3600;case"d":return n*86400;case"w":return n*604800;default:return null}}function Ie(e){return e>=604800&&e%604800===0?`${e/604800} week${e/604800>1?"s":""}`:e>=86400&&e%86400===0?`${e/86400} day${e/86400>1?"s":""}`:e>=3600&&e%3600===0?`${e/3600} hour${e/3600>1?"s":""}`:e>=60&&e%60===0?`${e/60} minute${e/60>1?"s":""}`:`${e} second${e>1?"s":""}`}function ut(e,t){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify(e)).toString("base64url"),s=ye.createHmac("sha256",t).update(`${n}.${r}`).digest("base64url");return`${n}.${r}.${s}`}function dt(e,t){try{let n=e.split(".");if(n.length!==3)return null;let[r,s,p]=n,l=ye.createHmac("sha256",t).update(`${r}.${s}`).digest("base64url");if(p!==l)return null;let y=JSON.parse(Buffer.from(s,"base64url").toString());return y.exp&&Date.now()/1e3>y.exp||y.sub!=="x402-access-pass"?null:y}catch{return null}}function mt(e){let{payTo:t,network:n=le,asset:r,facilitatorUrl:s,tiers:p,ratePerHour:l,secret:y,issuer:g="x402-access-pass",verbose:h=!1,description:S}=e,c=y??ye.randomBytes(32);if(y||console.warn("[x402:access-pass] No secret provided \u2014 access passes will be invalidated on server restart. Set `secret` for production use."),!p&&!l)throw new Error("x402AccessPass: at least one of `tiers` or `ratePerHour` is required");let o=h?console.log.bind(console,"[x402:access-pass]"):()=>{},f=r?.decimals??j,m=[];if(p){for(let[b,P]of Object.entries(p)){let R=lt(b);if(!R){console.warn(`x402AccessPass: skipping tier "${b}" \u2014 unrecognized duration format (use 5m, 1h, 24h, 7d)`);continue}m.push({id:b,label:Ie(R),seconds:R,price:P,priceAtomic:V(parseFloat(P),f)})}m.sort((b,P)=>b.seconds-P.seconds)}let x=Y({payTo:t,network:n,asset:r,facilitatorUrl:s}),T={tiers:m.length>0?m:void 0,ratePerHour:l||void 0,issuer:g},E=W(T);function d(b){if(!l)throw new Error("Custom durations not supported \u2014 no ratePerHour configured");let P=b/3600,R=(parseFloat(l)*P).toFixed(f>4?4:2);return{price:R,priceAtomic:V(parseFloat(R),f)}}function u(b){let P=b.query.tier,R=b.query.duration;if(P){let i=m.find(w=>w.id===P);if(i)return{tier:i.id,seconds:i.seconds,price:i.price,priceAtomic:i.priceAtomic,label:i.label}}if(R){let i=parseInt(R,10);if(i>0&&l){let w=d(i);return{tier:"custom",seconds:i,...w,label:Ie(i)}}}if(m.length>0){let i=m[0];return{tier:i.id,seconds:i.seconds,price:i.price,priceAtomic:i.priceAtomic,label:i.label}}return{tier:"custom",seconds:3600,...d(3600),label:"1 hour"}}return async(b,P,R)=>{try{let a=b.headers.authorization;if(a?.startsWith("Bearer ")){let k=dt(a.slice(7),c);if(k)return o("Valid access pass:",k.tier,"| expires:",new Date(k.exp*1e3).toISOString()),b.accessPass={tier:k.tier,duration:k.duration,expiresAt:new Date(k.exp*1e3).toISOString(),payer:k.payer,network:k.network},R();o("Invalid or expired access pass token")}let i=b.headers["payment-signature"];if(i){o("Payment signature received, verifying for pass purchase...");let k=await x.verifyPayment(i);if(!k.isValid){o("Payment verification failed:",k.invalidReason),P.status(402).json({error:"Payment verification failed",reason:k.invalidReason});return}let v=await x.settlePayment(i);if(!v.success){o("Payment settlement failed:",v.errorReason),P.status(402).json({error:"Payment settlement failed",reason:v.errorReason});return}o("Payment settled:",v.transaction);let N=u(b),F=Math.floor(Date.now()/1e3),C={sub:"x402-access-pass",tier:N.tier,duration:N.seconds,iat:F,exp:F+N.seconds,payer:k.payer??"",network:n,iss:g},Q=ut(C,c);b.x402={transaction:v.transaction,payer:k.payer??"",network:n};let de={success:!0,transaction:v.transaction,network:n,payer:k.payer??""};P.setHeader("PAYMENT-RESPONSE",W(de)),P.setHeader("ACCESS-PASS",Q),P.json({accessPass:{token:Q,tier:N.tier,duration:N.label,durationSeconds:N.seconds,expiresAt:new Date((F+N.seconds)*1e3).toISOString(),usage:"Include on subsequent requests as: Authorization: Bearer <token>"},transaction:v.transaction,payer:k.payer});return}o("No access pass or payment, returning 402");let w=u(b),_=w.priceAtomic,M=`${b.protocol}://${b.get("host")}${b.originalUrl}`,A=await x.buildRequirements({amountAtomic:_,resourceUrl:M,description:S||`Access pass: ${w.label}`,mimeType:"application/json"}),L=x.encodeRequirements(A);P.setHeader("PAYMENT-REQUIRED",L),P.setHeader("X-ACCESS-PASS-TIERS",E),P.status(402).json({error:"Access pass required",message:"Purchase an access pass to unlock unlimited API access for a time window.",accepts:A.accepts,resource:A.resource,accessPass:{tiers:m.length>0?m:void 0,ratePerHour:l||void 0,usage:"Add ?tier=<id> or ?duration=<seconds> to your payment request to choose a pass duration."}})}catch(a){o("Access pass middleware error:",a),P.status(500).json({error:"Payment processing error",message:a instanceof Error?a.message:"Unknown error"})}}}import{createHmac as ft,randomBytes as gt}from"crypto";var yt=300;function ht(e){let t={unitSize:e.unitSize,ratePerUnit:e.ratePerUnit,minUsd:e.minUsd??.01,maxUsd:e.maxUsd??1/0,roundingMode:e.roundingMode??"ceil",decimals:e.decimals??6},{unitSize:n,ratePerUnit:r,minUsd:s,maxUsd:p,roundingMode:l,decimals:y}=t;if(n<=0)throw new Error("unitSize must be positive");if(r<=0)throw new Error("ratePerUnit must be positive");if(s<0)throw new Error("minUsd cannot be negative");if(p<s)throw new Error("maxUsd must be >= minUsd");let g=gt(32);function h(o,f){let m=JSON.stringify({unitSize:n,ratePerUnit:r,minUsd:s,maxUsd:p===1/0?"none":p,roundingMode:l}),x=`${o}|${m}|${f}`;return ft("sha256",g).update(x).digest("hex").slice(0,16)}function S(o){let f=o.length,m=f/n,x;switch(l){case"ceil":x=Math.ceil(m);break;case"floor":x=Math.floor(m);break;case"round":x=Math.round(m);break}f>0&&x===0&&(x=1);let T=x*r;T=Math.max(s,T),T=Math.min(p,T);let E=Math.pow(10,y),d=Math.floor(T*E).toString(),u=Math.floor(Date.now()/1e3),b=h(o,u),P=`${u}.${b}`;return{amountAtomic:d,usdAmount:T,quoteHash:P,units:x,inputLength:f}}function c(o,f){if(!f)return!1;let m=f.indexOf(".");if(m===-1)return!1;let x=parseInt(f.slice(0,m),10),T=f.slice(m+1);if(isNaN(x)||!T)return!1;let E=Math.floor(Date.now()/1e3)-x;if(E<0||E>yt)return!1;let d=h(o,x);if(T.length!==d.length)return!1;let u=0;for(let b=0;b<T.length;b++)u|=T.charCodeAt(b)^d.charCodeAt(b);return u===0}return{calculate:S,validateQuote:c,config:t}}function xt(e){let t=e.ratePerUnit.toFixed(2),n=e.unitSize.toLocaleString();return`from $${t} per ${n} chars`}import{createHash as Mt}from"crypto";var I={usesMaxCompletionTokens:!1,supportsTemperature:!0,supportsTopP:!0,supportsFrequencyPenalty:!0,supportsPresencePenalty:!0,supportsReasoningEffort:!1,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},K={usesMaxCompletionTokens:!0,supportsTemperature:!1,supportsTopP:!1,supportsFrequencyPenalty:!1,supportsPresencePenalty:!1,supportsReasoningEffort:!1,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},$={usesMaxCompletionTokens:!0,supportsTemperature:!1,supportsTopP:!1,supportsFrequencyPenalty:!1,supportsPresencePenalty:!1,supportsReasoningEffort:!0,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},De={...$,supportsStreaming:!1},D=[{id:"gpt-4o-mini",displayName:"GPT-4o Mini",family:"gpt-4o",tier:"fast",capabilityRank:3,modalities:["text","vision"],apiType:"chat",pricing:{input:.15,output:.6,cached:.075},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:I,deprecated:!1,description:"Fast, affordable small model with vision support"},{id:"gpt-4.1-nano",displayName:"GPT-4.1 Nano",family:"gpt-4.1",tier:"fast",capabilityRank:2,modalities:["text"],apiType:"chat",pricing:{input:.1,output:.4,cached:.025},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:32768,parameters:I,deprecated:!1,description:"Smallest 4.1 model, very fast and cheap"},{id:"gpt-4.1-mini",displayName:"GPT-4.1 Mini",family:"gpt-4.1",tier:"fast",capabilityRank:4,modalities:["text"],apiType:"chat",pricing:{input:.4,output:1.6,cached:.1},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:32768,parameters:I,deprecated:!1,description:"Balanced 4.1 model, good price/performance"},{id:"gpt-5-nano",displayName:"GPT-5 Nano",family:"gpt-5",tier:"fast",capabilityRank:1,modalities:["text"],apiType:"chat",pricing:{input:.05,output:.4,cached:.005},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:K,deprecated:!1,description:"Cheapest GPT-5 variant, extremely fast"},{id:"gpt-5-mini",displayName:"GPT-5 Mini",family:"gpt-5",tier:"fast",capabilityRank:5,modalities:["text"],apiType:"chat",pricing:{input:.25,output:2,cached:.025},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Small but capable GPT-5, great value"},{id:"gpt-4o",displayName:"GPT-4o",family:"gpt-4o",tier:"standard",capabilityRank:5,modalities:["text","vision"],apiType:"chat",pricing:{input:2.5,output:10,cached:1.25},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:I,deprecated:!1,description:"Flagship multimodal model with vision"},{id:"gpt-4.1",displayName:"GPT-4.1",family:"gpt-4.1",tier:"standard",capabilityRank:6,modalities:["text"],apiType:"chat",pricing:{input:2,output:8,cached:.5},contextWindow:1e6,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:I,deprecated:!1,description:"Long context specialist, 1M token window"},{id:"gpt-5",displayName:"GPT-5",family:"gpt-5",tier:"standard",capabilityRank:7,modalities:["text"],apiType:"chat",pricing:{input:1.25,output:10,cached:.125},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Base GPT-5, excellent all-around"},{id:"gpt-5.1",displayName:"GPT-5.1",family:"gpt-5",tier:"standard",capabilityRank:8,modalities:["text"],apiType:"chat",pricing:{input:1.25,output:10,cached:.125},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Improved GPT-5 with better instruction following"},{id:"gpt-5.2",displayName:"GPT-5.2",family:"gpt-5",tier:"standard",capabilityRank:9,modalities:["text"],apiType:"chat",pricing:{input:1.75,output:14,cached:.175},contextWindow:128e3,defaultMaxOutput:8192,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Latest GPT-5, most capable standard model"},{id:"o1-mini",displayName:"o1 Mini",family:"o1",tier:"reasoning",capabilityRank:3,modalities:["text"],apiType:"chat",pricing:{input:1.1,output:4.4,cached:.55},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:$,deprecated:!1,description:"Fast reasoning model, good for math/code"},{id:"o3-mini",displayName:"o3 Mini",family:"o3",tier:"reasoning",capabilityRank:4,modalities:["text"],apiType:"chat",pricing:{input:1.1,output:4.4,cached:.55},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:$,deprecated:!1,description:"Improved mini reasoner with better efficiency"},{id:"o4-mini",displayName:"o4 Mini",family:"o4",tier:"reasoning",capabilityRank:5,modalities:["text"],apiType:"chat",pricing:{input:1.1,output:4.4,cached:.275},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:$,deprecated:!1,description:"Latest mini reasoner, best reasoning per dollar"},{id:"o3",displayName:"o3",family:"o3",tier:"reasoning",capabilityRank:7,modalities:["text"],apiType:"chat",pricing:{input:2,output:8,cached:.5},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:$,deprecated:!1,description:"Full o3 reasoning model, excellent for complex problems"},{id:"o1",displayName:"o1",family:"o1",tier:"reasoning",capabilityRank:8,modalities:["text"],apiType:"chat",pricing:{input:15,output:60,cached:7.5},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:$,deprecated:!1,description:"Original full reasoning model, very capable"},{id:"gpt-5-pro",displayName:"GPT-5 Pro",family:"gpt-5",tier:"premium",capabilityRank:7,modalities:["text"],apiType:"chat",pricing:{input:15,output:120},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Enhanced GPT-5 for demanding tasks"},{id:"gpt-5.2-pro",displayName:"GPT-5.2 Pro",family:"gpt-5",tier:"premium",capabilityRank:8,modalities:["text"],apiType:"chat",pricing:{input:21,output:168},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:32768,parameters:K,deprecated:!1,description:"Most capable standard model available"},{id:"o3-pro",displayName:"o3 Pro",family:"o3",tier:"premium",capabilityRank:9,modalities:["text"],apiType:"chat",pricing:{input:20,output:80},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:De,deprecated:!1,description:"Premium o3 with extended thinking time"},{id:"o1-pro",displayName:"o1 Pro",family:"o1",tier:"premium",capabilityRank:10,modalities:["text"],apiType:"chat",pricing:{input:150,output:600},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:De,deprecated:!1,description:"Most capable reasoning model, extended compute"},{id:"o3-deep-research",displayName:"o3 Deep Research",family:"o3",tier:"specialized",capabilityRank:8,modalities:["text"],apiType:"responses",pricing:{input:10,output:40,cached:2.5},contextWindow:2e5,defaultMaxOutput:32768,maxOutputTokens:1e5,parameters:{...$,supportsStreaming:!1},deprecated:!1,description:"Extended research sessions with web access"},{id:"o4-mini-deep-research",displayName:"o4 Mini Deep Research",family:"o4",tier:"specialized",capabilityRank:6,modalities:["text"],apiType:"responses",pricing:{input:2,output:8,cached:.5},contextWindow:128e3,defaultMaxOutput:16384,maxOutputTokens:65536,parameters:{...$,supportsStreaming:!1},deprecated:!1,description:"Affordable deep research with o4 mini"},{id:"computer-use-preview",displayName:"Computer Use Preview",family:"computer-use",tier:"specialized",capabilityRank:5,modalities:["text","vision"],apiType:"responses",pricing:{input:3,output:12},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:16384,parameters:{...I,supportsReasoningEffort:!1},deprecated:!1,description:"Can control computer interfaces via screenshots"},{id:"gpt-realtime",displayName:"GPT Realtime",family:"gpt-realtime",tier:"specialized",capabilityRank:7,modalities:["text","audio","realtime"],apiType:"chat",pricing:{input:4,output:16,cached:.4},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:4096,parameters:{...I,supportsReasoningEffort:!1},deprecated:!1,description:"Real-time audio conversation model"},{id:"gpt-realtime-mini",displayName:"GPT Realtime Mini",family:"gpt-realtime",tier:"specialized",capabilityRank:4,modalities:["text","audio","realtime"],apiType:"chat",pricing:{input:.6,output:2.4,cached:.06},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:4096,parameters:{...I,supportsReasoningEffort:!1},deprecated:!1,description:"Affordable real-time audio model"},{id:"gpt-4o-2024-05-13",displayName:"GPT-4o (May 2024)",family:"gpt-4o",tier:"standard",capabilityRank:4,modalities:["text","vision"],apiType:"chat",pricing:{input:5,output:15},contextWindow:128e3,defaultMaxOutput:4096,maxOutputTokens:4096,parameters:I,deprecated:!0,description:"Original GPT-4o snapshot, use gpt-4o instead"}],he=new Map(D.map(e=>[e.id,e]));function xe(e){let t=he.get(e);if(!t)throw new Error(`Unknown model: ${e}. Use getAvailableModelIds() to see valid options.`);return t}function bt(e){return he.get(e)}function Pt(e){return he.has(e)}function Tt(){return D.map(e=>e.id)}function St(e){return D.filter(t=>t.tier===e&&!t.deprecated).sort((t,n)=>t.capabilityRank-n.capabilityRank)}function wt(e){return D.filter(t=>t.family===e).sort((t,n)=>t.capabilityRank-n.capabilityRank)}function Rt(){let e={fast:1,standard:2,reasoning:3,premium:4,specialized:5};return D.filter(t=>!t.deprecated).sort((t,n)=>{let r=e[t.tier]-e[n.tier];return r!==0?r:t.capabilityRank-n.capabilityRank})}function At(){return D.filter(e=>!e.deprecated&&e.modalities.includes("text")&&!e.modalities.includes("realtime")&&e.apiType!=="responses").sort((e,t)=>{let n={fast:1,standard:2,reasoning:3,premium:4,specialized:5},r=n[e.tier]-n[t.tier];return r!==0?r:e.capabilityRank-t.capabilityRank})}function Et(e="fast"){let t={fast:1,standard:2,reasoning:3,premium:4,specialized:5},n=t[e];return D.filter(s=>!s.deprecated&&t[s.tier]>=n).sort((s,p)=>s.pricing.input-p.pricing.input)[0]}function kt(e,t,n,r=!1){let s=xe(e),p=r&&s.pricing.cached?t/1e6*s.pricing.cached:t/1e6*s.pricing.input,l=n/1e6*s.pricing.output;return p+l}function vt(e){let t=xe(e);return`$${t.pricing.input.toFixed(2)} in / $${t.pricing.output.toFixed(2)} out per 1M tokens`}var be=Object.fromEntries(D.map(e=>[e.id,{input:e.pricing.input,output:e.pricing.output,cached:e.pricing.cached,maxTokens:e.defaultMaxOutput,tier:e.tier}]));var ue=null;async function _t(){if(ue)return ue;try{return ue=await import("tiktoken"),ue}catch{throw new Error('Token pricing requires the "tiktoken" package. Install with: npm install tiktoken')}}var U=be,H="gpt-4o-mini";async function Ct(e){let t=await _t();try{return t.encoding_for_model(e)}catch{return t.get_encoding("cl100k_base")}}async function Pe(e,t=H){let n=await Ct(t);try{return n.encode(e).length}finally{n.free()}}function Ue(e,t,n,r){let s=JSON.stringify({model:t,rate:n,tokens:r});return Mt("sha256").update(e+s).digest("hex").slice(0,16)}function Nt(e={}){let t=e.model??H,n=U[t],r={input:e.inputRate??n?.input??U[H].input,output:e.outputRate??n?.output??U[H].output,maxTokens:e.maxTokens??n?.maxTokens??4096,tier:e.tier??n?.tier??"custom"},s=e.tokenizer,p={model:t,inputRate:r.input,outputRate:r.output,maxTokens:r.maxTokens,tier:r.tier,tokenizer:s??(o=>Pe(o,t)),minUsd:e.minUsd??.001,maxUsd:e.maxUsd??50,decimals:e.decimals??6},{minUsd:l,maxUsd:y,decimals:g}=p;async function h(o){return s?s(o):Pe(o,t)}async function S(o,f){let m=f?`${f}
|
|
285
285
|
|
|
286
|
-
${o}`:o,
|
|
286
|
+
${o}`:o,x=await h(m),T=x/1e6*r.input;T=Math.max(T,l),T=Math.min(T,y);let E=Math.pow(10,g),d=Math.floor(T*E).toString(),u=Ue(o,t,r.input,x);return{amountAtomic:d,usdAmount:T,inputTokens:x,model:t,tier:r.tier,inputRatePerMillion:r.input,outputRatePerMillion:r.output,maxOutputTokens:r.maxTokens,quoteHash:u}}async function c(o,f){if(!f)return!1;let m=await h(o);return Ue(o,t,r.input,m)===f}return{calculate:S,validateQuote:c,countTokens:h,config:p,modelInfo:r}}function Ot(){return Object.entries(U).map(([e,t])=>({model:e,inputRate:t.input,outputRate:t.output,maxTokens:t.maxTokens,tier:t.tier})).sort((e,t)=>{let n={fast:0,standard:1,reasoning:2,premium:3},r=n[e.tier]-n[t.tier];return r!==0?r:e.inputRate-t.inputRate})}function It(e){return e in U}function Dt(e=H){let t=U[e]??U[H],n=U[e]?e:H;return`$${t.input.toFixed(2)} per 1M tokens (${n})`}import{SPONSORED_ACCESS_EXTENSION_KEY as Gr}from"@dexterai/x402-ads-types";export{z as BASE_MAINNET_NETWORK,B as DEXTER_FACILITATOR_URL,J as FacilitatorClient,U as MODEL_PRICING,be as MODEL_PRICING_MAP,D as MODEL_REGISTRY,q as SOLANA_MAINNET_NETWORK,Gr as SPONSORED_ACCESS_EXTENSION_KEY,me as USDC_BASE,pe as USDC_MINT,Pe as countTokens,ht as createDynamicPricing,Nt as createTokenPricing,Y as createX402Server,O as escapeHtml,kt as estimateCost,bt as findModel,vt as formatModelPricing,xt as formatPricing,Dt as formatTokenPricing,Rt as getActiveModels,Tt as getAvailableModelIds,Ot as getAvailableModels,Et as getCheapestModel,xe as getModel,wt as getModelsByFamily,St as getModelsByTier,At as getTextModels,It as isValidModel,Pt as isValidModelId,Ke as stripePayTo,mt as x402AccessPass,ct as x402BrowserSupport,tt as x402Middleware};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { C as ChainAdapter, W as WalletSet } from './types-
|
|
2
|
-
import { A as AccessPassClientConfig, P as PaymentAccept } from './types-Bcsi5jQb.cjs';
|
|
1
|
+
import { C as ChainAdapter, W as WalletSet, A as AccessPassClientConfig, P as PaymentAccept } from './types-IqnDBsjL.cjs';
|
|
3
2
|
import { SponsoredRecommendation, SponsoredAccessSettlementInfo } from '@dexterai/x402-ads-types';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -41,6 +40,17 @@ interface PaymentReceipt {
|
|
|
41
40
|
payer?: string;
|
|
42
41
|
/** Protocol extensions (e.g., sponsored-access recommendations) */
|
|
43
42
|
extensions?: Record<string, unknown>;
|
|
43
|
+
/**
|
|
44
|
+
* Amount actually paid, in atomic units (e.g. '10000' for 0.01 USDC).
|
|
45
|
+
* Sourced from the payment requirement the client settled — the facilitator's
|
|
46
|
+
* PAYMENT-RESPONSE receipt does not echo the amount, so the client records it.
|
|
47
|
+
*/
|
|
48
|
+
amountAtomic?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Decimals of the paid asset, so `amountAtomic` can be converted to a human
|
|
51
|
+
* amount: `Number(amountAtomic) / 10 ** assetDecimals`.
|
|
52
|
+
*/
|
|
53
|
+
assetDecimals?: number;
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
46
56
|
* Get the x402 payment receipt from a response, or undefined if none.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { C as ChainAdapter, W as WalletSet } from './types-
|
|
2
|
-
import { A as AccessPassClientConfig, P as PaymentAccept } from './types-Bcsi5jQb.js';
|
|
1
|
+
import { C as ChainAdapter, W as WalletSet, A as AccessPassClientConfig, P as PaymentAccept } from './types-IqnDBsjL.js';
|
|
3
2
|
import { SponsoredRecommendation, SponsoredAccessSettlementInfo } from '@dexterai/x402-ads-types';
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -41,6 +40,17 @@ interface PaymentReceipt {
|
|
|
41
40
|
payer?: string;
|
|
42
41
|
/** Protocol extensions (e.g., sponsored-access recommendations) */
|
|
43
42
|
extensions?: Record<string, unknown>;
|
|
43
|
+
/**
|
|
44
|
+
* Amount actually paid, in atomic units (e.g. '10000' for 0.01 USDC).
|
|
45
|
+
* Sourced from the payment requirement the client settled — the facilitator's
|
|
46
|
+
* PAYMENT-RESPONSE receipt does not echo the amount, so the client records it.
|
|
47
|
+
*/
|
|
48
|
+
amountAtomic?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Decimals of the paid asset, so `amountAtomic` can be converted to a human
|
|
51
|
+
* amount: `Number(amountAtomic) / 10 ** assetDecimals`.
|
|
52
|
+
*/
|
|
53
|
+
assetDecimals?: number;
|
|
44
54
|
}
|
|
45
55
|
/**
|
|
46
56
|
* Get the x402 payment receipt from a response, or undefined if none.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { RequestHandler } from 'express';
|
|
2
|
+
import { ChannelStorage } from '@x402/evm/batch-settlement/server';
|
|
3
|
+
import { b as CloseReceipt } from './types-Bbt_SDZE.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Result of closing one channel from the seller side. Either a settlement
|
|
7
|
+
* receipt, or an error entry when that channel's claim/settle/refund failed.
|
|
8
|
+
*/
|
|
9
|
+
type SellerCloseResult = (CloseReceipt & {
|
|
10
|
+
channelId: string;
|
|
11
|
+
}) | {
|
|
12
|
+
channelId: string;
|
|
13
|
+
error: string;
|
|
14
|
+
};
|
|
15
|
+
/** Configuration for createBatchSettlementSeller. */
|
|
16
|
+
interface BatchSettlementSellerConfig {
|
|
17
|
+
/** Seller's payout address; also the channel receiver. */
|
|
18
|
+
payTo: string;
|
|
19
|
+
/** CAIP-2 network: eip155:8453 (Base), eip155:42161 (Arbitrum), eip155:137 (Polygon). */
|
|
20
|
+
network: string;
|
|
21
|
+
/** USDC charged per request, human units, e.g. "0.08". */
|
|
22
|
+
price: string;
|
|
23
|
+
/** Facilitator base URL. Default: https://x402.dexter.cash */
|
|
24
|
+
facilitatorUrl?: string;
|
|
25
|
+
/** The protected route, e.g. "GET /api/data". Default: "GET /". */
|
|
26
|
+
route?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Persistent server-side channel storage. Default: file-backed at
|
|
29
|
+
* ~/.dexter-x402/seller-channels/. Pass RedisChannelStorage or a custom
|
|
30
|
+
* server-side ChannelStorage for multi-instance deployments.
|
|
31
|
+
*/
|
|
32
|
+
channelStore?: ChannelStorage;
|
|
33
|
+
/**
|
|
34
|
+
* Auto-settlement loop. Default true (loop on, default intervals). Pass an
|
|
35
|
+
* object to tune; pass false to disable (settle only via closeChannel/closeAll).
|
|
36
|
+
*/
|
|
37
|
+
autoSettle?: boolean | {
|
|
38
|
+
claimIntervalSecs?: number;
|
|
39
|
+
settleIntervalSecs?: number;
|
|
40
|
+
refundIntervalSecs?: number;
|
|
41
|
+
};
|
|
42
|
+
/** Verbose logging. */
|
|
43
|
+
verbose?: boolean;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The seller runtime. It is callable — usable directly as an Express
|
|
47
|
+
* RequestHandler — and exposes lifecycle + settlement methods.
|
|
48
|
+
*/
|
|
49
|
+
interface BatchSettlementSeller extends RequestHandler {
|
|
50
|
+
/** Returns the Express request handler (same handler the object itself is). */
|
|
51
|
+
middleware(): RequestHandler;
|
|
52
|
+
/** Claim -> settle -> refund one channel. */
|
|
53
|
+
closeChannel(channelId: string): Promise<CloseReceipt>;
|
|
54
|
+
/** Settle every channel currently in storage; one result per channel. */
|
|
55
|
+
closeAll(): Promise<SellerCloseResult[]>;
|
|
56
|
+
/** Halt the auto-settle loop and flush a final claimAndSettle. */
|
|
57
|
+
stop(): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type { BatchSettlementSeller as B, SellerCloseResult as S, BatchSettlementSellerConfig as a };
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { ClientChannelStorage } from '@x402/evm/batch-settlement/client';
|
|
2
|
+
import { E as EvmWallet } from './types-IqnDBsjL.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Buyer withdrawal escape hatch for batch-settlement escrow channels.
|
|
6
|
+
*
|
|
7
|
+
* Normally a buyer's unspent escrow returns via the seller's
|
|
8
|
+
* `refundWithSignature`. If the seller goes dark and never settles, the buyer
|
|
9
|
+
* must be able to reclaim the unspent escrow directly on-chain. The
|
|
10
|
+
* `x402BatchSettlement` contract provides a two-step timed withdrawal:
|
|
11
|
+
*
|
|
12
|
+
* 1. `initiateWithdraw(config, amount)` — starts the `withdrawDelay` timer.
|
|
13
|
+
* 2. `finalizeWithdraw(config)` — after the delay, returns the funds.
|
|
14
|
+
*
|
|
15
|
+
* Both are buyer-submitted and cost the buyer gas. There is deliberately no
|
|
16
|
+
* facilitator-relayed variant: the escape cannot be sponsored by the party
|
|
17
|
+
* being escaped from.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
/** Thrown by finalizeWithdraw when called before the withdrawDelay elapses. */
|
|
21
|
+
declare class WithdrawNotReadyError extends Error {
|
|
22
|
+
constructor(message: string);
|
|
23
|
+
}
|
|
24
|
+
/** Result of forceWithdraw — the initiate tx and when finalize becomes possible. */
|
|
25
|
+
interface ForceWithdrawResult {
|
|
26
|
+
/** initiateWithdraw transaction hash. */
|
|
27
|
+
initiateTx: string;
|
|
28
|
+
/** Unix seconds at which finalizeWithdraw becomes callable. */
|
|
29
|
+
finalizableAt: number;
|
|
30
|
+
}
|
|
31
|
+
/** Result of finalizeWithdraw. */
|
|
32
|
+
interface FinalizeWithdrawResult {
|
|
33
|
+
/** finalizeWithdraw transaction hash. */
|
|
34
|
+
finalizeTx: string;
|
|
35
|
+
/** Amount returned to the buyer, USDC human units. */
|
|
36
|
+
withdrawnAmount: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Channel persistence. This is the upstream `ClientChannelStorage` interface
|
|
41
|
+
* (`get` / `set` / `delete`, keyed by lowercased channelId). The SDK ships
|
|
42
|
+
* file-backed and localStorage-backed implementations; a consumer may pass any
|
|
43
|
+
* `ClientChannelStorage` (e.g. one backed by their own database).
|
|
44
|
+
*/
|
|
45
|
+
type ChannelStore = ClientChannelStorage;
|
|
46
|
+
/** Channel accounting, all amounts USDC human units (e.g. "0.30"). */
|
|
47
|
+
interface ChannelState {
|
|
48
|
+
/** Total escrowed into the channel. */
|
|
49
|
+
deposited: string;
|
|
50
|
+
/** Cumulative amount spent via vouchers. */
|
|
51
|
+
spent: string;
|
|
52
|
+
/** deposited - spent. */
|
|
53
|
+
remaining: string;
|
|
54
|
+
}
|
|
55
|
+
/** Options for opening a fresh (or auto-resumed) channel. */
|
|
56
|
+
interface OpenBatchChannelOptions {
|
|
57
|
+
/** EVM wallet — any { address, signTypedData }. The same EvmWallet the exact scheme uses. */
|
|
58
|
+
wallet: EvmWallet;
|
|
59
|
+
/** CAIP-2 network: eip155:8453 (Base), eip155:42161 (Arbitrum), eip155:137 (Polygon). */
|
|
60
|
+
network: string;
|
|
61
|
+
/** Total escrow for the channel, USDC human units, e.g. "0.30". */
|
|
62
|
+
deposit: string;
|
|
63
|
+
/** Facilitator base URL. Default: https://x402.dexter.cash */
|
|
64
|
+
facilitatorUrl?: string;
|
|
65
|
+
/** RPC URL override. Default: per-network. */
|
|
66
|
+
rpcUrl?: string;
|
|
67
|
+
/** Channel persistence. Default: localStorage (browser) / file (Node). */
|
|
68
|
+
store?: ChannelStore;
|
|
69
|
+
}
|
|
70
|
+
/** Options for explicitly resuming an existing channel. */
|
|
71
|
+
interface ResumeBatchChannelOptions {
|
|
72
|
+
wallet: EvmWallet;
|
|
73
|
+
network: string;
|
|
74
|
+
facilitatorUrl?: string;
|
|
75
|
+
rpcUrl?: string;
|
|
76
|
+
store?: ChannelStore;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Result of the seller runtime's claim -> settle -> refund — the three
|
|
80
|
+
* settlement tx hashes and final amounts. Used by the SELLER module; the
|
|
81
|
+
* buyer's channel.close() returns {@link CloseResult} instead.
|
|
82
|
+
*/
|
|
83
|
+
interface CloseReceipt {
|
|
84
|
+
/** claimWithSignature tx hash. */
|
|
85
|
+
claimTx: string;
|
|
86
|
+
/** settle tx hash. */
|
|
87
|
+
settleTx: string;
|
|
88
|
+
/** refundWithSignature tx hash. */
|
|
89
|
+
refundTx: string;
|
|
90
|
+
/** Amount paid to the seller, USDC human units. */
|
|
91
|
+
settledAmount: string;
|
|
92
|
+
/** Unspent amount returned to the buyer, USDC human units. */
|
|
93
|
+
refundedAmount: string;
|
|
94
|
+
}
|
|
95
|
+
/** Result of the buyer's channel.close() — an intent signal, not a settlement. */
|
|
96
|
+
interface CloseResult {
|
|
97
|
+
/** Always true — the channel was marked done in the buyer's local store. */
|
|
98
|
+
closed: true;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* A live escrow channel. Returned by openBatchChannel / resumeBatchChannel.
|
|
102
|
+
* Hold this handle for the lifetime of a batching session.
|
|
103
|
+
*/
|
|
104
|
+
interface BatchSettlementChannel {
|
|
105
|
+
/** On-chain channel id (bytes32 hex). Empty until the first fetch resolves it. */
|
|
106
|
+
readonly channelId: string;
|
|
107
|
+
/** CAIP-2 network. */
|
|
108
|
+
readonly network: string;
|
|
109
|
+
/** Live channel accounting; updated after each fetch. */
|
|
110
|
+
readonly state: ChannelState;
|
|
111
|
+
/** Drop-in fetch. On a batch-settlement 402, signs a voucher and retries. */
|
|
112
|
+
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
113
|
+
/**
|
|
114
|
+
* Marks the channel done in the buyer's local store (an intent signal).
|
|
115
|
+
* The buyer does not settle — the seller's runtime claims accumulated
|
|
116
|
+
* vouchers and refunds the buyer's unspent escrow. Returns { closed: true }.
|
|
117
|
+
*/
|
|
118
|
+
close(): Promise<CloseResult>;
|
|
119
|
+
/**
|
|
120
|
+
* Escape hatch — initiates the contract's on-chain withdrawal of this
|
|
121
|
+
* channel's unspent escrow, starting the withdrawDelay timer. Use only if
|
|
122
|
+
* the seller never settles. COSTS THE BUYER GAS — the buyer's wallet must
|
|
123
|
+
* hold the chain's native token; there is no facilitator-relayed variant.
|
|
124
|
+
*/
|
|
125
|
+
forceWithdraw(): Promise<ForceWithdrawResult>;
|
|
126
|
+
/**
|
|
127
|
+
* Escape hatch — finalizes a withdrawal started by forceWithdraw, after the
|
|
128
|
+
* withdrawDelay has elapsed; returns the funds. Throws WithdrawNotReadyError
|
|
129
|
+
* if called too early. COSTS THE BUYER GAS.
|
|
130
|
+
*/
|
|
131
|
+
finalizeWithdraw(): Promise<FinalizeWithdrawResult>;
|
|
132
|
+
}
|
|
133
|
+
/** Thrown by openBatchChannel when the buyer wallet lacks USDC for the deposit. */
|
|
134
|
+
declare class InsufficientBalanceError extends Error {
|
|
135
|
+
constructor(message: string);
|
|
136
|
+
}
|
|
137
|
+
/** Thrown when a network has no deployed x402BatchSettlement contract. */
|
|
138
|
+
declare class UnsupportedNetworkError extends Error {
|
|
139
|
+
constructor(message: string);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export { type BatchSettlementChannel as B, type ChannelStore as C, type ForceWithdrawResult as F, InsufficientBalanceError as I, type OpenBatchChannelOptions as O, type ResumeBatchChannelOptions as R, UnsupportedNetworkError as U, WithdrawNotReadyError as W, type ChannelState as a, type CloseReceipt as b, type CloseResult as c, type FinalizeWithdrawResult as d };
|