@dexterai/x402 5.4.1 → 5.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tab/index.cjs +2 -2
- package/dist/tab/index.d.cts +10 -1
- package/dist/tab/index.d.ts +10 -1
- package/dist/tab/index.js +2 -2
- package/package.json +1 -1
package/dist/tab/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var fn=Object.create;var ct=Object.defineProperty;var gn=Object.getOwnPropertyDescriptor;var yn=Object.getOwnPropertyNames;var hn=Object.getPrototypeOf,An=Object.prototype.hasOwnProperty;var bn=(t,e)=>{for(var n in e)ct(t,n,{get:e[n],enumerable:!0})},Vt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of yn(e))!An.call(t,s)&&s!==n&&ct(t,s,{get:()=>e[s],enumerable:!(r=gn(e,s))||r.enumerable});return t};var J=(t,e,n)=>(n=t!=null?fn(hn(t)):{},Vt(e||!t||!t.__esModule?ct(n,"default",{value:t,enumerable:!0}):n,t)),Sn=t=>Vt(ct({},"__esModule",{value:!0}),t);var zn={};bn(zn,{DEFAULT_FACILITATOR_URL:()=>_e,DEXTER_VAULT_PROGRAM_ID:()=>W.DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID:()=>W.INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError:()=>lt,SECP256R1_PROGRAM_ID:()=>W.SECP256R1_PROGRAM_ID,SessionScopeExceededError:()=>ce,TabClosedError:()=>Z,UnsupportedNetworkError:()=>ie,atomicToHuman:()=>ue,buildRegisterSessionKeyInstruction:()=>me.buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction:()=>me.buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction:()=>It.buildSecp256r1VerifyInstruction,buildVoucherMessage:()=>B.buildVoucherMessage,deriveChannelId:()=>Re,generateSessionKeypair:()=>Wt,humanToAtomic:()=>ee,makeSessionKey:()=>ut,openTab:()=>pt,parseAtomic:()=>le,payUrlWithTab:()=>pn,resolveTabOffer:()=>ke,resolveTabTerms:()=>dn,resumeTab:()=>jt,scopeCapAtomic:()=>Ht,sessionRegisterMessage:()=>B.sessionRegisterMessage,sessionRevokeMessage:()=>B.sessionRevokeMessage,signVoucher:()=>mt,tabFromGrant:()=>Xt,voucherPayloadMessage:()=>B.voucherPayloadMessage,voucherToHeader:()=>Ve});module.exports=Sn(zn);var ie=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},ce=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Z=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},lt=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};var Ct=require("@solana/web3.js"),te=require("@noble/hashes/utils");var _t=J(require("tweetnacl"),1);var B=require("@dexterai/vault/messages");var Ft=require("@noble/hashes/sha256");function Wt(){let t=_t.default.sign.keyPair();return{publicKey:t.publicKey,privateKey:t.secretKey}}function ut(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function mt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=(0,B.voucherPayloadMessage)({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=_t.default.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function Ht(t){return le(t.maxAmountAtomic)}function le(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function Re(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=Ft.sha256.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var wn=3600,_e="https://x402.dexter.cash",qt=6;function ee(t,e=qt){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function ue(t,e=qt){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var Le=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:ue(this.cumulativeAtomic.toString()),remaining:ue(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Z(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new ce("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new ce("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Z(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",Ve(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return vn(o.body)}async close(){if(this.closed)throw new Z(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await xn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:ue(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function Ve(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:(0,te.bytesToHex)(t.sessionPublicKey),sessionRegistration:(0,te.bytesToHex)(t.sessionRegistration),sessionSignature:(0,te.bytesToHex)(t.sessionSignature)}),"utf8").toString("base64")}function Pe(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function Tn(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=Pe(e.attempted_cumulative),s=Pe(e.on_chain_spent),o=Pe(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function xn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,te.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,te.bytesToHex)(e.sessionSignature),sessionRegistration:(0,te.bytesToHex)(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&Tn(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=Pe(i.attemptedCumulative),p=Pe(i.onChainSpent),d=Pe(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function kt(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function pt(t){if(t.network!==t.vault.network)throw new ie(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ie(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new Ct.PublicKey(t.vault.vaultPda),r=Re({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=(0,te.bytesToHex)(r),o=BigInt(ee(t.perUnitCap)),a=BigInt(ee(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(ee(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??wn,c=Math.floor(Date.now()/1e3)+i,u=En(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?ee(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await kt(t.facilitatorUrl??_e,t.vault.swigAddress,a,t.network,u),new Le({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??_e})}async function jt(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function En(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new Ct.PublicKey(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*vn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
|
|
1
|
+
"use strict";var fn=Object.create;var lt=Object.defineProperty;var gn=Object.getOwnPropertyDescriptor;var yn=Object.getOwnPropertyNames;var hn=Object.getPrototypeOf,An=Object.prototype.hasOwnProperty;var bn=(t,e)=>{for(var n in e)lt(t,n,{get:e[n],enumerable:!0})},Vt=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of yn(e))!An.call(t,s)&&s!==n&<(t,s,{get:()=>e[s],enumerable:!(r=gn(e,s))||r.enumerable});return t};var J=(t,e,n)=>(n=t!=null?fn(hn(t)):{},Vt(e||!t||!t.__esModule?lt(n,"default",{value:t,enumerable:!0}):n,t)),Sn=t=>Vt(lt({},"__esModule",{value:!0}),t);var zn={};bn(zn,{DEFAULT_FACILITATOR_URL:()=>_e,DEXTER_VAULT_PROGRAM_ID:()=>W.DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID:()=>W.INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError:()=>ut,SECP256R1_PROGRAM_ID:()=>W.SECP256R1_PROGRAM_ID,SessionScopeExceededError:()=>ce,TabClosedError:()=>Z,UnsupportedNetworkError:()=>ie,armTabOpen:()=>We,atomicToHuman:()=>ue,buildRegisterSessionKeyInstruction:()=>me.buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction:()=>me.buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction:()=>It.buildSecp256r1VerifyInstruction,buildVoucherMessage:()=>B.buildVoucherMessage,deriveChannelId:()=>Re,generateSessionKeypair:()=>Wt,humanToAtomic:()=>ee,makeSessionKey:()=>mt,openTab:()=>dt,parseAtomic:()=>le,payUrlWithTab:()=>pn,resolveTabOffer:()=>ke,resolveTabTerms:()=>dn,resumeTab:()=>jt,scopeCapAtomic:()=>Ht,sessionRegisterMessage:()=>B.sessionRegisterMessage,sessionRevokeMessage:()=>B.sessionRevokeMessage,signVoucher:()=>pt,tabFromGrant:()=>Xt,voucherPayloadMessage:()=>B.voucherPayloadMessage,voucherToHeader:()=>Ve});module.exports=Sn(zn);var ie=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},ce=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Z=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},ut=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};var kt=require("@solana/web3.js"),te=require("@noble/hashes/utils");var Ct=J(require("tweetnacl"),1);var B=require("@dexterai/vault/messages");var Ft=require("@noble/hashes/sha256");function Wt(){let t=Ct.default.sign.keyPair();return{publicKey:t.publicKey,privateKey:t.secretKey}}function mt(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function pt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=(0,B.voucherPayloadMessage)({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=Ct.default.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function Ht(t){return le(t.maxAmountAtomic)}function le(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function Re(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=Ft.sha256.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var wn=3600,_e="https://x402.dexter.cash",qt=6;function ee(t,e=qt){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function ue(t,e=qt){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var Le=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:ue(this.cumulativeAtomic.toString()),remaining:ue(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Z(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new ce("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new ce("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Z(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",Ve(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return vn(o.body)}async close(){if(this.closed)throw new Z(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await xn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:ue(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function Ve(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:(0,te.bytesToHex)(t.sessionPublicKey),sessionRegistration:(0,te.bytesToHex)(t.sessionRegistration),sessionSignature:(0,te.bytesToHex)(t.sessionSignature)}),"utf8").toString("base64")}function Pe(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function Tn(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=Pe(e.attempted_cumulative),s=Pe(e.on_chain_spent),o=Pe(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function xn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,te.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,te.bytesToHex)(e.sessionSignature),sessionRegistration:(0,te.bytesToHex)(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&Tn(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=Pe(i.attemptedCumulative),p=Pe(i.onChainSpent),d=Pe(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function We(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function dt(t){if(t.network!==t.vault.network)throw new ie(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ie(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new kt.PublicKey(t.vault.vaultPda),r=Re({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=(0,te.bytesToHex)(r),o=BigInt(ee(t.perUnitCap)),a=BigInt(ee(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(ee(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??wn,c=Math.floor(Date.now()/1e3)+i,u=En(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?ee(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await We(t.facilitatorUrl??_e,t.vault.swigAddress,a,t.network,u),new Le({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??_e})}async function jt(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function En(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new kt.PublicKey(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*vn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
|
|
2
2
|
|
|
3
3
|
`))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=Rn(i);if(c.eventName==="end")return;if(c.data!==null){let u=c.data.replace(/\\(\\|n)/g,(p,d)=>d==="n"?`
|
|
4
4
|
`:"\\");yield new TextEncoder().encode(u)}}}}finally{e.releaseLock()}}function Rn(t){let e=null,n=[];for(let r of t.split(`
|
|
5
5
|
`))r.startsWith("event:")?e=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).trimStart());return{eventName:e,data:n.length?n.join(`
|
|
6
|
-
`):null}}var Ce=J(require("tweetnacl"),1),ne=require("@solana/web3.js"),Gt=require("@noble/hashes/utils"),dt=require("@dexterai/vault/session"),zt=require("@dexterai/vault/reader");var me=require("@dexterai/vault/instructions"),It=require("@dexterai/vault/precompile"),W=require("@dexterai/vault/constants");var Nt="solana:mainnet";async function Xt(t){let e=t.facilitatorUrl??_e,n=t.programId??W.DEXTER_VAULT_PROGRAM_ID,r=new ne.PublicKey(t.vaultPda),s=new ne.PublicKey(t.params.counterparty),o=le(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=le(t.params.maxAmountAtomic),i=le(t.params.maxRevolvingCapacityAtomic),c=Pn(t.sessionSecretKey),u=new ne.PublicKey(t.params.sessionPubkey).toBytes();if(!Jt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new ne.PublicKey(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ce.default.randomBytes(32),d=Ce.default.sign.detached(p,c.secretKey);if(!Ce.default.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=(0,B.sessionRegisterMessage)({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new ne.Connection(t.connection,"confirmed"):t.connection,l=await(0,dt.fetchSessionAccount)(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!(0,dt.isSessionLive)(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!Jt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new ne.PublicKey(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=Re({vaultPda:r,sellerUrl:x,nonce:g}),b=(0,Gt.bytesToHex)(y),C=t.swigAddress;if(!C){let M=await(0,zt.readVaultFull)(T,r);if(!M.exists||!M.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=M.swigAddress}await kt(e,C,a,Nt,t.params.counterparty);let $={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},H=ut({publicKey:c.publicKey,privateKey:c.secretKey},$,f),V={network:Nt,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(M,K)=>mt(M,K,y),signOpenTab:async M=>M.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new Le({vault:V,network:Nt,seller:x,counterparty:t.params.counterparty,session:H,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function Pn(t){if(t.length===64)return Ce.default.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ce.default.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function Jt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}var Qt=require("@solana/web3.js");var Yt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],_n=new Map(Yt.map(t=>[t.caip2.toLowerCase(),t])),Cn=new Map(Yt.map(t=>[t.bare.toLowerCase(),t]));function We(t){if(!t)return null;let e=t.toLowerCase(),n=_n.get(e)||Cn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function Ot(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function kn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=We(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function ft(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=Ot(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:kn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function ke(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await ft(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new Qt.PublicKey(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var He="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",gt="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",yt="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",pe=He,Fe=gt,qe=yt,de="eip155:8453",Ie="eip155:84532",Ne="eip155:42161",Oe="eip155:137",Ue="eip155:10",De="eip155:43114",Be="eip155:56",fe="eip155:480",ge="eip155:143",ye="eip155:4663",he="eip155:1187947933",Ae="eip155:324705682",Me="eip155:1",be=de,ht=Ie,je=Ne,Je=Oe,Ge=Ue,ze=De,Xe=Be,Ye=fe,Qe=ge,Ze=ye,et=he,tt=Ae,nt=Me,rt="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Zt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",en="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Ut="0x55d398326f99059fF775485246999027B3197955",At="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Dt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",bt={[Be]:At,[de]:en,[Ie]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[Ne]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Oe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ue]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[De]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[fe]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[ge]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[ye]:Dt,[he]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Ae]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Me]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},St={[Ut]:{symbol:"USDT",decimals:18},[At]:{symbol:"USDC",decimals:18}};var wt={[fe]:{name:"USDC",version:"2"},[ge]:{name:"USDC",version:"2"},[ye]:{name:"Global Dollar",version:"1"},[he]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},re="0x000000000022D473030F116dDEE9F6B43aC78BA3",st="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",ot={[Be]:56,[de]:8453,[Ie]:84532,[Ne]:42161,[Oe]:137,[Ue]:10,[De]:43114,[fe]:480,[ge]:143,[ye]:4663,[he]:1187947933,[Ae]:324705682,[Me]:1},Se={[He]:"https://api.dexter.cash/api/solana/rpc",[gt]:"https://api.devnet.solana.com",[yt]:"https://api.testnet.solana.com"},D={[Be]:"https://api.dexter.cash/api/evm/bsc/rpc",[de]:"https://api.dexter.cash/api/base/rpc",[Ie]:"https://sepolia.base.org",[Ne]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Oe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ue]:"https://api.dexter.cash/api/evm/optimism/rpc",[De]:"https://api.dexter.cash/api/evm/avalanche/rpc",[fe]:"https://worldchain-mainnet.g.alchemy.com/public",[ge]:"https://rpc.monad.xyz",[ye]:"https://rpc.mainnet.chain.robinhood.com",[he]:"https://skale-base.skalenodes.com/v1/base",[Ae]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Me]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};var N=require("@solana/web3.js"),O=require("@solana/spl-token");var In=12e3,Nn=1;function we(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var Tt=class{name="Solana";networks=[pe,Fe,qe];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:Se[e]?Se[e]:e==="solana"?Se[pe]:e==="solana-devnet"?Se[Fe]:e==="solana-testnet"?Se[qe]:Se[pe]}getAddress(e){return we(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return we(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!we(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),i=new N.PublicKey(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,p=await(0,O.getAssociatedTokenAddress)(i,a,!1,u),d=await(0,O.getAccount)(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!we(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new N.PublicKey(u.feePayer),f=new N.PublicKey(c),T=new N.PublicKey(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(N.ComputeBudgetProgram.setComputeUnitLimit({units:In})),l.push(N.ComputeBudgetProgram.setComputeUnitPrice({microLamports:Nn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,g=await(0,O.getMint)(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await(0,O.getAssociatedTokenAddress)(f,a,!1,x),b=await(0,O.getAssociatedTokenAddress)(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let H=BigInt(p);l.push((0,O.createTransferCheckedInstruction)(y,f,b,a,H,g.decimals,[],x));let{blockhash:V}=await o.getLatestBlockhash("confirmed"),M=new N.TransactionMessage({payerKey:d,recentBlockhash:V,instructions:l}).compileToV0Message(),K=new N.VersionedTransaction(M),h=await n.signTransaction(K);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:V}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new N.Connection(n,"confirmed"),s=new N.PublicKey(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function se(t){return new Tt(t)}var On={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},tn=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function Te(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var xt=class{name="EVM";networks=[Xe,be,ht,nt,je,Je,Ge,ze,Ye,Qe,Ze,et,tt];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:D[e]?D[e]:e==="base"?D[be]:e==="bsc"?D[Xe]:e==="ethereum"?D[nt]:e==="arbitrum"?D[je]:e==="polygon"?D[Je]:e==="optimism"?D[Ge]:e==="avalanche"?D[ze]:e==="world"?D[Ye]:e==="monad"?D[Qe]:e==="robinhood"?D[Ze]:e==="skale-base"?D[et]:e==="skale-base-sepolia"?D[tt]:D[be]}getAddress(e){return Te(e)?e.address:null}isConnected(e){return Te(e)?!!e.address:!1}getChainId(e){if(ot[e])return ot[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!Te(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,re,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!Te(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=wt[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let K=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${K} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,K),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((K,h)=>K*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(K=>K.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},$=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},H={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},V=await n.signTypedData({domain:C,types:$,primaryType:"Payment",message:H});this.log("EIP-712 Payment signature obtained");let M={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:V};return{serialized:JSON.stringify(M),signature:V}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,re),u;if(c<BigInt(a)){let C=this.encodeApprove(re,tn);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let $=this.getChainId(e.network),H=await this.readGasPrice(i),V=await this.readNonce(i,n.address),M=await n.signTransaction({to:o,data:C,chainId:$,gas:50000n,gasPrice:H,nonce:V});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:re,amount:tn.toString(),signedTransaction:M,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let $=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${$}`),await this.waitForReceipt(i,$),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,$)=>C*256n+BigInt($),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:re},g={permitted:{token:o,amount:BigInt(a)},spender:st,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:On,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:st,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function $e(t){return new xt(t)}function Bt(t){if(t===rt||t===Zt)return!0;let e=t.toLowerCase();for(let n of Object.values(bt))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(St))if(n.toLowerCase()===e)return!0;return!1}function Un(t){return{[He]:"Solana",[gt]:"Solana Devnet",[yt]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[de]:"Base",[Ie]:"Base Sepolia",[Me]:"Ethereum",[Ne]:"Arbitrum",[Oe]:"Polygon",[Ue]:"Optimism",[De]:"Avalanche",[Be]:"BSC",[fe]:"World Chain",[ge]:"Monad",[ye]:"Robinhood Chain",[he]:"SKALE Base",[Ae]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function nn(t,e){let n=Un(t);return n===t?e:n}async function Dn(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Bn=new WeakMap;function rn(t){let{adapters:e=[se({verbose:t.verbose}),$e({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,F=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:F}),l("Access pass cached for",E,"| expires:",new Date(F*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&we(r)&&(b.solana=r),r&&!b.evm&&Te(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function $(h,w){return nn(h,w)}function H(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function V(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let F=E.headers.get("PAYMENT-REQUIRED");if(!F)return null;let L;try{L=JSON.parse(atob(F))}catch{return null}let U=C(L.accepts);if(!U)return null;let{accept:k,adapter:j,wallet:xe}=U;if(j.name==="Solana"&&!k.extra?.feePayer)return null;let z=k.extra?.decimals??(Bt(k.asset)?6:void 0);if(typeof z!="number")return null;let Ke=k.amount??k.maxAmountRequired;if(!Ke)return null;let X=H(k.network,j);try{let m=await j.getBalance(k,xe,X),S=Number(Ke)/Math.pow(10,z);if(m<S){let Pt=$(k.network,j.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${Pt}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let Y=await j.buildTransaction(k,xe,X),Ee;j.name==="EVM"?Ee=JSON.parse(Y.serialized):Ee={transaction:Y.serialized};let oe=typeof h=="string"?h:h instanceof URL?h.href:h.url,ve=L.resource;if(typeof L.resource=="string")try{let m=new URL(L.resource,oe);["http:","https:"].includes(m.protocol)&&(ve=m.toString())}catch{}else if(L.resource&&typeof L.resource=="object"&&"url"in L.resource){let m=L.resource;try{let S=new URL(m.url,oe);["http:","https:"].includes(S.protocol)&&(ve={...m,url:S.toString()})}catch{}}let it={x402Version:k.x402Version??2,resource:ve,accepted:k,payload:Ee};Y.extensions&&(it.extensions=Y.extensions);let Q=btoa(JSON.stringify(it)),ae=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":Q}});if(!ae.ok)return l("Pass purchase failed:",ae.status),null;let q=ae.headers.get("ACCESS-PASS");return q&&(y(v,q),l("Access pass purchased and cached")),ae}async function M(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await V(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let F=A.headers.get("X-Quote-Hash");F&&l("Quote hash received:",F);let L=C(_.accepts);if(!L){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:U,adapter:k,wallet:j}=L;if(l(`Using ${k.name} for ${U.network}`),k.name==="Solana"&&!U.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let xe=U.extra?.decimals??(Bt(U.asset)?6:void 0);if(typeof xe!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let z=U.amount??U.maxAmountRequired;if(!z)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(z)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${z} exceeds maximum ${a}`);let Ke=H(U.network,k);l("Checking balance...");try{let m=await k.getBalance(U,j,Ke),S=Number(z)/Math.pow(10,xe);if(m<S){let Pt=$(U.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${Pt}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(U))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let X=await k.buildTransaction(U,j,Ke);l("Transaction signed");let Y;k.name==="EVM"?Y=JSON.parse(X.serialized):Y={transaction:X.serialized};let Ee=h,oe=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,Ee).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),oe=m}catch{oe=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,Ee).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),oe={...m,url:S})}catch{}}let ve={x402Version:U.x402Version??2,resource:oe,accepted:U,payload:Y};X.extensions&&(ve.extensions=X.extensions);let it=btoa(JSON.stringify(ve));if(d)try{d(U,X.settlementProbe)}catch{}l("Retrying request with payment...");let Q=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":it,...F?{"X-Quote-Hash":F}:{}}});if(l("Retry response status:",Q.status),Q.status===402){let m="unknown";try{let S=await Q.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let ae=Q.headers.get("PAYMENT-RESPONSE"),q;if(ae)try{q=JSON.parse(atob(ae))}catch{}return q??={},q.amountAtomic=z,q.assetDecimals=xe,Bn.set(Q,q),q.extensions&&l("Settlement extensions:",Object.keys(q.extensions).join(", ")),Q}async function K(h,w){let[E,A]=await Dn(h,w);return M(E,A)}return{fetch:K}}function G(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function at(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var Et="Payment authorization was sent, but the merchant did not respond within the timeout. ",vt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function Rt(t,e,n){if(!t)return{confirmed:!1,detail:Et+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+vt};try{if(t.kind==="solana"){let a=se(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return on();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:sn()}let r=$e(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return on();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:sn()}catch(r){return{confirmed:!1,detail:Et+`On-chain confirmation could not be completed (${G(r)}).`+vt}}}function sn(){return{confirmed:!1,detail:Et+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+vt}}function on(){return{confirmed:!1,detail:Et+"The chain adapter does not support on-chain confirmation."+vt}}var Mn=new Set(["exact","exact-approval"]);async function $n(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",Ve(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await at(i)}}var an={version:2,async parseChallenge(t){return ft(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await $n(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Mn.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=rn({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await at(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=Ot(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await Rt(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};var cn=require("viem");var Kn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Ln(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function Vn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Ln()},i=ot[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:(0,cn.getAddress)(e.asset)},types:Kn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Mt(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await Wn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Hn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:G(r)}}}async function Wn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await Vn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Hn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await se().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Fn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=We(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var ln={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Fn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Mt(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:qn(y)}:{ok:!1,...await at(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await Rt(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:G(p)}}finally{o!==void 0&&clearTimeout(o)}}};function qn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}var mn=J(require("tweetnacl"),1);var $t=require("@solana/web3.js"),un=Symbol.for("x402:keypair");function Kt(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[un];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>mn.sign.detached(s,r.secretKey)}}return null}var jn=[an,ln];async function Jn(t){let e=Kt(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${G(n)}`),fetch}}async function Lt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await Jn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:G(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of jn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function pn(t,e={},n){let r=await ke(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(ee(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await pt({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Lt(t,e,{},{tab:a}),tab:a}}function Gn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:ue(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function dn(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await ke(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==rt)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Gn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}0&&(module.exports={DEFAULT_FACILITATOR_URL,DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError,SECP256R1_PROGRAM_ID,SessionScopeExceededError,TabClosedError,UnsupportedNetworkError,atomicToHuman,buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction,buildVoucherMessage,deriveChannelId,generateSessionKeypair,humanToAtomic,makeSessionKey,openTab,parseAtomic,payUrlWithTab,resolveTabOffer,resolveTabTerms,resumeTab,scopeCapAtomic,sessionRegisterMessage,sessionRevokeMessage,signVoucher,tabFromGrant,voucherPayloadMessage,voucherToHeader});
|
|
6
|
+
`):null}}var Ce=J(require("tweetnacl"),1),ne=require("@solana/web3.js"),Gt=require("@noble/hashes/utils"),ft=require("@dexterai/vault/session"),zt=require("@dexterai/vault/reader");var me=require("@dexterai/vault/instructions"),It=require("@dexterai/vault/precompile"),W=require("@dexterai/vault/constants");var Nt="solana:mainnet";async function Xt(t){let e=t.facilitatorUrl??_e,n=t.programId??W.DEXTER_VAULT_PROGRAM_ID,r=new ne.PublicKey(t.vaultPda),s=new ne.PublicKey(t.params.counterparty),o=le(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=le(t.params.maxAmountAtomic),i=le(t.params.maxRevolvingCapacityAtomic),c=Pn(t.sessionSecretKey),u=new ne.PublicKey(t.params.sessionPubkey).toBytes();if(!Jt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new ne.PublicKey(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ce.default.randomBytes(32),d=Ce.default.sign.detached(p,c.secretKey);if(!Ce.default.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=(0,B.sessionRegisterMessage)({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new ne.Connection(t.connection,"confirmed"):t.connection,l=await(0,ft.fetchSessionAccount)(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!(0,ft.isSessionLive)(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!Jt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new ne.PublicKey(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=Re({vaultPda:r,sellerUrl:x,nonce:g}),b=(0,Gt.bytesToHex)(y),C=t.swigAddress;if(!C){let M=await(0,zt.readVaultFull)(T,r);if(!M.exists||!M.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=M.swigAddress}await We(e,C,a,Nt,t.params.counterparty);let $={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},H=mt({publicKey:c.publicKey,privateKey:c.secretKey},$,f),V={network:Nt,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(M,K)=>pt(M,K,y),signOpenTab:async M=>M.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new Le({vault:V,network:Nt,seller:x,counterparty:t.params.counterparty,session:H,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function Pn(t){if(t.length===64)return Ce.default.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ce.default.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function Jt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}var Qt=require("@solana/web3.js");var Yt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],_n=new Map(Yt.map(t=>[t.caip2.toLowerCase(),t])),Cn=new Map(Yt.map(t=>[t.bare.toLowerCase(),t]));function He(t){if(!t)return null;let e=t.toLowerCase(),n=_n.get(e)||Cn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function Ot(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function kn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=He(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function gt(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=Ot(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:kn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function ke(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await gt(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new Qt.PublicKey(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var Fe="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",yt="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ht="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",pe=Fe,qe=yt,je=ht,de="eip155:8453",Ie="eip155:84532",Ne="eip155:42161",Oe="eip155:137",Ue="eip155:10",De="eip155:43114",Be="eip155:56",fe="eip155:480",ge="eip155:143",ye="eip155:4663",he="eip155:1187947933",Ae="eip155:324705682",Me="eip155:1",be=de,At=Ie,Je=Ne,Ge=Oe,ze=Ue,Xe=De,Ye=Be,Qe=fe,Ze=ge,et=ye,tt=he,nt=Ae,rt=Me,st="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Zt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",en="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Ut="0x55d398326f99059fF775485246999027B3197955",bt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Dt="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",St={[Be]:bt,[de]:en,[Ie]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[Ne]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Oe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ue]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[De]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[fe]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[ge]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[ye]:Dt,[he]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Ae]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Me]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},wt={[Ut]:{symbol:"USDT",decimals:18},[bt]:{symbol:"USDC",decimals:18}};var Tt={[fe]:{name:"USDC",version:"2"},[ge]:{name:"USDC",version:"2"},[ye]:{name:"Global Dollar",version:"1"},[he]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},re="0x000000000022D473030F116dDEE9F6B43aC78BA3",ot="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",at={[Be]:56,[de]:8453,[Ie]:84532,[Ne]:42161,[Oe]:137,[Ue]:10,[De]:43114,[fe]:480,[ge]:143,[ye]:4663,[he]:1187947933,[Ae]:324705682,[Me]:1},Se={[Fe]:"https://api.dexter.cash/api/solana/rpc",[yt]:"https://api.devnet.solana.com",[ht]:"https://api.testnet.solana.com"},D={[Be]:"https://api.dexter.cash/api/evm/bsc/rpc",[de]:"https://api.dexter.cash/api/base/rpc",[Ie]:"https://sepolia.base.org",[Ne]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Oe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ue]:"https://api.dexter.cash/api/evm/optimism/rpc",[De]:"https://api.dexter.cash/api/evm/avalanche/rpc",[fe]:"https://worldchain-mainnet.g.alchemy.com/public",[ge]:"https://rpc.monad.xyz",[ye]:"https://rpc.mainnet.chain.robinhood.com",[he]:"https://skale-base.skalenodes.com/v1/base",[Ae]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Me]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};var N=require("@solana/web3.js"),O=require("@solana/spl-token");var In=12e3,Nn=1;function we(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var xt=class{name="Solana";networks=[pe,qe,je];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:Se[e]?Se[e]:e==="solana"?Se[pe]:e==="solana-devnet"?Se[qe]:e==="solana-testnet"?Se[je]:Se[pe]}getAddress(e){return we(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return we(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!we(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),i=new N.PublicKey(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,p=await(0,O.getAssociatedTokenAddress)(i,a,!1,u),d=await(0,O.getAccount)(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!we(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new N.Connection(s,"confirmed"),a=new N.PublicKey(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new N.PublicKey(u.feePayer),f=new N.PublicKey(c),T=new N.PublicKey(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(N.ComputeBudgetProgram.setComputeUnitLimit({units:In})),l.push(N.ComputeBudgetProgram.setComputeUnitPrice({microLamports:Nn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===O.TOKEN_2022_PROGRAM_ID.toBase58()?O.TOKEN_2022_PROGRAM_ID:O.TOKEN_PROGRAM_ID,g=await(0,O.getMint)(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await(0,O.getAssociatedTokenAddress)(f,a,!1,x),b=await(0,O.getAssociatedTokenAddress)(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let H=BigInt(p);l.push((0,O.createTransferCheckedInstruction)(y,f,b,a,H,g.decimals,[],x));let{blockhash:V}=await o.getLatestBlockhash("confirmed"),M=new N.TransactionMessage({payerKey:d,recentBlockhash:V,instructions:l}).compileToV0Message(),K=new N.VersionedTransaction(M),h=await n.signTransaction(K);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:V}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new N.Connection(n,"confirmed"),s=new N.PublicKey(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function se(t){return new xt(t)}var On={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},tn=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function Te(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var Et=class{name="EVM";networks=[Ye,be,At,rt,Je,Ge,ze,Xe,Qe,Ze,et,tt,nt];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:D[e]?D[e]:e==="base"?D[be]:e==="bsc"?D[Ye]:e==="ethereum"?D[rt]:e==="arbitrum"?D[Je]:e==="polygon"?D[Ge]:e==="optimism"?D[ze]:e==="avalanche"?D[Xe]:e==="world"?D[Qe]:e==="monad"?D[Ze]:e==="robinhood"?D[et]:e==="skale-base"?D[tt]:e==="skale-base-sepolia"?D[nt]:D[be]}getAddress(e){return Te(e)?e.address:null}isConnected(e){return Te(e)?!!e.address:!1}getChainId(e){if(at[e])return at[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!Te(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,re,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!Te(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=Tt[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let K=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${K} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,K),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((K,h)=>K*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(K=>K.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},$=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},H={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},V=await n.signTypedData({domain:C,types:$,primaryType:"Payment",message:H});this.log("EIP-712 Payment signature obtained");let M={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:V};return{serialized:JSON.stringify(M),signature:V}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,re),u;if(c<BigInt(a)){let C=this.encodeApprove(re,tn);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let $=this.getChainId(e.network),H=await this.readGasPrice(i),V=await this.readNonce(i,n.address),M=await n.signTransaction({to:o,data:C,chainId:$,gas:50000n,gasPrice:H,nonce:V});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:re,amount:tn.toString(),signedTransaction:M,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let $=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${$}`),await this.waitForReceipt(i,$),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,$)=>C*256n+BigInt($),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:re},g={permitted:{token:o,amount:BigInt(a)},spender:ot,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:On,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:ot,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function $e(t){return new Et(t)}function Bt(t){if(t===st||t===Zt)return!0;let e=t.toLowerCase();for(let n of Object.values(St))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(wt))if(n.toLowerCase()===e)return!0;return!1}function Un(t){return{[Fe]:"Solana",[yt]:"Solana Devnet",[ht]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[de]:"Base",[Ie]:"Base Sepolia",[Me]:"Ethereum",[Ne]:"Arbitrum",[Oe]:"Polygon",[Ue]:"Optimism",[De]:"Avalanche",[Be]:"BSC",[fe]:"World Chain",[ge]:"Monad",[ye]:"Robinhood Chain",[he]:"SKALE Base",[Ae]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function nn(t,e){let n=Un(t);return n===t?e:n}async function Dn(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Bn=new WeakMap;function rn(t){let{adapters:e=[se({verbose:t.verbose}),$e({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,F=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:F}),l("Access pass cached for",E,"| expires:",new Date(F*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&we(r)&&(b.solana=r),r&&!b.evm&&Te(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function $(h,w){return nn(h,w)}function H(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function V(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let F=E.headers.get("PAYMENT-REQUIRED");if(!F)return null;let L;try{L=JSON.parse(atob(F))}catch{return null}let U=C(L.accepts);if(!U)return null;let{accept:k,adapter:j,wallet:xe}=U;if(j.name==="Solana"&&!k.extra?.feePayer)return null;let z=k.extra?.decimals??(Bt(k.asset)?6:void 0);if(typeof z!="number")return null;let Ke=k.amount??k.maxAmountRequired;if(!Ke)return null;let X=H(k.network,j);try{let m=await j.getBalance(k,xe,X),S=Number(Ke)/Math.pow(10,z);if(m<S){let _t=$(k.network,j.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${_t}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let Y=await j.buildTransaction(k,xe,X),Ee;j.name==="EVM"?Ee=JSON.parse(Y.serialized):Ee={transaction:Y.serialized};let oe=typeof h=="string"?h:h instanceof URL?h.href:h.url,ve=L.resource;if(typeof L.resource=="string")try{let m=new URL(L.resource,oe);["http:","https:"].includes(m.protocol)&&(ve=m.toString())}catch{}else if(L.resource&&typeof L.resource=="object"&&"url"in L.resource){let m=L.resource;try{let S=new URL(m.url,oe);["http:","https:"].includes(S.protocol)&&(ve={...m,url:S.toString()})}catch{}}let ct={x402Version:k.x402Version??2,resource:ve,accepted:k,payload:Ee};Y.extensions&&(ct.extensions=Y.extensions);let Q=btoa(JSON.stringify(ct)),ae=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":Q}});if(!ae.ok)return l("Pass purchase failed:",ae.status),null;let q=ae.headers.get("ACCESS-PASS");return q&&(y(v,q),l("Access pass purchased and cached")),ae}async function M(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await V(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let F=A.headers.get("X-Quote-Hash");F&&l("Quote hash received:",F);let L=C(_.accepts);if(!L){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:U,adapter:k,wallet:j}=L;if(l(`Using ${k.name} for ${U.network}`),k.name==="Solana"&&!U.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let xe=U.extra?.decimals??(Bt(U.asset)?6:void 0);if(typeof xe!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let z=U.amount??U.maxAmountRequired;if(!z)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(z)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${z} exceeds maximum ${a}`);let Ke=H(U.network,k);l("Checking balance...");try{let m=await k.getBalance(U,j,Ke),S=Number(z)/Math.pow(10,xe);if(m<S){let _t=$(U.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${_t}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(U))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let X=await k.buildTransaction(U,j,Ke);l("Transaction signed");let Y;k.name==="EVM"?Y=JSON.parse(X.serialized):Y={transaction:X.serialized};let Ee=h,oe=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,Ee).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),oe=m}catch{oe=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,Ee).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),oe={...m,url:S})}catch{}}let ve={x402Version:U.x402Version??2,resource:oe,accepted:U,payload:Y};X.extensions&&(ve.extensions=X.extensions);let ct=btoa(JSON.stringify(ve));if(d)try{d(U,X.settlementProbe)}catch{}l("Retrying request with payment...");let Q=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":ct,...F?{"X-Quote-Hash":F}:{}}});if(l("Retry response status:",Q.status),Q.status===402){let m="unknown";try{let S=await Q.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let ae=Q.headers.get("PAYMENT-RESPONSE"),q;if(ae)try{q=JSON.parse(atob(ae))}catch{}return q??={},q.amountAtomic=z,q.assetDecimals=xe,Bn.set(Q,q),q.extensions&&l("Settlement extensions:",Object.keys(q.extensions).join(", ")),Q}async function K(h,w){let[E,A]=await Dn(h,w);return M(E,A)}return{fetch:K}}function G(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function it(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var vt="Payment authorization was sent, but the merchant did not respond within the timeout. ",Rt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function Pt(t,e,n){if(!t)return{confirmed:!1,detail:vt+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+Rt};try{if(t.kind==="solana"){let a=se(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return on();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:sn()}let r=$e(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return on();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:sn()}catch(r){return{confirmed:!1,detail:vt+`On-chain confirmation could not be completed (${G(r)}).`+Rt}}}function sn(){return{confirmed:!1,detail:vt+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+Rt}}function on(){return{confirmed:!1,detail:vt+"The chain adapter does not support on-chain confirmation."+Rt}}var Mn=new Set(["exact","exact-approval"]);async function $n(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",Ve(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await it(i)}}var an={version:2,async parseChallenge(t){return gt(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await $n(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Mn.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=rn({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await it(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=Ot(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await Pt(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};var cn=require("viem");var Kn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Ln(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function Vn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Ln()},i=at[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:(0,cn.getAddress)(e.asset)},types:Kn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Mt(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await Wn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Hn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:G(r)}}}async function Wn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await Vn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Hn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await se().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Fn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=He(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var ln={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Fn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Mt(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:qn(y)}:{ok:!1,...await it(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await Pt(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:G(p)}}finally{o!==void 0&&clearTimeout(o)}}};function qn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}var mn=J(require("tweetnacl"),1);var $t=require("@solana/web3.js"),un=Symbol.for("x402:keypair");function Kt(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[un];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>mn.sign.detached(s,r.secretKey)}}return null}var jn=[an,ln];async function Jn(t){let e=Kt(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${G(n)}`),fetch}}async function Lt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await Jn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:G(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of jn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function pn(t,e={},n){let r=await ke(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(ee(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await dt({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Lt(t,e,{},{tab:a}),tab:a}}function Gn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:ue(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function dn(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await ke(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==st)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Gn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}0&&(module.exports={DEFAULT_FACILITATOR_URL,DEXTER_VAULT_PROGRAM_ID,INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError,SECP256R1_PROGRAM_ID,SessionScopeExceededError,TabClosedError,UnsupportedNetworkError,armTabOpen,atomicToHuman,buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction,buildVoucherMessage,deriveChannelId,generateSessionKeypair,humanToAtomic,makeSessionKey,openTab,parseAtomic,payUrlWithTab,resolveTabOffer,resolveTabTerms,resumeTab,scopeCapAtomic,sessionRegisterMessage,sessionRevokeMessage,signVoucher,tabFromGrant,voucherPayloadMessage,voucherToHeader});
|
package/dist/tab/index.d.cts
CHANGED
|
@@ -45,6 +45,15 @@ declare function atomicToHuman(atomic: AtomicAmount, decimals?: number): HumanAm
|
|
|
45
45
|
* pay a `tab`-scheme accepts entry directly.
|
|
46
46
|
*/
|
|
47
47
|
declare function voucherToHeader(signed: SignedVoucher): string;
|
|
48
|
+
/**
|
|
49
|
+
* Arm drain-protection for a freshly-registered tab via the facilitator's
|
|
50
|
+
* /tab/open. THROWS if protection cannot be confirmed — a tab that is not
|
|
51
|
+
* drain-protected must never be returned to the caller.
|
|
52
|
+
*/
|
|
53
|
+
declare function armTabOpen(facilitatorUrl: string, buyerSwigAddress: string, maxAmountAtomic: bigint, network: string, counterparty: string): Promise<{
|
|
54
|
+
armed: true;
|
|
55
|
+
signature: string;
|
|
56
|
+
}>;
|
|
48
57
|
declare function openTab(options: OpenTabOptions): Promise<Tab>;
|
|
49
58
|
declare function resumeTab(_options: ResumeTabOptions): Promise<Tab>;
|
|
50
59
|
|
|
@@ -304,4 +313,4 @@ interface ResolveTabTermsOptions {
|
|
|
304
313
|
*/
|
|
305
314
|
declare function resolveTabTerms(url: string, init?: RequestInit, opts?: ResolveTabTermsOptions): Promise<TabTermsResult>;
|
|
306
315
|
|
|
307
|
-
export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
|
|
316
|
+
export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, armTabOpen, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
|
package/dist/tab/index.d.ts
CHANGED
|
@@ -45,6 +45,15 @@ declare function atomicToHuman(atomic: AtomicAmount, decimals?: number): HumanAm
|
|
|
45
45
|
* pay a `tab`-scheme accepts entry directly.
|
|
46
46
|
*/
|
|
47
47
|
declare function voucherToHeader(signed: SignedVoucher): string;
|
|
48
|
+
/**
|
|
49
|
+
* Arm drain-protection for a freshly-registered tab via the facilitator's
|
|
50
|
+
* /tab/open. THROWS if protection cannot be confirmed — a tab that is not
|
|
51
|
+
* drain-protected must never be returned to the caller.
|
|
52
|
+
*/
|
|
53
|
+
declare function armTabOpen(facilitatorUrl: string, buyerSwigAddress: string, maxAmountAtomic: bigint, network: string, counterparty: string): Promise<{
|
|
54
|
+
armed: true;
|
|
55
|
+
signature: string;
|
|
56
|
+
}>;
|
|
48
57
|
declare function openTab(options: OpenTabOptions): Promise<Tab>;
|
|
49
58
|
declare function resumeTab(_options: ResumeTabOptions): Promise<Tab>;
|
|
50
59
|
|
|
@@ -304,4 +313,4 @@ interface ResolveTabTermsOptions {
|
|
|
304
313
|
*/
|
|
305
314
|
declare function resolveTabTerms(url: string, init?: RequestInit, opts?: ResolveTabTermsOptions): Promise<TabTermsResult>;
|
|
306
315
|
|
|
307
|
-
export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
|
|
316
|
+
export { DEFAULT_FACILITATOR_URL, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, armTabOpen, atomicToHuman, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
|
package/dist/tab/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var ye=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},he=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Q=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},At=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};import{PublicKey as Mt}from"@solana/web3.js";import{bytesToHex as ee}from"@noble/hashes/utils";import Bt from"tweetnacl";import{sessionRegisterMessage as bt,sessionRevokeMessage as en,voucherPayloadMessage as St,buildVoucherMessage as tn}from"@dexterai/vault/messages";import{sha256 as sn}from"@noble/hashes/sha256";function nn(){let t=Bt.sign.keyPair();return{publicKey:t.publicKey,privateKey:t.secretKey}}function wt(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function Tt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=St({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=Bt.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function rn(t){return Ae(t.maxAmountAtomic)}function Ae(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function ke(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=sn.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var on=3600,Ie="https://x402.dexter.cash",$t=6;function Z(t,e=$t){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function be(t,e=$t){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var Ne=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:be(this.cumulativeAtomic.toString()),remaining:be(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Q(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new he("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new he("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Q(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",nt(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return mn(o.body)}async close(){if(this.closed)throw new Q(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await cn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:be(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function nt(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:ee(t.sessionPublicKey),sessionRegistration:ee(t.sessionRegistration),sessionSignature:ee(t.sessionSignature)}),"utf8").toString("base64")}function Se(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function an(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=Se(e.attempted_cumulative),s=Se(e.on_chain_spent),o=Se(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function cn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:ee(e.sessionPublicKey),sessionSignature:ee(e.sessionSignature),sessionRegistration:ee(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&an(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=Se(i.attemptedCumulative),p=Se(i.onChainSpent),d=Se(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function xt(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function Et(t){if(t.network!==t.vault.network)throw new ye(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ye(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new Mt(t.vault.vaultPda),r=ke({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=ee(r),o=BigInt(Z(t.perUnitCap)),a=BigInt(Z(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(Z(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??on,c=Math.floor(Date.now()/1e3)+i,u=un(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?Z(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await xt(t.facilitatorUrl??Ie,t.vault.swigAddress,a,t.network,u),new Ne({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??Ie})}async function ln(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function un(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new Mt(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*mn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
|
|
1
|
+
var ye=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}},he=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}},Q=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}},bt=class extends Error{constructor(n){super(`a LIVE session already exists for counterparty ${n.allowedCounterparty} (session ${n.sessionPubkeyHex.slice(0,16)}\u2026, expires ${n.expiresAtUnix}; on-chain spent=${n.spentAtomic}, crystallized=${n.crystallizedCumulativeAtomic}, frontier=${n.frontierAtomic}). Replacing it voids any signed-but-unsettled vouchers beyond the frontier. Settle the old tab first (tab.close() or POST its last voucher to /tab/settle), or pass onLiveSession: 'replace' to atomically revoke-then-register over it.`);this.details=n;this.name="LiveSessionExistsError"}};import{PublicKey as Mt}from"@solana/web3.js";import{bytesToHex as ee}from"@noble/hashes/utils";import Bt from"tweetnacl";import{sessionRegisterMessage as St,sessionRevokeMessage as en,voucherPayloadMessage as wt,buildVoucherMessage as tn}from"@dexterai/vault/messages";import{sha256 as sn}from"@noble/hashes/sha256";function nn(){let t=Bt.sign.keyPair();return{publicKey:t.publicKey,privateKey:t.secretKey}}function Tt(t,e,n){return{publicKey:t.publicKey,privateKey:t.privateKey,scope:e,registration:n}}function xt(t,e,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let r=BigInt(e.cumulativeAmount),s=BigInt(t.scope.maxAmountAtomic);if(r>s)throw new Error(`voucher cumulative ${r} exceeds session cap ${s}`);let o=Math.floor(Date.now()/1e3);if(o>=t.scope.expiresAtUnix)throw new Error(`session expired at ${t.scope.expiresAtUnix}, now ${o}`);let a=wt({channelId:n,cumulativeAmount:r,sequenceNumber:e.sequenceNumber}),i=Bt.sign.detached(a,t.privateKey);return{payload:e,sessionPublicKey:t.publicKey,sessionRegistration:t.registration,sessionSignature:i}}function rn(t){return Ae(t.maxAmountAtomic)}function Ae(t){if(!/^\d+$/.test(t))throw new Error(`atomic amount must be a non-negative integer string, got "${t}"`);return BigInt(t)}function ke(t){let e=new Uint8Array(8);new DataView(e.buffer).setBigUint64(0,t.nonce,!0);let n=new TextEncoder().encode(t.sellerUrl),r=sn.create();return r.update(t.vaultPda.toBytes()),r.update(n),r.update(e),r.digest()}var on=3600,Ie="https://x402.dexter.cash",$t=6;function Z(t,e=$t){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let s=r.padEnd(e,"0"),o=`${n}${s}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function be(t,e=$t){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",s=n.slice(-e).replace(/0+$/,"");return s?`${r}.${s}`:r}var Ne=class{channelId;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber=0;closed=!1;lastSignedVoucher=null;previousSignedVoucher=null;constructor(e){this.internals=e,this.channelId=e.channelIdHex,this.network=e.network,this.counterparty=e.counterparty,this.initialCumulativeAtomic=e.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic}get state(){let e=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:be(this.cumulativeAtomic.toString()),remaining:be(e.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(e){if(this.closed)throw new Q(this.channelId);let n=BigInt(e);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${e}`);if(n>this.internals.perUnitCapAtomic)throw new he("cap_exceeded",`single voucher increment ${n} exceeds perUnitCap ${this.internals.perUnitCapAtomic}`);let r=this.cumulativeAtomic+n;if(r>this.internals.totalCapAtomic)throw new he("cap_exceeded",`cumulative ${r} would exceed totalCap ${this.internals.totalCapAtomic}`);let s=this.sequenceNumber+1,o={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:s},a=await this.internals.vault.signWithSession(this.internals.session,o);return this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=s,this.cumulativeAtomic=r,a}rollbackVoucher(e){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==e.payload.sequenceNumber||n.payload.cumulativeAmount!==e.payload.cumulativeAmount)return!1;let r=this.previousSignedVoucher;if(r)this.sequenceNumber=r.payload.sequenceNumber,this.cumulativeAtomic=BigInt(r.payload.cumulativeAmount),this.lastSignedVoucher=r;else if(n.payload.sequenceNumber===1)this.sequenceNumber=0,this.cumulativeAtomic=this.initialCumulativeAtomic,this.lastSignedVoucher=null;else return!1;return this.previousSignedVoucher=null,!0}async stream(e,n){if(this.closed)throw new Q(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),s=new Headers(n?.headers);s.set("X-Tab-Voucher",nt(r)),s.set("Accept","text/event-stream");let o=await fetch(e,{...n,headers:s});if(!o.ok){let a=await o.text().catch(()=>"");throw new Error(`tab.stream HTTP ${o.status}: ${a.slice(0,500)}`)}if(!o.body)throw new Error("tab.stream response has no body");return mn(o.body)}async close(){if(this.closed)throw new Q(this.channelId);let e={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(e=await cn(this.internals.facilitatorUrl,this.lastSignedVoucher,this.internals.network));let n=(this.internals.closeMode??"revoke")==="revoke";return n&&await this.internals.vault.signCloseTab(this.internals.session,this.channelId,this.cumulativeAtomic.toString()),this.closed=!0,this.internals.session.privateKey.fill(0),{settledAmount:be(this.cumulativeAtomic.toString()),sessionRevoked:n,...e}}};function nt(t){return Buffer.from(JSON.stringify({payload:t.payload,sessionPublicKey:ee(t.sessionPublicKey),sessionRegistration:ee(t.sessionRegistration),sessionSignature:ee(t.sessionSignature)}),"utf8").toString("base64")}function Se(t){return typeof t!="string"||!/^\d+$/.test(t)?null:BigInt(t)}function an(t){let e;try{e=JSON.parse(t)}catch{return!1}if(typeof e!="object"||e===null)return!1;let n="non_monotonic_cumulative";if(e.error!==n&&e.reason!==n)return!1;let r=Se(e.attempted_cumulative),s=Se(e.on_chain_spent),o=Se(e.frontier);return r===null||s===null||o===null?!1:r>s&&r<=o}async function cn(t,e,n){let r=`${t.replace(/\/$/,"")}/tab/settle`,s={channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:ee(e.sessionPublicKey),sessionSignature:ee(e.sessionSignature),sessionRegistration:ee(e.sessionRegistration),network:n},o=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(s)}),a=await o.text();if(!o.ok){if(o.status===409&&an(a))return{settleTx:""};throw new Error(`tab settle ${o.status}: ${a.slice(0,500)}`)}let i;try{i=JSON.parse(a)}catch{throw new Error(`tab settle returned non-JSON: ${a.slice(0,200)}`)}if(i.reason==="covered_by_frontier"){let u=Se(i.attemptedCumulative),p=Se(i.onChainSpent),d=Se(i.frontier);if(u!==null&&p!==null&&d!==null&&u>p&&u<=d)return{settleTx:""}}if(!i.settleTx)throw new Error(`tab settle returned no settleTx: ${a.slice(0,200)}`);let c={settleTx:i.settleTx};return typeof i.grossAmount=="string"&&(c.grossAmount=i.grossAmount),typeof i.feeAmount=="string"&&(c.feeAmount=i.feeAmount),typeof i.netAmount=="string"&&(c.netAmount=i.netAmount),c}async function rt(t,e,n,r,s){let o=`${t.replace(/\/$/,"")}/tab/open`,a=await fetch(o,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({buyer_swig_address:e,seller:s,max_amount_atomic:n.toString(),network:r})}),i=await a.json().catch(()=>({}));if(!a.ok||!i.success||!i.armed)throw new Error(`tab_open_unprotected: ${i.error??`http_${a.status}`}`);return{armed:!0,signature:i.signature??""}}async function Et(t){if(t.network!==t.vault.network)throw new ye(`options.network (${t.network}) doesn't match vault.network (${t.vault.network})`);if(t.network!=="solana:mainnet")throw new ye(t.network);let e=BigInt(Math.floor(Math.random()*4294967295)),n=new Mt(t.vault.vaultPda),r=ke({vaultPda:n,sellerUrl:t.seller,nonce:BigInt(e)}),s=ee(r),o=BigInt(Z(t.perUnitCap)),a=BigInt(Z(t.totalCap));if(o<=0n)throw new Error("perUnitCap must be > 0");if(a<o)throw new Error("totalCap must be >= perUnitCap");if(t.revolvingCapacity!==void 0&&BigInt(Z(t.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=t.sessionDuration??on,c=Math.floor(Date.now()/1e3)+i,u=un(t.seller),p={channelId:s,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:t.revolvingCapacity?Z(t.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:u},d=await t.vault.authorizeSession(p,{onLiveSession:t.onLiveSession});return await rt(t.facilitatorUrl??Ie,t.vault.swigAddress,a,t.network,u),new Ne({vault:t.vault,network:t.network,seller:t.seller,counterparty:u,session:d,channelIdHex:s,channelIdBytes:r,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:t.facilitatorUrl??Ie})}async function ln(t){throw new Error("resumeTab is Phase 3 work. Session keys are memory-only by design; recovery requires reading active_session on chain and re-authorizing. Tracked in dexter-vault roadmap.")}function un(t){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(t))try{return new Mt(t),t}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${t}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*mn(t){let e=t.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:s,value:o}=await e.read();if(s)break;r+=n.decode(o,{stream:!0});let a;for(;(a=r.indexOf(`
|
|
2
2
|
|
|
3
3
|
`))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=pn(i);if(c.eventName==="end")return;if(c.data!==null){let u=c.data.replace(/\\(\\|n)/g,(p,d)=>d==="n"?`
|
|
4
4
|
`:"\\");yield new TextEncoder().encode(u)}}}}finally{e.releaseLock()}}function pn(t){let e=null,n=[];for(let r of t.split(`
|
|
5
5
|
`))r.startsWith("event:")?e=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).trimStart());return{eventName:e,data:n.length?n.join(`
|
|
6
|
-
`):null}}import Ue from"tweetnacl";import{Connection as An,PublicKey as Oe}from"@solana/web3.js";import{bytesToHex as bn}from"@noble/hashes/utils";import{fetchSessionAccount as Sn,isSessionLive as wn}from"@dexterai/vault/session";import{readVaultFull as Tn}from"@dexterai/vault/reader";import{buildRegisterSessionKeyInstruction as dn,buildRevokeSessionKeyInstruction as fn,deriveSwigWalletAddress as gr}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as gn}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as vt,SECP256R1_PROGRAM_ID as yn,INSTRUCTIONS_SYSVAR_ID as hn}from"@dexterai/vault/constants";var Rt="solana:mainnet";async function xn(t){let e=t.facilitatorUrl??Ie,n=t.programId??vt,r=new Oe(t.vaultPda),s=new Oe(t.params.counterparty),o=Ae(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=Ae(t.params.maxAmountAtomic),i=Ae(t.params.maxRevolvingCapacityAtomic),c=En(t.sessionSecretKey),u=new Oe(t.params.sessionPubkey).toBytes();if(!Kt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new Oe(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ue.randomBytes(32),d=Ue.sign.detached(p,c.secretKey);if(!Ue.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=bt({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new An(t.connection,"confirmed"):t.connection,l=await Sn(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!wn(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!Kt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new Oe(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=ke({vaultPda:r,sellerUrl:x,nonce:g}),b=bn(y),C=t.swigAddress;if(!C){let U=await Tn(T,r);if(!U.exists||!U.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=U.swigAddress}await xt(e,C,a,Rt,t.params.counterparty);let D={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},K=wt({publicKey:c.publicKey,privateKey:c.secretKey},D,f),$={network:Rt,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(U,B)=>Tt(U,B,y),signOpenTab:async U=>U.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new Ne({vault:$,network:Rt,seller:x,counterparty:t.params.counterparty,session:K,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function En(t){if(t.length===64)return Ue.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ue.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function Kt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}import{PublicKey as _n}from"@solana/web3.js";var Lt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],vn=new Map(Lt.map(t=>[t.caip2.toLowerCase(),t])),Rn=new Map(Lt.map(t=>[t.bare.toLowerCase(),t]));function De(t){if(!t)return null;let e=t.toLowerCase(),n=vn.get(e)||Rn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function Pt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function Pn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=De(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function rt(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=Pt(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:Pn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function Be(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await rt(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new _n(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var Me="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",st="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ot="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",te=Me,$e=st,Ke=ot,ne="eip155:8453",we="eip155:84532",Te="eip155:42161",xe="eip155:137",Ee="eip155:10",ve="eip155:43114",Re="eip155:56",re="eip155:480",se="eip155:143",oe="eip155:4663",ae="eip155:1187947933",ie="eip155:324705682",Pe="eip155:1",ce=ne,at=we,Le=Te,Ve=xe,We=Ee,He=ve,Fe=Re,qe=re,je=se,Je=oe,Ge=ae,ze=ie,Xe=Pe,Ye="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Vt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Wt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",_t="0x55d398326f99059fF775485246999027B3197955",it="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ct="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",ct={[Re]:it,[ne]:Wt,[we]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[Te]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[xe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ee]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[ve]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[re]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[se]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[oe]:Ct,[ae]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ie]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Pe]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},lt={[_t]:{symbol:"USDT",decimals:18},[it]:{symbol:"USDC",decimals:18}};var ut={[re]:{name:"USDC",version:"2"},[se]:{name:"USDC",version:"2"},[oe]:{name:"Global Dollar",version:"1"},[ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[ie]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},G="0x000000000022D473030F116dDEE9F6B43aC78BA3",Qe="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",Ze={[Re]:56,[ne]:8453,[we]:84532,[Te]:42161,[xe]:137,[Ee]:10,[ve]:43114,[re]:480,[se]:143,[oe]:4663,[ae]:1187947933,[ie]:324705682,[Pe]:1},le={[Me]:"https://api.dexter.cash/api/solana/rpc",[st]:"https://api.devnet.solana.com",[ot]:"https://api.testnet.solana.com"},O={[Re]:"https://api.dexter.cash/api/evm/bsc/rpc",[ne]:"https://api.dexter.cash/api/base/rpc",[we]:"https://sepolia.base.org",[Te]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[xe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ee]:"https://api.dexter.cash/api/evm/optimism/rpc",[ve]:"https://api.dexter.cash/api/evm/avalanche/rpc",[re]:"https://worldchain-mainnet.g.alchemy.com/public",[se]:"https://rpc.monad.xyz",[oe]:"https://rpc.mainnet.chain.robinhood.com",[ae]:"https://skale-base.skalenodes.com/v1/base",[ie]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Pe]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};import{PublicKey as ue,Connection as kt,TransactionMessage as Cn,VersionedTransaction as kn,ComputeBudgetProgram as Ht}from"@solana/web3.js";import{getAssociatedTokenAddress as It,getAccount as In,createTransferCheckedInstruction as Nn,getMint as On,TOKEN_PROGRAM_ID as Ft,TOKEN_2022_PROGRAM_ID as mt}from"@solana/spl-token";var Un=12e3,Dn=1;function me(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var pt=class{name="Solana";networks=[te,$e,Ke];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:le[e]?le[e]:e==="solana"?le[te]:e==="solana-devnet"?le[$e]:e==="solana-testnet"?le[Ke]:le[te]}getAddress(e){return me(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return me(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!me(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new kt(s,"confirmed"),a=new ue(n.publicKey.toBase58()),i=new ue(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===mt.toBase58()?mt:Ft,p=await It(i,a,!1,u),d=await In(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!me(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new kt(s,"confirmed"),a=new ue(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new ue(u.feePayer),f=new ue(c),T=new ue(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(Ht.setComputeUnitLimit({units:Un})),l.push(Ht.setComputeUnitPrice({microLamports:Dn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===mt.toBase58()?mt:Ft,g=await On(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await It(f,a,!1,x),b=await It(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let K=BigInt(p);l.push(Nn(y,f,b,a,K,g.decimals,[],x));let{blockhash:$}=await o.getLatestBlockhash("confirmed"),U=new Cn({payerKey:d,recentBlockhash:$,instructions:l}).compileToV0Message(),B=new kn(U),h=await n.signTransaction(B);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:$}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new kt(n,"confirmed"),s=new ue(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function z(t){return new pt(t)}var Bn={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},qt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function pe(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var dt=class{name="EVM";networks=[Fe,ce,at,Xe,Le,Ve,We,He,qe,je,Je,Ge,ze];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:O[e]?O[e]:e==="base"?O[ce]:e==="bsc"?O[Fe]:e==="ethereum"?O[Xe]:e==="arbitrum"?O[Le]:e==="polygon"?O[Ve]:e==="optimism"?O[We]:e==="avalanche"?O[He]:e==="world"?O[qe]:e==="monad"?O[je]:e==="robinhood"?O[Je]:e==="skale-base"?O[Ge]:e==="skale-base-sepolia"?O[ze]:O[ce]}getAddress(e){return pe(e)?e.address:null}isConnected(e){return pe(e)?!!e.address:!1}getChainId(e){if(Ze[e])return Ze[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!pe(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,G,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!pe(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=ut[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let B=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${B} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,B),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((B,h)=>B*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(B=>B.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},D=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},K={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},$=await n.signTypedData({domain:C,types:D,primaryType:"Payment",message:K});this.log("EIP-712 Payment signature obtained");let U={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:$};return{serialized:JSON.stringify(U),signature:$}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,G),u;if(c<BigInt(a)){let C=this.encodeApprove(G,qt);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let D=this.getChainId(e.network),K=await this.readGasPrice(i),$=await this.readNonce(i,n.address),U=await n.signTransaction({to:o,data:C,chainId:D,gas:50000n,gasPrice:K,nonce:$});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:G,amount:qt.toString(),signedTransaction:U,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let D=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${D}`),await this.waitForReceipt(i,D),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,D)=>C*256n+BigInt(D),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:G},g={permitted:{token:o,amount:BigInt(a)},spender:Qe,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:Bn,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:Qe,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function _e(t){return new dt(t)}function Nt(t){if(t===Ye||t===Vt)return!0;let e=t.toLowerCase();for(let n of Object.values(ct))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(lt))if(n.toLowerCase()===e)return!0;return!1}function Mn(t){return{[Me]:"Solana",[st]:"Solana Devnet",[ot]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[ne]:"Base",[we]:"Base Sepolia",[Pe]:"Ethereum",[Te]:"Arbitrum",[xe]:"Polygon",[Ee]:"Optimism",[ve]:"Avalanche",[Re]:"BSC",[re]:"World Chain",[se]:"Monad",[oe]:"Robinhood Chain",[ae]:"SKALE Base",[ie]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function jt(t,e){let n=Mn(t);return n===t?e:n}async function $n(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Kn=new WeakMap;function Jt(t){let{adapters:e=[z({verbose:t.verbose}),_e({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,L=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:L}),l("Access pass cached for",E,"| expires:",new Date(L*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&me(r)&&(b.solana=r),r&&!b.evm&&pe(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function D(h,w){return jt(h,w)}function K(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function $(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let L=E.headers.get("PAYMENT-REQUIRED");if(!L)return null;let M;try{M=JSON.parse(atob(L))}catch{return null}let N=C(M.accepts);if(!N)return null;let{accept:k,adapter:W,wallet:de}=N;if(W.name==="Solana"&&!k.extra?.feePayer)return null;let F=k.extra?.decimals??(Nt(k.asset)?6:void 0);if(typeof F!="number")return null;let Ce=k.amount??k.maxAmountRequired;if(!Ce)return null;let q=K(k.network,W);try{let m=await W.getBalance(k,de,q),S=Number(Ce)/Math.pow(10,F);if(m<S){let ht=D(k.network,W.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${ht}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let j=await W.buildTransaction(k,de,q),fe;W.name==="EVM"?fe=JSON.parse(j.serialized):fe={transaction:j.serialized};let X=typeof h=="string"?h:h instanceof URL?h.href:h.url,ge=M.resource;if(typeof M.resource=="string")try{let m=new URL(M.resource,X);["http:","https:"].includes(m.protocol)&&(ge=m.toString())}catch{}else if(M.resource&&typeof M.resource=="object"&&"url"in M.resource){let m=M.resource;try{let S=new URL(m.url,X);["http:","https:"].includes(S.protocol)&&(ge={...m,url:S.toString()})}catch{}}let tt={x402Version:k.x402Version??2,resource:ge,accepted:k,payload:fe};j.extensions&&(tt.extensions=j.extensions);let J=btoa(JSON.stringify(tt)),Y=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":J}});if(!Y.ok)return l("Pass purchase failed:",Y.status),null;let V=Y.headers.get("ACCESS-PASS");return V&&(y(v,V),l("Access pass purchased and cached")),Y}async function U(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await $(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let L=A.headers.get("X-Quote-Hash");L&&l("Quote hash received:",L);let M=C(_.accepts);if(!M){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:N,adapter:k,wallet:W}=M;if(l(`Using ${k.name} for ${N.network}`),k.name==="Solana"&&!N.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let de=N.extra?.decimals??(Nt(N.asset)?6:void 0);if(typeof de!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let F=N.amount??N.maxAmountRequired;if(!F)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(F)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${F} exceeds maximum ${a}`);let Ce=K(N.network,k);l("Checking balance...");try{let m=await k.getBalance(N,W,Ce),S=Number(F)/Math.pow(10,de);if(m<S){let ht=D(N.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${ht}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(N))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let q=await k.buildTransaction(N,W,Ce);l("Transaction signed");let j;k.name==="EVM"?j=JSON.parse(q.serialized):j={transaction:q.serialized};let fe=h,X=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,fe).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),X=m}catch{X=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,fe).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),X={...m,url:S})}catch{}}let ge={x402Version:N.x402Version??2,resource:X,accepted:N,payload:j};q.extensions&&(ge.extensions=q.extensions);let tt=btoa(JSON.stringify(ge));if(d)try{d(N,q.settlementProbe)}catch{}l("Retrying request with payment...");let J=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":tt,...L?{"X-Quote-Hash":L}:{}}});if(l("Retry response status:",J.status),J.status===402){let m="unknown";try{let S=await J.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let Y=J.headers.get("PAYMENT-RESPONSE"),V;if(Y)try{V=JSON.parse(atob(Y))}catch{}return V??={},V.amountAtomic=F,V.assetDecimals=de,Kn.set(J,V),V.extensions&&l("Settlement extensions:",Object.keys(V.extensions).join(", ")),J}async function B(h,w){let[E,A]=await $n(h,w);return U(E,A)}return{fetch:B}}function H(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function et(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var ft="Payment authorization was sent, but the merchant did not respond within the timeout. ",gt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function yt(t,e,n){if(!t)return{confirmed:!1,detail:ft+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+gt};try{if(t.kind==="solana"){let a=z(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return zt();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:Gt()}let r=_e(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return zt();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:Gt()}catch(r){return{confirmed:!1,detail:ft+`On-chain confirmation could not be completed (${H(r)}).`+gt}}}function Gt(){return{confirmed:!1,detail:ft+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+gt}}function zt(){return{confirmed:!1,detail:ft+"The chain adapter does not support on-chain confirmation."+gt}}var Ln=new Set(["exact","exact-approval"]);async function Vn(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",nt(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await et(i)}}var Xt={version:2,async parseChallenge(t){return rt(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await Vn(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Ln.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=Jt({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await et(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=Pt(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await yt(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};import{getAddress as Wn}from"viem";var Hn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Fn(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function qn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Fn()},i=Ze[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:Wn(e.asset)},types:Hn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Ot(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await jn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Jn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:H(r)}}}async function jn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await qn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Jn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await z().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Gn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=De(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var Yt={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Gn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Ot(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:zn(y)}:{ok:!1,...await et(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await yt(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:H(p)}}finally{o!==void 0&&clearTimeout(o)}}};function zn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}import*as Zt from"tweetnacl";import{Keypair as Rs,VersionedTransaction as Ps,Transaction as _s}from"@solana/web3.js";var Qt=Symbol.for("x402:keypair");function Ut(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[Qt];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>Zt.sign.detached(s,r.secretKey)}}return null}var Xn=[Xt,Yt];async function Yn(t){let e=Ut(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${H(n)}`),fetch}}async function Dt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await Yn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:H(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of Xn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function Qn(t,e={},n){let r=await Be(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(Z(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await Et({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Dt(t,e,{},{tab:a}),tab:a}}function Zn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:be(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function er(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await Be(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==Ye)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Zn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}export{Ie as DEFAULT_FACILITATOR_URL,vt as DEXTER_VAULT_PROGRAM_ID,hn as INSTRUCTIONS_SYSVAR_ID,At as LiveSessionExistsError,yn as SECP256R1_PROGRAM_ID,he as SessionScopeExceededError,Q as TabClosedError,ye as UnsupportedNetworkError,be as atomicToHuman,dn as buildRegisterSessionKeyInstruction,fn as buildRevokeSessionKeyInstruction,gn as buildSecp256r1VerifyInstruction,tn as buildVoucherMessage,ke as deriveChannelId,nn as generateSessionKeypair,Z as humanToAtomic,wt as makeSessionKey,Et as openTab,Ae as parseAtomic,Qn as payUrlWithTab,Be as resolveTabOffer,er as resolveTabTerms,ln as resumeTab,rn as scopeCapAtomic,bt as sessionRegisterMessage,en as sessionRevokeMessage,Tt as signVoucher,xn as tabFromGrant,St as voucherPayloadMessage,nt as voucherToHeader};
|
|
6
|
+
`):null}}import Ue from"tweetnacl";import{Connection as An,PublicKey as Oe}from"@solana/web3.js";import{bytesToHex as bn}from"@noble/hashes/utils";import{fetchSessionAccount as Sn,isSessionLive as wn}from"@dexterai/vault/session";import{readVaultFull as Tn}from"@dexterai/vault/reader";import{buildRegisterSessionKeyInstruction as dn,buildRevokeSessionKeyInstruction as fn,deriveSwigWalletAddress as gr}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as gn}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as vt,SECP256R1_PROGRAM_ID as yn,INSTRUCTIONS_SYSVAR_ID as hn}from"@dexterai/vault/constants";var Rt="solana:mainnet";async function xn(t){let e=t.facilitatorUrl??Ie,n=t.programId??vt,r=new Oe(t.vaultPda),s=new Oe(t.params.counterparty),o=Ae(t.perUnitCapAtomic);if(o<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${t.perUnitCapAtomic}`);let a=Ae(t.params.maxAmountAtomic),i=Ae(t.params.maxRevolvingCapacityAtomic),c=En(t.sessionSecretKey),u=new Oe(t.params.sessionPubkey).toBytes();if(!Kt(c.publicKey,u))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new Oe(c.publicKey).toBase58()} but params.sessionPubkey is ${t.params.sessionPubkey} \u2014 wrong key handed to this process`);let p=Ue.randomBytes(32),d=Ue.sign.detached(p,c.secretKey);if(!Ue.sign.detached.verify(p,d,u))throw new Error("tab_session_key_mismatch: secret key failed the sign/verify self-check against params.sessionPubkey \u2014 the seed half does not sign for the granted pubkey");let f=St({programId:n,vaultPda:r,sessionPubkey:c.publicKey,maxAmount:a,expiresAt:BigInt(t.params.expiresAtUnix),allowedCounterparty:s,nonce:t.params.nonce,maxRevolvingCapacity:i}),T=typeof t.connection=="string"?new An(t.connection,"confirmed"):t.connection,l=await Sn(T,r,s,n);if(!l||l.version===0)throw new Error("tab_session_not_live: no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!wn(l))throw new Error(l.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${l.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${l.session.expiresAt})`);if(!Kt(l.session.sessionPubkey,c.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new Oe(l.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(l.session.maxAmount!==a||l.session.expiresAt!==t.params.expiresAtUnix||l.session.nonce!==t.params.nonce||l.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${l.session.maxAmount} expiresAt=${l.session.expiresAt} nonce=${l.session.nonce} revolving=${l.session.maxRevolvingCapacity}; params: ${t.params.maxAmountAtomic}/${t.params.expiresAtUnix}/${t.params.nonce}/${t.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);let R=l.session.spent>l.session.crystallizedCumulative?l.session.spent:l.session.crystallizedCumulative;if(R>=a)throw new Error(`tab_exhausted: on-chain frontier ${R} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let x=t.sellerUrl??t.params.counterparty,g=BigInt(Math.floor(Math.random()*4294967295)),y=ke({vaultPda:r,sellerUrl:x,nonce:g}),b=bn(y),C=t.swigAddress;if(!C){let U=await Tn(T,r);if(!U.exists||!U.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);C=U.swigAddress}await rt(e,C,a,Rt,t.params.counterparty);let D={channelId:b,maxAmountAtomic:t.params.maxAmountAtomic,revolvingCapacityAtomic:t.params.maxRevolvingCapacityAtomic,expiresAtUnix:t.params.expiresAtUnix,allowedCounterparty:t.params.counterparty},K=Tt({publicKey:c.publicKey,privateKey:c.secretKey},D,f),$={network:Rt,swigAddress:C,vaultPda:r.toBase58(),authorizeSession:async()=>{throw new Error("grant_tab_no_passkey: a grant-held tab cannot authorize sessions \u2014 session birth requires the wallet owner's passkey ceremony")},signWithSession:async(U,B)=>xt(U,B,y),signOpenTab:async U=>U.registration,signCloseTab:async()=>{throw new Error("grant_tab_cannot_revoke: session revocation is passkey-signed and belongs to the wallet owner's surfaces \u2014 a grant-held tab closes settle-only")}};return new Ne({vault:$,network:Rt,seller:x,counterparty:t.params.counterparty,session:K,channelIdHex:b,channelIdBytes:y,perUnitCapAtomic:o,totalCapAtomic:a,expiresAtUnix:t.params.expiresAtUnix,facilitatorUrl:e,initialCumulativeAtomic:R,closeMode:"settle-only"})}function En(t){if(t.length===64)return Ue.sign.keyPair.fromSecretKey(t);if(t.length===32)return Ue.sign.keyPair.fromSeed(t);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${t.length} bytes`)}function Kt(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r++)n|=t[r]^e[r];return n===0}import{PublicKey as _n}from"@solana/web3.js";var Lt=[{caip2:"eip155:8453",bare:"base",family:"evm"},{caip2:"eip155:1",bare:"ethereum",family:"evm"},{caip2:"eip155:137",bare:"polygon",family:"evm"},{caip2:"eip155:42161",bare:"arbitrum",family:"evm"},{caip2:"eip155:10",bare:"optimism",family:"evm"},{caip2:"eip155:43114",bare:"avalanche",family:"evm"},{caip2:"eip155:56",bare:"bsc",family:"evm"},{caip2:"eip155:480",bare:"world",family:"evm"},{caip2:"eip155:143",bare:"monad",family:"evm"},{caip2:"eip155:4663",bare:"robinhood",family:"evm"},{caip2:"eip155:1187947933",bare:"skale-base",family:"evm"},{caip2:"eip155:324705682",bare:"skale-base-sepolia",family:"evm"},{caip2:"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",bare:"solana",family:"svm"}],vn=new Map(Lt.map(t=>[t.caip2.toLowerCase(),t])),Rn=new Map(Lt.map(t=>[t.bare.toLowerCase(),t]));function De(t){if(!t)return null;let e=t.toLowerCase(),n=vn.get(e)||Rn.get(e);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function Pt(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),n=e+"=".repeat((4-(e.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function Pn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=De(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.amount??r.maxAmountRequired??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}async function st(t){let e=t.headers.get("payment-required");if(!e)return null;let n;try{n=Pt(e)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:Pn(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function Be(t,e={},n=fetch){let r={method:e.method??"GET",headers:e.headers};typeof e.body=="string"&&(r.body=e.body);let s;try{s=await n(t,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(s.status!==402)return s.ok?{kind:"free",response:s}:{kind:"error",detail:`probe returned HTTP ${s.status}`};let o=await st(s);if(!o)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=o.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:o.options.map(i=>i.scheme)};try{new _n(a.payTo)}catch{return{kind:"error",detail:`tab option payTo is not a valid Solana pubkey: "${a.payTo}"`}}return{kind:"offer",offer:{payTo:a.payTo,amountAtomic:a.amount,asset:a.asset,networkCaip2:a.network.caip2,resourceUrl:o.resourceUrl}}}var Me="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",ot="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",at="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",te=Me,$e=ot,Ke=at,ne="eip155:8453",we="eip155:84532",Te="eip155:42161",xe="eip155:137",Ee="eip155:10",ve="eip155:43114",Re="eip155:56",re="eip155:480",se="eip155:143",oe="eip155:4663",ae="eip155:1187947933",ie="eip155:324705682",Pe="eip155:1",ce=ne,it=we,Le=Te,Ve=xe,We=Ee,He=ve,Fe=Re,qe=re,je=se,Je=oe,Ge=ae,ze=ie,Xe=Pe,Ye="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",Vt="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Wt="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",_t="0x55d398326f99059fF775485246999027B3197955",ct="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ct="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",lt={[Re]:ct,[ne]:Wt,[we]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[Te]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[xe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ee]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[ve]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[re]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[se]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[oe]:Ct,[ae]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[ie]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Pe]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ut={[_t]:{symbol:"USDT",decimals:18},[ct]:{symbol:"USDC",decimals:18}};var mt={[re]:{name:"USDC",version:"2"},[se]:{name:"USDC",version:"2"},[oe]:{name:"Global Dollar",version:"1"},[ae]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[ie]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},G="0x000000000022D473030F116dDEE9F6B43aC78BA3",Qe="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",Ze={[Re]:56,[ne]:8453,[we]:84532,[Te]:42161,[xe]:137,[Ee]:10,[ve]:43114,[re]:480,[se]:143,[oe]:4663,[ae]:1187947933,[ie]:324705682,[Pe]:1},le={[Me]:"https://api.dexter.cash/api/solana/rpc",[ot]:"https://api.devnet.solana.com",[at]:"https://api.testnet.solana.com"},O={[Re]:"https://api.dexter.cash/api/evm/bsc/rpc",[ne]:"https://api.dexter.cash/api/base/rpc",[we]:"https://sepolia.base.org",[Te]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[xe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ee]:"https://api.dexter.cash/api/evm/optimism/rpc",[ve]:"https://api.dexter.cash/api/evm/avalanche/rpc",[re]:"https://worldchain-mainnet.g.alchemy.com/public",[se]:"https://rpc.monad.xyz",[oe]:"https://rpc.mainnet.chain.robinhood.com",[ae]:"https://skale-base.skalenodes.com/v1/base",[ie]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Pe]:"https://eth.llamarpc.com"};var I=class t extends Error{code;details;constructor(e,n,r){super(n),this.name="X402Error",this.code=e,this.details=r,Object.setPrototypeOf(this,t.prototype)}};import{PublicKey as ue,Connection as kt,TransactionMessage as Cn,VersionedTransaction as kn,ComputeBudgetProgram as Ht}from"@solana/web3.js";import{getAssociatedTokenAddress as It,getAccount as In,createTransferCheckedInstruction as Nn,getMint as On,TOKEN_PROGRAM_ID as Ft,TOKEN_2022_PROGRAM_ID as pt}from"@solana/spl-token";var Un=12e3,Dn=1;function me(t){if(!t||typeof t!="object")return!1;let e=t;return"publicKey"in e&&"signTransaction"in e&&typeof e.signTransaction=="function"}var dt=class{name="Solana";networks=[te,$e,Ke];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="solana"||e==="solana-devnet"||e==="solana-testnet"||e.startsWith("solana:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:le[e]?le[e]:e==="solana"?le[te]:e==="solana-devnet"?le[$e]:e==="solana-testnet"?le[Ke]:le[te]}getAddress(e){return me(e)?e.publicKey?.toBase58()??null:null}isConnected(e){return me(e)?e.publicKey!==null:!1}async getBalance(e,n,r){if(!me(n)||!n.publicKey)return 0;let s=r||this.getDefaultRpcUrl(e.network),o=new kt(s,"confirmed"),a=new ue(n.publicKey.toBase58()),i=new ue(e.asset);try{let u=(await o.getAccountInfo(i,"confirmed"))?.owner.toBase58()===pt.toBase58()?pt:Ft,p=await It(i,a,!1,u),d=await In(o,p,void 0,u),f=e.extra?.decimals??6;return Number(d.amount)/Math.pow(10,f)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(e,n,r){if(!me(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let s=r||this.getDefaultRpcUrl(e.network),o=new kt(s,"confirmed"),a=new ue(n.publicKey.toBase58()),{payTo:i,asset:c,extra:u}=e,p=e.amount??e.maxAmountRequired;if(!p)throw new Error("Missing amount in payment requirements");if(!u?.feePayer)throw new Error("Missing feePayer in payment requirements");let d=new ue(u.feePayer),f=new ue(c),T=new ue(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:p,asset:c,feePayer:u.feePayer});let l=[];l.push(Ht.setComputeUnitLimit({units:Un})),l.push(Ht.setComputeUnitPrice({microLamports:Dn}));let R=await o.getAccountInfo(f,"confirmed");if(!R)throw new Error(`Token mint ${c} not found`);let x=R.owner.toBase58()===pt.toBase58()?pt:Ft,g=await On(o,f,void 0,x);typeof u?.decimals=="number"&&g.decimals!==u.decimals&&this.log(`Decimals mismatch: requirements say ${u.decimals}, mint says ${g.decimals}`);let y=await It(f,a,!1,x),b=await It(f,T,!0,x);if(!await o.getAccountInfo(y,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await o.getAccountInfo(b,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let K=BigInt(p);l.push(Nn(y,f,b,a,K,g.decimals,[],x));let{blockhash:$}=await o.getLatestBlockhash("confirmed"),U=new Cn({payerKey:d,recentBlockhash:$,instructions:l}).compileToV0Message(),B=new kn(U),h=await n.signTransaction(B);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:y.toBase58(),destinationAta:b.toBase58(),asset:c,amount:p,blockhash:$}}}async confirmSettlement(e,n){if(e.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`);let r=new kt(n,"confirmed"),s=new ue(e.destinationAta),o=await r.getSignaturesForAddress(s,{limit:25});if(o.length===0)return{settled:!1};let a=BigInt(e.amount);for(let i of o){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let u=c.transaction.message.getAccountKeys().keySegments().flat(),p=c.meta.preTokenBalances??[],d=c.meta.postTokenBalances??[];for(let f of d){if(f.mint!==e.asset)continue;let T=u[f.accountIndex];if(!T||!T.equals(s))continue;let l=p.find(g=>g.accountIndex===f.accountIndex),R=BigInt(l?.uiTokenAmount.amount??"0");if(BigInt(f.uiTokenAmount.amount??"0")-R===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function z(t){return new dt(t)}var Bn={PermitWitnessTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"witness",type:"Witness"}],TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],Witness:[{name:"to",type:"address"},{name:"validAfter",type:"uint256"}]},qt=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function pe(t){if(!t||typeof t!="object")return!1;let e=t;return"address"in e&&typeof e.address=="string"&&e.address.startsWith("0x")}var ft=class{name="EVM";networks=[Fe,ce,it,Xe,Le,Ve,We,He,qe,je,Je,Ge,ze];config;log;constructor(e={}){this.config=e,this.log=e.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(e){return!!(this.networks.includes(e)||e==="base"||e==="bsc"||e==="ethereum"||e==="arbitrum"||e==="polygon"||e==="optimism"||e==="avalanche"||e==="world"||e==="monad"||e==="robinhood"||e==="skale-base"||e==="skale-base-sepolia"||e.startsWith("eip155:"))}getDefaultRpcUrl(e){return this.config.rpcUrls?.[e]?this.config.rpcUrls[e]:O[e]?O[e]:e==="base"?O[ce]:e==="bsc"?O[Fe]:e==="ethereum"?O[Xe]:e==="arbitrum"?O[Le]:e==="polygon"?O[Ve]:e==="optimism"?O[We]:e==="avalanche"?O[He]:e==="world"?O[qe]:e==="monad"?O[je]:e==="robinhood"?O[Je]:e==="skale-base"?O[Ge]:e==="skale-base-sepolia"?O[ze]:O[ce]}getAddress(e){return pe(e)?e.address:null}isConnected(e){return pe(e)?!!e.address:!1}getChainId(e){if(Ze[e])return Ze[e];if(e.startsWith("eip155:")){let n=e.split(":")[1];return parseInt(n,10)}return e==="base"?8453:e==="bsc"?56:e==="ethereum"?1:e==="arbitrum"?42161:e==="polygon"?137:e==="optimism"?10:e==="avalanche"?43114:e==="world"?480:e==="monad"?143:e==="robinhood"?4663:e==="skale-base"?1187947933:e==="skale-base-sepolia"?324705682:8453}async getBalance(e,n,r){if(!pe(n)||!n.address)return 0;let s=r||this.getDefaultRpcUrl(e.network);try{let o=this.encodeBalanceOf(n.address),a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:e.asset,data:o},"latest"]})});if(!a.ok)throw new Error(`RPC request failed: ${a.status}`);let i=await a.json();if(i.error)throw new Error(`RPC error: ${JSON.stringify(i.error)}`);if(!i.result||i.result==="0x")return 0;let c=BigInt(i.result),u=e.extra?.decimals??6;return Number(c)/Math.pow(10,u)}catch(o){throw o}}encodeBalanceOf(e){let n="0x70a08231",r=e.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(e,n){if(e.kind==="eip3009"){let r="0xe94a0102",s=e.from.slice(2).toLowerCase().padStart(64,"0"),o=e.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+s+o,i=await this.ethCall(n,e.asset,a);return{settled:BigInt(i)!==0n}}if(e.kind==="permit2"){let r="0x4fe02b44",s=BigInt(e.nonce),o=s>>8n,a=s&0xffn,i=e.from.slice(2).toLowerCase().padStart(64,"0"),c=o.toString(16).padStart(64,"0"),u=r+i+c,p=await this.ethCall(n,G,u);return{settled:(BigInt(p)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${e.kind}"`)}async ethCall(e,n,r){let s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:r},"latest"]})});if(!s.ok)throw new Error(`RPC request failed: ${s.status}`);let o=await s.json();if(o.error)throw new Error(`RPC error: ${JSON.stringify(o.error)}`);if(!o.result||o.result==="0x")throw new Error("RPC returned an empty result");return o.result}async buildTransaction(e,n,r){if(!pe(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(e.scheme==="exact-approval")return this.buildApprovalTransaction(e,n,r);if(e.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(e,n,r);let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network});let c=this.getChainId(e.network),u=mt[`eip155:${c}`],p={name:a?.name??u?.name??"USD Coin",version:a?.version??u?.version??"2",chainId:BigInt(c),verifyingContract:o},d={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]},f=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(f);let T="0x"+[...f].map(b=>b.toString(16).padStart(2,"0")).join(""),l=Math.floor(Date.now()/1e3),R={from:n.address,to:s,value:i,validAfter:String(l-600),validBefore:String(l+(e.maxTimeoutSeconds||60)),nonce:T},x={from:n.address,to:s,value:BigInt(i),validAfter:BigInt(l-600),validBefore:BigInt(l+(e.maxTimeoutSeconds||60)),nonce:T};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let g=await n.signTypedData({domain:p,types:d,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:R,signature:g}),signature:g,settlementProbe:{kind:"eip3009",from:n.address,nonce:T,asset:o,chainId:c}}}async buildApprovalTransaction(e,n,r){let{payTo:s,asset:o,extra:a}=e,i=e.amount??e.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");let c=a?.facilitatorContract;if(!c)throw new Error("exact-approval scheme requires extra.facilitatorContract from the facilitator. The /supported endpoint should provide this.");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building approval-based transaction:",{from:n.address,to:s,amount:i,asset:o,network:e.network,facilitatorContract:c});let u=r||this.getDefaultRpcUrl(e.network),p=a?.fee??"0",d=BigInt(i)+BigInt(p),f=await this.readAllowance(u,o,n.address,c);if(f<d){if(!n.sendTransaction)throw new Error("BSC payments require a wallet that supports sendTransaction for the one-time token approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.");let B=this.calculateApprovalAmount(i,p,a?.approvalStrategy);this.log(`Approving ${B} for ${c} (current allowance: ${f})`);let h=await n.sendTransaction({to:o,data:this.encodeApprove(c,B),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(u,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let T=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(T);let l=[...T].reduce((B,h)=>B*256n+BigInt(h),0n).toString(),R=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(R);let x="0x"+[...R].map(B=>B.toString(16).padStart(2,"0")).join(""),y=Math.floor(Date.now()/1e3)+(e.maxTimeoutSeconds||300),b=a?.eip712Domain,C=b?{name:b.name,version:b.version,chainId:BigInt(b.chainId),verifyingContract:b.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(e.network)),verifyingContract:c},D=a?.eip712Types??{Payment:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"token",type:"address"},{name:"amount",type:"uint256"},{name:"fee",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"},{name:"paymentId",type:"bytes32"}]},K={from:n.address,to:s,token:o,amount:BigInt(i),fee:BigInt(p),nonce:BigInt(l),deadline:BigInt(y),paymentId:x},$=await n.signTypedData({domain:C,types:D,primaryType:"Payment",message:K});this.log("EIP-712 Payment signature obtained");let U={from:n.address,to:s,token:o,amount:i,fee:p,nonce:l,deadline:y,paymentId:x,signature:$};return{serialized:JSON.stringify(U),signature:$}}async buildPermit2Transaction(e,n,r){let{payTo:s,asset:o}=e,a=e.amount??e.maxAmountRequired;if(!a)throw new Error("Missing amount in payment requirements");if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");this.log("Building Permit2 transaction:",{from:n.address,to:s,amount:a,asset:o,network:e.network});let i=r||this.getDefaultRpcUrl(e.network),c=await this.readAllowance(i,o,n.address,G),u;if(c<BigInt(a)){let C=this.encodeApprove(G,qt);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let D=this.getChainId(e.network),K=await this.readGasPrice(i),$=await this.readNonce(i,n.address),U=await n.signTransaction({to:o,data:C,chainId:D,gas:50000n,gasPrice:K,nonce:$});u={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:o,spender:G,amount:qt.toString(),signedTransaction:U,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let D=await n.sendTransaction({to:o,data:C,value:0n});this.log(`Permit2 approval tx sent: ${D}`),await this.waitForReceipt(i,D),this.log("Permit2 approval confirmed")}else throw new Error("Permit2 payments require a wallet that supports signTransaction or sendTransaction for the one-time Permit2 approval. Use createEvmKeypairWallet() or a browser wallet with transaction support.")}else this.log("Sufficient Permit2 allowance, skipping approval");let p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let d=[...p].reduce((C,D)=>C*256n+BigInt(D),0n),f=Math.floor(Date.now()/1e3),T=f-600,l=f+(e.maxTimeoutSeconds||300),R=this.getChainId(e.network),x={name:"Permit2",chainId:BigInt(R),verifyingContract:G},g={permitted:{token:o,amount:BigInt(a)},spender:Qe,nonce:d,deadline:BigInt(l),witness:{to:s,validAfter:BigInt(T)}},y=await n.signTypedData({domain:x,types:Bn,primaryType:"PermitWitnessTransferFrom",message:g});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let b={signature:y,permit2Authorization:{from:n.address,permitted:{token:o,amount:a},spender:Qe,nonce:d.toString(),deadline:String(l),witness:{to:s,validAfter:String(T)}}};return{serialized:JSON.stringify(b),signature:y,extensions:u,settlementProbe:{kind:"permit2",from:n.address,nonce:d.toString(),chainId:R}}}async readAllowance(e,n,r,s){let o="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=s.slice(2).toLowerCase().padStart(64,"0"),c=o+a+i;try{let p=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:n,data:c},"latest"]})})).json();return p.error||!p.result||p.result==="0x"?0n:BigInt(p.result)}catch{return 0n}}encodeApprove(e,n){let r="0x095ea7b3",s=e.slice(2).toLowerCase().padStart(64,"0"),o=n.toString(16).padStart(64,"0");return r+s+o}async waitForReceipt(e,n,r=3e4){let s=Date.now();for(;Date.now()-s<r;){try{let a=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionReceipt",params:[n]})})).json();if(a.result){if(a.result.status==="0x0")throw new Error(`Approval transaction reverted: ${n}`);return}}catch(o){if(o instanceof Error&&o.message.includes("reverted"))throw o}await new Promise(o=>setTimeout(o,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(e){try{let r=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_gasPrice",params:[]})})).json();return r.result?BigInt(r.result):50000000n}catch{return 50000000n}}async readNonce(e,n){try{let s=await(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return s.result?parseInt(s.result,16):0}catch{return 0}}calculateApprovalAmount(e,n,r){let s=BigInt(e)+BigInt(n);if(!r||r.mode==="exact")return s;let o=BigInt(r.defaultMultiple??10),a=s*o;if(r.maxCapUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(e),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(e)>c)return s}return a}inferDecimals(e){return e.length>12?18:6}};function _e(t){return new ft(t)}function Nt(t){if(t===Ye||t===Vt)return!0;let e=t.toLowerCase();for(let n of Object.values(lt))if(n.toLowerCase()===e)return!0;for(let n of Object.keys(ut))if(n.toLowerCase()===e)return!0;return!1}function Mn(t){return{[Me]:"Solana",[ot]:"Solana Devnet",[at]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[ne]:"Base",[we]:"Base Sepolia",[Pe]:"Ethereum",[Te]:"Arbitrum",[xe]:"Polygon",[Ee]:"Optimism",[ve]:"Avalanche",[Re]:"BSC",[re]:"World Chain",[se]:"Monad",[oe]:"Robinhood Chain",[ae]:"SKALE Base",[ie]:"SKALE Base Sepolia",base:"Base","base-sepolia":"Base Sepolia",ethereum:"Ethereum",arbitrum:"Arbitrum",polygon:"Polygon",optimism:"Optimism",avalanche:"Avalanche",bsc:"BSC",world:"World Chain",monad:"Monad",robinhood:"Robinhood Chain","skale-base":"SKALE Base","skale-base-sepolia":"SKALE Base Sepolia"}[t]||t}function jt(t,e){let n=Mn(t);return n===t?e:n}async function $n(t,e){if(typeof t=="string")return[t,e];if(t instanceof URL)return[t.href,e];let n=t,r=new Headers(n.headers);e?.headers&&new Headers(e.headers).forEach((a,i)=>r.set(i,a));let s={method:e?.method??n.method,headers:r,signal:e?.signal??n.signal,redirect:e?.redirect??n.redirect,credentials:e?.credentials??n.credentials},o=(s.method??"GET").toUpperCase();return e&&"body"in e?s.body=e.body:o!=="GET"&&o!=="HEAD"&&n.body&&(s.body=await n.arrayBuffer()),[n.url,s]}var Kn=new WeakMap;function Jt(t){let{adapters:e=[z({verbose:t.verbose}),_e({verbose:t.verbose})],wallets:n,wallet:r,preferredNetwork:s,rpcUrls:o={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:u,onPaymentRequired:p,onPaymentDispatched:d,maxRetries:f=0,retryDelayMs:T=500}=t,l=c?console.log.bind(console,"[x402]"):()=>{};async function R(h,w){let E;for(let A=0;A<=f;A++)try{let v=await i(h,w);if(v.status>=502&&v.status<=504&&A<f){l(`Retry ${A+1}/${f}: server returned ${v.status}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A)));continue}return v}catch(v){E=v,A<f&&(l(`Retry ${A+1}/${f}: ${v instanceof Error?v.message:"network error"}`),await new Promise(P=>setTimeout(P,T*Math.pow(2,A))))}throw E}let x=new Map;function g(h){try{let w=new URL(h).host,E=x.get(w);if(E&&E.expiresAt>Date.now()/1e3+10)return E.jwt;E&&x.delete(w)}catch{}return null}function y(h,w){try{let E=new URL(h).host,A=w.split(".");if(A.length===3){let v=JSON.parse(atob(A[1].replace(/-/g,"+").replace(/_/g,"/"))),P=Math.floor(Date.now()/1e3),_=P+86400,L=Math.min(typeof v.exp=="number"?v.exp:P,_);x.set(E,{jwt:w,expiresAt:L}),l("Access pass cached for",E,"| expires:",new Date(L*1e3).toISOString())}}catch{l("Failed to cache access pass")}}let b=n||{};r&&!b.solana&&me(r)&&(b.solana=r),r&&!b.evm&&pe(r)&&(b.evm=r);function C(h){let w=[];for(let E of h){let A=E.scheme??"exact";if(A!=="exact"&&A!=="exact-approval")continue;let v=e.find(_=>_.canHandle(E.network));if(!v)continue;let P;v.name==="Solana"?P=b.solana:v.name==="EVM"&&(P=b.evm),P&&v.isConnected(P)&&w.push({accept:E,adapter:v,wallet:P})}if(w.length===0)return null;if(s){let E=w.find(A=>A.accept.network===s);if(E)return E}return w[0]}function D(h,w){return jt(h,w)}function K(h,w){return o[h]||w.getDefaultRpcUrl(h)}async function $(h,w,E,A,v){let P="";if(u?.preferTier&&A.tiers){let m=A.tiers.find(S=>S.id===u.preferTier);if(m){if(u.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Access pass tier "${m.id}" costs $${m.price}, exceeds max spend $${u.maxSpend}`);P=`tier=${m.id}`}}else if(u?.preferDuration&&A.ratePerHour)P=`duration=${u.preferDuration}`;else if(A.tiers&&A.tiers.length>0){let m=A.tiers[0];if(u?.maxSpend&&parseFloat(m.price)>parseFloat(u.maxSpend))throw new I("access_pass_exceeds_max_spend",`Cheapest access pass costs $${m.price}, exceeds max spend $${u?.maxSpend}`);P=`tier=${m.id}`}let _=P?v.includes("?")?`${v}&${P}`:`${v}?${P}`:v;l("Purchasing access pass:",P||"default tier");let L=E.headers.get("PAYMENT-REQUIRED");if(!L)return null;let M;try{M=JSON.parse(atob(L))}catch{return null}let N=C(M.accepts);if(!N)return null;let{accept:k,adapter:W,wallet:de}=N;if(W.name==="Solana"&&!k.extra?.feePayer)return null;let F=k.extra?.decimals??(Nt(k.asset)?6:void 0);if(typeof F!="number")return null;let Ce=k.amount??k.maxAmountRequired;if(!Ce)return null;let q=K(k.network,W);try{let m=await W.getBalance(k,de,q),S=Number(Ce)/Math.pow(10,F);if(m<S){let At=D(k.network,W.name);throw new I("insufficient_balance",`Insufficient balance for access pass on ${At}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}}catch(m){if(m instanceof I)throw m}let j=await W.buildTransaction(k,de,q),fe;W.name==="EVM"?fe=JSON.parse(j.serialized):fe={transaction:j.serialized};let X=typeof h=="string"?h:h instanceof URL?h.href:h.url,ge=M.resource;if(typeof M.resource=="string")try{let m=new URL(M.resource,X);["http:","https:"].includes(m.protocol)&&(ge=m.toString())}catch{}else if(M.resource&&typeof M.resource=="object"&&"url"in M.resource){let m=M.resource;try{let S=new URL(m.url,X);["http:","https:"].includes(S.protocol)&&(ge={...m,url:S.toString()})}catch{}}let tt={x402Version:k.x402Version??2,resource:ge,accepted:k,payload:fe};j.extensions&&(tt.extensions=j.extensions);let J=btoa(JSON.stringify(tt)),Y=await i(_,{...w,method:"POST",headers:{...w?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":J}});if(!Y.ok)return l("Pass purchase failed:",Y.status),null;let V=Y.headers.get("ACCESS-PASS");return V&&(y(v,V),l("Access pass purchased and cached")),Y}async function U(h,w){let E=h;if(l("Making request:",E),u){let m=g(E);if(m){l("Using cached access pass");let S=await i(h,{...w,headers:{...w?.headers||{},Authorization:`Bearer ${m}`}});if(S.status!==401&&S.status!==402)return S;l("Cached pass rejected (status",S.status,"), purchasing new pass");try{x.delete(new URL(E).host)}catch{}}}let A=await R(h,w);if(A.status!==402)return A;l("Received 402 Payment Required");let v=A.headers.get("X-ACCESS-PASS-TIERS");if(u&&v){l("Server offers access passes, purchasing...");try{let m=JSON.parse(atob(v)),S=await $(h,w,A,m,E);if(S)return S}catch(m){l("Access pass purchase failed, falling back to per-request payment:",m)}}let P=A.headers.get("PAYMENT-REQUIRED");if(!P)throw new I("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let _;try{let m=atob(P);_=JSON.parse(m)}catch{throw new I("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}l("Payment requirements:",_);let L=A.headers.get("X-Quote-Hash");L&&l("Quote hash received:",L);let M=C(_.accepts);if(!M){let m=_.accepts.map(S=>S.network).join(", ");throw new I("no_matching_payment_option",`No connected wallet for any available network: ${m}`)}let{accept:N,adapter:k,wallet:W}=M;if(l(`Using ${k.name} for ${N.network}`),k.name==="Solana"&&!N.extra?.feePayer)throw new I("missing_fee_payer","Solana payment option missing feePayer in extra");let de=N.extra?.decimals??(Nt(N.asset)?6:void 0);if(typeof de!="number")throw new I("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let F=N.amount??N.maxAmountRequired;if(!F)throw new I("missing_amount","Payment option missing amount");if(a&&BigInt(F)>BigInt(a))throw new I("amount_exceeds_max",`Payment amount ${F} exceeds maximum ${a}`);let Ce=K(N.network,k);l("Checking balance...");try{let m=await k.getBalance(N,W,Ce),S=Number(F)/Math.pow(10,de);if(m<S){let At=D(N.network,k.name);throw new I("insufficient_balance",`Insufficient balance on ${At}. Have $${m.toFixed(4)}, need $${S.toFixed(4)}`)}l(`Balance OK: $${m.toFixed(4)} >= $${S.toFixed(4)}`)}catch(m){if(m instanceof I)throw m;l("Balance check failed (RPC error), proceeding with transaction attempt")}if(p&&!await p(N))throw new I("payment_rejected","Payment rejected by onPaymentRequired callback");l("Building transaction...");let q=await k.buildTransaction(N,W,Ce);l("Transaction signed");let j;k.name==="EVM"?j=JSON.parse(q.serialized):j={transaction:q.serialized};let fe=h,X=_.resource;if(typeof _.resource=="string")try{let m=new URL(_.resource,fe).toString();m!==_.resource&&l("Resolved relative resource URL:",_.resource,"\u2192",m),X=m}catch{X=_.resource}else if(_.resource&&typeof _.resource=="object"&&"url"in _.resource){let m=_.resource;try{let S=new URL(m.url,fe).toString();S!==m.url&&(l("Resolved relative resource URL:",m.url,"\u2192",S),X={...m,url:S})}catch{}}let ge={x402Version:N.x402Version??2,resource:X,accepted:N,payload:j};q.extensions&&(ge.extensions=q.extensions);let tt=btoa(JSON.stringify(ge));if(d)try{d(N,q.settlementProbe)}catch{}l("Retrying request with payment...");let J=await R(h,{...w,headers:{...w?.headers||{},"PAYMENT-SIGNATURE":tt,...L?{"X-Quote-Hash":L}:{}}});if(l("Retry response status:",J.status),J.status===402){let m="unknown";try{let S=await J.clone().json();m=String(S.error||S.message||JSON.stringify(S)),l("Rejection reason:",m)}catch{}throw new I("payment_rejected",`Payment was rejected by the server: ${m}`)}let Y=J.headers.get("PAYMENT-RESPONSE"),V;if(Y)try{V=JSON.parse(atob(Y))}catch{}return V??={},V.amountAtomic=F,V.assetDecimals=de,Kn.set(J,V),V.extensions&&l("Settlement extensions:",Object.keys(V.extensions).join(", ")),J}async function B(h,w){let[E,A]=await $n(h,w);return U(E,A)}return{fetch:B}}function H(t){if(t instanceof Error){if(t.message&&t.message.length>0)return t.message;if(t.name&&t.name.length>0)return t.name}let e=String(t);return e.length>0?e:"unknown error"}async function et(t){let e="";try{e=(await t.clone().text()).slice(0,600)}catch{}let n=e.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),s=e;try{let o=JSON.parse(e),a=[o.error,o.detail,o.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(s=a.join(" \u2014 "))}catch{}return s||(s=`HTTP ${t.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${t.status}: ${s}`}}var gt="Payment authorization was sent, but the merchant did not respond within the timeout. ",yt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function ht(t,e,n){if(!t)return{confirmed:!1,detail:gt+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+yt};try{if(t.kind==="solana"){let a=z(),i=n??a.getDefaultRpcUrl(e.caip2);if(!a.confirmSettlement)return zt();let c=await a.confirmSettlement(t,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:Gt()}let r=_e(),s=r.getDefaultRpcUrl(e.caip2);if(!r.confirmSettlement)return zt();let o=await r.confirmSettlement(t,s);return o.settled?{confirmed:!0,txSignature:o.txSignature}:Gt()}catch(r){return{confirmed:!1,detail:gt+`On-chain confirmation could not be completed (${H(r)}).`+yt}}}function Gt(){return{confirmed:!1,detail:gt+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+yt}}function zt(){return{confirmed:!1,detail:gt+"The chain adapter does not support on-chain confirmation."+yt}}var Ln=new Set(["exact","exact-approval"]);async function Vn(t,e,n,r){let s;try{s=await r.signNextVoucher(n.amount)}catch{return null}let o=new Headers(e.headers??void 0);o.set("X-Tab-Voucher",nt(s));let a={method:e.method??"GET",headers:o};e.signal&&(a.signal=e.signal),typeof e.body=="string"&&(a.body=e.body);let i;try{i=await fetch(t,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?(r.rollbackVoucher?.call(r,s),null):i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await et(i)}}var Xt={version:2,async parseChallenge(t){return st(t)},async pay(t,e,n,r,s){if(s.tab){let g=n.options.find(y=>y.scheme==="tab"&&y.network.family==="svm"&&y.payTo===s.tab.counterparty);if(g){let y=await Vn(t,e,g,s.tab);if(y)return y}}let o=n.options.filter(g=>Ln.has(g.scheme));if(o.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(g=>g.scheme).join(", ")})`};let a=o.find(g=>g.network.family==="evm"?!!r.evm:g.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=s.timeoutMs??15e3,c=s.responseTimeoutMs??12e4,u=new AbortController,p=setTimeout(()=>u.abort(),i),d=!1,f,T=(g,y)=>{d=!0,f=y,clearTimeout(p),p=setTimeout(()=>u.abort(),c)},l=Jt({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:s.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:T}),R=e.signal?AbortSignal.any([e.signal,u.signal]):u.signal,x={method:e.method??"GET",headers:e.headers,signal:R};typeof e.body=="string"&&(x.body=e.body);try{let g=await l.fetch(t,x);if(clearTimeout(p),!g.ok)return{ok:!1,...await et(g)};let y,b=g.headers.get("PAYMENT-RESPONSE");if(b)try{let C=Pt(b);C&&typeof C.transaction=="string"&&(y=C.transaction)}catch{}return{ok:!0,paid:!0,response:g,amountPaid:a.amount,network:a.network,txSignature:y}}catch(g){clearTimeout(p);let y=g;if(y?.name==="AbortError"){if(!d)return{ok:!1,reason:"timeout"};let b=await ht(f,a.network,s.solanaRpcUrl);return b.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:b.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:b.detail}}return{ok:!1,reason:"error",detail:y?.message??String(g)}}}};import{getAddress as Wn}from"viem";var Hn={TransferWithAuthorization:[{name:"from",type:"address"},{name:"to",type:"address"},{name:"value",type:"uint256"},{name:"validAfter",type:"uint256"},{name:"validBefore",type:"uint256"},{name:"nonce",type:"bytes32"}]};async function Fn(){let t=globalThis.crypto??(await import("crypto")).webcrypto,e=new Uint8Array(32);return t.getRandomValues(e),"0x"+Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}async function qn(t,e,n){if(typeof t.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),s=String(r-600),o=String(r+(e.maxTimeoutSeconds??60)),a={from:t.address,to:e.payTo,value:e.amount,validAfter:s,validBefore:o,nonce:await Fn()},i=Ze[e.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${e.network.caip2}`);let c=e.extra,u=await t.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:Wn(e.asset)},types:Hn,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:e.scheme,network:n,payload:{signature:u,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:e.asset,chainId:i}}}async function Ot(t,e,n){try{let r;for(let s of t.options){let o=s.network.family==="evm"&&!!e.evm||s.network.family==="svm"&&!!e.solana;if(s.scheme!=="exact"){o&&(r=s.scheme);continue}if(s.network.family==="evm"&&e.evm){let a=await e.evm;return await jn(s,a,n)}if(s.network.family==="svm"&&e.solana){let a=await e.solana;return await Jn(s,a,n)}}return r!==void 0?{ok:!1,reason:"merchant_rejected",detail:`v1 supports only the 'exact' scheme, got '${r}'`}:{ok:!1,reason:"unsupported_network"}}catch(r){return{ok:!1,reason:"error",detail:H(r)}}}async function jn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=t.extra??{},s=r.name,o=r.version;if(typeof s!="string"||s.length===0||typeof o!="string"||o.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=t.network.bare,{payment:i,settlementProbe:c}=await qn(e,t,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:t,settlementProbe:c}}async function Jn(t,e,n){if(n.maxAmountAtomic!==void 0&&BigInt(t.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(t.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${t.scheme}'`};let r=t.extra??{};if(typeof r.feePayer!="string"||r.feePayer.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 SVM challenge missing extra.feePayer (required as the transaction fee payer)"};let s=t.network.bare,o={x402Version:1,scheme:t.scheme,network:s,asset:t.asset,payTo:t.payTo,amount:t.amount,maxAmountRequired:t.amount,maxTimeoutSeconds:t.maxTimeoutSeconds??60,extra:r},i=await z().buildTransaction(o,e,n.solanaRpcUrl),c={x402Version:1,scheme:t.scheme,network:s,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:t,settlementProbe:i.settlementProbe}}function Gn(t){let e=[];for(let n of t){if(!n||typeof n!="object")continue;let r=n,s=De(String(r.network??""));s&&e.push({scheme:String(r.scheme??"exact"),network:s,amount:String(r.maxAmountRequired??r.amount??"0"),asset:String(r.asset??""),payTo:String(r.payTo??""),maxTimeoutSeconds:typeof r.maxTimeoutSeconds=="number"?r.maxTimeoutSeconds:void 0,extra:r.extra&&typeof r.extra=="object"?r.extra:void 0})}return e}var Yt={version:1,async parseChallenge(t){if(t.headers.get("payment-required"))return null;let e;try{e=await t.clone().json()}catch{return null}let n=Array.isArray(e.accepts)?e.accepts:[];if(n.length===0)return null;let r=Gn(n);return r.length===0?null:{x402Version:1,options:r}},async pay(t,e,n,r,s){let o,a=new AbortController,i=!1,c,u;try{let p=s.timeoutMs??15e3;o=setTimeout(()=>a.abort(),p);let d=await Ot(n,r,s);if(!d.ok)return{ok:!1,reason:d.reason,detail:d.detail};let f=d.headerValue,T=d.option;u=T,c=d.settlementProbe;let l=new Headers(e.headers??void 0);l.set("X-PAYMENT",f);let R=e.signal!=null?AbortSignal.any([e.signal,a.signal]):a.signal,x={method:e.method,headers:l,signal:R};typeof e.body=="string"&&(x.body=e.body),i=!0,clearTimeout(o);let g=s.responseTimeoutMs??12e4;o=setTimeout(()=>a.abort(),g);let y=await fetch(t,x);return y.ok?{ok:!0,paid:!0,response:y,amountPaid:T.amount,network:T.network,txSignature:zn(y)}:{ok:!1,...await et(y)}}catch(p){if(p instanceof Error&&p.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let d=await ht(c,u.network,s.solanaRpcUrl);return d.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:u.amount,network:u.network,txSignature:d.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:d.detail}}return{ok:!1,reason:"error",detail:H(p)}}finally{o!==void 0&&clearTimeout(o)}}};function zn(t){let e=t.headers.get("x-payment-response")??t.headers.get("X-PAYMENT-RESPONSE");if(e)try{let n=JSON.parse(Buffer.from(e,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}import*as Zt from"tweetnacl";import{Keypair as Rs,VersionedTransaction as Ps,Transaction as _s}from"@solana/web3.js";var Qt=Symbol.for("x402:keypair");function Ut(t){let e=t.evm;if(e&&typeof e.signMessage=="function"&&typeof e.address=="string")return{address:e.address,signMessage:e.signMessage};let n=t.solana;if(n){let r=n[Qt];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async s=>Zt.sign.detached(s,r.secretKey)}}return null}var Xn=[Xt,Yt];async function Yn(t){let e=Ut(t);if(!e)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,e)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${H(n)}`),fetch}}async function Dt(t,e,n,r){if(e.body!==void 0&&e.body!==null&&typeof e.body!="string")return{ok:!1,reason:"error",detail:"payAndFetch requires a string body; non-string bodies (Buffer, FormData, URLSearchParams, ReadableStream) cannot be safely re-sent on the paid retry"};let s;try{s=await(await Yn(n))(t,{...e})}catch(o){return{ok:!1,reason:"error",detail:H(o)}}if(s.status!==402)return{ok:!0,paid:!1,response:s};for(let o of Xn){let a=await o.parseChallenge(s.clone());if(a)return o.pay(t,e,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function Qn(t,e={},n){let r=await Be(t,e);if(r.kind==="free")return{result:{ok:!0,paid:!1,response:r.response},tab:null};if(r.kind==="no_tab")return{result:{ok:!1,reason:"no_payment_options",detail:`no tab option offered (schemes: ${r.schemesOffered.join(", ")})`},tab:null};if(r.kind==="error")return{result:{ok:!1,reason:"error",detail:r.detail},tab:null};let{offer:s}=r,o=BigInt(Z(n.perUnitCap));if(BigInt(s.amountAtomic)>o)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${s.amountAtomic} atomic; perUnitCap allows ${o}`},tab:null};let a=n.tabs?.get(s.payTo);return(!a||!a.state.isOpen)&&(a=await Et({vault:n.vault,network:"solana:mainnet",seller:s.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession}),n.tabs?.set(s.payTo,a)),{result:await Dt(t,e,{},{tab:a}),tab:a}}function Zn(t){return{counterparty:t.payTo,perRequest:{atomic:t.amountAtomic,human:be(t.amountAtomic)},asset:t.asset,network:{caip2:t.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...t.resourceUrl!==void 0?{resourceUrl:t.resourceUrl}:{}}}async function er(t,e={},n={}){let r=n.cache?.get(t);if(r)return{kind:"terms",terms:r};let s=await Be(t,e,n.fetchImpl??fetch);if(s.kind!=="offer")return s;if(s.offer.asset!==Ye)return{kind:"error",detail:`tab offer asset is not USDC ("${s.offer.asset}"); refusing to render a human price`};let o=Zn(s.offer);return n.cache?.set(t,o),{kind:"terms",terms:o}}export{Ie as DEFAULT_FACILITATOR_URL,vt as DEXTER_VAULT_PROGRAM_ID,hn as INSTRUCTIONS_SYSVAR_ID,bt as LiveSessionExistsError,yn as SECP256R1_PROGRAM_ID,he as SessionScopeExceededError,Q as TabClosedError,ye as UnsupportedNetworkError,rt as armTabOpen,be as atomicToHuman,dn as buildRegisterSessionKeyInstruction,fn as buildRevokeSessionKeyInstruction,gn as buildSecp256r1VerifyInstruction,tn as buildVoucherMessage,ke as deriveChannelId,nn as generateSessionKeypair,Z as humanToAtomic,Tt as makeSessionKey,Et as openTab,Ae as parseAtomic,Qn as payUrlWithTab,Be as resolveTabOffer,er as resolveTabTerms,ln as resumeTab,rn as scopeCapAtomic,St as sessionRegisterMessage,en as sessionRevokeMessage,xt as signVoucher,xn as tabFromGrant,wt as voucherPayloadMessage,nt as voucherToHeader};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexterai/x402",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.2",
|
|
4
4
|
"description": "Full-stack x402 SDK - add paid API monetization to any endpoint. Express middleware, React hooks, Access Pass, dynamic pricing. Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, World Chain, Monad, Robinhood Chain, SKALE.",
|
|
5
5
|
"author": "Dexter",
|
|
6
6
|
"license": "MIT",
|