@dexterai/x402 3.18.1 → 4.1.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 +19 -5
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +32 -70
- package/dist/client/index.d.ts +32 -70
- package/dist/client/index.js +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.cts +5 -107
- package/dist/react/index.d.ts +5 -107
- package/dist/react/index.js +1 -1
- package/dist/server/index.cjs +1 -286
- package/dist/server/index.d.cts +1 -724
- package/dist/server/index.d.ts +1 -724
- package/dist/server/index.js +1 -286
- package/dist/tab/adapters/solana/index.cjs +1 -1
- package/dist/tab/adapters/solana/index.d.cts +19 -24
- package/dist/tab/adapters/solana/index.d.ts +19 -24
- package/dist/tab/adapters/solana/index.js +1 -1
- package/dist/{x402-client-Ug0vrj74.d.ts → x402-client-BQKDeNxq.d.cts} +1 -123
- package/dist/{x402-client-DmRbvqoc.d.cts → x402-client-BQKDeNxq.d.ts} +1 -123
- package/package.json +2 -2
package/dist/server/index.js
CHANGED
|
@@ -1,286 +1 @@
|
|
|
1
|
-
var H="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",we="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Ae="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var z="eip155:8453",te="eip155:84532",re="eip155:42161",ne="eip155:137",oe="eip155:10",se="eip155:43114",ie="eip155:56",ae="eip155:1187947933",ce="eip155:324705682",pe="eip155:1";var V="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var ye="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",je="0x55d398326f99059fF775485246999027B3197955",Ee="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",ve={[ie]:Ee,[z]:ye,[te]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[re]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[ne]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[oe]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[se]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[ae]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ce]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[pe]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ke={[je]:{symbol:"USDT",decimals:18},[Ee]:{symbol:"USDC",decimals:18}},ue=6;var Qt={[ie]:56,[z]:8453,[te]:84532,[re]:42161,[ne]:137,[oe]:10,[se]:43114,[ae]:1187947933,[ce]:324705682,[pe]:1},Yt={[H]:"https://api.dexter.cash/api/solana/rpc",[we]:"https://api.devnet.solana.com",[Ae]:"https://api.testnet.solana.com"},Zt={[ie]:"https://api.dexter.cash/api/evm/bsc/rpc",[z]:"https://api.dexter.cash/api/base/rpc",[te]:"https://sepolia.base.org",[re]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[ne]:"https://api.dexter.cash/api/evm/polygon/rpc",[oe]:"https://api.dexter.cash/api/evm/optimism/rpc",[se]:"https://api.dexter.cash/api/evm/avalanche/rpc",[ae]:"https://skale-base.skalenodes.com/v1/base",[ce]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[pe]:"https://eth.llamarpc.com"},$="https://x402.dexter.cash",le=H;function G(e,t){if(!Number.isFinite(e))throw new Error(`toAtomicUnits: amount must be finite, got ${e}`);if(e<0)throw new Error(`toAtomicUnits: amount must be non-negative, got ${e}`);if(!Number.isInteger(t)||t<0)throw new Error(`toAtomicUnits: decimals must be a non-negative integer, got ${t}`);let n=ze(Math.abs(e)),[r,o=""]=n.split("."),s=o.slice(0,t).padEnd(t,"0");return BigInt(r+s).toString()}function ze(e){let t=e.toString();if(!/[eE]/.test(t))return t;let[n,r]=t.split(/[eE]/),o=parseInt(r,10),s=n.startsWith("-"),p=s?n.slice(1):n,[y,g=""]=p.split("."),m=y+g,b=y.length+o,c;return b<=0?c="0."+"0".repeat(-b)+m:b>=m.length?c=m+"0".repeat(b-m.length):c=m.slice(0,b)+"."+m.slice(b),(s?"-":"")+c}function de(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 Ge(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 X(e){return JSON.parse(Ge(e))}function Xe(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 J=class extends Error{status;body;constructor(t,n){super(`HTTP ${t}`),this.status=t,this.body=n}},Q=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(t=$,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,o=setTimeout(()=>r.abort(),this.timeoutMs);try{return await fetch(t,{...n,signal:r.signal})}finally{clearTimeout(o)}}async fetchWithRetry(t,n){let r;for(let o=0;o<this.maxRetries;o++)try{let s=await this.fetchWithTimeout(t,n);if(!s.ok&&s.status>=500)throw new J(s.status,await s.text());return s}catch(s){if(r=s,o<this.maxRetries-1&&Xe(s)){let p=this.retryBaseMs*Math.pow(2,o);await new Promise(y=>setTimeout(y,p));continue}throw s}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(o=>o.x402Version===2&&(o.scheme==="exact"||o.scheme==="exact-approval")&&o.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(o=>o.x402Version===2&&(o.scheme==="exact"||o.scheme==="exact-approval"||o.scheme==="batch-settlement")&&o.network===t)?.extra}async verifyPayment(t,n){try{let r=X(t),o=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return o.ok?await o.json():{isValid:!1,invalidReason:`facilitator_error_${o.status}`}}catch(r){return{isValid:!1,invalidReason:r instanceof J?`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=X(t),o=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return o.ok?{...await o.json(),network:n.network}:{success:!1,network:n.network,errorReason:`facilitator_error_${o.status}`}}catch(r){let o=r instanceof J?`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:o}}}};function Ce(e){if(de(e))return{address:V,decimals:6};let t=ve[e];if(t){let n=ke[t]?.decimals??6;return{address:t,decimals:n}}return{address:V,decimals:6}}function Me(e){try{let t=X(e);return t?.accepted?.amount??t?.accepted?.maxAmountRequired}catch{return}}function Y(e){let{payTo:t,facilitatorUrl:n=$,network:r=H,defaultTimeoutSeconds:o=60}=e,s=e.asset??Ce(r),p=e.scheme??"exact";if(p==="tab"&&!de(r))throw new Error(`scheme 'tab' is SVM-only; got network "${r}"`);let y=new Q(n),g=null,m=new Map,b=3e4,c=Date.now();function a(u){let d=(u.maxTimeoutSeconds||o)*1e3;if(m.set(u.payTo,{accept:u,expiresAt:Date.now()+d}),Date.now()-c>b){let T=Date.now();for(let[E,_]of m)_.expiresAt<T&&m.delete(E);c=T}}function h(u){let d=m.get(u);if(d){if(d.expiresAt<Date.now()){m.delete(u);return}return d.accept}}async function l(u){return typeof t=="string"?t:t(u||{})}async function x(){if(g||(g=await y.getNetworkExtra(r)),de(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,...p==="batch-settlement"&&g?.receiverAuthorizer?{receiverAuthorizer:g.receiverAuthorizer}:{},...p==="tab"?{voucherHeader:"x-tab-voucher",registrationEncoding:"base64(188-byte sessionRegisterMessage)"}:{}}}async function P(u,d){let{amountAtomic:T,timeoutSeconds:E=o}=d,_=await x(),O={scheme:p,network:r,amount:T,maxAmountRequired:T,asset:s.address,payTo:u,maxTimeoutSeconds:E,extra:_};return a(O),O}async function v(u){let d=await l({amountAtomic:u.amountAtomic,resourceUrl:u.resourceUrl});return P(d,u)}async function A(u){let{resourceUrl:d,description:T,mimeType:E="application/json"}=u,_={url:d,description:T,mimeType:E},O=await v(u);return{x402Version:2,resource:_,accepts:[O],error:"Payment required"}}function S(u){return W(u)}function i(u){return{status:402,headers:{"PAYMENT-REQUIRED":S(u)},body:{}}}async function f(u,d){if(!d){let T=await l({paymentHeader:u});d=h(T),d||(d=await P(T,{amountAtomic:Me(u)??"0",resourceUrl:""}))}return y.verifyPayment(u,d)}async function w(u,d){if(!d){let T=await l({paymentHeader:u});d=h(T),d||(d=await P(T,{amountAtomic:Me(u)??"0",resourceUrl:""}))}return y.settlePayment(u,d)}return{buildRequirements:A,encodeRequirements:S,create402Response:i,verifyPayment:f,settlePayment:w,getPaymentAccept:v,network:r,assetDecimals:s.decimals,facilitator:y}}var _e=new WeakMap;function Oe(e){return _e.get(e)}var Je={base:"base","base-sepolia":"base_sepolia"},Qe={base:"eip155:8453","base-sepolia":"eip155:84532"};function Ye(e){let t=typeof e=="string"?{secretKey:e}:e,n=t.network??"base",r=Je[n]??"base",o=Qe[n]??"eip155:8453",s=t.apiVersion??"2026-01-28.clover",p=null;async function y(){if(p)return p;try{let{default:m}=await import("stripe");return p=new m(t.secretKey,{apiVersion:s,appInfo:{name:"@dexterai/x402",url:"https://dexter.cash/sdk"}}),p}catch{throw new Error('The "stripe" package is required for stripePayTo(). Install it with: npm install stripe')}}let g=async m=>{if(m.paymentHeader){try{let v=JSON.parse(Buffer.from(m.paymentHeader,"base64").toString()),A=v.payload?.authorization?.to;if(A&&typeof A=="string")return A;let S=v.accepted?.payTo;if(S&&typeof S=="string")return S}catch{}throw new Error("Could not extract deposit address from payment header. Ensure the client is sending a valid x402 PAYMENT-SIGNATURE.")}let b=await y(),c=m.amountAtomic?parseInt(m.amountAtomic,10):1e4,a=Math.max(1,Math.round(c/Math.pow(10,ue-2))),l=(await b.paymentIntents.create({amount:a,currency:"usd",payment_method_types:["crypto"],payment_method_data:{type:"crypto"},payment_method_options:{crypto:{mode:"custom"}},confirm:!0})).next_action;if(!l?.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=l.crypto_collect_deposit_details,P=x.deposit_addresses?.[r]?.address;if(!P)throw new Error(`No deposit address found for network "${r}". Available networks: ${Object.keys(x.deposit_addresses||{}).join(", ")}`);return P};return g._x402Defaults={network:o,facilitatorUrl:$},_e.set(g,o),g}import{homedir as nt}from"os";import{join as ot}from"path";import{FileChannelStorage as st}from"@x402/evm/batch-settlement/server";import{HTTPFacilitatorClient as Ze,x402ResourceServer as et}from"@x402/core/server";import{x402HTTPResourceServer as tt}from"@x402/core/http";import{BatchSettlementEvmScheme as rt}from"@x402/evm/batch-settlement/server";function Ne(e){let t=e.verbose?console.log.bind(console,"[batch-settlement:seller]"):()=>{},n=new Ze({url:e.facilitatorUrl}),r=new rt(e.payTo,{storage:e.channelStore}),o=new et(n).register(e.network,r),s=new tt(o,{[e.route]:{accepts:{scheme:"batch-settlement",payTo:e.payTo,price:e.price,network:e.network},description:"batch-settlement protected route",mimeType:"application/json"}}),p=null;function y(){if(p)return p;let c=s.initialize();return c.catch(a=>{p===c&&(p=null),e.verbose?t("resource server initialize() failed:",a):console.error("[batch-settlement:seller] resource server initialize() failed:",a)}),p=c,c}let g=y();function m(c,a){if(c.headersSent)return;for(let[l,x]of Object.entries(a.headers))c.setHeader(l,x);c.status(a.status);let{body:h}=a;h==null?c.end():typeof h=="string"?c.send(h):c.json(h)}return{scheme:r,facilitator:n,handler:async(c,a,h)=>{try{await y();let l=c.get("host")??"",x=`${c.baseUrl??""}${c.path}`||"/",P={getHeader:w=>c.headers[w.toLowerCase()],getMethod:()=>c.method,getPath:()=>x,getUrl:()=>`${c.protocol}://${l}${c.originalUrl}`,getAcceptHeader:()=>c.headers.accept??"",getUserAgent:()=>c.headers["user-agent"]??"",getBody:()=>c.body??{},getQueryParams:()=>c.query,getQueryParam:w=>{let u=c.query[w];if(typeof u=="string"||Array.isArray(u))return u}},v=c.headers["payment-signature"]??c.headers["x-payment"],A={adapter:P,path:x,method:c.method,paymentHeader:v},S=await s.processHTTPRequest(A);if(t("processHTTPRequest ->",S.type),S.type==="no-payment-required"){h();return}if(S.type==="payment-error"){m(a,S.response);return}let i={request:A,responseBody:Buffer.alloc(0)},f=await s.processSettlement(S.paymentPayload,S.paymentRequirements,S.declaredExtensions,i);if(t("processSettlement ->",f.success?"success":`failure:${f.errorReason}`),!f.success){m(a,f.response);return}for(let[w,u]of Object.entries(f.headers))a.headersSent||a.setHeader(w,u);h()}catch(l){t("handler error:",l),a.headersSent||a.status(500).json({error:"Payment processing error"})}},ready:g}}import{formatUnits as De}from"viem";var Ie=6;async function ge(e){let{manager:t,store:n,channelId:r}=e,o=await n.get(r),s=BigInt(o?.chargedCumulativeAmount??"0"),p=BigInt(o?.balance??"0"),y=p>s?p-s:0n,{claims:g,settle:m}=await t.claimAndSettle(),b=await t.refund([r]),c=b.find(a=>a.channel===r)??b[0];return{claimTx:g[0]?.transaction??"",settleTx:m?.transaction??"",refundTx:c?.transaction??"",settledAmount:De(s,Ie),refundedAmount:De(y,Ie)}}async function Ue(e){let t=await e.store.list(),n=[];for(let r of t)try{let o=await ge({manager:e.manager,store:e.store,channelId:r.channelId});n.push({channelId:r.channelId,...o})}catch(o){n.push({channelId:r.channelId,error:o instanceof Error?o.message:String(o)})}return n}function Be(e){let t=!1,n=async()=>{try{await e.claimAndSettle()}catch(o){e.onError?.(o)}},r=setInterval(()=>{t||n()},e.claimIntervalMs);return typeof r.unref=="function"&&r.unref(),{async stop(){t||(t=!0,clearInterval(r),await n())}}}var it="https://x402.dexter.cash",at="GET /",$e=new Set(["eip155:8453","eip155:42161","eip155:137"]);function ct(e){return e===!1?null:e===void 0||e===!0?3e5:(e.claimIntervalSecs??300)*1e3}function he(e){if(!$e.has(e.network))throw new Error(`batch-settlement is not supported on network "${e.network}" \u2014 supported: ${[...$e].join(", ")}`);let t=e.facilitatorUrl??it,n=e.channelStore??new st({directory:ot(nt(),".dexter-x402","seller-channels")}),r=Ne({payTo:e.payTo,network:e.network,price:e.price,route:e.route??at,facilitatorUrl:t,channelStore:n,verbose:e.verbose}),o=r.scheme.createChannelManager(r.facilitator,e.network),s=async()=>{await o.claimAndSettle()},p=ct(e.autoSettle),y=null;p!==null&&(y=Be({claimAndSettle:s,claimIntervalMs:p,onError:c=>console.error("[batch-settlement:seller] auto-loop claim pass failed",c)}));let g=n,m=(c,a,h)=>{r.handler(c,a,h)},b=m;return b.middleware=()=>m,b.closeChannel=c=>ge({manager:o,store:g,channelId:c}),b.closeAll=()=>Ue({manager:o,store:g}),b.stop=async()=>{y&&await y.stop()},b}async function Le(e,t,n){let r={};for(let o of e)if(o.enrichPaymentRequiredResponse&&o.key in t)try{let s=await o.enrichPaymentRequiredResponse(t[o.key],n);s!==void 0&&(r[o.key]=s)}catch(s){console.warn(`[x402:extensions] extension "${o.key}" failed:`,s)}return Object.keys(r).length>0?r:void 0}function pt(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 ut(e){if(e.scheme==="batch-settlement"){let i=Array.isArray(e.network)?e.network[0]:e.network;if(!i)throw new Error('x402Middleware: scheme "batch-settlement" requires a network');let f=typeof e.payTo=="string"?e.payTo:void 0;if(!f)throw new Error('x402Middleware: scheme "batch-settlement" requires a string payTo address');return he({payTo:f,network:i,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:o,resourceUrl:s,mimeType:p,timeoutSeconds:y,verbose:g=!1,getResourceUrl:m,getAmount:b,getDescription:c,extensions:a,declarations:h}=e,l=g?console.log.bind(console,"[x402:middleware]"):()=>{},x=typeof t=="function"?t._x402Defaults:void 0,P=e.facilitatorUrl??x?.facilitatorUrl,v=e.network?Array.isArray(e.network)?e.network:[e.network]:x?.network?[x.network]:[le],A=new Map;for(let i of v){let f=pt(t,i);if(typeof f=="function"){let w=Oe(f);if(w&&i!==w)throw new Error(`stripePayTo is configured for "${w}" but middleware includes network "${i}". Stripe only supports Base deposit addresses. Use a static payTo for other chains.`)}A.set(i,Y({payTo:f,network:i,asset:r,facilitatorUrl:P,defaultTimeoutSeconds:y,scheme:e.scheme}))}let S=A.get(v[0]);return async(i,f,w)=>{try{let u=i.headers["payment-signature"];if(!u){l("No payment signature, returning 402");let q=m?.(i)??s??`${i.protocol}://${i.get("host")}${i.originalUrl}`,R=b?.(i)??n,C=c?.(i)??o,N=parseFloat(R),M=[],k=null;for(let[,F]of A)try{let fe={amountAtomic:G(N,F.assetDecimals),resourceUrl:q,description:C,mimeType:p,timeoutSeconds:y},Re=await F.buildRequirements(fe);M.push(...Re.accepts),k||(k=Re)}catch(fe){l("Failed to build requirements for a network:",fe)}if(!k||M.length===0){f.status(500).json({error:"Failed to build payment requirements"});return}if(k={...k,accepts:M},a&&a.length>0){let F=await Le(a,h??{},{response:k,request:{method:i.method,path:(i.baseUrl??"")+(i.route?.path??i.path),params:i.params}});F&&(k={...k,extensions:F})}let ee=S.encodeRequirements(k);f.setHeader("PAYMENT-REQUIRED",ee),f.status(402).json({error:"Payment required",accepts:k.accepts,resource:k.resource,...k.extensions?{extensions:k.extensions}:{}});return}l("Payment signature received, verifying...");let d=S;try{let R=JSON.parse(Buffer.from(u,"base64").toString())?.accepted?.network;R&&A.has(R)&&(d=A.get(R))}catch{}let T=await d.verifyPayment(u);if(!T.isValid){if(l("Payment verification failed:",T.invalidReason),e.onVerifyFailed)try{await e.onVerifyFailed({reason:T.invalidReason,resourceUrl:`${i.protocol}://${i.get("host")}${i.originalUrl}`})}catch{}f.status(402).json({error:"Payment verification failed",reason:T.invalidReason});return}l("Payment verified, settling...");let E=await d.settlePayment(u);if(!E.success){l("Payment settlement failed:",E.errorReason),f.status(402).json({error:"Payment settlement failed",reason:E.errorReason});return}l("Payment settled:",E.transaction);let _=E.network||v[0];if(e.onSettlement)try{await e.onSettlement({transaction:E.transaction,network:_,payer:T.payer??"",resourceUrl:`${i.protocol}://${i.get("host")}${i.originalUrl}`})}catch{}i.x402={transaction:E.transaction,payer:T.payer??"",network:_};let O={success:!0,transaction:E.transaction,network:_,payer:T.payer??""};if(E.extensions&&(O.extensions=E.extensions),f.setHeader("PAYMENT-RESPONSE",W(O)),e.sponsoredAccess&&E.extensions?.["sponsored-access"]){let q=E.extensions["sponsored-access"],R=q?.info?.recommendations??q?.recommendations;if(R&&R.length>0){if(l("Injecting sponsored-access recommendations into response"),typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.onMatch)try{e.sponsoredAccess.onMatch(R,{transaction:E.transaction,network:_,payer:T.payer??""})}catch{}let C=f.json.bind(f);f.json=function(M){return typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.inject?C(e.sponsoredAccess.inject(M,R)):M&&typeof M=="object"&&!Array.isArray(M)?C({_x402_sponsored:R,...M}):C(M)}}}w()}catch(u){l("Middleware error:",u),f.status(500).json({error:"Payment processing error"})}}}var lt=/^\/[a-zA-Z0-9_/:.\-~%]+$/;function qe(e){if(!e||!lt.test(e))return!1;let t;try{t=decodeURIComponent(e)}catch{return!1}return!(t.includes("..")||t.includes("://"))}function Z(e){return e.method==="POST"||e.method==="PUT"||e.method==="PATCH"}var dt=["GET","HEAD","DELETE"],mt=["POST","PUT","PATCH"];function Fe(e,t){let n=t.pathParams!==void 0&&Object.keys(t.pathParams).length>0,r={type:"http",method:e.method};Z(e)?(r.bodyType=e.bodyType,r.body=e.input??{}):e.input!==void 0&&(r.queryParams=e.input),n&&(r.pathParams=t.pathParams);let o=e.output?.example!==void 0?{type:"json",example:e.output.example}:void 0,s=Z(e)?mt:dt,p={type:{type:"string",const:"http"},method:{type:"string",enum:s}};Z(e)?(p.bodyType={type:"string",enum:["json","form-data","text"]},p.body={type:"object",...e.inputSchema??{}}):e.inputSchema&&(p.queryParams={type:"object",...e.inputSchema}),e.pathParamsSchema&&(p.pathParams={type:"object",...e.pathParamsSchema});let y={input:{type:"object",properties:p,required:Z(e)?["type","method","bodyType","body"]:["type","method"],additionalProperties:!1}};o&&(y.output={type:"object",properties:{type:{type:"string"},example:{type:"object",...e.output?.schema??{}}},required:["type"]});let g={$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:y,required:["input"]},m={info:{input:r,...o?{output:o}:{}},schema:g};return qe(t.routeTemplate)&&(m.routeTemplate=t.routeTemplate),m}var ft=["GET","HEAD","DELETE","POST","PUT","PATCH"];function yt(){return{key:"bazaar",enrichPaymentRequiredResponse:(e,t)=>{if(e==null)return;let n=e,r=(n.method??t.request.method).toUpperCase();if(!ft.includes(r))return;let o={...n,method:r};return Fe(o,{pathParams:t.request.params,routeTemplate:t.request.path})}}}function gt(e){return{bazaar:e}}function D(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}var ht='<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>',xt='<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>',bt=`
|
|
2
|
-
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Orbitron:wght@500;700&display=swap');
|
|
3
|
-
*{margin:0;padding:0;box-sizing:border-box}
|
|
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}
|
|
5
|
-
.card{max-width:460px;width:100%;background:rgba(20,20,20,.85);border:1px solid rgba(242,107,26,.12);border-radius:8px;padding:2rem 2rem 1.75rem;text-align:center;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
|
|
6
|
-
.crest{margin:0 auto .75rem}
|
|
7
|
-
h1{font-family:'Orbitron',sans-serif;font-size:1.15rem;font-weight:700;color:#f1f5f9;letter-spacing:.04em;margin-bottom:.35rem}
|
|
8
|
-
.desc{color:#94a3b8;font-size:.9rem;margin-bottom:1.25rem;line-height:1.5}
|
|
9
|
-
.price{font-family:'Orbitron',sans-serif;font-size:1.6rem;font-weight:700;color:#F26B1A;margin:.75rem 0 .25rem;display:inline-flex;align-items:center;gap:.35rem}
|
|
10
|
-
.price svg{width:1.3em;height:1.3em;flex-shrink:0}
|
|
11
|
-
.chain{color:#525252;font-size:.75rem;margin-bottom:1.25rem;letter-spacing:.03em}
|
|
12
|
-
.endpoint{background:rgba(242,107,26,.06);border:1px solid rgba(242,107,26,.12);border-radius:6px;padding:.5rem .75rem;margin-bottom:1.25rem}
|
|
13
|
-
.endpoint code{font-family:'SF Mono',Monaco,Consolas,monospace;font-size:.8rem;color:#F26B1A}
|
|
14
|
-
.info{background:rgba(255,255,255,.03);border:1px solid rgba(255,255,255,.06);border-radius:6px;padding:.85rem 1rem;font-size:.82rem;color:#737373;line-height:1.6;text-align:left}
|
|
15
|
-
.info strong{color:#a3a3a3}
|
|
16
|
-
.info code{background:rgba(242,107,26,.08);padding:2px 5px;border-radius:3px;font-size:.78rem;color:#F26B1A;font-family:'SF Mono',Monaco,Consolas,monospace}
|
|
17
|
-
.info a{color:#F26B1A;text-decoration:none;font-weight:600}
|
|
18
|
-
.info a:hover{text-decoration:underline}
|
|
19
|
-
.footer{margin-top:1.25rem;display:flex;align-items:center;justify-content:center;gap:.75rem;font-size:.7rem;color:#404040}
|
|
20
|
-
.footer a{color:#525252;text-decoration:none}
|
|
21
|
-
.footer a:hover{color:#737373}
|
|
22
|
-
.sep{width:3px;height:3px;border-radius:50%;background:#333}
|
|
23
|
-
`,Pt=`
|
|
24
|
-
.pay-section{margin:1.25rem 0}
|
|
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
|
-
.pay-btn:hover:not(:disabled){opacity:.9;transform:translateY(-1px)}
|
|
27
|
-
.pay-btn:active:not(:disabled){transform:translateY(0)}
|
|
28
|
-
.pay-btn:disabled{opacity:.6;cursor:not-allowed}
|
|
29
|
-
.pay-btn .spinner{width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite}
|
|
30
|
-
@keyframes spin{to{transform:rotate(360deg)}}
|
|
31
|
-
.pay-status{font-size:.8rem;color:#737373;margin-top:.5rem;min-height:1.2em}
|
|
32
|
-
.pay-status.error{color:#ef4444}
|
|
33
|
-
.pay-status.success{color:#22c55e}
|
|
34
|
-
.pay-alt{font-size:.78rem;color:#404040;margin-top:.75rem}
|
|
35
|
-
.pay-alt a{color:#F26B1A;text-decoration:none}
|
|
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
|
-
.result-box pre{color:#94a3b8;font-family:'SF Mono',Monaco,Consolas,monospace;white-space:pre-wrap;word-break:break-all}
|
|
38
|
-
.no-wallet{font-size:.82rem;color:#737373;margin:1rem 0}
|
|
39
|
-
`,Tt=`
|
|
40
|
-
<script type="module">
|
|
41
|
-
// Payment data is embedded in #x402-data attributes
|
|
42
|
-
const dataEl = document.getElementById('x402-data');
|
|
43
|
-
if (!dataEl) throw new Error('Missing payment data');
|
|
44
|
-
|
|
45
|
-
const requirements = JSON.parse(atob(dataEl.dataset.requirements));
|
|
46
|
-
const requestMethod = dataEl.dataset.method;
|
|
47
|
-
const requestUrl = dataEl.dataset.url;
|
|
48
|
-
const rpcUrl = dataEl.dataset.rpc || 'https://api.dexter.cash/api/solana/rpc';
|
|
49
|
-
|
|
50
|
-
// Detect wallet provider
|
|
51
|
-
function getWalletProvider() {
|
|
52
|
-
if (window.phantom?.solana?.isPhantom) return { name: 'Phantom', provider: window.phantom.solana };
|
|
53
|
-
if (window.solflare?.isSolflare) return { name: 'Solflare', provider: window.solflare };
|
|
54
|
-
if (window.backpack) return { name: 'Backpack', provider: window.backpack };
|
|
55
|
-
// Generic wallet-standard fallback
|
|
56
|
-
if (window.solana) return { name: 'Wallet', provider: window.solana };
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const walletInfo = getWalletProvider();
|
|
61
|
-
const btn = document.getElementById('pay-btn');
|
|
62
|
-
const status = document.getElementById('pay-status');
|
|
63
|
-
const section = document.getElementById('pay-section');
|
|
64
|
-
const noWallet = document.getElementById('no-wallet');
|
|
65
|
-
|
|
66
|
-
if (walletInfo && btn) {
|
|
67
|
-
section.style.display = 'block';
|
|
68
|
-
if (noWallet) noWallet.style.display = 'none';
|
|
69
|
-
} else if (noWallet) {
|
|
70
|
-
noWallet.style.display = 'block';
|
|
71
|
-
if (section) section.style.display = 'none';
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Preload Solana libraries in background
|
|
75
|
-
let solanaLibs = null;
|
|
76
|
-
const preload = (async () => {
|
|
77
|
-
try {
|
|
78
|
-
const [web3, spl] = await Promise.all([
|
|
79
|
-
import('https://esm.sh/@solana/web3.js@1.98.0'),
|
|
80
|
-
import('https://esm.sh/@solana/spl-token@0.4.9'),
|
|
81
|
-
]);
|
|
82
|
-
solanaLibs = { web3, spl };
|
|
83
|
-
} catch (e) {
|
|
84
|
-
console.warn('[x402] Failed to preload Solana libraries:', e);
|
|
85
|
-
}
|
|
86
|
-
})();
|
|
87
|
-
|
|
88
|
-
function setStatus(msg, type) {
|
|
89
|
-
if (!status) return;
|
|
90
|
-
status.textContent = msg;
|
|
91
|
-
status.className = 'pay-status' + (type ? ' ' + type : '');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
function setBtnState(text, disabled, loading) {
|
|
95
|
-
if (!btn) return;
|
|
96
|
-
btn.disabled = disabled;
|
|
97
|
-
btn.innerHTML = loading
|
|
98
|
-
? '<span class="spinner"></span>' + text
|
|
99
|
-
: text;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (btn) {
|
|
103
|
-
btn.addEventListener('click', async () => {
|
|
104
|
-
if (!walletInfo) return;
|
|
105
|
-
const { provider } = walletInfo;
|
|
106
|
-
|
|
107
|
-
try {
|
|
108
|
-
// 1. Connect wallet
|
|
109
|
-
setBtnState('Connecting...', true, true);
|
|
110
|
-
setStatus('');
|
|
111
|
-
await provider.connect();
|
|
112
|
-
|
|
113
|
-
if (!provider.publicKey) {
|
|
114
|
-
throw new Error('Wallet did not provide a public key');
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// 2. Load Solana libraries (should already be cached from preload)
|
|
118
|
-
setBtnState('Preparing...', true, true);
|
|
119
|
-
await preload;
|
|
120
|
-
if (!solanaLibs) {
|
|
121
|
-
// Retry once
|
|
122
|
-
const [web3, spl] = await Promise.all([
|
|
123
|
-
import('https://esm.sh/@solana/web3.js@1.98.0'),
|
|
124
|
-
import('https://esm.sh/@solana/spl-token@0.4.9'),
|
|
125
|
-
]);
|
|
126
|
-
solanaLibs = { web3, spl };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const { web3, spl } = solanaLibs;
|
|
130
|
-
const { PublicKey, Connection, TransactionMessage, VersionedTransaction, ComputeBudgetProgram } = web3;
|
|
131
|
-
const { getAssociatedTokenAddress, createTransferCheckedInstruction, getMint, TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } = spl;
|
|
132
|
-
|
|
133
|
-
// 3. Parse payment requirements
|
|
134
|
-
const accept = requirements.accepts[0];
|
|
135
|
-
if (!accept) throw new Error('No payment method available');
|
|
136
|
-
|
|
137
|
-
const payTo = new PublicKey(accept.payTo);
|
|
138
|
-
const amount = BigInt(accept.amount ?? accept.maxAmountRequired);
|
|
139
|
-
const mintPubkey = new PublicKey(accept.asset);
|
|
140
|
-
const feePayer = accept.extra?.feePayer ? new PublicKey(accept.extra.feePayer) : provider.publicKey;
|
|
141
|
-
const userPubkey = provider.publicKey;
|
|
142
|
-
|
|
143
|
-
// 4. Build transaction
|
|
144
|
-
setBtnState('Building tx...', true, true);
|
|
145
|
-
const connection = new Connection(rpcUrl, 'confirmed');
|
|
146
|
-
|
|
147
|
-
const instructions = [];
|
|
148
|
-
|
|
149
|
-
// ComputeBudget
|
|
150
|
-
instructions.push(ComputeBudgetProgram.setComputeUnitLimit({ units: 12000 }));
|
|
151
|
-
instructions.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 1 }));
|
|
152
|
-
|
|
153
|
-
// Determine token program
|
|
154
|
-
const mintInfo = await connection.getAccountInfo(mintPubkey, 'confirmed');
|
|
155
|
-
if (!mintInfo) throw new Error('Token mint not found');
|
|
156
|
-
const programId = mintInfo.owner.toBase58() === TOKEN_2022_PROGRAM_ID.toBase58() ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;
|
|
157
|
-
|
|
158
|
-
const mint = await getMint(connection, mintPubkey, undefined, programId);
|
|
159
|
-
|
|
160
|
-
// ATAs
|
|
161
|
-
const sourceAta = await getAssociatedTokenAddress(mintPubkey, userPubkey, false, programId);
|
|
162
|
-
const destAta = await getAssociatedTokenAddress(mintPubkey, payTo, false, programId);
|
|
163
|
-
|
|
164
|
-
// Verify source exists
|
|
165
|
-
const sourceInfo = await connection.getAccountInfo(sourceAta, 'confirmed');
|
|
166
|
-
if (!sourceInfo) throw new Error('No USDC token account found. Make sure you have USDC in your wallet.');
|
|
167
|
-
|
|
168
|
-
// TransferChecked
|
|
169
|
-
instructions.push(createTransferCheckedInstruction(sourceAta, mintPubkey, destAta, userPubkey, amount, mint.decimals, [], programId));
|
|
170
|
-
|
|
171
|
-
const { blockhash } = await connection.getLatestBlockhash('confirmed');
|
|
172
|
-
const message = new TransactionMessage({ payerKey: feePayer, recentBlockhash: blockhash, instructions }).compileToV0Message();
|
|
173
|
-
const transaction = new VersionedTransaction(message);
|
|
174
|
-
|
|
175
|
-
// 5. Sign
|
|
176
|
-
setBtnState('Sign in wallet...', true, true);
|
|
177
|
-
setStatus('Approve the transaction in your wallet');
|
|
178
|
-
const signed = await provider.signTransaction(transaction);
|
|
179
|
-
const serialized = signed.serialize();
|
|
180
|
-
|
|
181
|
-
// Convert Uint8Array to base64
|
|
182
|
-
let payload = '';
|
|
183
|
-
const bytes = new Uint8Array(serialized);
|
|
184
|
-
const chunk = 8192;
|
|
185
|
-
for (let i = 0; i < bytes.length; i += chunk) {
|
|
186
|
-
payload += String.fromCharCode.apply(null, bytes.slice(i, i + chunk));
|
|
187
|
-
}
|
|
188
|
-
payload = btoa(payload);
|
|
189
|
-
|
|
190
|
-
// 6. Build payment-signature header (x402 v2 format)
|
|
191
|
-
// Solana: payload must be { transaction: base64Tx } per SDK spec
|
|
192
|
-
const paymentSignature = {
|
|
193
|
-
x402Version: accept.x402Version ?? 2,
|
|
194
|
-
resource: requirements.resource,
|
|
195
|
-
accepted: accept,
|
|
196
|
-
payload: { transaction: payload },
|
|
197
|
-
};
|
|
198
|
-
const paymentHeader = btoa(JSON.stringify(paymentSignature));
|
|
199
|
-
|
|
200
|
-
// 7. Submit payment
|
|
201
|
-
setBtnState('Verifying...', true, true);
|
|
202
|
-
setStatus('Payment submitted, verifying...');
|
|
203
|
-
|
|
204
|
-
// Use the original request body if available
|
|
205
|
-
const originalBody = dataEl.dataset.body ? atob(dataEl.dataset.body) : '{}';
|
|
206
|
-
const response = await fetch(requestUrl, {
|
|
207
|
-
method: requestMethod,
|
|
208
|
-
headers: {
|
|
209
|
-
'Content-Type': 'application/json',
|
|
210
|
-
'PAYMENT-SIGNATURE': paymentHeader,
|
|
211
|
-
},
|
|
212
|
-
body: requestMethod !== 'GET' ? originalBody : undefined,
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
if (response.ok) {
|
|
216
|
-
const data = await response.json();
|
|
217
|
-
setBtnState('Paid', true, false);
|
|
218
|
-
setStatus('Payment successful', 'success');
|
|
219
|
-
// Show response
|
|
220
|
-
const resultBox = document.createElement('div');
|
|
221
|
-
resultBox.className = 'result-box';
|
|
222
|
-
resultBox.innerHTML = '<pre>' + JSON.stringify(data, null, 2).replace(/</g, '<') + '</pre>';
|
|
223
|
-
section.appendChild(resultBox);
|
|
224
|
-
} else {
|
|
225
|
-
const err = await response.json().catch(() => ({ error: 'Payment verification failed' }));
|
|
226
|
-
throw new Error(err.error || err.reason || 'Payment failed');
|
|
227
|
-
}
|
|
228
|
-
} catch (err) {
|
|
229
|
-
console.error('[x402] Payment error:', err);
|
|
230
|
-
setBtnState('Pay ' + document.getElementById('price-value').textContent, false, false);
|
|
231
|
-
setStatus(err.message || 'Payment failed', 'error');
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
</script>
|
|
236
|
-
`;function St(e,t,n,r,o,s){let p="?",y="This resource requires payment",g="";try{let c=JSON.parse(Buffer.from(e,"base64").toString()),a=c.accepts?.[0];if(a){let h=a.amount??a.maxAmountRequired??"0",l=a.extra?.decimals||6;p=(Number(h)/Math.pow(10,l)).toFixed(l>4?4:2),g=a.network||""}c.resource?.description&&(y=c.resource.description)}catch{}let m=g.includes("solana")?"Solana":g.includes("eip155")?"Base":"",b=r.showEndpoint?`<div class="endpoint"><code>${D(n)} ${D(t)}</code></div>`:"";return`<!DOCTYPE html>
|
|
237
|
-
<html lang="en">
|
|
238
|
-
<head>
|
|
239
|
-
<meta charset="utf-8">
|
|
240
|
-
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
241
|
-
<title>${D(r.title)} \u2014 ${D(p)} USDC</title>
|
|
242
|
-
<style>${bt}${Pt}</style>
|
|
243
|
-
</head>
|
|
244
|
-
<body>
|
|
245
|
-
<div class="card">
|
|
246
|
-
<div class="crest">${xt}</div>
|
|
247
|
-
<h1>${D(r.title)}</h1>
|
|
248
|
-
<p class="desc">${D(y)}</p>
|
|
249
|
-
<div class="price">${ht}<span id="price-value">${D(p)}</span></div>
|
|
250
|
-
<div class="chain">${D(m)}${m?" network":""}</div>
|
|
251
|
-
${b}
|
|
252
|
-
|
|
253
|
-
<div id="pay-section" class="pay-section" style="display:none">
|
|
254
|
-
<button id="pay-btn" class="pay-btn">Pay ${p}</button>
|
|
255
|
-
<div id="pay-status" class="pay-status"></div>
|
|
256
|
-
<div class="pay-alt">or use <a href="${r.sdkUrl}">x402 SDK</a> for programmatic access</div>
|
|
257
|
-
</div>
|
|
258
|
-
|
|
259
|
-
<div id="no-wallet" class="no-wallet" style="display:none">
|
|
260
|
-
<div class="info">
|
|
261
|
-
<strong>Access this endpoint:</strong><br><br>
|
|
262
|
-
Use any x402-compatible client or a browser with a Solana wallet extension (Phantom, Solflare, Backpack).<br><br>
|
|
263
|
-
<code>npm install @dexterai/x402</code><br><br>
|
|
264
|
-
<a href="${r.sdkUrl}">x402 SDK docs →</a>
|
|
265
|
-
</div>
|
|
266
|
-
</div>
|
|
267
|
-
|
|
268
|
-
<div class="footer">
|
|
269
|
-
<a href="https://docs.dexter.cash/docs/sdk/">x402</a>
|
|
270
|
-
<span class="sep"></span>
|
|
271
|
-
<a href="https://dexter.cash">Dexter</a>
|
|
272
|
-
</div>
|
|
273
|
-
</div>
|
|
274
|
-
|
|
275
|
-
<div id="x402-data" style="display:none"
|
|
276
|
-
data-requirements="${e}"
|
|
277
|
-
data-method="${n}"
|
|
278
|
-
data-url="${t}"
|
|
279
|
-
data-rpc="${o}"
|
|
280
|
-
data-body="${s?Buffer.from(s).toString("base64"):""}"
|
|
281
|
-
></div>
|
|
282
|
-
${Tt}
|
|
283
|
-
</body>
|
|
284
|
-
</html>`}function Rt(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,o,s)=>{let p=o.json.bind(o);o.json=function(y){if(o.statusCode===402&&r.accepts("html")&&!r.headers["payment-signature"]){let g=o.getHeader("PAYMENT-REQUIRED")||o.getHeader("payment-required");if(g&&typeof g=="string"){let m;if(r.body&&typeof r.body=="object"&&Object.keys(r.body).length>0)try{m=JSON.stringify(r.body)}catch{}let b=St(g,r.originalUrl,r.method,t,n,m);return o.setHeader("Content-Security-Policy","default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline'; connect-src *; img-src data:; frame-ancestors 'none'"),o.setHeader("X-Content-Type-Options","nosniff"),o.status(402).type("html").send(b),o}}return p(y)},s()}}import xe from"crypto";var wt=/^(\d+)(m|h|d|w)$/;function At(e){let t=e.match(wt);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 He(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 Et(e,t){let n=Buffer.from(JSON.stringify({alg:"HS256",typ:"JWT"})).toString("base64url"),r=Buffer.from(JSON.stringify(e)).toString("base64url"),o=xe.createHmac("sha256",t).update(`${n}.${r}`).digest("base64url");return`${n}.${r}.${o}`}function vt(e,t){try{let n=e.split(".");if(n.length!==3)return null;let[r,o,s]=n,p=xe.createHmac("sha256",t).update(`${r}.${o}`).digest("base64url");if(s!==p)return null;let y=JSON.parse(Buffer.from(o,"base64url").toString());return y.exp&&Date.now()/1e3>y.exp||y.sub!=="x402-access-pass"?null:y}catch{return null}}function kt(e){let{payTo:t,network:n=le,asset:r,facilitatorUrl:o,tiers:s,ratePerHour:p,secret:y,issuer:g="x402-access-pass",verbose:m=!1,description:b}=e,c=y??xe.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."),!s&&!p)throw new Error("x402AccessPass: at least one of `tiers` or `ratePerHour` is required");let a=m?console.log.bind(console,"[x402:access-pass]"):()=>{},h=r?.decimals??ue,l=[];if(s){for(let[i,f]of Object.entries(s)){let w=At(i);if(!w){console.warn(`x402AccessPass: skipping tier "${i}" \u2014 unrecognized duration format (use 5m, 1h, 24h, 7d)`);continue}l.push({id:i,label:He(w),seconds:w,price:f,priceAtomic:G(parseFloat(f),h)})}l.sort((i,f)=>i.seconds-f.seconds)}let x=Y({payTo:t,network:n,asset:r,facilitatorUrl:o}),P={tiers:l.length>0?l:void 0,ratePerHour:p||void 0,issuer:g},v=W(P);function A(i){if(!p)throw new Error("Custom durations not supported \u2014 no ratePerHour configured");let f=i/3600,w=(parseFloat(p)*f).toFixed(h>4?4:2);return{price:w,priceAtomic:G(parseFloat(w),h)}}function S(i){let f=i.query.tier,w=i.query.duration;if(f){let d=l.find(T=>T.id===f);if(d)return{tier:d.id,seconds:d.seconds,price:d.price,priceAtomic:d.priceAtomic,label:d.label}}if(w){let d=parseInt(w,10);if(d>0&&p){let T=A(d);return{tier:"custom",seconds:d,...T,label:He(d)}}}if(l.length>0){let d=l[0];return{tier:d.id,seconds:d.seconds,price:d.price,priceAtomic:d.priceAtomic,label:d.label}}return{tier:"custom",seconds:3600,...A(3600),label:"1 hour"}}return async(i,f,w)=>{try{let u=i.headers.authorization;if(u?.startsWith("Bearer ")){let R=vt(u.slice(7),c);if(R)return a("Valid access pass:",R.tier,"| expires:",new Date(R.exp*1e3).toISOString()),i.accessPass={tier:R.tier,duration:R.duration,expiresAt:new Date(R.exp*1e3).toISOString(),payer:R.payer,network:R.network},w();a("Invalid or expired access pass token")}let d=i.headers["payment-signature"];if(d){a("Payment signature received, verifying for pass purchase...");let R=await x.verifyPayment(d);if(!R.isValid){a("Payment verification failed:",R.invalidReason),f.status(402).json({error:"Payment verification failed",reason:R.invalidReason});return}let C=await x.settlePayment(d);if(!C.success){a("Payment settlement failed:",C.errorReason),f.status(402).json({error:"Payment settlement failed",reason:C.errorReason});return}a("Payment settled:",C.transaction);let N=S(i),M=Math.floor(Date.now()/1e3),k={sub:"x402-access-pass",tier:N.tier,duration:N.seconds,iat:M,exp:M+N.seconds,payer:R.payer??"",network:n,iss:g},ee=Et(k,c);i.x402={transaction:C.transaction,payer:R.payer??"",network:n};let F={success:!0,transaction:C.transaction,network:n,payer:R.payer??""};f.setHeader("PAYMENT-RESPONSE",W(F)),f.setHeader("ACCESS-PASS",ee),f.json({accessPass:{token:ee,tier:N.tier,duration:N.label,durationSeconds:N.seconds,expiresAt:new Date((M+N.seconds)*1e3).toISOString(),usage:"Include on subsequent requests as: Authorization: Bearer <token>"},transaction:C.transaction,payer:R.payer});return}a("No access pass or payment, returning 402");let T=S(i),E=T.priceAtomic,_=`${i.protocol}://${i.get("host")}${i.originalUrl}`,O=await x.buildRequirements({amountAtomic:E,resourceUrl:_,description:b||`Access pass: ${T.label}`,mimeType:"application/json"}),q=x.encodeRequirements(O);f.setHeader("PAYMENT-REQUIRED",q),f.setHeader("X-ACCESS-PASS-TIERS",v),f.status(402).json({error:"Access pass required",message:"Purchase an access pass to unlock unlimited API access for a time window.",accepts:O.accepts,resource:O.resource,accessPass:{tiers:l.length>0?l:void 0,ratePerHour:p||void 0,usage:"Add ?tier=<id> or ?duration=<seconds> to your payment request to choose a pass duration."}})}catch(u){a("Access pass middleware error:",u),f.status(500).json({error:"Payment processing error",message:u instanceof Error?u.message:"Unknown error"})}}}import{createHmac as Mt,randomBytes as Ct}from"crypto";var _t=300;function Ot(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:o,maxUsd:s,roundingMode:p,decimals:y}=t;if(n<=0)throw new Error("unitSize must be positive");if(r<=0)throw new Error("ratePerUnit must be positive");if(o<0)throw new Error("minUsd cannot be negative");if(s<o)throw new Error("maxUsd must be >= minUsd");let g=Ct(32);function m(a,h){let l=JSON.stringify({unitSize:n,ratePerUnit:r,minUsd:o,maxUsd:s===1/0?"none":s,roundingMode:p}),x=`${a}|${l}|${h}`;return Mt("sha256",g).update(x).digest("hex").slice(0,16)}function b(a){let h=a.length,l=h/n,x;switch(p){case"ceil":x=Math.ceil(l);break;case"floor":x=Math.floor(l);break;case"round":x=Math.round(l);break}h>0&&x===0&&(x=1);let P=x*r;P=Math.max(o,P),P=Math.min(s,P);let v=Math.pow(10,y),A=Math.floor(P*v).toString(),S=Math.floor(Date.now()/1e3),i=m(a,S),f=`${S}.${i}`;return{amountAtomic:A,usdAmount:P,quoteHash:f,units:x,inputLength:h}}function c(a,h){if(!h)return!1;let l=h.indexOf(".");if(l===-1)return!1;let x=parseInt(h.slice(0,l),10),P=h.slice(l+1);if(isNaN(x)||!P)return!1;let v=Math.floor(Date.now()/1e3)-x;if(v<0||v>_t)return!1;let A=m(a,x);if(P.length!==A.length)return!1;let S=0;for(let i=0;i<P.length;i++)S|=P.charCodeAt(i)^A.charCodeAt(i);return S===0}return{calculate:b,validateQuote:c,config:t}}function Nt(e){let t=e.ratePerUnit.toFixed(2),n=e.unitSize.toLocaleString();return`from $${t} per ${n} chars`}import{createHash as Kt}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},L={usesMaxCompletionTokens:!0,supportsTemperature:!1,supportsTopP:!1,supportsFrequencyPenalty:!1,supportsPresencePenalty:!1,supportsReasoningEffort:!0,supportsStreaming:!0,supportsSystemMessage:!0,supportsTools:!0,supportsStructuredOutput:!0},We={...L,supportsStreaming:!1},U=[{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:L,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:L,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:L,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:L,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:L,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:We,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:We,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:{...L,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:{...L,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"}],be=new Map(U.map(e=>[e.id,e]));function Pe(e){let t=be.get(e);if(!t)throw new Error(`Unknown model: ${e}. Use getAvailableModelIds() to see valid options.`);return t}function Dt(e){return be.get(e)}function It(e){return be.has(e)}function Ut(){return U.map(e=>e.id)}function Bt(e){return U.filter(t=>t.tier===e&&!t.deprecated).sort((t,n)=>t.capabilityRank-n.capabilityRank)}function $t(e){return U.filter(t=>t.family===e).sort((t,n)=>t.capabilityRank-n.capabilityRank)}function Lt(){let e={fast:1,standard:2,reasoning:3,premium:4,specialized:5};return U.filter(t=>!t.deprecated).sort((t,n)=>{let r=e[t.tier]-e[n.tier];return r!==0?r:t.capabilityRank-n.capabilityRank})}function qt(){return U.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 Ft(e="fast"){let t={fast:1,standard:2,reasoning:3,premium:4,specialized:5},n=t[e];return U.filter(o=>!o.deprecated&&t[o.tier]>=n).sort((o,s)=>o.pricing.input-s.pricing.input)[0]}function Ht(e,t,n,r=!1){let o=Pe(e),s=r&&o.pricing.cached?t/1e6*o.pricing.cached:t/1e6*o.pricing.input,p=n/1e6*o.pricing.output;return s+p}function Wt(e){let t=Pe(e);return`$${t.pricing.input.toFixed(2)} in / $${t.pricing.output.toFixed(2)} out per 1M tokens`}var Te=Object.fromEntries(U.map(e=>[e.id,{input:e.pricing.input,output:e.pricing.output,cached:e.pricing.cached,maxTokens:e.defaultMaxOutput,tier:e.tier}]));var me=null;async function jt(){if(me)return me;try{return me=await import("tiktoken"),me}catch{throw new Error('Token pricing requires the "tiktoken" package. Install with: npm install tiktoken')}}var B=Te,j="gpt-4o-mini";async function zt(e){let t=await jt();try{return t.encoding_for_model(e)}catch{return t.get_encoding("cl100k_base")}}async function Se(e,t=j){let n=await zt(t);try{return n.encode(e).length}finally{n.free()}}function Ke(e,t,n,r){let o=JSON.stringify({model:t,rate:n,tokens:r});return Kt("sha256").update(e+o).digest("hex").slice(0,16)}function Vt(e={}){let t=e.model??j,n=B[t],r={input:e.inputRate??n?.input??B[j].input,output:e.outputRate??n?.output??B[j].output,maxTokens:e.maxTokens??n?.maxTokens??4096,tier:e.tier??n?.tier??"custom"},o=e.tokenizer,s={model:t,inputRate:r.input,outputRate:r.output,maxTokens:r.maxTokens,tier:r.tier,tokenizer:o??(a=>Se(a,t)),minUsd:e.minUsd??.001,maxUsd:e.maxUsd??50,decimals:e.decimals??6},{minUsd:p,maxUsd:y,decimals:g}=s;async function m(a){return o?o(a):Se(a,t)}async function b(a,h){let l=h?`${h}
|
|
285
|
-
|
|
286
|
-
${a}`:a,x=await m(l),P=x/1e6*r.input;P=Math.max(P,p),P=Math.min(P,y);let v=Math.pow(10,g),A=Math.floor(P*v).toString(),S=Ke(a,t,r.input,x);return{amountAtomic:A,usdAmount:P,inputTokens:x,model:t,tier:r.tier,inputRatePerMillion:r.input,outputRatePerMillion:r.output,maxOutputTokens:r.maxTokens,quoteHash:S}}async function c(a,h){if(!h)return!1;let l=await m(a);return Ke(a,t,r.input,l)===h}return{calculate:b,validateQuote:c,countTokens:m,config:s,modelInfo:r}}function Gt(){return Object.entries(B).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 Xt(e){return e in B}function Jt(e=j){let t=B[e]??B[j],n=B[e]?e:j;return`$${t.input.toFixed(2)} per 1M tokens (${n})`}import{SPONSORED_ACCESS_EXTENSION_KEY as Tn}from"@dexterai/x402-ads-types";export{z as BASE_MAINNET_NETWORK,$ as DEXTER_FACILITATOR_URL,Q as FacilitatorClient,B as MODEL_PRICING,Te as MODEL_PRICING_MAP,U as MODEL_REGISTRY,H as SOLANA_MAINNET_NETWORK,Tn as SPONSORED_ACCESS_EXTENSION_KEY,ye as USDC_BASE,V as USDC_MINT,yt as bazaarExtension,Se as countTokens,Ot as createDynamicPricing,Vt as createTokenPricing,Y as createX402Server,gt as declareDiscoveryExtension,D as escapeHtml,Ht as estimateCost,Dt as findModel,Wt as formatModelPricing,Nt as formatPricing,Jt as formatTokenPricing,Lt as getActiveModels,Ut as getAvailableModelIds,Gt as getAvailableModels,Ft as getCheapestModel,Pe as getModel,$t as getModelsByFamily,Bt as getModelsByTier,qt as getTextModels,Xt as isValidModel,It as isValidModelId,Ce as resolveDefaultAsset,Ye as stripePayTo,kt as x402AccessPass,Rt as x402BrowserSupport,ut as x402Middleware};
|
|
1
|
+
var k="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",ae="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ce="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var I="eip155:8453",F="eip155:84532",W="eip155:42161",j="eip155:137",V="eip155:10",X="eip155:43114",z="eip155:56",J="eip155:1187947933",Y="eip155:324705682",G="eip155:1";var L="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var te="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",_e="0x55d398326f99059fF775485246999027B3197955",pe="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",ue={[z]:pe,[I]:te,[F]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[W]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[j]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[V]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[X]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[J]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Y]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[G]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},le={[_e]:{symbol:"USDT",decimals:18},[pe]:{symbol:"USDC",decimals:18}};var Ge={[z]:56,[I]:8453,[F]:84532,[W]:42161,[j]:137,[V]:10,[X]:43114,[J]:1187947933,[Y]:324705682,[G]:1},Qe={[k]:"https://api.dexter.cash/api/solana/rpc",[ae]:"https://api.devnet.solana.com",[ce]:"https://api.testnet.solana.com"},Ze={[z]:"https://api.dexter.cash/api/evm/bsc/rpc",[I]:"https://api.dexter.cash/api/base/rpc",[F]:"https://sepolia.base.org",[W]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[j]:"https://api.dexter.cash/api/evm/polygon/rpc",[V]:"https://api.dexter.cash/api/evm/optimism/rpc",[X]:"https://api.dexter.cash/api/evm/avalanche/rpc",[J]:"https://skale-base.skalenodes.com/v1/base",[Y]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[G]:"https://eth.llamarpc.com"},O="https://x402.dexter.cash",de=k;function me(e,t){if(!Number.isFinite(e))throw new Error(`toAtomicUnits: amount must be finite, got ${e}`);if(e<0)throw new Error(`toAtomicUnits: amount must be non-negative, got ${e}`);if(!Number.isInteger(t)||t<0)throw new Error(`toAtomicUnits: decimals must be a non-negative integer, got ${t}`);let s=we(Math.abs(e)),[r,n=""]=s.split("."),a=n.slice(0,t).padEnd(t,"0");return BigInt(r+a).toString()}function we(e){let t=e.toString();if(!/[eE]/.test(t))return t;let[s,r]=t.split(/[eE]/),n=parseInt(r,10),a=s.startsWith("-"),p=a?s.slice(1):s,[m,f=""]=p.split("."),l=m+f,g=m.length+n,o;return g<=0?o="0."+"0".repeat(-g)+l:g>=l.length?o=l+"0".repeat(g-l.length):o=l.slice(0,g)+"."+l.slice(g),(a?"-":"")+o}function Q(e){return e.startsWith("solana:")||e==="solana"}function Ce(e){if(typeof Buffer<"u")return Buffer.from(e,"utf-8").toString("base64");let t=new TextEncoder().encode(e),s="";for(let r=0;r<t.length;r++)s+=String.fromCharCode(t[r]);return btoa(s)}function Ne(e){if(typeof Buffer<"u")return Buffer.from(e,"base64").toString("utf-8");let t=atob(e),s=new Uint8Array(t.length);for(let r=0;r<t.length;r++)s[r]=t.charCodeAt(r);return new TextDecoder().decode(s)}function Z(e){return Ce(JSON.stringify(e))}function q(e){return JSON.parse(Ne(e))}function De(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 $=class extends Error{status;body;constructor(t,s){super(`HTTP ${t}`),this.status=t,this.body=s}},K=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(t=O,s){this.facilitatorUrl=t.replace(/\/$/,""),this.timeoutMs=s?.timeoutMs??1e4,this.maxRetries=s?.maxRetries??3,this.retryBaseMs=s?.retryBaseMs??500}async fetchWithTimeout(t,s){let r=new AbortController,n=setTimeout(()=>r.abort(),this.timeoutMs);try{return await fetch(t,{...s,signal:r.signal})}finally{clearTimeout(n)}}async fetchWithRetry(t,s){let r;for(let n=0;n<this.maxRetries;n++)try{let a=await this.fetchWithTimeout(t,s);if(!a.ok&&a.status>=500)throw new $(a.status,await a.text());return a}catch(a){if(r=a,n<this.maxRetries-1&&De(a)){let p=this.retryBaseMs*Math.pow(2,n);await new Promise(m=>setTimeout(m,p));continue}throw a}throw r}async getSupported(){let t=Date.now();if(this.cachedSupported&&t-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let s=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!s.ok)throw new Error(`Facilitator /supported returned ${s.status}`);return this.cachedSupported=await s.json(),this.cacheTime=t,this.cachedSupported}async getFeePayer(t){let r=(await this.getSupported()).kinds.find(n=>n.x402Version===2&&(n.scheme==="exact"||n.scheme==="exact-approval")&&n.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(n=>n.x402Version===2&&(n.scheme==="exact"||n.scheme==="exact-approval"||n.scheme==="batch-settlement")&&n.network===t)?.extra}async verifyPayment(t,s){try{let r=q(t),n=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:s})});return n.ok?await n.json():{isValid:!1,invalidReason:`facilitator_error_${n.status}`}}catch(r){return{isValid:!1,invalidReason:r instanceof $?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_verify_error"}}}async settlePayment(t,s){try{let r=q(t),n=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:s})});return n.ok?{...await n.json(),network:s.network}:{success:!1,network:s.network,errorReason:`facilitator_error_${n.status}`}}catch(r){let n=r instanceof $?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_settle_error";return{success:!1,network:s.network,errorReason:n}}}};function ye(e){if(Q(e))return{address:L,decimals:6};let t=ue[e];if(t){let s=le[t]?.decimals??6;return{address:t,decimals:s}}return{address:L,decimals:6}}function fe(e){try{let t=q(e);return t?.accepted?.amount??t?.accepted?.maxAmountRequired}catch{return}}function re(e){let{payTo:t,facilitatorUrl:s=O,network:r=k,defaultTimeoutSeconds:n=60}=e,a=e.asset??ye(r),p=e.scheme??"exact";if(p==="tab"&&!Q(r))throw new Error(`scheme 'tab' is SVM-only; got network "${r}"`);let m=new K(s),f=null,l=new Map,g=3e4,o=Date.now();function y(i){let u=(i.maxTimeoutSeconds||n)*1e3;if(l.set(i.payTo,{accept:i,expiresAt:Date.now()+u}),Date.now()-o>g){let h=Date.now();for(let[S,_]of l)_.expiresAt<h&&l.delete(S);o=h}}function E(i){let u=l.get(i);if(u){if(u.expiresAt<Date.now()){l.delete(i);return}return u.accept}}async function x(i){return typeof t=="string"?t:t(i||{})}async function b(){if(f||(f=await m.getNetworkExtra(r)),Q(r)&&!f?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${r}"`);return{...f?.feePayer?{feePayer:f.feePayer}:{},decimals:f?.decimals??a.decimals,name:f?.name,version:f?.version,...p==="batch-settlement"&&f?.receiverAuthorizer?{receiverAuthorizer:f.receiverAuthorizer}:{},...p==="tab"?{voucherHeader:"x-tab-voucher",registrationEncoding:"base64(188-byte sessionRegisterMessage)"}:{}}}async function N(i,u){let{amountAtomic:h,timeoutSeconds:S=n}=u,_=await b(),D={scheme:p,network:r,amount:h,maxAmountRequired:h,asset:a.address,payTo:i,maxTimeoutSeconds:S,extra:_};return y(D),D}async function C(i){let u=await x({amountAtomic:i.amountAtomic,resourceUrl:i.resourceUrl});return N(u,i)}async function v(i){let{resourceUrl:u,description:h,mimeType:S="application/json"}=i,_={url:u,description:h,mimeType:S},D=await C(i);return{x402Version:2,resource:_,accepts:[D],error:"Payment required"}}function R(i){return Z(i)}function c(i){return{status:402,headers:{"PAYMENT-REQUIRED":R(i)},body:{}}}async function d(i,u){if(!u){let h=await x({paymentHeader:i});u=E(h),u||(u=await N(h,{amountAtomic:fe(i)??"0",resourceUrl:""}))}return m.verifyPayment(i,u)}async function A(i,u){if(!u){let h=await x({paymentHeader:i});u=E(h),u||(u=await N(h,{amountAtomic:fe(i)??"0",resourceUrl:""}))}return m.settlePayment(i,u)}return{buildRequirements:v,encodeRequirements:R,create402Response:c,verifyPayment:d,settlePayment:A,getPaymentAccept:C,network:r,assetDecimals:a.decimals,facilitator:m}}var ke=new WeakMap;function he(e){return ke.get(e)}import{homedir as Me}from"os";import{join as Le}from"path";import{FileChannelStorage as qe}from"@x402/evm/batch-settlement/server";import{HTTPFacilitatorClient as Oe,x402ResourceServer as Ie}from"@x402/core/server";import{x402HTTPResourceServer as Ue}from"@x402/core/http";import{BatchSettlementEvmScheme as Be}from"@x402/evm/batch-settlement/server";function ge(e){let t=e.verbose?console.log.bind(console,"[batch-settlement:seller]"):()=>{},s=new Oe({url:e.facilitatorUrl}),r=new Be(e.payTo,{storage:e.channelStore}),n=new Ie(s).register(e.network,r),a=new Ue(n,{[e.route]:{accepts:{scheme:"batch-settlement",payTo:e.payTo,price:e.price,network:e.network},description:"batch-settlement protected route",mimeType:"application/json"}}),p=null;function m(){if(p)return p;let o=a.initialize();return o.catch(y=>{p===o&&(p=null),e.verbose?t("resource server initialize() failed:",y):console.error("[batch-settlement:seller] resource server initialize() failed:",y)}),p=o,o}let f=m();function l(o,y){if(o.headersSent)return;for(let[x,b]of Object.entries(y.headers))o.setHeader(x,b);o.status(y.status);let{body:E}=y;E==null?o.end():typeof E=="string"?o.send(E):o.json(E)}return{scheme:r,facilitator:s,handler:async(o,y,E)=>{try{await m();let x=o.get("host")??"",b=`${o.baseUrl??""}${o.path}`||"/",N={getHeader:A=>o.headers[A.toLowerCase()],getMethod:()=>o.method,getPath:()=>b,getUrl:()=>`${o.protocol}://${x}${o.originalUrl}`,getAcceptHeader:()=>o.headers.accept??"",getUserAgent:()=>o.headers["user-agent"]??"",getBody:()=>o.body??{},getQueryParams:()=>o.query,getQueryParam:A=>{let i=o.query[A];if(typeof i=="string"||Array.isArray(i))return i}},C=o.headers["payment-signature"]??o.headers["x-payment"],v={adapter:N,path:b,method:o.method,paymentHeader:C},R=await a.processHTTPRequest(v);if(t("processHTTPRequest ->",R.type),R.type==="no-payment-required"){E();return}if(R.type==="payment-error"){l(y,R.response);return}let c={request:v,responseBody:Buffer.alloc(0)},d=await a.processSettlement(R.paymentPayload,R.paymentRequirements,R.declaredExtensions,c);if(t("processSettlement ->",d.success?"success":`failure:${d.errorReason}`),!d.success){l(y,d.response);return}for(let[A,i]of Object.entries(d.headers))y.headersSent||y.setHeader(A,i);E()}catch(x){t("handler error:",x),y.headersSent||y.status(500).json({error:"Payment processing error"})}},ready:f}}import{formatUnits as xe}from"viem";var Se=6;async function ne(e){let{manager:t,store:s,channelId:r}=e,n=await s.get(r),a=BigInt(n?.chargedCumulativeAmount??"0"),p=BigInt(n?.balance??"0"),m=p>a?p-a:0n,{claims:f,settle:l}=await t.claimAndSettle(),g=await t.refund([r]),o=g.find(y=>y.channel===r)??g[0];return{claimTx:f[0]?.transaction??"",settleTx:l?.transaction??"",refundTx:o?.transaction??"",settledAmount:xe(a,Se),refundedAmount:xe(m,Se)}}async function Ee(e){let t=await e.store.list(),s=[];for(let r of t)try{let n=await ne({manager:e.manager,store:e.store,channelId:r.channelId});s.push({channelId:r.channelId,...n})}catch(n){s.push({channelId:r.channelId,error:n instanceof Error?n.message:String(n)})}return s}function Re(e){let t=!1,s=async()=>{try{await e.claimAndSettle()}catch(n){e.onError?.(n)}},r=setInterval(()=>{t||s()},e.claimIntervalMs);return typeof r.unref=="function"&&r.unref(),{async stop(){t||(t=!0,clearInterval(r),await s())}}}var $e="https://x402.dexter.cash",Ke="GET /",Ae=new Set(["eip155:8453","eip155:42161","eip155:137"]);function He(e){return e===!1?null:e===void 0||e===!0?3e5:(e.claimIntervalSecs??300)*1e3}function se(e){if(!Ae.has(e.network))throw new Error(`batch-settlement is not supported on network "${e.network}" \u2014 supported: ${[...Ae].join(", ")}`);let t=e.facilitatorUrl??$e,s=e.channelStore??new qe({directory:Le(Me(),".dexter-x402","seller-channels")}),r=ge({payTo:e.payTo,network:e.network,price:e.price,route:e.route??Ke,facilitatorUrl:t,channelStore:s,verbose:e.verbose}),n=r.scheme.createChannelManager(r.facilitator,e.network),a=async()=>{await n.claimAndSettle()},p=He(e.autoSettle),m=null;p!==null&&(m=Re({claimAndSettle:a,claimIntervalMs:p,onError:o=>console.error("[batch-settlement:seller] auto-loop claim pass failed",o)}));let f=s,l=(o,y,E)=>{r.handler(o,y,E)},g=l;return g.middleware=()=>l,g.closeChannel=o=>ne({manager:n,store:f,channelId:o}),g.closeAll=()=>Ee({manager:n,store:f}),g.stop=async()=>{m&&await m.stop()},g}async function Pe(e,t,s){let r={};for(let n of e)if(n.enrichPaymentRequiredResponse&&n.key in t)try{let a=await n.enrichPaymentRequiredResponse(t[n.key],s);a!==void 0&&(r[n.key]=a)}catch(a){console.warn(`[x402:extensions] extension "${n.key}" failed:`,a)}return Object.keys(r).length>0?r:void 0}function Fe(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 We(e){if(e.scheme==="batch-settlement"){let c=Array.isArray(e.network)?e.network[0]:e.network;if(!c)throw new Error('x402Middleware: scheme "batch-settlement" requires a network');let d=typeof e.payTo=="string"?e.payTo:void 0;if(!d)throw new Error('x402Middleware: scheme "batch-settlement" requires a string payTo address');return se({payTo:d,network:c,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:s,asset:r,description:n,resourceUrl:a,mimeType:p,timeoutSeconds:m,verbose:f=!1,getResourceUrl:l,getAmount:g,getDescription:o,extensions:y,declarations:E}=e,x=f?console.log.bind(console,"[x402:middleware]"):()=>{},b=typeof t=="function"?t._x402Defaults:void 0,N=e.facilitatorUrl??b?.facilitatorUrl,C=e.network?Array.isArray(e.network)?e.network:[e.network]:b?.network?[b.network]:[de],v=new Map;for(let c of C){let d=Fe(t,c);if(typeof d=="function"){let A=he(d);if(A&&c!==A)throw new Error(`stripePayTo is configured for "${A}" but middleware includes network "${c}". Stripe only supports Base deposit addresses. Use a static payTo for other chains.`)}v.set(c,re({payTo:d,network:c,asset:r,facilitatorUrl:N,defaultTimeoutSeconds:m,scheme:e.scheme}))}let R=v.get(C[0]);return async(c,d,A)=>{try{let i=c.headers["payment-signature"];if(!i){x("No payment signature, returning 402");let U=l?.(c)??a??`${c.protocol}://${c.get("host")}${c.originalUrl}`,T=g?.(c)??s,B=o?.(c)??n,oe=parseFloat(T),w=[],P=null;for(let[,M]of v)try{let ee={amountAtomic:me(oe,M.assetDecimals),resourceUrl:U,description:B,mimeType:p,timeoutSeconds:m},ie=await M.buildRequirements(ee);w.push(...ie.accepts),P||(P=ie)}catch(ee){x("Failed to build requirements for a network:",ee)}if(!P||w.length===0){d.status(500).json({error:"Failed to build payment requirements"});return}if(P={...P,accepts:w},y&&y.length>0){let M=await Pe(y,E??{},{response:P,request:{method:c.method,path:(c.baseUrl??"")+(c.route?.path??c.path),params:c.params}});M&&(P={...P,extensions:M})}let ve=R.encodeRequirements(P);d.setHeader("PAYMENT-REQUIRED",ve),d.status(402).json({error:"Payment required",accepts:P.accepts,resource:P.resource,...P.extensions?{extensions:P.extensions}:{}});return}x("Payment signature received, verifying...");let u=R;try{let T=JSON.parse(Buffer.from(i,"base64").toString())?.accepted?.network;T&&v.has(T)&&(u=v.get(T))}catch{}let h=await u.verifyPayment(i);if(!h.isValid){if(x("Payment verification failed:",h.invalidReason),e.onVerifyFailed)try{await e.onVerifyFailed({reason:h.invalidReason,resourceUrl:`${c.protocol}://${c.get("host")}${c.originalUrl}`})}catch{}d.status(402).json({error:"Payment verification failed",reason:h.invalidReason});return}x("Payment verified, settling...");let S=await u.settlePayment(i);if(!S.success){x("Payment settlement failed:",S.errorReason),d.status(402).json({error:"Payment settlement failed",reason:S.errorReason});return}x("Payment settled:",S.transaction);let _=S.network||C[0];if(e.onSettlement)try{await e.onSettlement({transaction:S.transaction,network:_,payer:h.payer??"",resourceUrl:`${c.protocol}://${c.get("host")}${c.originalUrl}`})}catch{}c.x402={transaction:S.transaction,payer:h.payer??"",network:_};let D={success:!0,transaction:S.transaction,network:_,payer:h.payer??""};if(S.extensions&&(D.extensions=S.extensions),d.setHeader("PAYMENT-RESPONSE",Z(D)),e.sponsoredAccess&&S.extensions?.["sponsored-access"]){let U=S.extensions["sponsored-access"],T=U?.info?.recommendations??U?.recommendations;if(T&&T.length>0){if(x("Injecting sponsored-access recommendations into response"),typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.onMatch)try{e.sponsoredAccess.onMatch(T,{transaction:S.transaction,network:_,payer:h.payer??""})}catch{}let B=d.json.bind(d);d.json=function(w){return typeof e.sponsoredAccess=="object"&&e.sponsoredAccess.inject?B(e.sponsoredAccess.inject(w,T)):w&&typeof w=="object"&&!Array.isArray(w)?B({_x402_sponsored:T,...w}):B(w)}}}A()}catch(i){x("Middleware error:",i),d.status(500).json({error:"Payment processing error"})}}}var je=/^\/[a-zA-Z0-9_/:.\-~%]+$/;function Te(e){if(!e||!je.test(e))return!1;let t;try{t=decodeURIComponent(e)}catch{return!1}return!(t.includes("..")||t.includes("://"))}function H(e){return e.method==="POST"||e.method==="PUT"||e.method==="PATCH"}var Ve=["GET","HEAD","DELETE"],Xe=["POST","PUT","PATCH"];function be(e,t){let s=t.pathParams!==void 0&&Object.keys(t.pathParams).length>0,r={type:"http",method:e.method};H(e)?(r.bodyType=e.bodyType,r.body=e.input??{}):e.input!==void 0&&(r.queryParams=e.input),s&&(r.pathParams=t.pathParams);let n=e.output?.example!==void 0?{type:"json",example:e.output.example}:void 0,a=H(e)?Xe:Ve,p={type:{type:"string",const:"http"},method:{type:"string",enum:a}};H(e)?(p.bodyType={type:"string",enum:["json","form-data","text"]},p.body={type:"object",...e.inputSchema??{}}):e.inputSchema&&(p.queryParams={type:"object",...e.inputSchema}),e.pathParamsSchema&&(p.pathParams={type:"object",...e.pathParamsSchema});let m={input:{type:"object",properties:p,required:H(e)?["type","method","bodyType","body"]:["type","method"],additionalProperties:!1}};n&&(m.output={type:"object",properties:{type:{type:"string"},example:{type:"object",...e.output?.schema??{}}},required:["type"]});let f={$schema:"https://json-schema.org/draft/2020-12/schema",type:"object",properties:m,required:["input"]},l={info:{input:r,...n?{output:n}:{}},schema:f};return Te(t.routeTemplate)&&(l.routeTemplate=t.routeTemplate),l}var ze=["GET","HEAD","DELETE","POST","PUT","PATCH"];function Je(){return{key:"bazaar",enrichPaymentRequiredResponse:(e,t)=>{if(e==null)return;let s=e,r=(s.method??t.request.method).toUpperCase();if(!ze.includes(r))return;let n={...s,method:r};return be(n,{pathParams:t.request.params,routeTemplate:t.request.path})}}}function Ye(e){return{bazaar:e}}import{SPONSORED_ACCESS_EXTENSION_KEY as nr}from"@dexterai/x402-ads-types";export{I as BASE_MAINNET_NETWORK,O as DEXTER_FACILITATOR_URL,K as FacilitatorClient,k as SOLANA_MAINNET_NETWORK,nr as SPONSORED_ACCESS_EXTENSION_KEY,te as USDC_BASE,L as USDC_MINT,Je as bazaarExtension,re as createX402Server,Ye as declareDiscoveryExtension,ye as resolveDefaultAsset,We as x402Middleware};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var te=Object.create;var f=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,se=Object.prototype.hasOwnProperty;var oe=(e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})},V=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ie(t))!se.call(e,r)&&r!==n&&f(e,r,{get:()=>t[r],enumerable:!(i=ne(t,r))||i.enumerable});return e};var L=(e,t,n)=>(n=e!=null?te(re(e)):{},V(t||!e||!e.__esModule?f(n,"default",{value:e,enumerable:!0}):n,e)),ae=e=>V(f({},"__esModule",{value:!0}),e);var Pe={};oe(Pe,{buildAdapterRegisterInstruction:()=>Q,createSolanaVaultAdapter:()=>he,deriveChannelId:()=>q,passkeySignerFromP256Keypair:()=>z});module.exports=ae(Pe);var c=require("@solana/web3.js"),Z=require("@solana/spl-token");var ce="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",pe="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",le="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var w="eip155:8453",U="eip155:84532",C="eip155:42161",R="eip155:137",O="eip155:10",D="eip155:43114",N="eip155:56",T="eip155:1187947933",_="eip155:324705682",I="eip155:1";var W="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var ue="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",ye="0x55d398326f99059fF775485246999027B3197955",F="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ee={[N]:F,[w]:ue,[U]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[C]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[R]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[O]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[D]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[T]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[_]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[I]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Ke={[ye]:{symbol:"USDT",decimals:18},[F]:{symbol:"USDC",decimals:18}};var ve={[N]:56,[w]:8453,[U]:84532,[C]:42161,[R]:137,[O]:10,[D]:43114,[T]:1187947933,[_]:324705682,[I]:1},we={[ce]:"https://api.dexter.cash/api/solana/rpc",[pe]:"https://api.devnet.solana.com",[le]:"https://api.testnet.solana.com"},Ue={[N]:"https://api.dexter.cash/api/evm/bsc/rpc",[w]:"https://api.dexter.cash/api/base/rpc",[U]:"https://sepolia.base.org",[C]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[R]:"https://api.dexter.cash/api/evm/polygon/rpc",[O]:"https://api.dexter.cash/api/evm/optimism/rpc",[D]:"https://api.dexter.cash/api/evm/avalanche/rpc",[T]:"https://skale-base.skalenodes.com/v1/base",[_]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[I]:"https://eth.llamarpc.com"};var a=require("@dexterai/vault/instructions"),P=require("@dexterai/vault/precompile"),m=require("@dexterai/vault/constants");var s=require("@dexterai/vault/messages");var k=L(require("tweetnacl"),1);var $=require("@noble/hashes/sha256");function J(){let e=k.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function H(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function G(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),r=BigInt(e.scope.maxAmountAtomic);if(i>r)throw new Error(`voucher cumulative ${i} exceeds session cap ${r}`);let o=Math.floor(Date.now()/1e3);if(o>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${o}`);let p=(0,s.voucherPayloadMessage)({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),l=k.default.sign.detached(p,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:l}}function b(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function q(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=$.sha256.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}var d=require("@dexterai/vault/session"),g=require("@noble/hashes/sha256");var X=require("@noble/curves/p256"),E=require("@noble/hashes/sha256"),Y="dexter.cash";function me(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function de(e,t=`https://${Y}`){let i={type:"webauthn.get",challenge:me(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function ge(e=1){let t=(0,E.sha256)(new TextEncoder().encode(Y)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function Ae(e,t){let n=de(t),i=ge(1),r=new Uint8Array(i.length+32);r.set(i,0),r.set((0,E.sha256)(n),i.length);let o=(0,E.sha256)(r);return{signature:X.p256.sign(o,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:n,authenticatorData:i}}function z(e){return{publicKey:e.publicKey,sign:async t=>Ae(e,t)}}function Q(e){let t=(0,a.deriveSwigWalletAddress)(e.swigAddress),n=(0,Z.getAssociatedTokenAddressSync)(new c.PublicKey(W),t,!0);return(0,a.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var B=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new c.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new c.PublicKey(t.allowedCounterparty),i=b(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=J(),o=Se(),p=(0,s.sessionRegisterMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:r.publicKey,maxAmount:b(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:o}),l=(0,g.sha256)(p),{signature:A,clientDataJSON:h,authenticatorData:S}=await this.passkey.sign(l),K=j(S,(0,g.sha256)(h)),u=(0,P.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,A,K),x=(0,d.sessionPdasOf)(await(0,d.fetchVaultSessionAccounts)(this.connection,this.vaultPdaKey)),v=Q({vaultPda:this.vaultPdaKey,swigAddress:new c.PublicKey(this.swigAddress),sessionPubkey:r.publicKey,maxAmount:b(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:o,clientDataJSON:h,authenticatorData:S,payer:this.feePayer.publicKey,siblingSessionPdas:x}),y=new c.Transaction().add(u,v);y.feePayer=this.feePayer.publicKey;let{blockhash:M}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);y.recentBlockhash=M,y.sign(this.feePayer);let ee=await this.connection.sendRawTransaction(y.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:ee,blockhash:M,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await(0,d.waitForSession)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:r.publicKey,timeoutMs:2e4}),H(r,t,p)}async signWithSession(t,n){let i=await xe(n.channelId);return G(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let r=(0,s.sessionRevokeMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),o=(0,g.sha256)(r),{signature:p,clientDataJSON:l,authenticatorData:A}=await this.passkey.sign(o),h=j(A,(0,g.sha256)(l)),S=(0,P.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,p,h),K=(0,a.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,allowedCounterparty:new c.PublicKey(t.scope.allowedCounterparty),clientDataJSON:l,authenticatorData:A}),u=new c.Transaction().add(S,K);u.feePayer=this.feePayer.publicKey;let{blockhash:x,lastValidBlockHeight:v}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);u.recentBlockhash=x,u.sign(this.feePayer);let y=await this.connection.sendRawTransaction(u.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:y,blockhash:x,lastValidBlockHeight:v},this.confirmOptions.commitment),r}};function he(e){return new B(e)}function j(e,t){let n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}function Se(){return Math.floor(Math.random()*4294967295)>>>0}async function xe(e){if(/^[0-9a-f]{64}$/i.test(e))return fe(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function fe(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}0&&(module.exports={buildAdapterRegisterInstruction,createSolanaVaultAdapter,deriveChannelId,passkeySignerFromP256Keypair});
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as _solana_web3_js from '@solana/web3.js';
|
|
2
2
|
import { PublicKey, Connection, Signer, ConfirmOptions } from '@solana/web3.js';
|
|
3
3
|
import { V as VaultAdapter } from '../../../types-DuoL3s8n.cjs';
|
|
4
|
+
import { PasskeySignerWithPublicKey } from '@dexterai/vault/signers';
|
|
5
|
+
export { PasskeySignerWithPublicKey as PasskeySigner } from '@dexterai/vault/signers';
|
|
4
6
|
import '@dexterai/vault/types';
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -53,29 +55,22 @@ interface P256Keypair {
|
|
|
53
55
|
/** 32-byte raw scalar. NEVER persist this anywhere user-readable. */
|
|
54
56
|
privateKey: Uint8Array;
|
|
55
57
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
signature: Uint8Array;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
interface PasskeySigner {
|
|
68
|
-
/** 33-byte SEC1 compressed P-256 public key. The vault stores this on
|
|
69
|
-
* init; the on-chain verifier compares against it on every passkey-
|
|
70
|
-
* signed instruction. */
|
|
58
|
+
/**
|
|
59
|
+
* Build a unified `PasskeySignerWithPublicKey` (vault's canonical shape)
|
|
60
|
+
* from a locally-held P-256 keypair — the node/CLI path. Returns
|
|
61
|
+
* `{ publicKey, sign(challenge) }`; the adapter computes the challenge and
|
|
62
|
+
* rebuilds the precompile message. Drop-in equivalent to vault's
|
|
63
|
+
* DexterApiBrowserPasskeySigner.
|
|
64
|
+
*/
|
|
65
|
+
declare function passkeySignerFromP256Keypair(kp: P256Keypair): {
|
|
71
66
|
publicKey: Uint8Array;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
sign(challenge: Uint8Array): Promise<{
|
|
68
|
+
signature: Uint8Array;
|
|
69
|
+
clientDataJSON: Uint8Array;
|
|
70
|
+
authenticatorData: Uint8Array;
|
|
71
|
+
}>;
|
|
72
|
+
};
|
|
73
|
+
|
|
79
74
|
interface CreateSolanaVaultAdapterOptions {
|
|
80
75
|
/** RPC the adapter uses to submit txs. The buyer can pass their own
|
|
81
76
|
* connection (browser wallet RPC, Helius URL, etc.) — the adapter has
|
|
@@ -89,7 +84,7 @@ interface CreateSolanaVaultAdapterOptions {
|
|
|
89
84
|
/** The buyer's vault PDA (gate account). */
|
|
90
85
|
vaultPda: string | PublicKey;
|
|
91
86
|
/** The passkey signing path. */
|
|
92
|
-
passkeySigner:
|
|
87
|
+
passkeySigner: PasskeySignerWithPublicKey;
|
|
93
88
|
/** Lamport-fee payer. In Phase 2 this is the buyer; later phases may
|
|
94
89
|
* route through a facilitator co-signer. Required because the buyer's
|
|
95
90
|
* vault account is not a signer for register/revoke (the passkey
|
|
@@ -121,4 +116,4 @@ declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): _s
|
|
|
121
116
|
/** Factory entry point. */
|
|
122
117
|
declare function createSolanaVaultAdapter(opts: CreateSolanaVaultAdapterOptions): VaultAdapter;
|
|
123
118
|
|
|
124
|
-
export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions,
|
|
119
|
+
export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, buildAdapterRegisterInstruction, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
|