@dexterai/x402 5.4.2 → 6.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/REFERENCE.md +79 -8
- package/dist/adapters/index.d.cts +3 -3
- package/dist/adapters/index.d.ts +3 -3
- package/dist/batch-settlement/index.d.cts +3 -3
- package/dist/batch-settlement/index.d.ts +3 -3
- package/dist/batch-settlement/seller/index.d.cts +4 -4
- package/dist/batch-settlement/seller/index.d.ts +4 -4
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +6 -6
- package/dist/client/index.d.ts +6 -6
- package/dist/client/index.js +1 -1
- package/dist/{constants-Icc4CXNG.d.cts → constants-BLvApMMl.d.cts} +1 -1
- package/dist/{constants-Icc4CXNG.d.ts → constants-BLvApMMl.d.ts} +1 -1
- package/dist/react/index.cjs +1 -1
- package/dist/react/index.d.cts +4 -4
- package/dist/react/index.d.ts +4 -4
- package/dist/react/index.js +1 -1
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +5 -5
- package/dist/server/index.d.ts +5 -5
- package/dist/server/index.js +1 -1
- package/dist/{sessions-BG2OYLBi.d.cts → sessions-rPdO1CgK.d.cts} +35 -3
- package/dist/{sessions-BG2OYLBi.d.ts → sessions-rPdO1CgK.d.ts} +35 -3
- package/dist/tab/adapters/solana/index.cjs +1 -1
- package/dist/tab/adapters/solana/index.d.cts +178 -26
- package/dist/tab/adapters/solana/index.d.ts +178 -26
- package/dist/tab/adapters/solana/index.js +1 -1
- package/dist/tab/index.cjs +5 -5
- package/dist/tab/index.d.cts +117 -16
- package/dist/tab/index.d.ts +117 -16
- package/dist/tab/index.js +4 -4
- package/dist/tab/seller/index.cjs +3 -3
- package/dist/tab/seller/index.d.cts +4 -4
- package/dist/tab/seller/index.d.ts +4 -4
- package/dist/tab/seller/index.js +3 -3
- package/dist/{types-CSuISjXA.d.cts → types-45M9fb5M.d.cts} +109 -6
- package/dist/{types-CSuISjXA.d.ts → types-45M9fb5M.d.ts} +109 -6
- package/dist/{types-BdS_uvNs.d.cts → types-BbvuPNXl.d.cts} +2 -2
- package/dist/{types-Co5YYhVB.d.ts → types-BhXu7cgi.d.ts} +3 -3
- package/dist/{types-xQu1U4xk.d.cts → types-BvQpNtFw.d.cts} +9 -1
- package/dist/{types-xQu1U4xk.d.ts → types-BvQpNtFw.d.ts} +9 -1
- package/dist/{types-CZHPdVkg.d.cts → types-C6z04Mxr.d.cts} +3 -3
- package/dist/{types-DY8xKheW.d.ts → types-CkcNYx1Q.d.ts} +2 -2
- package/dist/{types-_wdHzVG-.d.ts → types-DwVhPqOZ.d.ts} +2 -2
- package/dist/{types-WMqs5xII.d.cts → types-JpkrtFbZ.d.cts} +2 -2
- package/dist/utils/index.d.cts +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/{x402-client-BQKDeNxq.d.cts → x402-client-B8zdDeat.d.cts} +2 -2
- package/dist/{x402-client-BQKDeNxq.d.ts → x402-client-B8zdDeat.d.ts} +2 -2
- package/package.json +7 -6
package/dist/tab/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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(`
|
|
1
|
+
"use strict";var ar=Object.create;var Tt=Object.defineProperty;var ir=Object.getOwnPropertyDescriptor;var cr=Object.getOwnPropertyNames;var ur=Object.getPrototypeOf,lr=Object.prototype.hasOwnProperty;var mr=(e,t)=>{for(var n in t)Tt(e,n,{get:t[n],enumerable:!0})},An=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of cr(t))!lr.call(e,o)&&o!==n&&Tt(e,o,{get:()=>t[o],enumerable:!(r=ir(t,o))||r.enumerable});return e};var J=(e,t,n)=>(n=e!=null?ar(ur(e)):{},An(t||!e||!e.__esModule?Tt(n,"default",{value:e,enumerable:!0}):n,e)),dr=e=>An(Tt({},"__esModule",{value:!0}),e);var no={};mr(no,{DEFAULT_FACILITATOR_URL:()=>ot,DEXTER_VAULT_PROGRAM_ID:()=>q.DEXTER_VAULT_PROGRAM_ID,FINAL_VOUCHER_V2_RESERVATION_BINDING_DOMAIN:()=>kt,FINAL_VOUCHER_V2_RESERVATION_MEMO_PREFIX:()=>rn,FINAL_VOUCHER_V2_SOLANA_MAINNET_CAIP2:()=>Vt,HOSTED_TAB_ACCEPTANCE_RULE:()=>qn,HOSTED_TAB_REGISTRATION_ENCODING:()=>Hn,HOSTED_TAB_TERMS_VERSION:()=>$n,HOSTED_TAB_VOUCHER_HEADER:()=>Wn,HistoricalV1MigrationRequiredError:()=>Y,INSTRUCTIONS_SYSVAR_ID:()=>q.INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError:()=>Et,SECP256R1_PROGRAM_ID:()=>q.SECP256R1_PROGRAM_ID,SessionScopeExceededError:()=>he,TabClosedError:()=>oe,UnsupportedNetworkError:()=>ge,armTabOpen:()=>In,assertFinalVoucherV2ReservationReceipt:()=>ae,atomicToHuman:()=>ve,buildRegisterSessionKeyInstruction:()=>be.buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction:()=>be.buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction:()=>an.buildSecp256r1VerifyInstruction,buildVoucherMessage:()=>T.buildVoucherMessage,canonicalFinalVoucherV2ReservationNetwork:()=>tt,deriveChannelId:()=>Be,finalVoucherV2Digest:()=>nt,finalVoucherV2ReservationBindingDigest:()=>sn,finalVoucherV2ReservationBindingDigestFromIdentity:()=>on,finalVoucherV2ReservationIdentity:()=>Ue,finalVoucherV2ReservationMemo:()=>Ot,finalVoucherV2Sequence:()=>T.finalVoucherV2Sequence,generateSessionKeypair:()=>vn,humanToAtomic:()=>ce,makeSessionKey:()=>Pt,openTab:()=>Bt,parseAtomic:()=>ye,payUrlWithTab:()=>or,resolveTabOffer:()=>qe,resolveTabTerms:()=>sr,resumeTab:()=>Nn,scopeCapAtomic:()=>Sn,sessionRegisterMessage:()=>T.sessionRegisterMessage,sessionReplaceV1Message:()=>T.sessionReplaceV1Message,sessionRevokeMessage:()=>T.sessionRevokeMessage,sessionVoucherV2AuthorizationNonce:()=>T.sessionVoucherV2AuthorizationNonce,sessionVoucherV2Nonce:()=>T.sessionVoucherV2Nonce,signContextBoundFinalVoucherV2:()=>Nt,signVoucher:()=>It,tabFromGrant:()=>Kn,voucherPayloadMessage:()=>T.voucherPayloadMessage,voucherToHeader:()=>st,voucherV2SequenceOrdinal:()=>T.voucherV2SequenceOrdinal});module.exports=dr(no);var ge=class extends Error{constructor(n){super(`Network ${n} is not yet supported by @dexterai/x402/tab`);this.network=n;this.name="UnsupportedNetworkError"}network},Y=class extends Error{constructor(n){super(`native_tab_v1_migration_required: @dexterai/x402 v6 cannot safely arm or reconstruct a buyer-side V1 tab through ${n}; settle or revoke the historical session through the deployment that originally opened it, then create a context-bound V2 session`);this.surface=n;this.name="HistoricalV1MigrationRequiredError"}surface;code="native_tab_v1_migration_required"},he=class extends Error{constructor(n,r){super(`Session scope exceeded: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="SessionScopeExceededError"}reason},oe=class extends Error{constructor(n){super(`Tab ${n} is already closed`);this.channelId=n;this.name="TabClosedError"}channelId},Et=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"}details};var ie=require("@solana/web3.js"),ue=require("@noble/hashes/utils");var et=J(require("tweetnacl"),1),Qe=require("@solana/web3.js"),se=require("@dexterai/vault/messages"),bn=require("@dexterai/vault/session");var T=require("@dexterai/vault/messages");var wn=require("@noble/hashes/sha256");function vn(){let e=et.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function Pt(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function It(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);if(e.registration.length===188&&new DataView(e.registration.buffer,e.registration.byteOffset,e.registration.byteLength).getUint32(176,!0)>=2147483648)throw new Error("context-bound V2 sessions require signContextBoundFinalVoucherV2 and a durable reservation");let r=BigInt(t.cumulativeAmount),o=BigInt(e.scope.maxAmountAtomic);if(r>o)throw new Error(`voucher cumulative ${r} exceeds session cap ${o}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let a=(0,T.voucherPayloadMessage)({channelId:n,cumulativeAmount:r,sequenceNumber:t.sequenceNumber}),i=et.default.sign.detached(a,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:i}}var pr=/^[0-9a-f]{64}$/,fr=(1n<<64n)-1n;function Qt(e){return Buffer.from(e).toString("hex")}function gr(e){return Uint8Array.from(Buffer.from(e,"hex"))}function en(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r+=1)n|=(e[r]??0)^(t[r]??0);return n===0}function Nt(e){if(!pr.test(e.channelId)||e.sessionPublicKey.length!==32||e.sessionPrivateKey.length!==64||e.sessionRegistration.length!==188||!/^[1-9][0-9]*$/.test(e.cumulativeAmountAtomic))throw new Error("native_tab_v2_signing_input_invalid");let t=BigInt(e.cumulativeAmountAtomic);if(t>fr)throw new Error("native_tab_v2_cumulative_amount_invalid");let n=new Qe.PublicKey(e.programId),r=new Qe.PublicKey(e.vaultPda),o=new Qe.PublicKey(e.sessionPda),s=new Qe.PublicKey(e.seller),[a]=(0,bn.deriveSessionPda)(r,s,n);if(!o.equals(a))throw new Error("native_tab_v2_session_pda_mismatch");let i=e.sessionRegistration,c=new DataView(i.buffer,i.byteOffset,i.byteLength),l=c.getBigUint64(128,!0),m=c.getBigInt64(136,!0),f=c.getBigUint64(180,!0),d=e.nowUnixSeconds??Math.floor(Date.now()/1e3);if(!Number.isSafeInteger(d)||d<0)throw new Error("native_tab_v2_signing_time_invalid");if(!en(i,(0,se.sessionRegisterMessage)({programId:n,vaultPda:r,sessionPubkey:e.sessionPublicKey,maxAmount:l,expiresAt:m,allowedCounterparty:s,nonce:e.sessionNonce,maxRevolvingCapacity:f})))throw new Error("native_tab_v2_registration_identity_mismatch");if(l===0n||f===0n||f>l||m<=BigInt(d)||m>0x7fffffffffffffffn-604800n||t>l)throw new Error("native_tab_v2_registration_semantics_invalid");(0,se.sessionVoucherV2AuthorizationNonce)(e.sessionNonce);let u=et.default.sign.keyPair.fromSeed(e.sessionPrivateKey.subarray(0,32)),p=!1;try{p=en(u.publicKey,e.sessionPublicKey)&&en(e.sessionPrivateKey.subarray(32,64),e.sessionPublicKey)}finally{u.secretKey.fill(0)}if(!p)throw new Error("native_tab_v2_session_key_mismatch");let x=(0,se.finalVoucherV2Sequence)(e.sequenceOrdinal),y=(0,se.contextBoundVoucherV2Message)({programId:n,vaultPda:r,sessionPda:o,seller:s,sessionNonce:e.sessionNonce,channelId:gr(e.channelId),cumulativeAmount:t,sequenceNumber:x}),b=et.default.sign.detached(y,e.sessionPrivateKey);return{channelId:e.channelId,cumulativeAmount:e.cumulativeAmountAtomic,sequenceNumber:x,sessionPublicKey:Qt(e.sessionPublicKey),sessionSignature:Qt(b),sessionRegistration:Qt(i)}}function Sn(e){return ye(e.maxAmountAtomic)}function ye(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function Be(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),r=wn.sha256.create();return r.update(e.vaultPda.toBytes()),r.update(n),r.update(t),r.digest()}var nn=require("@noble/hashes/sha256"),Ae=require("@noble/hashes/utils"),_n=/^[0-9a-f]{64}$/,xn=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,hr=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,Vt="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",kt="dexter-native-tab-v2-reservation/v1",rn=`${kt}:`;function tn(e){if(e===null||typeof e=="string"||typeof e=="boolean")return e;if(typeof e=="number"){if(!Number.isFinite(e))throw new Error("canonical_non_finite_number");return e}if(typeof e=="bigint")return e.toString();if(Array.isArray(e))return e.map(tn);if(typeof e=="object")return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[n])=>t.localeCompare(n)).map(([t,n])=>[t,tn(n)]));throw new Error("canonical_value_unsupported")}function Rn(e){return JSON.stringify(tn(e))}function tt(e){if(e==="solana:mainnet"||e===Vt)return Vt;throw new Error("native_tab_v2_reservation_network_unsupported")}function nt(e){return(0,Ae.bytesToHex)((0,nn.sha256)(new TextEncoder().encode(Rn({channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,Ae.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,Ae.bytesToHex)(e.sessionSignature),sessionRegistration:(0,Ae.bytesToHex)(e.sessionRegistration)}))))}function Ue(e){let t=nt(e);return{voucherDigest:t,idempotencyKey:`native-tab-v2:${t}`}}function on(e){return(0,Ae.bytesToHex)((0,nn.sha256)(new TextEncoder().encode(Rn({contract:kt,network:tt(e.network),programId:e.programId,buyerSwigAddress:e.buyerSwigAddress,vaultPda:e.vaultPda,sessionPda:e.sessionPda,seller:e.seller,channelId:e.channelId,sessionNonce:e.sessionNonce,reservationAmountAtomic:e.reservationAmountAtomic,previousCumulativeAtomic:e.previousCumulativeAtomic,voucherDigest:e.voucherDigest,cumulativeAmountAtomic:e.cumulativeAmountAtomic,sequenceNumber:e.sequenceNumber}))))}function sn(e){let t=nt(e.voucher);return on({network:e.network,programId:e.programId,buyerSwigAddress:e.buyerSwigAddress,vaultPda:e.vaultPda,sessionPda:e.sessionPda,seller:e.seller,channelId:e.channelId,sessionNonce:e.sessionNonce,reservationAmountAtomic:e.reservationAmountAtomic,previousCumulativeAtomic:e.previousCumulativeAtomic,voucherDigest:t,cumulativeAmountAtomic:e.voucher.payload.cumulativeAmount,sequenceNumber:e.voucher.payload.sequenceNumber})}function Ot(e){return`${rn}${sn(e)}`}function $(e){throw new Error(`native_tab_v2_reservation_receipt_invalid:${e}`)}function Ct(e,t){(!Number.isSafeInteger(e)||e<0)&&$(t)}function ae(e,t){(!t||typeof t!="object")&&$("missing");let n=nt(e.voucher);(!_n.test(e.voucherDigest)||e.voucherDigest!==n)&&$("input_voucher_digest"),e.idempotencyKey!==`native-tab-v2:${n}`&&$("input_idempotency_identity");let r=BigInt(e.voucher.payload.cumulativeAmount),o=BigInt(e.previousCumulativeAtomic),s=BigInt(e.reservationAmountAtomic);(r<=o||r-o!==s||s<=0n)&&$("input_reservation_delta"),(e.voucher.payload.channelId!==e.channelId||(e.voucher.payload.sequenceNumber&2147483648)===0||(e.sessionNonce&2147483648)===0||e.voucher.sessionPublicKey.length!==32||e.voucher.sessionSignature.length!==64||e.voucher.sessionRegistration.length!==188)&&$("input_voucher_identity"),t.contract!=="dexter-native-tab-open-receipt/v1"&&t.contract!=="dexter-native-tab-open-receipt/v2"&&$("contract"),_n.test(t.operationId)||$("operation_id"),xn.test(t.callerOperationId)||$("caller_operation_id"),hr.test(t.transaction)||$("transaction"),t.commitment!=="finalized"&&$("commitment"),Ct(t.confirmationSlot,"confirmation_slot"),Ct(t.postStateSlot,"post_state_slot"),(t.confirmationSlot===0||t.postStateSlot<t.confirmationSlot)&&$("post_state_slot");let a,i;try{a=tt(e.network),i=tt(t.network)}catch{return $("network")}(i!==a||t.buyerSwigAddress!==e.buyerSwigAddress||t.vaultPda!==e.vaultPda||t.sessionPda!==e.sessionPda||t.seller!==e.seller||t.channelId!==e.channelId||t.sessionPublicKey!==(0,Ae.bytesToHex)(e.voucher.sessionPublicKey)||t.voucherDigest!==n||t.cumulativeAmountAtomic!==e.voucher.payload.cumulativeAmount||t.sequenceNumber!==e.voucher.payload.sequenceNumber||!xn.test(t.providerReceiptId)||t.reservationAmountAtomic!==e.reservationAmountAtomic||t.currentOutstandingBeforeAtomic!=="0"||t.currentOutstandingAfterAtomic!==e.reservationAmountAtomic)&&$("economic_identity"),Ct(t.pendingVoucherCountBefore,"pending_voucher_count_before"),Ct(t.pendingVoucherCountAfter,"pending_voucher_count_after"),t.contract==="dexter-native-tab-open-receipt/v1"?t.callerOperationId!==e.idempotencyKey&&$("idempotency_key"):(t.rootOperationId!==e.idempotencyKey||!Number.isSafeInteger(t.generation)||Number(t.generation)<2||!t.predecessorCallerOperationId||!t.predecessorLifecycleOperationId||!t.predecessorReleaseDigest||!t.stableReservationId||!t.economicEffectDigest)&&$("successor_identity")}var Tn=require("@dexterai/vault/session");var be=require("@dexterai/vault/instructions"),an=require("@dexterai/vault/precompile"),q=require("@dexterai/vault/constants");var yr=3600,ot="https://x402.dexter.cash",En=6;function ce(e,t=En){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[n,r=""]=e.split(".");if(r.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let o=r.padEnd(t,"0"),s=`${n}${o}`.replace(/^0+(?=\d)/,"");return s===""?"0":s}function ve(e,t=En){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let n=e.padStart(t+1,"0"),r=n.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",o=n.slice(-t).replace(/0+$/,"");return o?`${r}.${o}`:r}var rt=class{channelId;voucherVersion;network;counterparty;internals;initialCumulativeAtomic;cumulativeAtomic;sequenceNumber;isFinalV2;closed=!1;operationInFlight=null;lastSignedVoucher=null;previousSignedVoucher=null;constructor(t){if(this.internals=t,this.channelId=t.channelIdHex,this.network=t.network,this.counterparty=t.counterparty,this.initialCumulativeAtomic=t.initialCumulativeAtomic??0n,this.cumulativeAtomic=this.initialCumulativeAtomic,this.sequenceNumber=t.initialSequenceOrdinal??0,this.isFinalV2=Pn(t.session),this.voucherVersion=this.isFinalV2?2:1,this.isFinalV2!==!!t.beforeVoucherRelease)throw new Error(this.isFinalV2?"native_tab_v2_reservation_fence_required":"native_tab_v1_must_not_use_v2_reservation_fence")}get state(){let t=this.internals.totalCapAtomic-this.cumulativeAtomic,n=Math.floor(Date.now()/1e3);return{isOpen:!this.closed,spent:ve(this.cumulativeAtomic.toString()),remaining:ve(t.toString()),expiresInSec:Math.max(0,this.internals.expiresAtUnix-n)}}async signNextVoucher(t){this.beginOperation("voucher");try{return await this.signNextVoucherExclusive(t)}finally{this.endOperation("voucher")}}async signNextVoucherExclusive(t){if(this.closed)throw new oe(this.channelId);let n=BigInt(t);if(n<=0n)throw new Error(`voucher increment must be > 0, got ${t}`);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 o=this.sequenceNumber+1,s={channelId:this.channelId,cumulativeAmount:r.toString(),sequenceNumber:o},a=await this.internals.vault.signWithSession(this.internals.session,s);if(a.payload.channelId!==s.channelId||a.payload.cumulativeAmount!==s.cumulativeAmount||(this.isFinalV2?(a.payload.sequenceNumber&2147483647)!==o||(a.payload.sequenceNumber&2147483648)===0:a.payload.sequenceNumber!==o))throw new Error("tab_signer_returned_unexpected_voucher");return this.internals.beforeVoucherRelease&&await this.internals.beforeVoucherRelease({voucher:a,incrementAtomic:n.toString(),previousCumulativeAtomic:this.cumulativeAtomic.toString()}),this.previousSignedVoucher=this.lastSignedVoucher,this.lastSignedVoucher=a,this.sequenceNumber=o,this.cumulativeAtomic=r,a}beginOperation(t){if(this.operationInFlight!==null)throw new Error(`tab_operation_in_flight: ${this.operationInFlight}`);this.operationInFlight=t}endOperation(t){if(this.operationInFlight!==t)throw new Error("tab_operation_gate_corrupted");this.operationInFlight=null}rollbackVoucher(t){if(this.isFinalV2||this.operationInFlight!==null)return!1;this.beginOperation("rollback");try{return this.rollbackVoucherExclusive(t)}finally{this.endOperation("rollback")}}rollbackVoucherExclusive(t){let n=this.lastSignedVoucher;if(!n||n.payload.sequenceNumber!==t.payload.sequenceNumber||n.payload.cumulativeAmount!==t.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(t,n){if(this.closed)throw new oe(this.channelId);let r=await this.signNextVoucher(this.internals.perUnitCapAtomic.toString()),o=new Headers(n?.headers);o.set("X-Tab-Voucher",st(r)),o.set("Accept","text/event-stream");let s=await fetch(t,{...n,headers:o});if(!s.ok){let a=await s.text().catch(()=>"");throw new Error(`tab.stream HTTP ${s.status}: ${a.slice(0,500)}`)}if(!s.body)throw new Error("tab.stream response has no body");return Sr(s.body)}async close(){this.beginOperation("close");try{if(this.closed)throw new oe(this.channelId);let t={settleTx:""};this.lastSignedVoucher&&this.cumulativeAtomic>0n&&(t=await br(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:ve(this.cumulativeAtomic.toString()),sessionRevoked:n,...t}}finally{this.endOperation("close")}}};function Pn(e){return e.registration.length!==188?!1:(new DataView(e.registration.buffer,e.registration.byteOffset,e.registration.byteLength).getUint32(176,!0)&2147483648)!==0}function st(e){return Buffer.from(JSON.stringify({payload:e.payload,sessionPublicKey:(0,ue.bytesToHex)(e.sessionPublicKey),sessionRegistration:(0,ue.bytesToHex)(e.sessionRegistration),sessionSignature:(0,ue.bytesToHex)(e.sessionSignature)}),"utf8").toString("base64")}function De(e){return typeof e!="string"||!/^\d+$/.test(e)?null:BigInt(e)}function Ar(e){let t;try{t=JSON.parse(e)}catch{return!1}if(typeof t!="object"||t===null)return!1;let n="non_monotonic_cumulative";if(t.error!==n&&t.reason!==n)return!1;let r=De(t.attempted_cumulative),o=De(t.on_chain_spent),s=De(t.frontier);return r===null||o===null||s===null?!1:r>o&&r<=s}async function br(e,t,n){let r=`${e.replace(/\/$/,"")}/tab/settle`,o={channelId:t.payload.channelId,cumulativeAmount:t.payload.cumulativeAmount,sequenceNumber:t.payload.sequenceNumber,sessionPublicKey:(0,ue.bytesToHex)(t.sessionPublicKey),sessionSignature:(0,ue.bytesToHex)(t.sessionSignature),sessionRegistration:(0,ue.bytesToHex)(t.sessionRegistration),network:n},s=await fetch(r,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(o)}),a=await s.text();if(!s.ok){if(s.status===409&&Ar(a))return{settleTx:""};throw new Error(`tab settle ${s.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 l=De(i.attemptedCumulative),m=De(i.onChainSpent),f=De(i.frontier);if(l!==null&&m!==null&&f!==null&&l>m&&l<=f)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 In(e,t,n,r,o){throw new Y("armTabOpen")}async function Bt(e){if(e.network!==e.vault.network)throw new ge(`options.network (${e.network}) doesn't match vault.network (${e.vault.network})`);if(e.network!=="solana:mainnet")throw new ge(e.network);if(e.vault.sessionVoucherVersion!==1&&e.vault.sessionVoucherVersion!==2)throw new Error("native_tab_adapter_voucher_version_required");if(e.vault.sessionVoucherVersion===1)throw new Y("openTab");if(e.vault.sessionVoucherVersion===2&&(!e.reserveFinalVoucherV2||!e.vault.verifyFinalVoucherV2Reservation))throw new Error("native_tab_v2_reservation_fence_required");let t=BigInt(Math.floor(Math.random()*4294967295)),n=new ie.PublicKey(e.vault.vaultPda),r=Be({vaultPda:n,sellerUrl:e.seller,nonce:BigInt(t)}),o=(0,ue.bytesToHex)(r),s=BigInt(ce(e.perUnitCap)),a=BigInt(ce(e.totalCap));if(s<=0n)throw new Error("perUnitCap must be > 0");if(a<s)throw new Error("totalCap must be >= perUnitCap");if(e.revolvingCapacity!==void 0&&BigInt(ce(e.revolvingCapacity))<=0n)throw new Error("revolvingCapacity must be > 0");let i=e.sessionDuration??yr,c=Math.floor(Date.now()/1e3)+i,l=vr(e.seller),m={channelId:o,maxAmountAtomic:a.toString(),revolvingCapacityAtomic:e.revolvingCapacity?ce(e.revolvingCapacity):a.toString(),expiresAtUnix:c,allowedCounterparty:l},f=await e.vault.authorizeSession(m,{onLiveSession:e.onLiveSession}),d=Pn(f);if(e.vault.sessionVoucherVersion!==(d?2:1))throw new Error("native_tab_adapter_voucher_version_mismatch");let S;if(d){if(!e.reserveFinalVoucherV2)throw new Error("native_tab_v2_reservation_fence_required");let u=f.registration,p=new DataView(u.buffer,u.byteOffset,u.byteLength),x=new ie.PublicKey(u.subarray(32,64)),y=new ie.PublicKey(u.subarray(64,96)),b=new ie.PublicKey(u.subarray(144,176)),_=p.getUint32(176,!0),k=p.getBigUint64(180,!0),V=(0,T.sessionRegisterMessage)({programId:q.DEXTER_VAULT_PROGRAM_ID,vaultPda:n,sessionPubkey:f.publicKey,maxAmount:a,expiresAt:BigInt(c),allowedCounterparty:new ie.PublicKey(l),nonce:_,maxRevolvingCapacity:BigInt(m.revolvingCapacityAtomic)});if(!x.equals(q.DEXTER_VAULT_PROGRAM_ID)||!y.equals(n)||!b.equals(new ie.PublicKey(l))||k!==BigInt(m.revolvingCapacityAtomic)||!Buffer.from(u).equals(Buffer.from(V)))throw new Error("native_tab_v2_registration_identity_mismatch");let[W]=(0,Tn.deriveSessionPda)(y,b,x);S=async({voucher:L,incrementAtomic:P,previousCumulativeAtomic:C})=>{let h=Ue(L),v={network:e.network,programId:x.toBase58(),buyerSwigAddress:e.vault.swigAddress,vaultPda:y.toBase58(),sessionPda:W.toBase58(),seller:b.toBase58(),channelId:o,sessionNonce:_,reservationAmountAtomic:P,previousCumulativeAtomic:C,...h,voucher:L},w=await e.reserveFinalVoucherV2(v);ae(v,w),await e.vault.verifyFinalVoucherV2Reservation(v,w)}}return new rt({vault:e.vault,network:e.network,seller:e.seller,counterparty:l,session:f,channelIdHex:o,channelIdBytes:r,perUnitCapAtomic:s,totalCapAtomic:a,expiresAtUnix:c,facilitatorUrl:e.facilitatorUrl??ot,beforeVoucherRelease:S})}async function Nn(e){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 vr(e){if(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(e))try{return new ie.PublicKey(e),e}catch{}throw new Error(`seller must be a base58 Solana pubkey for Phase 2 (got "${e}"). URL-based counterparty resolution lands in Phase 3 (seller middleware).`)}async function*Sr(e){let t=e.getReader(),n=new TextDecoder,r="";try{for(;;){let{done:o,value:s}=await t.read();if(o)break;r+=n.decode(s,{stream:!0});let a;for(;(a=r.indexOf(`
|
|
2
2
|
|
|
3
|
-
`))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=
|
|
4
|
-
`:"\\");yield new TextEncoder().encode(
|
|
5
|
-
`))r.startsWith("event:")?
|
|
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});
|
|
3
|
+
`))!==-1;){let i=r.slice(0,a);r=r.slice(a+2);let c=wr(i);if(c.eventName==="end")return;if(c.data!==null){let l=c.data.replace(/\\(\\|n)/g,(m,f)=>f==="n"?`
|
|
4
|
+
`:"\\");yield new TextEncoder().encode(l)}}}}finally{t.releaseLock()}}function wr(e){let t=null,n=[];for(let r of e.split(`
|
|
5
|
+
`))r.startsWith("event:")?t=r.slice(6).trim():r.startsWith("data:")&&n.push(r.slice(5).trimStart());return{eventName:t,data:n.length?n.join(`
|
|
6
|
+
`):null}}var Le=J(require("tweetnacl"),1),le=require("@solana/web3.js"),Un=require("@noble/hashes/utils"),$e=require("@dexterai/vault/session"),Dn=require("@dexterai/vault/messages"),Mn=require("@dexterai/vault/reader");var Z=require("@solana/web3.js"),Dt=require("@noble/hashes/utils"),Ke=require("@dexterai/vault/credit"),Mt=require("@dexterai/vault/constants"),Cn=require("@dexterai/vault/instructions"),Vn=require("@dexterai/vault/reader"),Fe=require("@dexterai/vault/session");var _r=Uint8Array.from([56,67,4,209,238,143,0,129]),xr=74,kn=new Set([1,2]),Rr=188,Tr=new Z.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),Er=(()=>{let e=Buffer.alloc(32);return e.write("OTS_SESSION_REGISTER_V2","ascii"),e})(),cn=class extends Error{constructor(n,r){super(`native_tab_v2_solana_reservation_invalid:${n}`+(r?`:${r}`:""));this.code=n;this.name="SolanaFinalVoucherV2ReservationError"}code};function A(e,t){throw new cn(e,t)}function H(e,t){try{return new Z.PublicKey(e)}catch{return A(t)}}function Ut(e,t){return e.length===t.length&&e.every((n,r)=>n===t[r])}async function Pr(e){let t=await e.connection.getTransaction(e.signature,{commitment:e.commitment,maxSupportedTransactionVersion:0});if(!t)return null;t.meta||A("transaction_meta_missing");let n=t.transaction.message,r=n.version===0?n.getAccountKeys({accountKeysFromLookups:t.meta.loadedAddresses??null}):n.getAccountKeys(),o=(s,a)=>{let i=r.get(s);return i||A(a),i};return{slot:t.slot,err:t.meta.err,signatures:[...t.transaction.signatures],accountKeys:Array.from({length:r.length},(s,a)=>({address:o(a,"transaction_account_key").toBase58(),signer:n.isAccountSigner(a),writable:n.isAccountWritable(a)})),instructions:n.compiledInstructions.map(s=>({programId:o(s.programIdIndex,"transaction_program_id").toBase58(),accounts:s.accountKeyIndexes.map(a=>o(a,"transaction_instruction_account").toBase58()),data:Uint8Array.from(s.data)}))}}function Ir(e,t,n,r){r.length!==xr&&A("binding_length"),Ut(r.subarray(0,8),_r)||A("binding_discriminator");let o=r.readUInt8(8),s=r.readUInt8(9);return kn.has(o)||A("binding_version"),s!==t&&A("binding_bump"),{address:e.toBase58(),owner:n.toBase58(),version:o,bump:s,swig:new Z.PublicKey(r.subarray(10,42)).toBase58(),vault:new Z.PublicKey(r.subarray(42,74)).toBase58()}}async function Nr(e){let t=H(e.input.programId,"program_id"),n=H(e.input.buyerSwigAddress,"buyer_swig"),r=H(e.input.vaultPda,"vault_pda"),o=H(e.input.seller,"seller"),[s,a]=(0,Ke.deriveSwigVaultBindingPda)(n,t),[i]=(0,Fe.deriveSessionPda)(r,o,t),c=await e.connection.getMultipleAccountsInfoAndContext([s,r,i],{commitment:e.receipt.commitment,minContextSlot:e.receipt.postStateSlot}),[l,m,f]=c.value;l||A("binding_missing"),m||A("vault_missing"),f||A("session_missing");let d,S;try{d=(0,Vn.decodeVaultFull)(Buffer.from(m.data)),S=(0,Fe.decodeSessionAccount)(i,f.data)}catch(p){return A("post_state_decode",p instanceof Error?p.message:String(p))}let u=S.session;return{contextSlot:c.context.slot,binding:Ir(s,a,l.owner,Buffer.from(l.data)),vault:{owner:m.owner.toBase58(),exists:d.exists,version:d.version,swigAddress:d.swigAddress,dexterAuthority:d.dexterAuthority,pendingVoucherCount:d.pendingVoucherCount},session:{owner:f.owner.toBase58(),version:S.version,bump:S.bump,vault:S.vault,sessionPublicKey:(0,Dt.bytesToHex)(u.sessionPubkey),maxAmount:u.maxAmount,expiresAt:u.expiresAt,seller:u.allowedCounterparty,nonce:u.nonce,spent:u.spent,currentOutstanding:u.currentOutstanding,maxRevolvingCapacity:u.maxRevolvingCapacity,crystallizedCumulative:u.crystallizedCumulative}}}function Cr(e){let t=Buffer.from(e.voucher.sessionRegistration);return t.length!==Rr&&A("registration_length"),Ut(t.subarray(0,32),Er)||A("registration_domain"),{programId:new Z.PublicKey(t.subarray(32,64)).toBase58(),vaultPda:new Z.PublicKey(t.subarray(64,96)).toBase58(),sessionPublicKey:(0,Dt.bytesToHex)(t.subarray(96,128)),maxAmount:t.readBigUInt64LE(128),expiresAt:t.readBigInt64LE(136),seller:new Z.PublicKey(t.subarray(144,176)).toBase58(),nonce:t.readUInt32LE(176),maxRevolvingCapacity:t.readBigUInt64LE(180)}}function Me(e,t,n){let r=e.accountKeys.filter(o=>o.address===t);return r.length!==1&&A(`${n}_account_key`),r[0]}function Vr(e,t,n){(!Number.isSafeInteger(n.slot)||n.slot<=0)&&A("transaction_slot"),n.slot!==t.confirmationSlot&&A("transaction_confirmation_slot"),n.err!==null&&A("transaction_failed"),n.signatures[0]!==t.transaction&&A("transaction_signature"),n.instructions.length!==2&&A("transaction_instruction_count");let r=H(e.programId,"program_id"),o=H(e.buyerSwigAddress,"buyer_swig"),s=H(e.vaultPda,"vault_pda"),a=H(e.seller,"seller"),i=H(e.sessionPda,"session_pda"),[c]=(0,Fe.deriveSessionPda)(s,a,r),l=(0,Ke.deriveSwigVaultBindingPda)(o,r)[0],m=(0,Cn.deriveSwigWalletAddress)(o),f=(0,Ke.deriveGraphConfigPda)(r)[0];i.equals(c)||A("session_pda_derivation");let d=Buffer.from(Mt.DISCRIMINATORS.settle_voucher),S=n.instructions.filter(P=>{if(P.programId!==e.programId)return!1;let C=P.data;return C.length>=d.length&&Ut(C.subarray(0,d.length),d)});S.length!==1&&A("settle_voucher_instruction_count");let u=S[0];n.instructions[0]!==u&&A("settle_voucher_instruction_order");let p=Buffer.from(u.data);p.length!==49&&A("settle_voucher_instruction_length"),p.readBigUInt64LE(8).toString()!==e.reservationAmountAtomic&&A("settle_voucher_amount"),p.readUInt8(16)!==1&&A("settle_voucher_increment"),new Z.PublicKey(p.subarray(17,49)).equals(a)||A("settle_voucher_seller"),u.accounts.length<8&&A("settle_voucher_accounts"),[s.toBase58(),null,i.toBase58(),null,o.toBase58(),m.toBase58(),l.toBase58(),f.toBase58()].forEach((P,C)=>{P!==null&&u.accounts[C]!==P&&A(`settle_voucher_account_${C}`)});let y=u.accounts[1];y||A("dexter_authority");let b=Me(n,u.accounts[0],"vault"),_=Me(n,y,"dexter_authority"),k=Me(n,u.accounts[2],"session");(!b.writable||b.signer)&&A("vault_privileges"),_.signer||A("dexter_authority_signature"),(!k.writable||k.signer)&&A("session_privileges");for(let P=3;P<Math.min(u.accounts.length,8);P+=1)Me(n,u.accounts[P],`account_${P}`).signer&&A(`settle_voucher_account_${P}_signer`);for(let P=8;P<u.accounts.length;P+=1){let C=Me(n,u.accounts[P],`sibling_${P-8}`);(!C.writable||C.signer)&&A("settle_voucher_sibling_privileges")}let V=n.instructions[1];V.programId!==Tr.toBase58()&&A("reservation_memo_program"),(V.accounts.length!==1||V.accounts[0]!==y)&&A("reservation_memo_authority"),Me(n,y,"reservation_memo_authority").signer||A("reservation_memo_authority_signature");let L=new TextEncoder().encode(Ot(e));return Ut(V.data,L)||A("reservation_memo_digest"),y}function kr(e,t,n,r){let o=H(e.programId,"program_id"),s=H(e.buyerSwigAddress,"buyer_swig"),a=H(e.vaultPda,"vault_pda"),i=H(e.seller,"seller"),[c,l]=(0,Ke.deriveSwigVaultBindingPda)(s,o),[m,f]=(0,Fe.deriveSessionPda)(a,i,o);(!Number.isSafeInteger(r.contextSlot)||r.contextSlot<t.postStateSlot||r.contextSlot<t.confirmationSlot)&&A("post_state_slot"),(r.binding.address!==c.toBase58()||r.binding.owner!==e.programId||r.binding.bump!==l||!kn.has(r.binding.version)||r.binding.swig!==e.buyerSwigAddress||r.binding.vault!==e.vaultPda)&&A("binding_identity"),(r.vault.owner!==e.programId||!r.vault.exists||r.vault.version!==7||r.vault.swigAddress!==e.buyerSwigAddress||r.vault.dexterAuthority!==n)&&A("vault_post_state"),(e.sessionPda!==m.toBase58()||r.session.owner!==e.programId||r.session.version!==1||r.session.bump!==f||r.session.vault!==e.vaultPda||r.session.sessionPublicKey!==(0,Dt.bytesToHex)(e.voucher.sessionPublicKey)||r.session.seller!==e.seller||r.session.nonce!==e.sessionNonce||r.session.currentOutstanding.toString()!==e.reservationAmountAtomic)&&A("session_post_state");let d=Cr(e);(d.programId!==e.programId||d.vaultPda!==e.vaultPda||d.sessionPublicKey!==r.session.sessionPublicKey||d.seller!==e.seller||d.nonce!==e.sessionNonce||d.maxAmount!==r.session.maxAmount||d.expiresAt!==BigInt(r.session.expiresAt)||d.maxRevolvingCapacity!==r.session.maxRevolvingCapacity)&&A("registration_post_state"),(r.session.spent>r.session.crystallizedCumulative?r.session.spent:r.session.crystallizedCumulative).toString()!==e.previousCumulativeAtomic&&A("session_frontier")}async function On(e,t,n,r={}){try{ae(t,n)}catch(i){return A("provider_receipt",i instanceof Error?i.message:String(i))}t.network!=="solana:mainnet"&&A("network"),t.programId!==Mt.DEXTER_VAULT_PROGRAM_ID.toBase58()&&A("program_id");let o=await(r.readTransaction??Pr)({connection:e,signature:n.transaction,commitment:n.commitment});o||A("transaction_missing");let s=Vr(t,n,o),a=await(r.readPostState??Nr)({connection:e,input:t,receipt:n});kr(t,n,s,a)}var un="solana:mainnet";async function Kn(e){let t=e.facilitatorUrl??ot,n=e.programId??q.DEXTER_VAULT_PROGRAM_ID,r=new le.PublicKey(e.vaultPda),o=new le.PublicKey(e.params.counterparty),s=ye(e.perUnitCapAtomic);if(s<=0n)throw new Error(`perUnitCapAtomic must be > 0, got ${e.perUnitCapAtomic}`);let a=ye(e.params.maxAmountAtomic),i=ye(e.params.maxRevolvingCapacityAtomic),c=(e.params.nonce&2147483648)!==0;if(!c)throw new Y("tabFromGrant");if(c&&!e.reserveFinalVoucherV2)throw new Error("native_tab_v2_reservation_fence_required: provide reserveFinalVoucherV2; a FINAL voucher may not be released before its exact durable reservation");let l=Or(e.sessionSecretKey),m=new le.PublicKey(e.params.sessionPubkey).toBytes();if(!Bn(l.publicKey,m))throw new Error(`tab_session_key_mismatch: the supplied secret derives ${new le.PublicKey(l.publicKey).toBase58()} but params.sessionPubkey is ${e.params.sessionPubkey} \u2014 wrong key handed to this process`);let f=Le.default.randomBytes(32),d=Le.default.sign.detached(f,l.secretKey);if(!Le.default.sign.detached.verify(f,d,m))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 S=(0,T.sessionRegisterMessage)({programId:n,vaultPda:r,sessionPubkey:l.publicKey,maxAmount:a,expiresAt:BigInt(e.params.expiresAtUnix),allowedCounterparty:o,nonce:e.params.nonce,maxRevolvingCapacity:i}),u=typeof e.connection=="string"?new le.Connection(e.connection,"confirmed"):e.connection,p=await(0,$e.fetchSessionAccount)(u,r,o,n);if(!p||p.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,$e.isSessionLive)(p))throw new Error(p.version!==1?`tab_session_not_live: SessionAccount has unsupported version ${p.version} \u2014 not a live v1 session`:`tab_session_not_live: SessionAccount is present but expired (expiresAt=${p.session.expiresAt})`);if(!Bn(p.session.sessionPubkey,l.publicKey))throw new Error(`tab_session_pubkey_mismatch: the on-chain session carries ${new le.PublicKey(p.session.sessionPubkey).toBase58()} \u2014 the grant this key belongs to was replaced by a newer registration`);if(p.vault!==r.toBase58()||p.session.allowedCounterparty!==o.toBase58()||p.session.maxAmount!==a||p.session.expiresAt!==e.params.expiresAtUnix||p.session.nonce!==e.params.nonce||p.session.maxRevolvingCapacity!==i)throw new Error(`tab_grant_params_stale: params disagree with the on-chain session scope (chain: maxAmount=${p.session.maxAmount} expiresAt=${p.session.expiresAt} nonce=${p.session.nonce} revolving=${p.session.maxRevolvingCapacity}; params: ${e.params.maxAmountAtomic}/${e.params.expiresAtUnix}/${e.params.nonce}/${e.params.maxRevolvingCapacityAtomic}) \u2014 refresh the grant hand-off`);if(c&&p.session.currentOutstanding!==0n)throw new Error(`native_tab_v2_reservation_pending: the session already has an exact outstanding reservation of ${p.session.currentOutstanding}; recover that immutable attempt before issuing another FINAL voucher`);let x=p.session.spent>p.session.crystallizedCumulative?p.session.spent:p.session.crystallizedCumulative;if(x>=a)throw new Error(`tab_exhausted: on-chain frontier ${x} has consumed the session cap ${a} \u2014 no voucher can strictly exceed it; open a new grant`);let y=e.sellerUrl??e.params.counterparty,b=BigInt(Math.floor(Math.random()*4294967295)),_=Be({vaultPda:r,sellerUrl:y,nonce:b}),k=(0,Un.bytesToHex)(_),V=e.swigAddress;if(!V){let h=await(0,Mn.readVaultFull)(u,r);if(!h.exists||!h.swigAddress)throw new Error(`tab_vault_unreadable: vault ${r.toBase58()} has no readable swig_address on chain \u2014 pass options.swigAddress explicitly`);V=h.swigAddress}let W={channelId:k,maxAmountAtomic:e.params.maxAmountAtomic,revolvingCapacityAtomic:e.params.maxRevolvingCapacityAtomic,expiresAtUnix:e.params.expiresAtUnix,allowedCounterparty:e.params.counterparty},L=Pt({publicKey:l.publicKey,privateKey:l.secretKey},W,S),[P]=(0,$e.deriveSessionPda)(r,o,n),C={network:un,swigAddress:V,vaultPda:r.toBase58(),sessionVoucherVersion:c?2:1,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(h,v)=>{if(!c)return It(h,v,_);let w=Nt({programId:n.toBase58(),vaultPda:r.toBase58(),sessionPda:P.toBase58(),seller:o.toBase58(),sessionNonce:e.params.nonce,channelId:v.channelId,cumulativeAmountAtomic:v.cumulativeAmount,sequenceOrdinal:v.sequenceNumber,sessionPrivateKey:h.privateKey,sessionPublicKey:h.publicKey,sessionRegistration:h.registration});return{payload:{channelId:w.channelId,cumulativeAmount:w.cumulativeAmount,sequenceNumber:w.sequenceNumber},sessionPublicKey:Uint8Array.from(Buffer.from(w.sessionPublicKey,"hex")),sessionSignature:Uint8Array.from(Buffer.from(w.sessionSignature,"hex")),sessionRegistration:Uint8Array.from(Buffer.from(w.sessionRegistration,"hex"))}},signOpenTab:async h=>h.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")},verifyFinalVoucherV2Reservation:c?(h,v)=>On(u,h,v):void 0};return new rt({vault:C,network:un,seller:y,counterparty:e.params.counterparty,session:L,channelIdHex:k,channelIdBytes:_,perUnitCapAtomic:s,totalCapAtomic:a,expiresAtUnix:e.params.expiresAtUnix,facilitatorUrl:t,initialCumulativeAtomic:x,initialSequenceOrdinal:c&&p.session.lastLockedSequence!==0?(0,Dn.voucherV2SequenceOrdinal)(p.session.lastLockedSequence):0,beforeVoucherRelease:c?async({voucher:h,incrementAtomic:v,previousCumulativeAtomic:w})=>{let R=Ue(h),E={network:un,programId:n.toBase58(),buyerSwigAddress:V,vaultPda:r.toBase58(),sessionPda:P.toBase58(),seller:o.toBase58(),channelId:k,sessionNonce:e.params.nonce,reservationAmountAtomic:v,previousCumulativeAtomic:w,...R,voucher:h},N=await e.reserveFinalVoucherV2(E);ae(E,N),await C.verifyFinalVoucherV2Reservation(E,N)}:void 0,closeMode:"settle-only"})}function Or(e){if(e.length===64)return Le.default.sign.keyPair.fromSecretKey(e);if(e.length===32)return Le.default.sign.keyPair.fromSeed(e);throw new Error(`tab_session_key_invalid: expected a 64-byte nacl secretKey or a 32-byte ed25519 seed, got ${e.length} bytes`)}function Bn(e,t){if(e.length!==t.length)return!1;let n=0;for(let r=0;r<e.length;r++)n|=e[r]^t[r];return n===0}var Ln=require("@solana/web3.js");var Fn=[{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"}],Br=new Map(Fn.map(e=>[e.caip2.toLowerCase(),e])),Ur=new Map(Fn.map(e=>[e.bare.toLowerCase(),e]));function at(e){if(!e)return null;let t=e.toLowerCase(),n=Br.get(t)||Ur.get(t);return n?{caip2:n.caip2,bare:n.bare,family:n.family}:null}function ln(e){let t=e.replace(/-/g,"+").replace(/_/g,"/"),n=t+"=".repeat((4-(t.length%4||4))%4);return JSON.parse(Buffer.from(n,"base64").toString("utf8"))}function Dr(e){let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n,o=at(String(r.network??""));o&&t.push({scheme:String(r.scheme??"exact"),network:o,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 t}async function Kt(e){let t=e.headers.get("payment-required");if(!t)return null;let n;try{n=ln(t)}catch{return null}let r=Array.isArray(n.accepts)?n.accepts:[];return r.length===0?null:{x402Version:2,options:Dr(r),resourceUrl:n.resource&&typeof n.resource=="object"?String(n.resource.url??""):void 0}}async function qe(e,t={},n=fetch){let r={method:t.method??"GET",headers:t.headers};typeof t.body=="string"&&(r.body=t.body);let o;try{o=await n(e,r)}catch(i){return{kind:"error",detail:`probe failed: ${i?.message??String(i)}`}}if(o.status!==402)return o.ok?{kind:"free",response:o}:{kind:"error",detail:`probe returned HTTP ${o.status}`};let s=await Kt(o);if(!s)return{kind:"error",detail:"the 402 carries no x402 v2 PAYMENT-REQUIRED challenge"};let a=s.options.find(i=>i.scheme==="tab"&&i.network.family==="svm");if(!a)return{kind:"no_tab",schemesOffered:s.options.map(i=>i.scheme)};try{new Ln.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,...typeof a.extra?.voucherHeader=="string"?{voucherHeader:a.extra.voucherHeader}:{},...typeof a.extra?.registrationEncoding=="string"?{registrationEncoding:a.extra.registrationEncoding}:{},...typeof a.extra?.termsVersion=="string"?{termsVersion:a.extra.termsVersion}:{},...typeof a.extra?.acceptanceRule=="string"?{acceptanceRule:a.extra.acceptanceRule}:{},resourceUrl:s.resourceUrl}}}var $n="dexter-tab-hosted-pay-before-delivery/v1",qn="pay_before_delivery_seller_2xx",Wn="x-tab-voucher",Hn="base64(188-byte sessionRegisterMessage)";var it="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ft="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",Lt="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z",Se=it,ct=Ft,ut=Lt,we="eip155:8453",We="eip155:84532",He="eip155:42161",je="eip155:137",Ge="eip155:10",ze="eip155:43114",Xe="eip155:56",_e="eip155:480",xe="eip155:143",Re="eip155:4663",Te="eip155:1187947933",Ee="eip155:324705682",Je="eip155:1",Pe=we,$t=We,lt=He,mt=je,dt=Ge,pt=ze,ft=Xe,gt=_e,ht=xe,yt=Re,At=Te,bt=Ee,vt=Je,St="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",jn="4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",Gn="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",mn="0x55d398326f99059fF775485246999027B3197955",qt="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",dn="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",Wt={[Xe]:qt,[we]:Gn,[We]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[He]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[je]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Ge]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[ze]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[_e]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[xe]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[Re]:dn,[Te]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Ee]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Je]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Ht={[mn]:{symbol:"USDT",decimals:18},[qt]:{symbol:"USDC",decimals:18}};var jt={[_e]:{name:"USDC",version:"2"},[xe]:{name:"USDC",version:"2"},[Re]:{name:"Global Dollar",version:"1"},[Te]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Ee]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}},me="0x000000000022D473030F116dDEE9F6B43aC78BA3",wt="0x402085c248EeA27D92E8b30b2C58ed07f9E20001",_t={[Xe]:56,[we]:8453,[We]:84532,[He]:42161,[je]:137,[Ge]:10,[ze]:43114,[_e]:480,[xe]:143,[Re]:4663,[Te]:1187947933,[Ee]:324705682,[Je]:1},Ie={[it]:"https://api.dexter.cash/api/solana/rpc",[Ft]:"https://api.devnet.solana.com",[Lt]:"https://api.testnet.solana.com"},F={[Xe]:"https://api.dexter.cash/api/evm/bsc/rpc",[we]:"https://api.dexter.cash/api/base/rpc",[We]:"https://sepolia.base.org",[He]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[je]:"https://api.dexter.cash/api/evm/polygon/rpc",[Ge]:"https://api.dexter.cash/api/evm/optimism/rpc",[ze]:"https://api.dexter.cash/api/evm/avalanche/rpc",[_e]:"https://worldchain-mainnet.g.alchemy.com/public",[xe]:"https://rpc.monad.xyz",[Re]:"https://rpc.mainnet.chain.robinhood.com",[Te]:"https://skale-base.skalenodes.com/v1/base",[Ee]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Je]:"https://eth.llamarpc.com"};var U=class e extends Error{code;details;constructor(t,n,r){super(n),this.name="X402Error",this.code=t,this.details=r,Object.setPrototypeOf(this,e.prototype)}};var D=require("@solana/web3.js"),M=require("@solana/spl-token");var Mr=12e3,Kr=1;function Ne(e){if(!e||typeof e!="object")return!1;let t=e;return"publicKey"in t&&"signTransaction"in t&&typeof t.signTransaction=="function"}var Gt=class{name="Solana";networks=[Se,ct,ut];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:solana]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="solana"||t==="solana-devnet"||t==="solana-testnet"||t.startsWith("solana:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:Ie[t]?Ie[t]:t==="solana"?Ie[Se]:t==="solana-devnet"?Ie[ct]:t==="solana-testnet"?Ie[ut]:Ie[Se]}getAddress(t){return Ne(t)?t.publicKey?.toBase58()??null:null}isConnected(t){return Ne(t)?t.publicKey!==null:!1}async getBalance(t,n,r){if(!Ne(n)||!n.publicKey)return 0;let o=r||this.getDefaultRpcUrl(t.network),s=new D.Connection(o,"confirmed"),a=new D.PublicKey(n.publicKey.toBase58()),i=new D.PublicKey(t.asset);try{let l=(await s.getAccountInfo(i,"confirmed"))?.owner.toBase58()===M.TOKEN_2022_PROGRAM_ID.toBase58()?M.TOKEN_2022_PROGRAM_ID:M.TOKEN_PROGRAM_ID,m=await(0,M.getAssociatedTokenAddress)(i,a,!1,l),f=await(0,M.getAccount)(s,m,void 0,l),d=t.extra?.decimals??6;return Number(f.amount)/Math.pow(10,d)}catch(c){if(c&&typeof c=="object"&&"name"in c&&(c.name==="TokenAccountNotFoundError"||c.name==="TokenInvalidAccountOwnerError"))return 0;throw c}}async buildTransaction(t,n,r){if(!Ne(n))throw new Error("Invalid Solana wallet");if(!n.publicKey)throw new Error("Wallet not connected");let o=r||this.getDefaultRpcUrl(t.network),s=new D.Connection(o,"confirmed"),a=new D.PublicKey(n.publicKey.toBase58()),{payTo:i,asset:c,extra:l}=t,m=t.amount??t.maxAmountRequired;if(!m)throw new Error("Missing amount in payment requirements");if(!l?.feePayer)throw new Error("Missing feePayer in payment requirements");let f=new D.PublicKey(l.feePayer),d=new D.PublicKey(c),S=new D.PublicKey(i);this.log("Building transaction:",{from:a.toBase58(),to:i,amount:m,asset:c,feePayer:l.feePayer});let u=[];u.push(D.ComputeBudgetProgram.setComputeUnitLimit({units:Mr})),u.push(D.ComputeBudgetProgram.setComputeUnitPrice({microLamports:Kr}));let p=await s.getAccountInfo(d,"confirmed");if(!p)throw new Error(`Token mint ${c} not found`);let x=p.owner.toBase58()===M.TOKEN_2022_PROGRAM_ID.toBase58()?M.TOKEN_2022_PROGRAM_ID:M.TOKEN_PROGRAM_ID,y=await(0,M.getMint)(s,d,void 0,x);typeof l?.decimals=="number"&&y.decimals!==l.decimals&&this.log(`Decimals mismatch: requirements say ${l.decimals}, mint says ${y.decimals}`);let b=await(0,M.getAssociatedTokenAddress)(d,a,!1,x),_=await(0,M.getAssociatedTokenAddress)(d,S,!0,x);if(!await s.getAccountInfo(b,"confirmed"))throw new Error(`No token account found for ${c}. Please ensure you have USDC in your wallet.`);if(!await s.getAccountInfo(_,"confirmed"))throw new Error(`Seller token account not found. The seller (${i}) must have a USDC account.`);let W=BigInt(m);u.push((0,M.createTransferCheckedInstruction)(b,d,_,a,W,y.decimals,[],x));let{blockhash:L}=await s.getLatestBlockhash("confirmed"),P=new D.TransactionMessage({payerKey:f,recentBlockhash:L,instructions:u}).compileToV0Message(),C=new D.VersionedTransaction(P),h=await n.signTransaction(C);return this.log("Transaction signed successfully"),{serialized:Buffer.from(h.serialize()).toString("base64"),settlementProbe:{kind:"solana",sourceAta:b.toBase58(),destinationAta:_.toBase58(),asset:c,amount:m,blockhash:L}}}async confirmSettlement(t,n){if(t.kind!=="solana")throw new Error(`SolanaAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`);let r=new D.Connection(n,"confirmed"),o=new D.PublicKey(t.destinationAta),s=await r.getSignaturesForAddress(o,{limit:25});if(s.length===0)return{settled:!1};let a=BigInt(t.amount);for(let i of s){if(i.err)continue;let c=await r.getTransaction(i.signature,{commitment:"confirmed",maxSupportedTransactionVersion:0});if(!c?.meta)continue;let l=c.transaction.message.getAccountKeys().keySegments().flat(),m=c.meta.preTokenBalances??[],f=c.meta.postTokenBalances??[];for(let d of f){if(d.mint!==t.asset)continue;let S=l[d.accountIndex];if(!S||!S.equals(o))continue;let u=m.find(y=>y.accountIndex===d.accountIndex),p=BigInt(u?.uiTokenAmount.amount??"0");if(BigInt(d.uiTokenAmount.amount??"0")-p===a)return{settled:!0,txSignature:i.signature}}}return{settled:!1}}};function de(e){return new Gt(e)}var Fr={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"}]},zn=BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");function Ce(e){if(!e||typeof e!="object")return!1;let t=e;return"address"in t&&typeof t.address=="string"&&t.address.startsWith("0x")}var zt=class{name="EVM";networks=[ft,Pe,$t,vt,lt,mt,dt,pt,gt,ht,yt,At,bt];config;log;constructor(t={}){this.config=t,this.log=t.verbose?console.log.bind(console,"[x402:evm]"):()=>{}}canHandle(t){return!!(this.networks.includes(t)||t==="base"||t==="bsc"||t==="ethereum"||t==="arbitrum"||t==="polygon"||t==="optimism"||t==="avalanche"||t==="world"||t==="monad"||t==="robinhood"||t==="skale-base"||t==="skale-base-sepolia"||t.startsWith("eip155:"))}getDefaultRpcUrl(t){return this.config.rpcUrls?.[t]?this.config.rpcUrls[t]:F[t]?F[t]:t==="base"?F[Pe]:t==="bsc"?F[ft]:t==="ethereum"?F[vt]:t==="arbitrum"?F[lt]:t==="polygon"?F[mt]:t==="optimism"?F[dt]:t==="avalanche"?F[pt]:t==="world"?F[gt]:t==="monad"?F[ht]:t==="robinhood"?F[yt]:t==="skale-base"?F[At]:t==="skale-base-sepolia"?F[bt]:F[Pe]}getAddress(t){return Ce(t)?t.address:null}isConnected(t){return Ce(t)?!!t.address:!1}getChainId(t){if(_t[t])return _t[t];if(t.startsWith("eip155:")){let n=t.split(":")[1];return parseInt(n,10)}return t==="base"?8453:t==="bsc"?56:t==="ethereum"?1:t==="arbitrum"?42161:t==="polygon"?137:t==="optimism"?10:t==="avalanche"?43114:t==="world"?480:t==="monad"?143:t==="robinhood"?4663:t==="skale-base"?1187947933:t==="skale-base-sepolia"?324705682:8453}async getBalance(t,n,r){if(!Ce(n)||!n.address)return 0;let o=r||this.getDefaultRpcUrl(t.network);try{let s=this.encodeBalanceOf(n.address),a=await fetch(o,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_call",params:[{to:t.asset,data:s},"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),l=t.extra?.decimals??6;return Number(c)/Math.pow(10,l)}catch(s){throw s}}encodeBalanceOf(t){let n="0x70a08231",r=t.slice(2).toLowerCase().padStart(64,"0");return n+r}async confirmSettlement(t,n){if(t.kind==="eip3009"){let r="0xe94a0102",o=t.from.slice(2).toLowerCase().padStart(64,"0"),s=t.nonce.slice(2).toLowerCase().padStart(64,"0"),a=r+o+s,i=await this.ethCall(n,t.asset,a);return{settled:BigInt(i)!==0n}}if(t.kind==="permit2"){let r="0x4fe02b44",o=BigInt(t.nonce),s=o>>8n,a=o&0xffn,i=t.from.slice(2).toLowerCase().padStart(64,"0"),c=s.toString(16).padStart(64,"0"),l=r+i+c,m=await this.ethCall(n,me,l);return{settled:(BigInt(m)>>a&1n)===1n}}throw new Error(`EvmAdapter.confirmSettlement cannot handle probe kind "${t.kind}"`)}async ethCall(t,n,r){let o=await fetch(t,{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(!o.ok)throw new Error(`RPC request failed: ${o.status}`);let s=await o.json();if(s.error)throw new Error(`RPC error: ${JSON.stringify(s.error)}`);if(!s.result||s.result==="0x")throw new Error("RPC returned an empty result");return s.result}async buildTransaction(t,n,r){if(!Ce(n))throw new Error("Invalid EVM wallet");if(!n.address)throw new Error("Wallet not connected");if(t.scheme==="exact-approval")return this.buildApprovalTransaction(t,n,r);if(t.extra?.assetTransferMethod==="permit2")return this.buildPermit2Transaction(t,n,r);let{payTo:o,asset:s,extra:a}=t,i=t.amount??t.maxAmountRequired;if(!i)throw new Error("Missing amount in payment requirements");this.log("Building EVM transaction:",{from:n.address,to:o,amount:i,asset:s,network:t.network});let c=this.getChainId(t.network),l=jt[`eip155:${c}`],m={name:a?.name??l?.name??"USD Coin",version:a?.version??l?.version??"2",chainId:BigInt(c),verifyingContract:s},f={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"}]},d=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(d);let S="0x"+[...d].map(_=>_.toString(16).padStart(2,"0")).join(""),u=Math.floor(Date.now()/1e3),p={from:n.address,to:o,value:i,validAfter:String(u-600),validBefore:String(u+(t.maxTimeoutSeconds||60)),nonce:S},x={from:n.address,to:o,value:BigInt(i),validAfter:BigInt(u-600),validBefore:BigInt(u+(t.maxTimeoutSeconds||60)),nonce:S};if(!n.signTypedData)throw new Error("Wallet does not support signTypedData (EIP-712)");let y=await n.signTypedData({domain:m,types:f,primaryType:"TransferWithAuthorization",message:x});return this.log("EIP-712 signature obtained"),{serialized:JSON.stringify({authorization:p,signature:y}),signature:y,settlementProbe:{kind:"eip3009",from:n.address,nonce:S,asset:s,chainId:c}}}async buildApprovalTransaction(t,n,r){let{payTo:o,asset:s,extra:a}=t,i=t.amount??t.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:o,amount:i,asset:s,network:t.network,facilitatorContract:c});let l=r||this.getDefaultRpcUrl(t.network),m=a?.fee??"0",f=BigInt(i)+BigInt(m),d=await this.readAllowance(l,s,n.address,c);if(d<f){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 C=this.calculateApprovalAmount(i,m,a?.approvalStrategy);this.log(`Approving ${C} for ${c} (current allowance: ${d})`);let h=await n.sendTransaction({to:s,data:this.encodeApprove(c,C),value:0n});this.log(`Approval tx sent: ${h}`),await this.waitForReceipt(l,h),this.log("Approval confirmed")}else this.log("Sufficient allowance, skipping approval");let S=new Uint8Array(16);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(S);let u=[...S].reduce((C,h)=>C*256n+BigInt(h),0n).toString(),p=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(p);let x="0x"+[...p].map(C=>C.toString(16).padStart(2,"0")).join(""),b=Math.floor(Date.now()/1e3)+(t.maxTimeoutSeconds||300),_=a?.eip712Domain,k=_?{name:_.name,version:_.version,chainId:BigInt(_.chainId),verifyingContract:_.verifyingContract}:{name:"DexterBSCFacilitator",version:"1",chainId:BigInt(this.getChainId(t.network)),verifyingContract:c},V=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"}]},W={from:n.address,to:o,token:s,amount:BigInt(i),fee:BigInt(m),nonce:BigInt(u),deadline:BigInt(b),paymentId:x},L=await n.signTypedData({domain:k,types:V,primaryType:"Payment",message:W});this.log("EIP-712 Payment signature obtained");let P={from:n.address,to:o,token:s,amount:i,fee:m,nonce:u,deadline:b,paymentId:x,signature:L};return{serialized:JSON.stringify(P),signature:L}}async buildPermit2Transaction(t,n,r){let{payTo:o,asset:s}=t,a=t.amount??t.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:o,amount:a,asset:s,network:t.network});let i=r||this.getDefaultRpcUrl(t.network),c=await this.readAllowance(i,s,n.address,me),l;if(c<BigInt(a)){let k=this.encodeApprove(me,zn);if(n.signTransaction){this.log(`Signing Permit2 approval for relay (current allowance: ${c})`);let V=this.getChainId(t.network),W=await this.readGasPrice(i),L=await this.readNonce(i,n.address),P=await n.signTransaction({to:s,data:k,chainId:V,gas:50000n,gasPrice:W,nonce:L});l={erc20ApprovalGasSponsoring:{info:{from:n.address,asset:s,spender:me,amount:zn.toString(),signedTransaction:P,version:"1"}}},this.log("Permit2 approval signed for facilitator relay")}else if(n.sendTransaction){this.log(`Approving Permit2 directly (current allowance: ${c})`);let V=await n.sendTransaction({to:s,data:k,value:0n});this.log(`Permit2 approval tx sent: ${V}`),await this.waitForReceipt(i,V),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 m=new Uint8Array(32);(globalThis.crypto??(await import("crypto")).webcrypto).getRandomValues(m);let f=[...m].reduce((k,V)=>k*256n+BigInt(V),0n),d=Math.floor(Date.now()/1e3),S=d-600,u=d+(t.maxTimeoutSeconds||300),p=this.getChainId(t.network),x={name:"Permit2",chainId:BigInt(p),verifyingContract:me},y={permitted:{token:s,amount:BigInt(a)},spender:wt,nonce:f,deadline:BigInt(u),witness:{to:o,validAfter:BigInt(S)}},b=await n.signTypedData({domain:x,types:Fr,primaryType:"PermitWitnessTransferFrom",message:y});this.log("Permit2 PermitWitnessTransferFrom signature obtained");let _={signature:b,permit2Authorization:{from:n.address,permitted:{token:s,amount:a},spender:wt,nonce:f.toString(),deadline:String(u),witness:{to:o,validAfter:String(S)}}};return{serialized:JSON.stringify(_),signature:b,extensions:l,settlementProbe:{kind:"permit2",from:n.address,nonce:f.toString(),chainId:p}}}async readAllowance(t,n,r,o){let s="0xdd62ed3e",a=r.slice(2).toLowerCase().padStart(64,"0"),i=o.slice(2).toLowerCase().padStart(64,"0"),c=s+a+i;try{let m=await(await fetch(t,{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 m.error||!m.result||m.result==="0x"?0n:BigInt(m.result)}catch{return 0n}}encodeApprove(t,n){let r="0x095ea7b3",o=t.slice(2).toLowerCase().padStart(64,"0"),s=n.toString(16).padStart(64,"0");return r+o+s}async waitForReceipt(t,n,r=3e4){let o=Date.now();for(;Date.now()-o<r;){try{let a=await(await fetch(t,{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(s){if(s instanceof Error&&s.message.includes("reverted"))throw s}await new Promise(s=>setTimeout(s,2e3))}throw new Error(`Approval transaction receipt timeout after ${r}ms: ${n}`)}async readGasPrice(t){try{let r=await(await fetch(t,{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(t,n){try{let o=await(await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:"eth_getTransactionCount",params:[n,"latest"]})})).json();return o.result?parseInt(o.result,16):0}catch{return 0}}calculateApprovalAmount(t,n,r){let o=BigInt(t)+BigInt(n);if(!r||r.mode==="exact")return o;let s=BigInt(r.defaultMultiple??10),a=o*s;if(r.maxCapUsd){let i=this.inferDecimals(t),c=BigInt(Math.floor(r.maxCapUsd*Math.pow(10,i)));if(a>c)return c}if(r.exactAboveUsd){let i=this.inferDecimals(t),c=BigInt(Math.floor(r.exactAboveUsd*Math.pow(10,i)));if(BigInt(t)>c)return o}return a}inferDecimals(t){return t.length>12?18:6}};function Ye(e){return new zt(e)}function pn(e){if(e===St||e===jn)return!0;let t=e.toLowerCase();for(let n of Object.values(Wt))if(n.toLowerCase()===t)return!0;for(let n of Object.keys(Ht))if(n.toLowerCase()===t)return!0;return!1}function Lr(e){return{[it]:"Solana",[Ft]:"Solana Devnet",[Lt]:"Solana Testnet",solana:"Solana","solana-devnet":"Solana Devnet","solana-testnet":"Solana Testnet",[we]:"Base",[We]:"Base Sepolia",[Je]:"Ethereum",[He]:"Arbitrum",[je]:"Polygon",[Ge]:"Optimism",[ze]:"Avalanche",[Xe]:"BSC",[_e]:"World Chain",[xe]:"Monad",[Re]:"Robinhood Chain",[Te]:"SKALE Base",[Ee]:"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"}[e]||e}function Xn(e,t){let n=Lr(e);return n===e?t:n}async function $r(e,t){if(typeof e=="string")return[e,t];if(e instanceof URL)return[e.href,t];let n=e,r=new Headers(n.headers);t?.headers&&new Headers(t.headers).forEach((a,i)=>r.set(i,a));let o={method:t?.method??n.method,headers:r,signal:t?.signal??n.signal,redirect:t?.redirect??n.redirect,credentials:t?.credentials??n.credentials},s=(o.method??"GET").toUpperCase();return t&&"body"in t?o.body=t.body:s!=="GET"&&s!=="HEAD"&&n.body&&(o.body=await n.arrayBuffer()),[n.url,o]}var qr=new WeakMap;function Jn(e){let{adapters:t=[de({verbose:e.verbose}),Ye({verbose:e.verbose})],wallets:n,wallet:r,preferredNetwork:o,rpcUrls:s={},maxAmountAtomic:a,fetch:i=globalThis.fetch,verbose:c=!1,accessPass:l,onPaymentRequired:m,onPaymentDispatched:f,maxRetries:d=0,retryDelayMs:S=500}=e,u=c?console.log.bind(console,"[x402]"):()=>{};async function p(h,v){let w;for(let R=0;R<=d;R++)try{let E=await i(h,v);if(E.status>=502&&E.status<=504&&R<d){u(`Retry ${R+1}/${d}: server returned ${E.status}`),await new Promise(N=>setTimeout(N,S*Math.pow(2,R)));continue}return E}catch(E){w=E,R<d&&(u(`Retry ${R+1}/${d}: ${E instanceof Error?E.message:"network error"}`),await new Promise(N=>setTimeout(N,S*Math.pow(2,R))))}throw w}let x=new Map;function y(h){try{let v=new URL(h).host,w=x.get(v);if(w&&w.expiresAt>Date.now()/1e3+10)return w.jwt;w&&x.delete(v)}catch{}return null}function b(h,v){try{let w=new URL(h).host,R=v.split(".");if(R.length===3){let E=JSON.parse(atob(R[1].replace(/-/g,"+").replace(/_/g,"/"))),N=Math.floor(Date.now()/1e3),O=N+86400,G=Math.min(typeof E.exp=="number"?E.exp:N,O);x.set(w,{jwt:v,expiresAt:G}),u("Access pass cached for",w,"| expires:",new Date(G*1e3).toISOString())}}catch{u("Failed to cache access pass")}}let _=n||{};r&&!_.solana&&Ne(r)&&(_.solana=r),r&&!_.evm&&Ce(r)&&(_.evm=r);function k(h){let v=[];for(let w of h){let R=w.scheme??"exact";if(R!=="exact"&&R!=="exact-approval")continue;let E=t.find(O=>O.canHandle(w.network));if(!E)continue;let N;E.name==="Solana"?N=_.solana:E.name==="EVM"&&(N=_.evm),N&&E.isConnected(N)&&v.push({accept:w,adapter:E,wallet:N})}if(v.length===0)return null;if(o){let w=v.find(R=>R.accept.network===o);if(w)return w}return v[0]}function V(h,v){return Xn(h,v)}function W(h,v){return s[h]||v.getDefaultRpcUrl(h)}async function L(h,v,w,R,E){let N="";if(l?.preferTier&&R.tiers){let g=R.tiers.find(I=>I.id===l.preferTier);if(g){if(l.maxSpend&&parseFloat(g.price)>parseFloat(l.maxSpend))throw new U("access_pass_exceeds_max_spend",`Access pass tier "${g.id}" costs $${g.price}, exceeds max spend $${l.maxSpend}`);N=`tier=${g.id}`}}else if(l?.preferDuration&&R.ratePerHour)N=`duration=${l.preferDuration}`;else if(R.tiers&&R.tiers.length>0){let g=R.tiers[0];if(l?.maxSpend&&parseFloat(g.price)>parseFloat(l.maxSpend))throw new U("access_pass_exceeds_max_spend",`Cheapest access pass costs $${g.price}, exceeds max spend $${l?.maxSpend}`);N=`tier=${g.id}`}let O=N?E.includes("?")?`${E}&${N}`:`${E}?${N}`:E;u("Purchasing access pass:",N||"default tier");let G=w.headers.get("PAYMENT-REQUIRED");if(!G)return null;let j;try{j=JSON.parse(atob(G))}catch{return null}let K=k(j.accepts);if(!K)return null;let{accept:B,adapter:X,wallet:Ve}=K;if(X.name==="Solana"&&!B.extra?.feePayer)return null;let ee=B.extra?.decimals??(pn(B.asset)?6:void 0);if(typeof ee!="number")return null;let Ze=B.amount??B.maxAmountRequired;if(!Ze)return null;let te=W(B.network,X);try{let g=await X.getBalance(B,Ve,te),I=Number(Ze)/Math.pow(10,ee);if(g<I){let Zt=V(B.network,X.name);throw new U("insufficient_balance",`Insufficient balance for access pass on ${Zt}. Have $${g.toFixed(4)}, need $${I.toFixed(4)}`)}}catch(g){if(g instanceof U)throw g}let ne=await X.buildTransaction(B,Ve,te),ke;X.name==="EVM"?ke=JSON.parse(ne.serialized):ke={transaction:ne.serialized};let pe=typeof h=="string"?h:h instanceof URL?h.href:h.url,Oe=j.resource;if(typeof j.resource=="string")try{let g=new URL(j.resource,pe);["http:","https:"].includes(g.protocol)&&(Oe=g.toString())}catch{}else if(j.resource&&typeof j.resource=="object"&&"url"in j.resource){let g=j.resource;try{let I=new URL(g.url,pe);["http:","https:"].includes(I.protocol)&&(Oe={...g,url:I.toString()})}catch{}}let Rt={x402Version:B.x402Version??2,resource:Oe,accepted:B,payload:ke};ne.extensions&&(Rt.extensions=ne.extensions);let re=btoa(JSON.stringify(Rt)),fe=await i(O,{...v,method:"POST",headers:{...v?.headers||{},"Content-Type":"application/json","PAYMENT-SIGNATURE":re}});if(!fe.ok)return u("Pass purchase failed:",fe.status),null;let z=fe.headers.get("ACCESS-PASS");return z&&(b(E,z),u("Access pass purchased and cached")),fe}async function P(h,v){let w=h;if(u("Making request:",w),l){let g=y(w);if(g){u("Using cached access pass");let I=await i(h,{...v,headers:{...v?.headers||{},Authorization:`Bearer ${g}`}});if(I.status!==401&&I.status!==402)return I;u("Cached pass rejected (status",I.status,"), purchasing new pass");try{x.delete(new URL(w).host)}catch{}}}let R=await p(h,v);if(R.status!==402)return R;u("Received 402 Payment Required");let E=R.headers.get("X-ACCESS-PASS-TIERS");if(l&&E){u("Server offers access passes, purchasing...");try{let g=JSON.parse(atob(E)),I=await L(h,v,R,g,w);if(I)return I}catch(g){u("Access pass purchase failed, falling back to per-request payment:",g)}}let N=R.headers.get("PAYMENT-REQUIRED");if(!N)throw new U("missing_payment_required_header","Server returned 402 but no PAYMENT-REQUIRED header");let O;try{let g=atob(N);O=JSON.parse(g)}catch{throw new U("invalid_payment_required","Failed to decode PAYMENT-REQUIRED header")}u("Payment requirements:",O);let G=R.headers.get("X-Quote-Hash");G&&u("Quote hash received:",G);let j=k(O.accepts);if(!j){let g=O.accepts.map(I=>I.network).join(", ");throw new U("no_matching_payment_option",`No connected wallet for any available network: ${g}`)}let{accept:K,adapter:B,wallet:X}=j;if(u(`Using ${B.name} for ${K.network}`),B.name==="Solana"&&!K.extra?.feePayer)throw new U("missing_fee_payer","Solana payment option missing feePayer in extra");let Ve=K.extra?.decimals??(pn(K.asset)?6:void 0);if(typeof Ve!="number")throw new U("missing_decimals","Payment option missing decimals - provide in extra or use a known stablecoin");let ee=K.amount??K.maxAmountRequired;if(!ee)throw new U("missing_amount","Payment option missing amount");if(a&&BigInt(ee)>BigInt(a))throw new U("amount_exceeds_max",`Payment amount ${ee} exceeds maximum ${a}`);let Ze=W(K.network,B);u("Checking balance...");try{let g=await B.getBalance(K,X,Ze),I=Number(ee)/Math.pow(10,Ve);if(g<I){let Zt=V(K.network,B.name);throw new U("insufficient_balance",`Insufficient balance on ${Zt}. Have $${g.toFixed(4)}, need $${I.toFixed(4)}`)}u(`Balance OK: $${g.toFixed(4)} >= $${I.toFixed(4)}`)}catch(g){if(g instanceof U)throw g;u("Balance check failed (RPC error), proceeding with transaction attempt")}if(m&&!await m(K))throw new U("payment_rejected","Payment rejected by onPaymentRequired callback");u("Building transaction...");let te=await B.buildTransaction(K,X,Ze);u("Transaction signed");let ne;B.name==="EVM"?ne=JSON.parse(te.serialized):ne={transaction:te.serialized};let ke=h,pe=O.resource;if(typeof O.resource=="string")try{let g=new URL(O.resource,ke).toString();g!==O.resource&&u("Resolved relative resource URL:",O.resource,"\u2192",g),pe=g}catch{pe=O.resource}else if(O.resource&&typeof O.resource=="object"&&"url"in O.resource){let g=O.resource;try{let I=new URL(g.url,ke).toString();I!==g.url&&(u("Resolved relative resource URL:",g.url,"\u2192",I),pe={...g,url:I})}catch{}}let Oe={x402Version:K.x402Version??2,resource:pe,accepted:K,payload:ne};te.extensions&&(Oe.extensions=te.extensions);let Rt=btoa(JSON.stringify(Oe));if(f)try{f(K,te.settlementProbe)}catch{}u("Retrying request with payment...");let re=await p(h,{...v,headers:{...v?.headers||{},"PAYMENT-SIGNATURE":Rt,...G?{"X-Quote-Hash":G}:{}}});if(u("Retry response status:",re.status),re.status===402){let g="unknown";try{let I=await re.clone().json();g=String(I.error||I.message||JSON.stringify(I)),u("Rejection reason:",g)}catch{}throw new U("payment_rejected",`Payment was rejected by the server: ${g}`)}let fe=re.headers.get("PAYMENT-RESPONSE"),z;if(fe)try{z=JSON.parse(atob(fe))}catch{}return z??={},z.amountAtomic=ee,z.assetDecimals=Ve,qr.set(re,z),z.extensions&&u("Settlement extensions:",Object.keys(z.extensions).join(", ")),re}async function C(h,v){let[w,R]=await $r(h,v);return P(w,R)}return{fetch:C}}function Q(e){if(e instanceof Error){if(e.message&&e.message.length>0)return e.message;if(e.name&&e.name.length>0)return e.name}let t=String(e);return t.length>0?t:"unknown error"}async function xt(e){let t="";try{t=(await e.clone().text()).slice(0,600)}catch{}let n=t.toLowerCase(),r=n.includes("settle")||n.includes("facilitator"),o=t;try{let s=JSON.parse(t),a=[s.error,s.detail,s.message].filter(i=>typeof i=="string"&&i.length>0);a.length>0&&(o=a.join(" \u2014 "))}catch{}return o||(o=`HTTP ${e.status}`),{reason:r?"settlement_failed":"merchant_rejected",detail:`merchant HTTP ${e.status}: ${o}`}}var Xt="Payment authorization was sent, but the merchant did not respond within the timeout. ",Jt=" Do not retry without checking \u2014 inspect the funding wallet for a transfer to the merchant before attempting payment again.";async function Yt(e,t,n){if(!e)return{confirmed:!1,detail:Xt+"This payment scheme has no on-chain confirmation check, so the SDK cannot verify whether it settled."+Jt};try{if(e.kind==="solana"){let a=de(),i=n??a.getDefaultRpcUrl(t.caip2);if(!a.confirmSettlement)return Zn();let c=await a.confirmSettlement(e,i);return c.settled?{confirmed:!0,txSignature:c.txSignature}:Yn()}let r=Ye(),o=r.getDefaultRpcUrl(t.caip2);if(!r.confirmSettlement)return Zn();let s=await r.confirmSettlement(e,o);return s.settled?{confirmed:!0,txSignature:s.txSignature}:Yn()}catch(r){return{confirmed:!1,detail:Xt+`On-chain confirmation could not be completed (${Q(r)}).`+Jt}}}function Yn(){return{confirmed:!1,detail:Xt+"On-chain confirmation found no matching settlement yet \u2014 the payment may still be pending, or may not have settled."+Jt}}function Zn(){return{confirmed:!1,detail:Xt+"The chain adapter does not support on-chain confirmation."+Jt}}var Wr=new Set(["exact","exact-approval"]);async function Hr(e,t,n,r){let o;try{o=await r.signNextVoucher(n.amount)}catch(c){return r.voucherVersion!==1?{ok:!1,reason:"error",detail:`context-bound FINAL tab voucher was not safely released; retry or reconcile this tab before another payment rail is attempted (${c instanceof Error?c.message:String(c)})`}:null}let s=new Headers(t.headers??void 0);s.set("X-Tab-Voucher",st(o));let a={method:t.method??"GET",headers:s};t.signal&&(a.signal=t.signal),typeof t.body=="string"&&(a.body=t.body);let i;try{i=await fetch(e,a)}catch(c){return{ok:!1,reason:"error",detail:c?.message??String(c)}}return i.status===402?r.voucherVersion!==1?{ok:!1,reason:"error",detail:"seller refused an irrevocable FINAL tab voucher; its exact reservation must be reconciled before another payment rail is attempted"}:r.rollbackVoucher?.call(r,o)!==!0?{ok:!1,reason:"error",detail:"seller refused a V1 tab voucher but local rollback was unavailable or failed; another payment rail was not attempted to avoid double payment"}:null:i.ok?{ok:!0,paid:!0,response:i,amountPaid:n.amount,network:n.network}:{ok:!1,...await xt(i)}}var Qn={version:2,async parseChallenge(e){return Kt(e)},async pay(e,t,n,r,o){if(o.tab){let y=n.options.find(b=>b.scheme==="tab"&&b.network.family==="svm"&&b.payTo===o.tab.counterparty);if(y){let b=await Hr(e,t,y,o.tab);if(b)return b}}let s=n.options.filter(y=>Wr.has(y.scheme));if(s.length===0)return{ok:!1,reason:"no_payment_options",detail:`no generically payable scheme offered (got: ${n.options.map(y=>y.scheme).join(", ")})`};let a=s.find(y=>y.network.family==="evm"?!!r.evm:y.network.family==="svm"?!!r.solana:!1);if(!a)return{ok:!1,reason:"unsupported_network"};let i=o.timeoutMs??15e3,c=o.responseTimeoutMs??12e4,l=new AbortController,m=setTimeout(()=>l.abort(),i),f=!1,d,S=(y,b)=>{f=!0,d=b,clearTimeout(m),m=setTimeout(()=>l.abort(),c)},u=Jn({wallets:r,preferredNetwork:a.network.caip2,maxAmountAtomic:o.maxAmountAtomic,fetch:globalThis.fetch,onPaymentDispatched:S}),p=t.signal?AbortSignal.any([t.signal,l.signal]):l.signal,x={method:t.method??"GET",headers:t.headers,signal:p};typeof t.body=="string"&&(x.body=t.body);try{let y=await u.fetch(e,x);if(clearTimeout(m),!y.ok)return{ok:!1,...await xt(y)};let b,_=y.headers.get("PAYMENT-RESPONSE");if(_)try{let k=ln(_);k&&typeof k.transaction=="string"&&(b=k.transaction)}catch{}return{ok:!0,paid:!0,response:y,amountPaid:a.amount,network:a.network,txSignature:b}}catch(y){clearTimeout(m);let b=y;if(b?.name==="AbortError"){if(!f)return{ok:!1,reason:"timeout"};let _=await Yt(d,a.network,o.solanaRpcUrl);return _.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:a.amount,network:a.network,txSignature:_.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:_.detail}}return{ok:!1,reason:"error",detail:b?.message??String(y)}}}};var er=require("viem");var jr={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 Gr(){let e=globalThis.crypto??(await import("crypto")).webcrypto,t=new Uint8Array(32);return e.getRandomValues(t),"0x"+Array.from(t,n=>n.toString(16).padStart(2,"0")).join("")}async function zr(e,t,n){if(typeof e.signTypedData!="function")throw new Error("EVM wallet does not support signTypedData");let r=Math.floor(Date.now()/1e3),o=String(r-600),s=String(r+(t.maxTimeoutSeconds??60)),a={from:e.address,to:t.payTo,value:t.amount,validAfter:o,validBefore:s,nonce:await Gr()},i=_t[t.network.caip2];if(i===void 0)throw new Error(`unknown chain id for network ${t.network.caip2}`);let c=t.extra,l=await e.signTypedData({domain:{name:c.name,version:c.version,chainId:i,verifyingContract:(0,er.getAddress)(t.asset)},types:jr,primaryType:"TransferWithAuthorization",message:a});return{payment:{x402Version:1,scheme:t.scheme,network:n,payload:{signature:l,authorization:a}},settlementProbe:{kind:"eip3009",from:a.from,nonce:a.nonce,asset:t.asset,chainId:i}}}async function fn(e,t,n){try{let r;for(let o of e.options){let s=o.network.family==="evm"&&!!t.evm||o.network.family==="svm"&&!!t.solana;if(o.scheme!=="exact"){s&&(r=o.scheme);continue}if(o.network.family==="evm"&&t.evm){let a=await t.evm;return await Xr(o,a,n)}if(o.network.family==="svm"&&t.solana){let a=await t.solana;return await Jr(o,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:Q(r)}}}async function Xr(e,t,n){if(n.maxAmountAtomic!==void 0&&BigInt(e.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};let r=e.extra??{},o=r.name,s=r.version;if(typeof o!="string"||o.length===0||typeof s!="string"||s.length===0)return{ok:!1,reason:"merchant_rejected",detail:"v1 challenge missing exact-scheme EIP-712 domain (extra.name / extra.version)"};let a=e.network.bare,{payment:i,settlementProbe:c}=await zr(t,e,a);return{ok:!0,headerValue:Buffer.from(JSON.stringify(i),"utf8").toString("base64"),option:e,settlementProbe:c}}async function Jr(e,t,n){if(n.maxAmountAtomic!==void 0&&BigInt(e.amount)>BigInt(n.maxAmountAtomic))return{ok:!1,reason:"budget_exceeded"};if(e.scheme!=="exact")return{ok:!1,reason:"merchant_rejected",detail:`v1 SVM supports only the 'exact' scheme, got '${e.scheme}'`};let r=e.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 o=e.network.bare,s={x402Version:1,scheme:e.scheme,network:o,asset:e.asset,payTo:e.payTo,amount:e.amount,maxAmountRequired:e.amount,maxTimeoutSeconds:e.maxTimeoutSeconds??60,extra:r},i=await de().buildTransaction(s,t,n.solanaRpcUrl),c={x402Version:1,scheme:e.scheme,network:o,payload:{transaction:i.serialized}};return{ok:!0,headerValue:Buffer.from(JSON.stringify(c),"utf8").toString("base64"),option:e,settlementProbe:i.settlementProbe}}function Yr(e){let t=[];for(let n of e){if(!n||typeof n!="object")continue;let r=n,o=at(String(r.network??""));o&&t.push({scheme:String(r.scheme??"exact"),network:o,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 t}var tr={version:1,async parseChallenge(e){if(e.headers.get("payment-required"))return null;let t;try{t=await e.clone().json()}catch{return null}let n=Array.isArray(t.accepts)?t.accepts:[];if(n.length===0)return null;let r=Yr(n);return r.length===0?null:{x402Version:1,options:r}},async pay(e,t,n,r,o){let s,a=new AbortController,i=!1,c,l;try{let m=o.timeoutMs??15e3;s=setTimeout(()=>a.abort(),m);let f=await fn(n,r,o);if(!f.ok)return{ok:!1,reason:f.reason,detail:f.detail};let d=f.headerValue,S=f.option;l=S,c=f.settlementProbe;let u=new Headers(t.headers??void 0);u.set("X-PAYMENT",d);let p=t.signal!=null?AbortSignal.any([t.signal,a.signal]):a.signal,x={method:t.method,headers:u,signal:p};typeof t.body=="string"&&(x.body=t.body),i=!0,clearTimeout(s);let y=o.responseTimeoutMs??12e4;s=setTimeout(()=>a.abort(),y);let b=await fetch(e,x);return b.ok?{ok:!0,paid:!0,response:b,amountPaid:S.amount,network:S.network,txSignature:Zr(b)}:{ok:!1,...await xt(b)}}catch(m){if(m instanceof Error&&m.name==="AbortError"){if(!i)return{ok:!1,reason:"timeout"};let f=await Yt(c,l.network,o.solanaRpcUrl);return f.confirmed?{ok:!0,paid:!0,response:void 0,amountPaid:l.amount,network:l.network,txSignature:f.txSignature}:{ok:!1,reason:"payment_unconfirmed",detail:f.detail}}return{ok:!1,reason:"error",detail:Q(m)}}finally{s!==void 0&&clearTimeout(s)}}};function Zr(e){let t=e.headers.get("x-payment-response")??e.headers.get("X-PAYMENT-RESPONSE");if(t)try{let n=JSON.parse(Buffer.from(t,"base64").toString("utf8")),r=n.transaction??n.txHash??n.transactionHash;return typeof r=="string"?r:void 0}catch{return}}var rr=J(require("tweetnacl"),1);var gn=require("@solana/web3.js"),nr=Symbol.for("x402:keypair");function hn(e){let t=e.evm;if(t&&typeof t.signMessage=="function"&&typeof t.address=="string")return{address:t.address,signMessage:t.signMessage};let n=e.solana;if(n){let r=n[nr];if(r&&r.secretKey&&r.publicKey)return{publicKey:r.publicKey,signMessage:async o=>rr.sign.detached(o,r.secretKey)}}return null}var Qr=[Qn,tr];async function eo(e){let t=hn(e);if(!t)return fetch;try{return(await import("@x402/extensions/sign-in-with-x")).wrapFetchWithSIWx(fetch,t)}catch(n){return console.warn(`[x402] SIW-X unavailable \u2014 @x402/extensions failed to load; SIW-X merchants will not authenticate. ${Q(n)}`),fetch}}async function yn(e,t,n,r){if(t.body!==void 0&&t.body!==null&&typeof t.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 o;try{o=await(await eo(n))(e,{...t})}catch(s){return{ok:!1,reason:"error",detail:Q(s)}}if(o.status!==402)return{ok:!0,paid:!1,response:o};for(let s of Qr){let a=await s.parseChallenge(o.clone());if(a)return s.pay(e,t,a,n,r)}return{ok:!1,reason:"no_payment_options"}}async function or(e,t={},n){let r=await qe(e,t);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:o}=r,s=BigInt(ce(n.perUnitCap));if(BigInt(o.amountAtomic)>s)return{result:{ok:!1,reason:"budget_exceeded",detail:`seller quotes ${o.amountAtomic} atomic; perUnitCap allows ${s}`},tab:null};let a=n.tabs?.get(o.payTo);return(!a||!a.state.isOpen)&&(a=await Bt({vault:n.vault,network:"solana:mainnet",seller:o.payTo,perUnitCap:n.perUnitCap,totalCap:n.totalCap,sessionDuration:n.sessionDuration,facilitatorUrl:n.facilitatorUrl,onLiveSession:n.onLiveSession,reserveFinalVoucherV2:n.reserveFinalVoucherV2}),n.tabs?.set(o.payTo,a)),{result:await yn(e,t,{},{tab:a}),tab:a}}function to(e){return{counterparty:e.payTo,perRequest:{atomic:e.amountAtomic,human:ve(e.amountAtomic)},asset:e.asset,network:{caip2:e.networkCaip2},scheme:"tab",settlement:{custody:"non-custodial",protection:"lock",settleOn:"close"},credit:null,...e.resourceUrl!==void 0?{resourceUrl:e.resourceUrl}:{}}}async function sr(e,t={},n={}){let r=n.cache?.get(e);if(r)return{kind:"terms",terms:r};let o=await qe(e,t,n.fetchImpl??fetch);if(o.kind!=="offer")return o;if(o.offer.asset!==St)return{kind:"error",detail:`tab offer asset is not USDC ("${o.offer.asset}"); refusing to render a human price`};let s=to(o.offer);return n.cache?.set(e,s),{kind:"terms",terms:s}}0&&(module.exports={DEFAULT_FACILITATOR_URL,DEXTER_VAULT_PROGRAM_ID,FINAL_VOUCHER_V2_RESERVATION_BINDING_DOMAIN,FINAL_VOUCHER_V2_RESERVATION_MEMO_PREFIX,FINAL_VOUCHER_V2_SOLANA_MAINNET_CAIP2,HOSTED_TAB_ACCEPTANCE_RULE,HOSTED_TAB_REGISTRATION_ENCODING,HOSTED_TAB_TERMS_VERSION,HOSTED_TAB_VOUCHER_HEADER,HistoricalV1MigrationRequiredError,INSTRUCTIONS_SYSVAR_ID,LiveSessionExistsError,SECP256R1_PROGRAM_ID,SessionScopeExceededError,TabClosedError,UnsupportedNetworkError,armTabOpen,assertFinalVoucherV2ReservationReceipt,atomicToHuman,buildRegisterSessionKeyInstruction,buildRevokeSessionKeyInstruction,buildSecp256r1VerifyInstruction,buildVoucherMessage,canonicalFinalVoucherV2ReservationNetwork,deriveChannelId,finalVoucherV2Digest,finalVoucherV2ReservationBindingDigest,finalVoucherV2ReservationBindingDigestFromIdentity,finalVoucherV2ReservationIdentity,finalVoucherV2ReservationMemo,finalVoucherV2Sequence,generateSessionKeypair,humanToAtomic,makeSessionKey,openTab,parseAtomic,payUrlWithTab,resolveTabOffer,resolveTabTerms,resumeTab,scopeCapAtomic,sessionRegisterMessage,sessionReplaceV1Message,sessionRevokeMessage,sessionVoucherV2AuthorizationNonce,sessionVoucherV2Nonce,signContextBoundFinalVoucherV2,signVoucher,tabFromGrant,voucherPayloadMessage,voucherToHeader,voucherV2SequenceOrdinal});
|
package/dist/tab/index.d.cts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { O as OpenTabOptions, T as Tab, R as ResumeTabOptions,
|
|
2
|
-
export { A as AuthorizeSessionOptions, L as LiveSessionDetails,
|
|
3
|
-
import {
|
|
1
|
+
import { O as OpenTabOptions, T as Tab, R as ResumeTabOptions, F as FinalVoucherV2ReservationInput, a as FinalVoucherV2ReservationReceipt, d as ReserveFinalVoucherV2, b as VaultAdapter } from '../types-45M9fb5M.cjs';
|
|
2
|
+
export { A as AuthorizeSessionOptions, H as HistoricalV1MigrationRequiredError, L as LiveSessionDetails, c as LiveSessionExistsError, S as SessionScopeExceededError, e as TabCloseResult, f as TabClosedError, g as TabState, U as UnsupportedNetworkError, V as VerifyFinalVoucherV2Reservation } from '../types-45M9fb5M.cjs';
|
|
3
|
+
import { AtomicAmount, HumanAmount, SignedVoucher } from '@dexterai/vault/types';
|
|
4
4
|
export { AtomicAmount, HumanAmount, SessionKey, SessionScope, SignedVoucher, TabNetworkId, VoucherPayload } from '@dexterai/vault/types';
|
|
5
5
|
import { PublicKey, Connection } from '@solana/web3.js';
|
|
6
6
|
import { ApprovedSpendGrantParams } from '@dexterai/vault/grant';
|
|
7
7
|
export { ApprovedSpendGrantParams } from '@dexterai/vault/grant';
|
|
8
|
-
import {
|
|
9
|
-
export { SessionRegisterMessageArgs, SessionRevokeMessageArgs, VoucherPayloadBytes, buildVoucherMessage, sessionRegisterMessage, sessionRevokeMessage, voucherPayloadMessage } from '@dexterai/vault/messages';
|
|
8
|
+
import { b as PayResult } from '../types-C6z04Mxr.cjs';
|
|
9
|
+
export { SessionRegisterMessageArgs, SessionReplaceV1MessageArgs, SessionRevokeMessageArgs, VoucherPayloadBytes, buildVoucherMessage, finalVoucherV2Sequence, sessionRegisterMessage, sessionReplaceV1Message, sessionRevokeMessage, sessionVoucherV2AuthorizationNonce, sessionVoucherV2Nonce, voucherPayloadMessage, voucherV2SequenceOrdinal } from '@dexterai/vault/messages';
|
|
10
10
|
export { BuildRegisterSessionKeyArgs, BuildRevokeSessionKeyArgs, buildRegisterSessionKeyInstruction, buildRevokeSessionKeyInstruction } from '@dexterai/vault/instructions';
|
|
11
11
|
export { buildSecp256r1VerifyInstruction } from '@dexterai/vault/precompile';
|
|
12
12
|
export { DEXTER_VAULT_PROGRAM_ID, INSTRUCTIONS_SYSVAR_ID, SECP256R1_PROGRAM_ID } from '@dexterai/vault/constants';
|
|
13
|
-
export { d as deriveChannelId, g as generateSessionKeypair, m as makeSessionKey, p as parseAtomic,
|
|
14
|
-
import '../types-
|
|
13
|
+
export { S as SignContextBoundFinalVoucherV2Input, a as SignContextBoundFinalVoucherV2Result, d as deriveChannelId, g as generateSessionKeypair, m as makeSessionKey, p as parseAtomic, s as scopeCapAtomic, b as signContextBoundFinalVoucherV2, c as signVoucher } from '../sessions-rPdO1CgK.cjs';
|
|
14
|
+
import '../types-BvQpNtFw.cjs';
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* The `Tab` runtime — the live object returned by `openTab()`.
|
|
@@ -50,13 +50,83 @@ declare function voucherToHeader(signed: SignedVoucher): string;
|
|
|
50
50
|
* /tab/open. THROWS if protection cannot be confirmed — a tab that is not
|
|
51
51
|
* drain-protected must never be returned to the caller.
|
|
52
52
|
*/
|
|
53
|
-
|
|
53
|
+
/**
|
|
54
|
+
* @deprecated V6 has no buyer-side V1 arming route. This retained symbol is a
|
|
55
|
+
* deterministic migration fence for callers compiled against the old helper;
|
|
56
|
+
* it performs no fetch, signing, or chain action.
|
|
57
|
+
*/
|
|
58
|
+
declare function armTabOpen(_facilitatorUrl: string, _buyerSwigAddress: string, _maxAmountAtomic: bigint, _network: string, _counterparty: string): Promise<{
|
|
54
59
|
armed: true;
|
|
55
60
|
signature: string;
|
|
56
61
|
}>;
|
|
57
62
|
declare function openTab(options: OpenTabOptions): Promise<Tab>;
|
|
58
63
|
declare function resumeTab(_options: ResumeTabOptions): Promise<Tab>;
|
|
59
64
|
|
|
65
|
+
/** Canonical network carried by the managed native-Tab transaction record. */
|
|
66
|
+
declare const FINAL_VOUCHER_V2_SOLANA_MAINNET_CAIP2 = "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp";
|
|
67
|
+
/** Domain for the authority-signed transaction binding. Changing any bound
|
|
68
|
+
* field requires a new domain/version rather than silently changing bytes. */
|
|
69
|
+
declare const FINAL_VOUCHER_V2_RESERVATION_BINDING_DOMAIN = "dexter-native-tab-v2-reservation/v1";
|
|
70
|
+
/** UTF-8 prefix stored by the SPL Memo instruction. */
|
|
71
|
+
declare const FINAL_VOUCHER_V2_RESERVATION_MEMO_PREFIX = "dexter-native-tab-v2-reservation/v1:";
|
|
72
|
+
/** Shared economic identity committed by the authority-signed Memo. This is
|
|
73
|
+
* intentionally independent of provider lifecycle IDs and SDK retry keys so
|
|
74
|
+
* the SDK and facilitator can derive identical bytes from their common facts. */
|
|
75
|
+
interface FinalVoucherV2ReservationBindingIdentity {
|
|
76
|
+
network: string;
|
|
77
|
+
programId: string;
|
|
78
|
+
buyerSwigAddress: string;
|
|
79
|
+
vaultPda: string;
|
|
80
|
+
sessionPda: string;
|
|
81
|
+
seller: string;
|
|
82
|
+
channelId: string;
|
|
83
|
+
sessionNonce: number;
|
|
84
|
+
reservationAmountAtomic: string;
|
|
85
|
+
previousCumulativeAtomic: string;
|
|
86
|
+
voucherDigest: string;
|
|
87
|
+
cumulativeAmountAtomic: string;
|
|
88
|
+
sequenceNumber: number;
|
|
89
|
+
}
|
|
90
|
+
/** Normalize the SDK's historical Solana alias to the CAIP-2 value persisted
|
|
91
|
+
* by the managed facilitator. No other alias is accepted by this contract. */
|
|
92
|
+
declare function canonicalFinalVoucherV2ReservationNetwork(network: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* Byte-for-byte mirror of the facilitator's voucher identity digest. It binds
|
|
95
|
+
* the complete signed voucher, not merely its amount or local counter.
|
|
96
|
+
*/
|
|
97
|
+
declare function finalVoucherV2Digest(voucher: SignedVoucher): string;
|
|
98
|
+
declare function finalVoucherV2ReservationIdentity(voucher: SignedVoucher): {
|
|
99
|
+
voucherDigest: string;
|
|
100
|
+
idempotencyKey: string;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Low-level cross-system digest over the shared reservation identity. This
|
|
104
|
+
* helper exists so transaction builders and verifiers can lock byte-for-byte
|
|
105
|
+
* parity without manufacturing a SignedVoucher for an already-derived digest.
|
|
106
|
+
*/
|
|
107
|
+
declare function finalVoucherV2ReservationBindingDigestFromIdentity(identity: FinalVoucherV2ReservationBindingIdentity): string;
|
|
108
|
+
/**
|
|
109
|
+
* Digest that must be carried by the same Dexter-authority-signed Solana
|
|
110
|
+
* transaction as the exact `settle_voucher(increment=true)` reservation.
|
|
111
|
+
*
|
|
112
|
+
* The Vault instruction binds the on-chain amount and account identities. This
|
|
113
|
+
* separate domain binds that economic effect to the complete FINAL voucher and
|
|
114
|
+
* shared economic identity. Provider lifecycle, receipt, and retry identifiers
|
|
115
|
+
* are deliberately excluded. The digest is computed locally from the voucher
|
|
116
|
+
* bytes; a provider-supplied `voucherDigest` is never trusted as the source of
|
|
117
|
+
* this transaction binding.
|
|
118
|
+
*/
|
|
119
|
+
declare function finalVoucherV2ReservationBindingDigest(input: FinalVoucherV2ReservationInput): string;
|
|
120
|
+
/** Exact UTF-8 SPL Memo payload required in the reservation transaction. */
|
|
121
|
+
declare function finalVoucherV2ReservationMemo(input: FinalVoucherV2ReservationInput): string;
|
|
122
|
+
/**
|
|
123
|
+
* Validate the provider's immutable voucher-bound receipt before asking the
|
|
124
|
+
* chain adapter to prove the post-state independently. A receipt is evidence
|
|
125
|
+
* of the provider's durable lifecycle record; it is not a substitute for the
|
|
126
|
+
* adapter's chain read.
|
|
127
|
+
*/
|
|
128
|
+
declare function assertFinalVoucherV2ReservationReceipt(input: FinalVoucherV2ReservationInput, receipt: FinalVoucherV2ReservationReceipt): void;
|
|
129
|
+
|
|
60
130
|
/**
|
|
61
131
|
* tabFromGrant — open a buyer-side Tab from a GRANTED session key.
|
|
62
132
|
*
|
|
@@ -81,8 +151,11 @@ declare function resumeTab(_options: ResumeTabOptions): Promise<Tab>;
|
|
|
81
151
|
* odometer starts there so the first voucher strictly exceeds everything
|
|
82
152
|
* the chain has already terminally counted. The chain is the durable
|
|
83
153
|
* counter; there is no local state store to lose.
|
|
84
|
-
* -
|
|
85
|
-
*
|
|
154
|
+
* - a context-bound V2 reservation fence before every newly issued FINAL
|
|
155
|
+
* voucher. Historical low-bit V1 grants are rejected before I/O: the v6
|
|
156
|
+
* facilitator has no compatible buyer-side V1 arming/recovery endpoint.
|
|
157
|
+
* Seller-side V1 verification remains available for obligations that were
|
|
158
|
+
* already issued under the deployment that originally opened them.
|
|
86
159
|
*
|
|
87
160
|
* CUSTODY NOTE — why this constructor may hold a session secret when
|
|
88
161
|
* `resumeTab` refuses to: the passkey path's "session keys are memory-only"
|
|
@@ -154,20 +227,31 @@ interface TabFromGrantOptions {
|
|
|
154
227
|
*/
|
|
155
228
|
sellerUrl?: string;
|
|
156
229
|
/**
|
|
157
|
-
* The buyer's Swig STATE address (`vault.swig_address`)
|
|
158
|
-
*
|
|
159
|
-
* one extra RPC read, never a guess.
|
|
230
|
+
* The buyer's Swig STATE address (`vault.swig_address`) bound into the exact
|
|
231
|
+
* V2 reservation request and receipt. When omitted it is read from the
|
|
232
|
+
* on-chain vault account — one extra RPC read, never a guess.
|
|
160
233
|
*/
|
|
161
234
|
swigAddress?: string;
|
|
162
235
|
/** Facilitator base URL. Default: DEFAULT_FACILITATOR_URL (https://x402.dexter.cash). */
|
|
163
236
|
facilitatorUrl?: string;
|
|
164
237
|
/** Vault program id override (test/devnet). Default: DEXTER_VAULT_PROGRAM_ID. */
|
|
165
238
|
programId?: PublicKey;
|
|
239
|
+
/**
|
|
240
|
+
* Required for every context-bound V2 grant. Called with the exact FINAL
|
|
241
|
+
* voucher before it can be returned to merchant-facing code. The
|
|
242
|
+
* implementation must durably persist and establish that voucher's exact
|
|
243
|
+
* on-chain reservation, be idempotent for identical bytes, and resolve only
|
|
244
|
+
* after authoritative finalization. Low-bit V1 grants are rejected before
|
|
245
|
+
* this seam or any external I/O because v6 cannot reconstruct their arming
|
|
246
|
+
* identity safely.
|
|
247
|
+
*/
|
|
248
|
+
reserveFinalVoucherV2?: ReserveFinalVoucherV2;
|
|
166
249
|
}
|
|
167
250
|
/**
|
|
168
251
|
* Construct a live `Tab` from a granted session key. Fail-loud at every step:
|
|
169
|
-
* key/params mismatch, dead or drifted on-chain session, exhausted cap, and
|
|
170
|
-
*
|
|
252
|
+
* key/params mismatch, dead or drifted on-chain session, exhausted cap, and a
|
|
253
|
+
* missing exact V2 reservation fence all THROW — an invalid tab is never
|
|
254
|
+
* returned.
|
|
171
255
|
*/
|
|
172
256
|
declare function tabFromGrant(options: TabFromGrantOptions): Promise<Tab>;
|
|
173
257
|
|
|
@@ -179,6 +263,11 @@ interface TabOffer {
|
|
|
179
263
|
asset: string;
|
|
180
264
|
/** CAIP-2 network from the challenge (x402 v2 form). */
|
|
181
265
|
networkCaip2: string;
|
|
266
|
+
/** Preserved verbatim from accepts[].extra for policy-aware callers. */
|
|
267
|
+
voucherHeader?: string;
|
|
268
|
+
registrationEncoding?: string;
|
|
269
|
+
termsVersion?: string;
|
|
270
|
+
acceptanceRule?: string;
|
|
182
271
|
resourceUrl?: string;
|
|
183
272
|
}
|
|
184
273
|
type TabOfferResult = {
|
|
@@ -206,6 +295,16 @@ type TabOfferResult = {
|
|
|
206
295
|
*/
|
|
207
296
|
declare function resolveTabOffer(url: string, init?: RequestInit, fetchImpl?: typeof fetch): Promise<TabOfferResult>;
|
|
208
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Hosted-v1 commercial semantics advertised by the default Tab scheme.
|
|
300
|
+
* A different refund/dispute or delivery rule requires a new terms version;
|
|
301
|
+
* callers must never reinterpret these strings in place.
|
|
302
|
+
*/
|
|
303
|
+
declare const HOSTED_TAB_TERMS_VERSION: "dexter-tab-hosted-pay-before-delivery/v1";
|
|
304
|
+
declare const HOSTED_TAB_ACCEPTANCE_RULE: "pay_before_delivery_seller_2xx";
|
|
305
|
+
declare const HOSTED_TAB_VOUCHER_HEADER: "x-tab-voucher";
|
|
306
|
+
declare const HOSTED_TAB_REGISTRATION_ENCODING: "base64(188-byte sessionRegisterMessage)";
|
|
307
|
+
|
|
209
308
|
/**
|
|
210
309
|
* Step-3a buyer orchestration: pay a URL through a tab with ZERO seller
|
|
211
310
|
* knowledge. Resolution + lifecycle only — composes resolveTabOffer,
|
|
@@ -238,6 +337,8 @@ interface PayUrlWithTabOptions {
|
|
|
238
337
|
* `OpenTabOptions.onLiveSession` (K-T4e).
|
|
239
338
|
*/
|
|
240
339
|
onLiveSession?: 'error' | 'replace';
|
|
340
|
+
/** Exact V2 reservation fence forwarded to openTab. */
|
|
341
|
+
reserveFinalVoucherV2?: ReserveFinalVoucherV2;
|
|
241
342
|
/**
|
|
242
343
|
* Open-tab registry keyed by counterparty base58. Pass the SAME Map across
|
|
243
344
|
* calls to reuse one open tab per seller instead of re-registering
|
|
@@ -313,4 +414,4 @@ interface ResolveTabTermsOptions {
|
|
|
313
414
|
*/
|
|
314
415
|
declare function resolveTabTerms(url: string, init?: RequestInit, opts?: ResolveTabTermsOptions): Promise<TabTermsResult>;
|
|
315
416
|
|
|
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 };
|
|
417
|
+
export { DEFAULT_FACILITATOR_URL, FINAL_VOUCHER_V2_RESERVATION_BINDING_DOMAIN, FINAL_VOUCHER_V2_RESERVATION_MEMO_PREFIX, FINAL_VOUCHER_V2_SOLANA_MAINNET_CAIP2, type FinalVoucherV2ReservationBindingIdentity, FinalVoucherV2ReservationInput, FinalVoucherV2ReservationReceipt, HOSTED_TAB_ACCEPTANCE_RULE, HOSTED_TAB_REGISTRATION_ENCODING, HOSTED_TAB_TERMS_VERSION, HOSTED_TAB_VOUCHER_HEADER, OpenTabOptions, type PayUrlWithTabOptions, type PayUrlWithTabResult, ReserveFinalVoucherV2, type ResolveTabTermsOptions, ResumeTabOptions, Tab, type TabFromGrantOptions, type TabOffer, type TabOfferResult, type TabTerms, type TabTermsResult, VaultAdapter, armTabOpen, assertFinalVoucherV2ReservationReceipt, atomicToHuman, canonicalFinalVoucherV2ReservationNetwork, finalVoucherV2Digest, finalVoucherV2ReservationBindingDigest, finalVoucherV2ReservationBindingDigestFromIdentity, finalVoucherV2ReservationIdentity, finalVoucherV2ReservationMemo, humanToAtomic, openTab, payUrlWithTab, resolveTabOffer, resolveTabTerms, resumeTab, tabFromGrant, voucherToHeader };
|