@dexterai/x402 6.0.0-rc.3 → 6.0.0-rc.5
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [6.0.0-rc.5] - 2026-08-17
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Fresh Native Tab registration now preserves the complete sibling-session
|
|
15
|
+
account set and falls back from legacy serialization to the existing v0+ALT
|
|
16
|
+
transport when that exact register exceeds Solana's 1232-byte packet cap.
|
|
17
|
+
|
|
18
|
+
## [6.0.0-rc.4] - 2026-08-17
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Rebound the exact Vault peer and development dependency to
|
|
23
|
+
`@dexterai/vault@0.43.3-rc.1`. This is a package-metadata-only successor to
|
|
24
|
+
rc.3 so the canonical archive-mode Vault release resolves as one dependency
|
|
25
|
+
graph; x402 runtime source and declarations are unchanged.
|
|
26
|
+
|
|
10
27
|
## [6.0.0-rc.3] - 2026-08-17
|
|
11
28
|
|
|
12
29
|
### Added
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var mt=Object.create;var Q=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var pt=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var ft=(e,t)=>{for(var o in t)Q(e,o,{get:t[o],enumerable:!0})},ke=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of gt(t))!yt.call(e,i)&&i!==o&&Q(e,i,{get:()=>t[i],enumerable:!(n=dt(t,i))||n.enumerable});return e};var ee=(e,t,o)=>(o=e!=null?mt(pt(e)):{},ke(t||!e||!e.__esModule?Q(o,"default",{value:e,enumerable:!0}):o,e)),ht=e=>ke(Q({},"__esModule",{value:!0}),e);var jt={};ft(jt,{LiveSessionExistsError:()=>D,SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID:()=>nt,SOLANA_FINAL_VOUCHER_V2_PROGRAM_ID:()=>tt,SolanaFinalVoucherV2ReservationError:()=>Y,TX_SIZE_LIMIT_BYTES:()=>j,buildAdapterRegisterInstruction:()=>ut,collectAltAddresses:()=>we,compileComposeV0:()=>Se,createSelfPayingComposeSend:()=>se,createSolanaFinalVoucherV2ReservationVerifier:()=>et,createSolanaVaultAdapter:()=>Wt,deriveChannelId:()=>Ne,inspectSolanaFinalVoucherV2Reservation:()=>ue,passkeySignerFromP256Keypair:()=>st,verifySolanaFinalVoucherV2Reservation:()=>me});module.exports=ht(jt);var k=require("@solana/web3.js"),ct=ee(require("bs58"),1);var D=class extends Error{constructor(o){super(`a LIVE session already exists for counterparty ${o.allowedCounterparty} (session ${o.sessionPubkeyHex.slice(0,16)}\u2026, expires ${o.expiresAtUnix}; on-chain spent=${o.spentAtomic}, crystallized=${o.crystallizedCumulativeAtomic}, frontier=${o.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=o;this.name="LiveSessionExistsError"}details};var N=require("@dexterai/vault/instructions"),te=require("@dexterai/vault/precompile"),I=require("@dexterai/vault/constants");var _=require("@dexterai/vault/messages");var X=ee(require("tweetnacl"),1),J=require("@solana/web3.js"),U=require("@dexterai/vault/messages"),Ke=require("@dexterai/vault/session");var Ue=require("@noble/hashes/sha256");function Te(){let e=X.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function Ee(e,t,o){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:o}}function Oe(e,t,o){if(o.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${o.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 n=BigInt(t.cumulativeAmount),i=BigInt(e.scope.maxAmountAtomic);if(n>i)throw new Error(`voucher cumulative ${n} exceeds session cap ${i}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let r=(0,_.voucherPayloadMessage)({channelId:o,cumulativeAmount:n,sequenceNumber:t.sequenceNumber}),a=X.default.sign.detached(r,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}var vt=/^[0-9a-f]{64}$/,At=(1n<<64n)-1n;function ye(e){return Buffer.from(e).toString("hex")}function bt(e){return Uint8Array.from(Buffer.from(e,"hex"))}function fe(e,t){if(e.length!==t.length)return!1;let o=0;for(let n=0;n<e.length;n+=1)o|=(e[n]??0)^(t[n]??0);return o===0}function Be(e){if(!vt.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>At)throw new Error("native_tab_v2_cumulative_amount_invalid");let o=new J.PublicKey(e.programId),n=new J.PublicKey(e.vaultPda),i=new J.PublicKey(e.sessionPda),s=new J.PublicKey(e.seller),[r]=(0,Ke.deriveSessionPda)(n,s,o);if(!i.equals(r))throw new Error("native_tab_v2_session_pda_mismatch");let a=e.sessionRegistration,c=new DataView(a.buffer,a.byteOffset,a.byteLength),m=c.getBigUint64(128,!0),d=c.getBigInt64(136,!0),v=c.getBigUint64(180,!0),g=e.nowUnixSeconds??Math.floor(Date.now()/1e3);if(!Number.isSafeInteger(g)||g<0)throw new Error("native_tab_v2_signing_time_invalid");if(!fe(a,(0,U.sessionRegisterMessage)({programId:o,vaultPda:n,sessionPubkey:e.sessionPublicKey,maxAmount:m,expiresAt:d,allowedCounterparty:s,nonce:e.sessionNonce,maxRevolvingCapacity:v})))throw new Error("native_tab_v2_registration_identity_mismatch");if(m===0n||v===0n||v>m||d<=BigInt(g)||d>0x7fffffffffffffffn-604800n||t>m)throw new Error("native_tab_v2_registration_semantics_invalid");(0,U.sessionVoucherV2AuthorizationNonce)(e.sessionNonce);let y=X.default.sign.keyPair.fromSeed(e.sessionPrivateKey.subarray(0,32)),f=!1;try{f=fe(y.publicKey,e.sessionPublicKey)&&fe(e.sessionPrivateKey.subarray(32,64),e.sessionPublicKey)}finally{y.secretKey.fill(0)}if(!f)throw new Error("native_tab_v2_session_key_mismatch");let h=(0,U.finalVoucherV2Sequence)(e.sequenceOrdinal),p=(0,U.contextBoundVoucherV2Message)({programId:o,vaultPda:n,sessionPda:i,seller:s,sessionNonce:e.sessionNonce,channelId:bt(e.channelId),cumulativeAmount:t,sequenceNumber:h}),R=X.default.sign.detached(p,e.sessionPrivateKey);return{channelId:e.channelId,cumulativeAmount:e.cumulativeAmountAtomic,sequenceNumber:h,sessionPublicKey:ye(e.sessionPublicKey),sessionSignature:ye(R),sessionRegistration:ye(a)}}function $(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function Ne(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let o=new TextEncoder().encode(e.sellerUrl),n=Ue.sha256.create();return n.update(e.vaultPda.toBytes()),n.update(o),n.update(t),n.digest()}var w=require("@dexterai/vault/session"),lt=require("@dexterai/vault/reader"),pe=require("@dexterai/vault");var wt=ee(require("tweetnacl"),1),St=require("@noble/hashes/sha256"),Pt=require("@noble/curves/p256"),ne=require("@solana/web3.js");var ve=require("@dexterai/vault/session"),Ae=require("@dexterai/vault/messages"),he="OTS_SESSION_REGISTER_V2";var F=class extends Error{constructor(o,n){super(`Invalid registration: ${o}${n?` (${n})`:""}`);this.reason=o;this.name="InvalidRegistrationError"}reason};function oe(e){if(e.length!==188)throw new F("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,he.length));if(t!==he)throw new F("wrong_domain",`got "${t}"`);for(let v=he.length;v<32;v++)if(e[v]!==0)throw new F("wrong_domain",`non-NUL padding at byte ${v}`);let o=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new ne.PublicKey(e.slice(32,64)),i=new ne.PublicKey(e.slice(64,96)),s=e.slice(96,128),r=o.getBigUint64(128,!0),a=o.getBigInt64(136,!0),c=new ne.PublicKey(e.slice(144,176)),m=o.getUint32(176,!0),d=o.getBigUint64(180,!0);if(!n.equals(I.DEXTER_VAULT_PROGRAM_ID))throw new F("wrong_program",`${n.toBase58()} is not ${I.DEXTER_VAULT_PROGRAM_ID.toBase58()}`);if(r===0n)throw new F("cap_zero");return{programId:n,vaultPda:i,sessionPubkey:new Uint8Array(s),maxAmount:r,expiresAt:a,allowedCounterparty:c,nonce:m,maxRevolvingCapacity:d}}var Ve=require("@noble/hashes/sha256"),ge=require("@noble/hashes/utils");var K=require("@solana/web3.js"),j=1232,xt=40,$e=20,Fe=4,_t=20,ie=1e4,Rt=1e6,re=4,M="[tab/solana/compose]";function we(e,t){let o=new Set,n=[],i=t.toBase58();for(let s of e)for(let r of s.keys){if(r.isSigner)continue;let a=r.pubkey.toBase58();a===i||o.has(a)||(o.add(a),n.push(r.pubkey))}return n}function Se(e,t,o,n){let i=new K.TransactionMessage({payerKey:t,recentBlockhash:o,instructions:e}).compileToV0Message([n]);return new K.VersionedTransaction(i)}async function ze(e){try{let t=(await e.getRecentPrioritizationFees()).map(n=>n.prioritizationFee).filter(n=>n>0).sort((n,i)=>n-i);if(t.length===0)return ie;let o=t[Math.floor(.75*(t.length-1))]??ie;return Math.max(ie,Math.min(o,Rt))}catch{return ie}}function Vt(e){let t=e,o=String(t?.message??e??""),n=Array.isArray(t?.logs)?t.logs.join(" "):"";return/already in use/i.test(o)||/already in use/i.test(n)}function Le(e){let t=e;return(Array.isArray(t?.logs)?t.logs:[]).length===0&&/block height exceeded|has expired|blockhash not found/i.test(String(t?.message??e))}var be=e=>new Promise(t=>setTimeout(t,e));function se(e,t,o={}){let n=o.commitment??"confirmed",i=o.altWarmupPollMs??400,s=o.altReadbackPollMs??400,r=o.altCollisionPollMs??500,a=null,c=null;async function m(f,h){let p=await ze(e),R=[K.ComputeBudgetProgram.setComputeUnitPrice({microLamports:p}),...f],P;for(let x=0;x<re;x+=1){let{blockhash:b,lastValidBlockHeight:O}=await e.getLatestBlockhash(n),V=new K.Transaction().add(...R);V.feePayer=t.publicKey,V.recentBlockhash=b,V.sign(t);try{let u=await e.sendRawTransaction(V.serialize(),{skipPreflight:!1,maxRetries:5}),A=await e.confirmTransaction({signature:u,blockhash:b,lastValidBlockHeight:O},n);if(A.value.err)throw new Error(`${h} tx failed on-chain: ${JSON.stringify(A.value.err)}`);return u}catch(u){if(Le(u)&&x<re-1){console.warn(`${M} ${h} tx expired before landing (attempt ${x+1}) \u2014 rebroadcasting with a fresh blockhash`),P=u;continue}throw u}}throw P??new Error(`${h} tx did not land after rebroadcast attempts`)}async function d(f){for(let h=0;h<_t;h+=1){let p=await e.getSlot("finalized");if(p>f)return p;await be(r)}throw new Error(`ALT collision retry: finalized slot never advanced past ${f}`)}async function v(f){for(let h=0;h<xt;h+=1){if(await e.getSlot(n)>f)return;await be(i)}throw new Error(`ALT warmup timed out: preflight (${n}) slot never passed lastExtendedSlot ${f}`)}async function g(f){if(a)return a;let h=we(f,t.publicKey),p=null,R=null,P=-1;for(let b=0;b<Fe;b+=1){let O=P<0?await e.getSlot("finalized"):await d(P),[V,u]=K.AddressLookupTableProgram.createLookupTable({authority:t.publicKey,payer:t.publicKey,recentSlot:O}),A=K.AddressLookupTableProgram.extendLookupTable({payer:t.publicKey,authority:t.publicKey,lookupTable:u,addresses:h});try{R=await m([V,A],"ALT create/extend"),p=u;break}catch(L){if(Vt(L)&&b<Fe-1){P=O,console.warn(`${M} ALT address collision at slot ${O} (attempt ${b+1}) \u2014 retrying create with a fresh finalized slot`);continue}throw L}}if(!p||!R)throw new Error("ALT create exhausted retries after repeated address collisions");let x=await e.getAddressLookupTable(p);for(let b=0;b<$e&&!x.value;b+=1)await be(s),x=await e.getAddressLookupTable(p);if(!x.value)throw new Error(`ALT ${p.toBase58()} not visible after ${$e} read polls (${R})`);return await v(x.value.state.lastExtendedSlot),a=x.value,c=p,console.info(`${M} ephemeral compose ALT ready: ${p.toBase58()} (${h.length} addresses, createTx ${R})`),a}async function S(f){let h=await ze(e),p=[K.ComputeBudgetProgram.setComputeUnitPrice({microLamports:h}),...f],R=await g(p),P;for(let x=0;x<re;x+=1){let{blockhash:b,lastValidBlockHeight:O}=await e.getLatestBlockhash(n),V;try{let u=Se(p,t.publicKey,b,R);u.sign([t]),V=u.serialize()}catch(u){throw/overrun|too large/i.test(String(u?.message??u))?new Error(`composed revoke-then-register v0 tx exceeds the ${j}B wire cap \u2014 too many sibling PDAs outside the lookup table`):u}if(V.length>j)throw new Error(`composed revoke-then-register v0 tx ${V.length}B exceeds the ${j}B wire cap \u2014 too many sibling PDAs outside the lookup table`);try{let u=await e.sendRawTransaction(V,{skipPreflight:!1,maxRetries:5}),A=await e.confirmTransaction({signature:u,blockhash:b,lastValidBlockHeight:O},n);if(A.value.err)throw new Error(`composed tx failed on-chain: ${JSON.stringify(A.value.err)}`);return u}catch(u){if(Le(u)&&x<re-1){console.warn(`${M} compose tx expired before landing (attempt ${x+1}, priorityFee ${h}) \u2014 rebroadcasting with a fresh blockhash`),P=u;continue}let A=Array.isArray(u?.logs)?u.logs:[];throw A.length?new Error(`${u?.message??u} | ${A.join(" | ")}`):u}}throw P instanceof Error?P:new Error("compose tx did not land after rebroadcast attempts")}async function y(){if(c)try{let f=K.AddressLookupTableProgram.deactivateLookupTable({lookupTable:c,authority:t.publicKey}),h=await m([f],"ALT deactivate");console.info(`${M} ephemeral compose ALT deactivated: ${c.toBase58()} (${h}) \u2014 rent reclaimable via close_lookup_table after the deactivation cooldown`)}catch(f){console.warn(`${M} ALT deactivate failed for ${c?.toBase58()} \u2014 rent parks until a later cleanup retries (the compose already landed): ${String(f?.message??f)}`)}}return{send:S,getAltAddress:()=>c,deactivateAlt:y}}var B=require("@solana/web3.js"),le=require("@noble/hashes/utils"),H=require("@dexterai/vault/credit"),Z=require("@dexterai/vault/constants"),je=require("@dexterai/vault/instructions"),Ye=require("@dexterai/vault/reader"),G=require("@dexterai/vault/session");var _e=require("@noble/hashes/sha256"),z=require("@noble/hashes/utils"),De=/^[0-9a-f]{64}$/,Me=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,It=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,qe="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",He="dexter-native-tab-v2-reservation/v1",Ct=`${He}:`;function Pe(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(Pe);if(typeof e=="object")return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[o])=>t.localeCompare(o)).map(([t,o])=>[t,Pe(o)]));throw new Error("canonical_value_unsupported")}function Ge(e){return JSON.stringify(Pe(e))}function xe(e){if(e==="solana:mainnet"||e===qe)return qe;throw new Error("native_tab_v2_reservation_network_unsupported")}function We(e){return(0,z.bytesToHex)((0,_e.sha256)(new TextEncoder().encode(Ge({channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,z.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,z.bytesToHex)(e.sessionSignature),sessionRegistration:(0,z.bytesToHex)(e.sessionRegistration)}))))}function kt(e){return(0,z.bytesToHex)((0,_e.sha256)(new TextEncoder().encode(Ge({contract:He,network:xe(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 Kt(e){let t=We(e.voucher);return kt({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 Je(e){return`${Ct}${Kt(e)}`}function C(e){throw new Error(`native_tab_v2_reservation_receipt_invalid:${e}`)}function ae(e,t){(!Number.isSafeInteger(e)||e<0)&&C(t)}function Xe(e,t){(!t||typeof t!="object")&&C("missing");let o=We(e.voucher);(!De.test(e.voucherDigest)||e.voucherDigest!==o)&&C("input_voucher_digest"),e.idempotencyKey!==`native-tab-v2:${o}`&&C("input_idempotency_identity");let n=BigInt(e.voucher.payload.cumulativeAmount),i=BigInt(e.previousCumulativeAtomic),s=BigInt(e.reservationAmountAtomic);(n<=i||n-i!==s||s<=0n)&&C("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)&&C("input_voucher_identity"),t.contract!=="dexter-native-tab-open-receipt/v1"&&t.contract!=="dexter-native-tab-open-receipt/v2"&&C("contract"),De.test(t.operationId)||C("operation_id"),Me.test(t.callerOperationId)||C("caller_operation_id"),It.test(t.transaction)||C("transaction"),t.commitment!=="confirmed"&&t.commitment!=="finalized"&&C("commitment"),ae(t.confirmationSlot,"confirmation_slot"),ae(t.postStateSlot,"post_state_slot"),(t.confirmationSlot===0||t.postStateSlot<t.confirmationSlot)&&C("post_state_slot");let r,a;try{r=xe(e.network),a=xe(t.network)}catch{return C("network")}(a!==r||t.buyerSwigAddress!==e.buyerSwigAddress||t.vaultPda!==e.vaultPda||t.sessionPda!==e.sessionPda||t.seller!==e.seller||t.channelId!==e.channelId||t.sessionPublicKey!==(0,z.bytesToHex)(e.voucher.sessionPublicKey)||t.voucherDigest!==o||t.cumulativeAmountAtomic!==e.voucher.payload.cumulativeAmount||t.sequenceNumber!==e.voucher.payload.sequenceNumber||!Me.test(t.providerReceiptId)||t.reservationAmountAtomic!==e.reservationAmountAtomic||t.currentOutstandingBeforeAtomic!=="0"||t.currentOutstandingAfterAtomic!==e.reservationAmountAtomic)&&C("economic_identity"),ae(t.pendingVoucherCountBefore,"pending_voucher_count_before"),ae(t.pendingVoucherCountAfter,"pending_voucher_count_after"),t.contract==="dexter-native-tab-open-receipt/v1"?t.callerOperationId!==e.idempotencyKey&&C("idempotency_key"):(t.rootOperationId!==e.idempotencyKey||!Number.isSafeInteger(t.generation)||Number(t.generation)<2||!t.predecessorCallerOperationId||!t.predecessorLifecycleOperationId||!t.predecessorReleaseDigest||!t.stableReservationId||!t.economicEffectDigest)&&C("successor_identity")}var Tt=Uint8Array.from([56,67,4,209,238,143,0,129]),Et=74,Ze=new Set([1,2]),Ot=188,Qe=new B.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),Bt=(()=>{let e=Buffer.alloc(32);return e.write("OTS_SESSION_REGISTER_V2","ascii"),e})(),Y=class extends Error{constructor(o,n){super(`native_tab_v2_solana_reservation_invalid:${o}`+(n?`:${n}`:""));this.code=o;this.name="SolanaFinalVoucherV2ReservationError"}code};function l(e,t){throw new Y(e,t)}function T(e,t){try{return new B.PublicKey(e)}catch{return l(t)}}function ce(e,t){return e.length===t.length&&e.every((o,n)=>o===t[n])}async function Ut(e){let o=(await e.connection.getSignatureStatuses([e.signature],{searchTransactionHistory:!0})).value[0]??null;if(!o)return null;o.confirmationStatus!=="confirmed"&&o.confirmationStatus!=="finalized"&&l("transaction_commitment"),o.err!==null&&l("transaction_failed");let n=await e.connection.getTransaction(e.signature,{commitment:e.commitment,maxSupportedTransactionVersion:0});if(!n)return null;n.meta||l("transaction_meta_missing"),n.slot!==o.slot&&l("transaction_status_slot");let i=n.transaction.message,s=i.version===0?i.getAccountKeys({accountKeysFromLookups:n.meta.loadedAddresses??null}):i.getAccountKeys(),r=(a,c)=>{let m=s.get(a);return m||l(c),m};return{slot:n.slot,confirmationStatus:o.confirmationStatus,err:n.meta.err,signatures:[...n.transaction.signatures],accountKeys:Array.from({length:s.length},(a,c)=>({address:r(c,"transaction_account_key").toBase58(),signer:i.isAccountSigner(c),writable:i.isAccountWritable(c)})),instructions:i.compiledInstructions.map(a=>({programId:r(a.programIdIndex,"transaction_program_id").toBase58(),accounts:a.accountKeyIndexes.map(c=>r(c,"transaction_instruction_account").toBase58()),data:Uint8Array.from(a.data)}))}}function Nt(e,t,o,n){n.length!==Et&&l("binding_length"),ce(n.subarray(0,8),Tt)||l("binding_discriminator");let i=n.readUInt8(8),s=n.readUInt8(9);return Ze.has(i)||l("binding_version"),s!==t&&l("binding_bump"),{address:e.toBase58(),owner:o.toBase58(),version:i,bump:s,swig:new B.PublicKey(n.subarray(10,42)).toBase58(),vault:new B.PublicKey(n.subarray(42,74)).toBase58()}}async function $t(e){let t=T(e.input.programId,"program_id"),o=T(e.input.buyerSwigAddress,"buyer_swig"),n=T(e.input.vaultPda,"vault_pda"),i=T(e.input.seller,"seller"),[s,r]=(0,H.deriveSwigVaultBindingPda)(o,t),[a]=(0,G.deriveSessionPda)(n,i,t),c=await e.connection.getMultipleAccountsInfoAndContext([s,n,a],{commitment:e.commitment,minContextSlot:e.minimumSlot}),[m,d,v]=c.value;m||l("binding_missing"),d||l("vault_missing"),v||l("session_missing");let g,S;try{g=(0,Ye.decodeVaultFull)(Buffer.from(d.data)),S=(0,G.decodeSessionAccount)(a,v.data)}catch(f){return l("post_state_decode",f instanceof Error?f.message:String(f))}let y=S.session;return{contextSlot:c.context.slot,binding:Nt(s,r,m.owner,Buffer.from(m.data)),vault:{owner:d.owner.toBase58(),exists:g.exists,version:g.version,swigAddress:g.swigAddress,dexterAuthority:g.dexterAuthority,pendingVoucherCount:g.pendingVoucherCount},session:{owner:v.owner.toBase58(),version:S.version,bump:S.bump,vault:S.vault,sessionPublicKey:(0,le.bytesToHex)(y.sessionPubkey),maxAmount:y.maxAmount,expiresAt:y.expiresAt,seller:y.allowedCounterparty,nonce:y.nonce,spent:y.spent,currentOutstanding:y.currentOutstanding,maxRevolvingCapacity:y.maxRevolvingCapacity,crystallizedCumulative:y.crystallizedCumulative}}}function Ft(e){let t=Buffer.from(e.voucher.sessionRegistration);return t.length!==Ot&&l("registration_length"),ce(t.subarray(0,32),Bt)||l("registration_domain"),{programId:new B.PublicKey(t.subarray(32,64)).toBase58(),vaultPda:new B.PublicKey(t.subarray(64,96)).toBase58(),sessionPublicKey:(0,le.bytesToHex)(t.subarray(96,128)),maxAmount:t.readBigUInt64LE(128),expiresAt:t.readBigInt64LE(136),seller:new B.PublicKey(t.subarray(144,176)).toBase58(),nonce:t.readUInt32LE(176),maxRevolvingCapacity:t.readBigUInt64LE(180)}}function q(e,t,o){let n=e.accountKeys.filter(i=>i.address===t);return n.length!==1&&l(`${o}_account_key`),n[0]}function zt(e,t,o){(!Number.isSafeInteger(o.slot)||o.slot<=0)&&l("transaction_slot"),o.slot!==t.confirmationSlot&&l("transaction_confirmation_slot"),o.err!==null&&l("transaction_failed"),o.signatures[0]!==t.transaction&&l("transaction_signature"),o.instructions.length!==2&&l("transaction_instruction_count");let n=T(e.programId,"program_id"),i=T(e.buyerSwigAddress,"buyer_swig"),s=T(e.vaultPda,"vault_pda"),r=T(e.seller,"seller"),a=T(e.sessionPda,"session_pda"),[c]=(0,G.deriveSessionPda)(s,r,n),m=(0,H.deriveSwigVaultBindingPda)(i,n)[0],d=(0,je.deriveSwigWalletAddress)(i),v=(0,H.deriveGraphConfigPda)(n)[0];a.equals(c)||l("session_pda_derivation");let g=Buffer.from(Z.DISCRIMINATORS.settle_voucher),S=o.instructions.filter(u=>{if(u.programId!==e.programId)return!1;let A=u.data;return A.length>=g.length&&ce(A.subarray(0,g.length),g)});S.length!==1&&l("settle_voucher_instruction_count");let y=S[0];o.instructions[0]!==y&&l("settle_voucher_instruction_order");let f=Buffer.from(y.data);f.length!==49&&l("settle_voucher_instruction_length"),f.readBigUInt64LE(8).toString()!==e.reservationAmountAtomic&&l("settle_voucher_amount"),f.readUInt8(16)!==1&&l("settle_voucher_increment"),new B.PublicKey(f.subarray(17,49)).equals(r)||l("settle_voucher_seller"),y.accounts.length<8&&l("settle_voucher_accounts"),[s.toBase58(),null,a.toBase58(),null,i.toBase58(),d.toBase58(),m.toBase58(),v.toBase58()].forEach((u,A)=>{u!==null&&y.accounts[A]!==u&&l(`settle_voucher_account_${A}`)});let p=y.accounts[1];p||l("dexter_authority");let R=q(o,y.accounts[0],"vault"),P=q(o,p,"dexter_authority"),x=q(o,y.accounts[2],"session");(!R.writable||R.signer)&&l("vault_privileges"),P.signer||l("dexter_authority_signature"),(!x.writable||x.signer)&&l("session_privileges");for(let u=3;u<Math.min(y.accounts.length,8);u+=1)q(o,y.accounts[u],`account_${u}`).signer&&l(`settle_voucher_account_${u}_signer`);for(let u=8;u<y.accounts.length;u+=1){let A=q(o,y.accounts[u],`sibling_${u-8}`);(!A.writable||A.signer)&&l("settle_voucher_sibling_privileges")}let b=o.instructions[1];b.programId!==Qe.toBase58()&&l("reservation_memo_program"),(b.accounts.length!==1||b.accounts[0]!==p)&&l("reservation_memo_authority"),q(o,p,"reservation_memo_authority").signer||l("reservation_memo_authority_signature");let V=new TextEncoder().encode(Je(e));return ce(b.data,V)||l("reservation_memo_digest"),p}function Lt(e,t,o,n){let i=T(e.programId,"program_id"),s=T(e.buyerSwigAddress,"buyer_swig"),r=T(e.vaultPda,"vault_pda"),a=T(e.seller,"seller"),[c,m]=(0,H.deriveSwigVaultBindingPda)(s,i),[d,v]=(0,G.deriveSessionPda)(r,a,i);(!Number.isSafeInteger(n.contextSlot)||n.contextSlot<t)&&l("post_state_slot"),(n.binding.address!==c.toBase58()||n.binding.owner!==e.programId||n.binding.bump!==m||!Ze.has(n.binding.version)||n.binding.swig!==e.buyerSwigAddress||n.binding.vault!==e.vaultPda)&&l("binding_identity"),(n.vault.owner!==e.programId||!n.vault.exists||n.vault.version!==7||n.vault.swigAddress!==e.buyerSwigAddress||n.vault.dexterAuthority!==o)&&l("vault_post_state"),(e.sessionPda!==d.toBase58()||n.session.owner!==e.programId||n.session.version!==1||n.session.bump!==v||n.session.vault!==e.vaultPda||n.session.sessionPublicKey!==(0,le.bytesToHex)(e.voucher.sessionPublicKey)||n.session.seller!==e.seller||n.session.nonce!==e.sessionNonce||n.session.currentOutstanding.toString()!==e.reservationAmountAtomic)&&l("session_post_state");let g=Ft(e);(g.programId!==e.programId||g.vaultPda!==e.vaultPda||g.sessionPublicKey!==n.session.sessionPublicKey||g.seller!==e.seller||g.nonce!==e.sessionNonce||g.maxAmount!==n.session.maxAmount||g.expiresAt!==BigInt(n.session.expiresAt)||g.maxRevolvingCapacity!==n.session.maxRevolvingCapacity)&&l("registration_post_state");let S=n.session.spent>n.session.crystallizedCumulative?n.session.spent:n.session.crystallizedCumulative;return S.toString()!==e.previousCumulativeAtomic&&l("session_frontier"),{commitment:"confirmed",confirmationSlot:t,postStateSlot:n.contextSlot,sessionAccountVersion:n.session.version,wireVersion:2,frontierAtomic:S.toString(),spentAtomic:n.session.spent.toString(),currentOutstandingAtomic:n.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:n.session.crystallizedCumulative.toString()}}async function ue(e,t,o,n={}){try{Xe(t,o)}catch(a){return l("provider_receipt",a instanceof Error?a.message:String(a))}t.network!=="solana:mainnet"&&l("network"),t.programId!==Z.DEXTER_VAULT_PROGRAM_ID.toBase58()&&l("program_id");let i=await(n.readTransaction??Ut)({connection:e,signature:o.transaction,commitment:"confirmed"});i||l("transaction_missing"),i.confirmationStatus!=="confirmed"&&i.confirmationStatus!=="finalized"&&l("transaction_commitment");let s=zt(t,o,i),r=await(n.readPostState??$t)({connection:e,input:t,minimumSlot:i.slot,commitment:"confirmed"});return{...Lt(t,i.slot,s,r),commitment:i.confirmationStatus}}async function me(e,t,o,n={}){await ue(e,t,o,n)}function et(e,t={}){return async(o,n)=>{await ue(e,o,n,t)}}var tt=Z.DEXTER_VAULT_PROGRAM_ID,nt=Qe;var Re=require("@noble/curves/p256"),W=require("@noble/hashes/sha256"),de=require("@dexterai/vault"),it=require("@dexterai/vault/messages"),rt="dexter.cash";function Dt(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Mt(e,t=`https://${rt}`){let n={type:"webauthn.get",challenge:Dt(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(n))}function qt(e=1){let t=(0,W.sha256)(new TextEncoder().encode(rt)),o=new Uint8Array(37);return o.set(t,0),o[32]=5,new DataView(o.buffer).setUint32(33,e,!1),o}function ot(e,t){let o=Mt(t),n=qt(1),i=new Uint8Array(n.length+32);i.set(n,0),i.set((0,W.sha256)(o),n.length);let s=(0,W.sha256)(i);return{signature:Re.p256.sign(s,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:o,authenticatorData:n}}function st(e,t={}){return{credentialId:new Uint8Array(0),publicKey:e.publicKey,signOperation:async o=>{let n=t.resolveAuthorizationContext?await t.resolveAuthorizationContext(o.slice()):Ht(o);if(!n){if(t.allowLegacyOperationHash===!0)return ot(e,(0,W.sha256)(o));throw new Error("passkey_authorization_context_required")}let i=t.ceremonyNonce?t.ceremonyNonce():Re.p256.utils.randomPrivateKey();if(i.length!==32)throw new Error("ceremonyNonce must be exactly 32 bytes");let s=(0,de.buildPasskeyAuthorizationChallenge)({programId:n.programId,vault:n.vault,nonce:n.nonce,operationHash:(0,W.sha256)(o),ceremonyNonce:i});return ot(e,s)}}}function Ht(e){let t=(0,de.classifyPasskeyAuthorizationOperation)(e);return t.kind==="session_register_v2"?{programId:t.fields.programId,vault:t.fields.vault,nonce:BigInt((0,it.sessionVoucherV2AuthorizationNonce)(t.fields.registrationNonce))}:t.kind==="session_replace_v1"?{programId:t.fields.programId,vault:t.fields.vault,nonce:t.fields.authorizationNonce}:null}async function Gt({connection:e,vaultPda:t,allowedCounterparty:o,programId:n=I.DEXTER_VAULT_PROGRAM_ID,commitment:i="finalized"}){let[s]=(0,w.deriveSessionPda)(t,o,n),r=await e.getMultipleAccountsInfoAndContext([t,s],{commitment:i}),[a,c]=r.value;if(!a)throw new Error("close revocation: vault account not found");if(!a.owner.equals(n))throw new Error("close revocation: vault has the wrong owner");let m=(0,lt.decodeVaultFull)(Buffer.from(a.data));if(!m.exists||m.version!==7)throw new Error("close revocation: Vault V7 required");if(!c)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"absent"};if(!c.owner.equals(n))throw new Error("close revocation: session has the wrong owner");let d=(0,w.decodeSessionAccount)(s,c.data);if(d.version===0)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"cleared"};if(d.version!==1)throw new Error("close revocation: live SessionAccount required");if(d.vault!==t.toBase58())throw new Error("close revocation: session belongs to a different vault");if(d.session.allowedCounterparty!==o.toBase58())throw new Error("close revocation: session counterparty mismatch");return{kind:"live",snapshot:{contextSlot:r.context.slot,programId:new k.PublicKey(n),vaultPda:new k.PublicKey(t),sessionPda:s,sessionPubkey:Uint8Array.from(d.session.sessionPubkey),maxAmount:d.session.maxAmount,expiresAt:Buffer.from(c.data).readBigInt64LE(82),allowedCounterparty:new k.PublicKey(o),nonce:d.session.nonce,spent:d.session.spent,currentOutstanding:d.session.currentOutstanding,maxRevolvingCapacity:d.session.maxRevolvingCapacity,crystallizedCumulative:d.session.crystallizedCumulative,lastLockedSequence:d.session.lastLockedSequence,expectedPendingVoucherCount:m.pendingVoucherCount}}}function ut(e){return(0,N.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:e.vaultUsdcAta,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var Ie=class{network="solana:mainnet";sessionVoucherVersion=2;swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;seams;pendingCloseRevocations=new Map;completedCloseRevocations=new Map;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new k.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"},this.seams=t.seams??{}}closeRevocationKey(t){let o=oe(t.registration),[n]=(0,w.deriveSessionPda)(this.vaultPdaKey,o.allowedCounterparty,I.DEXTER_VAULT_PROGRAM_ID);return[n.toBase58(),(0,ge.bytesToHex)(o.sessionPubkey),o.nonce.toString()].join(":")}async readCloseTargetState(t){let o={connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:t,programId:I.DEXTER_VAULT_PROGRAM_ID,commitment:"finalized"};if(this.seams.readCloseRevocationTargetState)return this.seams.readCloseRevocationTargetState(o);if(this.seams.readCloseRevocationSnapshot)try{return{kind:"live",snapshot:await this.seams.readCloseRevocationSnapshot(o)}}catch{return null}return Gt(o)}targetInvalidated(t,o){if(t.kind==="invalidated")return!0;let n=t.snapshot,[i]=(0,w.deriveSessionPda)(this.vaultPdaKey,o.allowedCounterparty,I.DEXTER_VAULT_PROGRAM_ID);if(!n.programId.equals(I.DEXTER_VAULT_PROGRAM_ID)||!n.vaultPda.equals(this.vaultPdaKey)||!n.sessionPda.equals(i)||!n.allowedCounterparty.equals(o.allowedCounterparty))throw new Error("session revocation snapshot identity mismatch");if(!Buffer.from(n.sessionPubkey).equals(Buffer.from(o.sessionPubkey))||n.nonce!==o.nonce)return!0;if(n.maxAmount!==o.maxAmount||n.expiresAt!==o.expiresAt||n.maxRevolvingCapacity!==o.maxRevolvingCapacity)throw new Error("session revocation snapshot identity mismatch");return!1}rememberCompletedClose(t,o){let n=Uint8Array.from(o);return this.pendingCloseRevocations.delete(t),this.completedCloseRevocations.set(t,n),Uint8Array.from(n)}async reconcilePendingClose(t,o,n){let i=!1,s=null;try{let c=await this.connection.getSignatureStatuses([t.signature],{searchTransactionHistory:!0});if(i=!0,s=c.value[0]??null,s?.confirmationStatus==="finalized")return s.err===null?"complete":"fresh_allowed"}catch{}let r=!1;try{let c=await this.connection.getTransaction(t.signature,{commitment:"finalized",maxSupportedTransactionVersion:0});if(r=!0,c)return!c.meta||!Object.prototype.hasOwnProperty.call(c.meta,"err")?"unresolved":c.meta.err===null?"complete":"fresh_allowed"}catch{}let a=await this.readCloseTargetState(o.allowedCounterparty).catch(()=>null);if(a&&this.targetInvalidated(a,o))return"complete";if(n&&i&&s===null)try{if((await this.connection.isBlockhashValid(t.blockhash,{commitment:"confirmed"})).value)return await this.connection.sendRawTransaction(t.serializedTransaction,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment})!==t.signature?"unresolved":(await this.connection.confirmTransaction({signature:t.signature,blockhash:t.blockhash,lastValidBlockHeight:t.lastValidBlockHeight},"finalized")).value.err===null?"complete":"fresh_allowed"}catch{}if(i&&s!==null||!i||!r||t.finalizedHistoryFloorSlot===null)return"unresolved";try{let[c,m]=await Promise.all([this.connection.getBlockHeight("finalized"),this.connection.getMinimumLedgerSlot()]);if(c>t.lastValidBlockHeight&&m<=t.finalizedHistoryFloorSlot)return"fresh_allowed"}catch{}return"unresolved"}async authorizeSession(t,o){let n=new k.PublicKey(t.allowedCounterparty),i=$(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=await(this.seams.fetchSession??w.fetchSessionAccount)(this.connection,this.vaultPdaKey,n),a=r!==null&&(0,w.isSessionLive)(r);if(a&&(o?.onLiveSession??"error")!=="replace"){let h=r.session.spent,p=r.session.crystallizedCumulative;throw new D({allowedCounterparty:t.allowedCounterparty,sessionPubkeyHex:(0,ge.bytesToHex)(r.session.sessionPubkey),expiresAtUnix:r.session.expiresAt,spentAtomic:h.toString(),crystallizedCumulativeAtomic:p.toString(),currentOutstandingAtomic:r.session.currentOutstanding.toString(),frontierAtomic:(h>p?h:p).toString()})}let m=await(this.seams.fetchPasskeyAuthorization??pe.fetchPasskeyAuthorizationState)(this.connection,this.vaultPdaKey,I.DEXTER_VAULT_PROGRAM_ID);if(m===null||m.version!==1||!m.vault.equals(this.vaultPdaKey))throw new Error("passkey_authorization_guard_unavailable");let d=Te(),v=(0,_.sessionVoucherV2Nonce)(m.nonce),g=(0,_.sessionRegisterMessage)({programId:I.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:d.publicKey,maxAmount:$(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v}),S=a?(0,_.sessionReplaceV1Message)({programId:I.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPda:new k.PublicKey(r.address),authorizationNonce:m.nonce,retired:{sessionPubkey:r.session.sessionPubkey,maxAmount:r.session.maxAmount,expiresAt:BigInt(r.session.expiresAt),allowedCounterparty:new k.PublicKey(r.session.allowedCounterparty),nonce:r.session.nonce,spent:r.session.spent,currentOutstanding:r.session.currentOutstanding,maxRevolvingCapacity:r.session.maxRevolvingCapacity,crystallizedCumulative:r.session.crystallizedCumulative,lastLockedSequence:r.session.lastLockedSequence},replacement:{sessionPubkey:d.publicKey,maxAmount:$(t.maxAmountAtomic),expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v,maxRevolvingCapacity:i}}):g,y=await this.passkey.signOperation(S);if(a)await this.sendAtomicReplace(t,n,d.publicKey,v,i,y);else{if((0,pe.validatePasskeyAuthorizationClientData)({clientDataJSON:y.clientDataJSON,operationMessage:S,expectedVault:this.vaultPdaKey,expectedProgramId:I.DEXTER_VAULT_PROGRAM_ID}).nonce!==m.nonce)throw new Error("passkey_authorization_guard_changed");await this.sendBareRegister(t,n,d.publicKey,v,i,y)}return await(this.seams.waitForSession??w.waitForSession)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:d.publicKey,timeoutMs:2e4}),Ee(d,t,g)}async sendBareRegister(t,o,n,i,s,r){let{signature:a,clientDataJSON:c,authenticatorData:m}=r,d=at(m,(0,Ve.sha256)(c)),v=(0,te.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,a,d),g=this.seams.fetchSessions??w.fetchVaultSessionAccounts,S=(0,w.sessionPdasOf)(await g(this.connection,this.vaultPdaKey)),f=await(this.seams.resolveUsdcAta??w.resolveVaultUsdcAta)(this.connection,new k.PublicKey(this.swigAddress)),h=ut({vaultPda:this.vaultPdaKey,swigAddress:new k.PublicKey(this.swigAddress),sessionPubkey:n,maxAmount:$(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:o,nonce:i,clientDataJSON:c,authenticatorData:m,payer:this.feePayer.publicKey,siblingSessionPdas:S,vaultUsdcAta:f}),p=new k.Transaction().add(v,h);p.feePayer=this.feePayer.publicKey;let{blockhash:R}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=R,p.sign(this.feePayer);let P=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});await this.connection.confirmTransaction({signature:P,blockhash:R,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment)}async sendAtomicReplace(t,o,n,i,s,r){let c=await(this.seams.resolveUsdcAta??w.resolveVaultUsdcAta)(this.connection,new k.PublicKey(this.swigAddress)),m=this.seams.composeSend?{send:this.seams.composeSend,deactivateAlt:async()=>{}}:se(this.connection,this.feePayer,{commitment:this.confirmOptions.commitment});try{await(0,w.composeRevokeThenRegister)({connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:o,registerArgs:{sessionPubkey:n,maxAmount:$(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),nonce:i,swigAddress:new k.PublicKey(this.swigAddress),vaultUsdcAta:c,payer:this.feePayer.publicKey},registerCeremony:{clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData,signature:r.signature},credentialPublicKey:this.passkey.publicKey,send:m.send,fetchSession:this.seams.fetchSession,fetchSessions:this.seams.fetchSessions,fetchPasskeyAuthorization:this.seams.fetchPasskeyAuthorization})}finally{m.deactivateAlt()}}async signWithSession(t,o){let n=await Jt(o.channelId),i=oe(t.registration);if((i.nonce&2147483648)!==0){let[s]=(0,w.deriveSessionPda)(i.vaultPda,i.allowedCounterparty,i.programId),r=Be({programId:i.programId.toBase58(),vaultPda:i.vaultPda.toBase58(),sessionPda:s.toBase58(),seller:i.allowedCounterparty.toBase58(),sessionNonce:i.nonce,channelId:(0,ge.bytesToHex)(n),cumulativeAmountAtomic:o.cumulativeAmount,sequenceOrdinal:o.sequenceNumber,sessionPrivateKey:t.privateKey,sessionPublicKey:t.publicKey,sessionRegistration:t.registration});return{payload:{channelId:r.channelId,cumulativeAmount:r.cumulativeAmount,sequenceNumber:r.sequenceNumber},sessionPublicKey:Uint8Array.from(Buffer.from(r.sessionPublicKey,"hex")),sessionSignature:Uint8Array.from(Buffer.from(r.sessionSignature,"hex")),sessionRegistration:Uint8Array.from(Buffer.from(r.sessionRegistration,"hex"))}}return Oe(t,o,n)}async signOpenTab(t,o){return t.registration}async verifyFinalVoucherV2Reservation(t,o){await me(this.connection,t,o)}async signCloseTab(t,o,n){let i=oe(t.registration);if(!i.vaultPda.equals(this.vaultPdaKey)||!Buffer.from(i.sessionPubkey).equals(Buffer.from(t.publicKey)))throw new Error("session registration identity mismatch");let s=this.closeRevocationKey(t),r=this.completedCloseRevocations.get(s);if(r)return Uint8Array.from(r);let a=this.pendingCloseRevocations.get(s);if(a){let E=await this.reconcilePendingClose(a,i,!0);if(E==="complete")return this.rememberCompletedClose(s,a.message);if(E==="unresolved")throw new Error(`session revoke finality unresolved for ${a.signature}; retry close`);this.pendingCloseRevocations.delete(s)}let c=await this.readCloseTargetState(i.allowedCounterparty);if(!c)throw new Error("close revocation target state unavailable");if(c.kind==="invalidated"||this.targetInvalidated(c,i))return this.rememberCompletedClose(s,t.registration);let m=c.snapshot,d=$(n);if((m.spent>m.crystallizedCumulative?m.spent:m.crystallizedCumulative)<d)throw new Error("session revocation snapshot is behind final settlement");let g=(0,_.sessionRevokeMessage)(m),{signature:S,clientDataJSON:y,authenticatorData:f}=await this.passkey.signOperation(g),h=at(f,(0,Ve.sha256)(y)),p=(0,te.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,S,h),R=(0,N.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,allowedCounterparty:m.allowedCounterparty,expectedPendingVoucherCount:m.expectedPendingVoucherCount,clientDataJSON:y,authenticatorData:f}),P=new k.Transaction().add(p,R);P.feePayer=this.feePayer.publicKey;let x=null;try{let E=await this.connection.getSlot("finalized");x=Number.isSafeInteger(E)&&E>=0?E:null}catch{}let{blockhash:b,lastValidBlockHeight:O}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);if(P.recentBlockhash=b,P.sign(this.feePayer),!P.signature)throw new Error("session revoke transaction is unsigned");let V=Uint8Array.from(P.serialize()),u=ct.default.encode(P.signature),A={key:s,message:Uint8Array.from(g),serializedTransaction:V,signature:u,blockhash:b,lastValidBlockHeight:O,finalizedHistoryFloorSlot:x};this.pendingCloseRevocations.set(s,A);let L;try{let E=await this.connection.sendRawTransaction(V,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});if(E!==u)throw new Error(`session revoke signature mismatch expected=${u} returned=${E}`);L=await this.connection.confirmTransaction({signature:u,blockhash:b,lastValidBlockHeight:O},"finalized")}catch(E){let Ce=await this.reconcilePendingClose(A,i,!1);if(Ce==="complete")return this.rememberCompletedClose(s,g);throw Ce==="fresh_allowed"?(this.pendingCloseRevocations.delete(s),new Error("session revoke transaction finalized without effect; retry close",{cause:E})):new Error(`session revoke finality unresolved for ${u}; retry close`,{cause:E})}if(L.value.err)throw this.pendingCloseRevocations.delete(s),new Error(`session revoke transaction failed: ${JSON.stringify(L.value.err)}`);return this.rememberCompletedClose(s,g)}};function Wt(e){return new Ie(e)}function at(e,t){let o=new Uint8Array(e.length+t.length);return o.set(e,0),o.set(t,e.length),o}async function Jt(e){if(/^[0-9a-f]{64}$/i.test(e))return Xt(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function Xt(e){let t=new Uint8Array(e.length/2);for(let o=0;o<t.length;o++)t[o]=parseInt(e.substr(o*2,2),16);return t}0&&(module.exports={LiveSessionExistsError,SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID,SOLANA_FINAL_VOUCHER_V2_PROGRAM_ID,SolanaFinalVoucherV2ReservationError,TX_SIZE_LIMIT_BYTES,buildAdapterRegisterInstruction,collectAltAddresses,compileComposeV0,createSelfPayingComposeSend,createSolanaFinalVoucherV2ReservationVerifier,createSolanaVaultAdapter,deriveChannelId,inspectSolanaFinalVoucherV2Reservation,passkeySignerFromP256Keypair,verifySolanaFinalVoucherV2Reservation});
|
|
1
|
+
"use strict";var mt=Object.create;var ee=Object.defineProperty;var dt=Object.getOwnPropertyDescriptor;var gt=Object.getOwnPropertyNames;var pt=Object.getPrototypeOf,yt=Object.prototype.hasOwnProperty;var ft=(e,t)=>{for(var o in t)ee(e,o,{get:t[o],enumerable:!0})},ke=(e,t,o,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of gt(t))!yt.call(e,i)&&i!==o&&ee(e,i,{get:()=>t[i],enumerable:!(n=dt(t,i))||n.enumerable});return e};var te=(e,t,o)=>(o=e!=null?mt(pt(e)):{},ke(t||!e||!e.__esModule?ee(o,"default",{value:e,enumerable:!0}):o,e)),ht=e=>ke(ee({},"__esModule",{value:!0}),e);var jt={};ft(jt,{LiveSessionExistsError:()=>D,SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID:()=>nt,SOLANA_FINAL_VOUCHER_V2_PROGRAM_ID:()=>tt,SolanaFinalVoucherV2ReservationError:()=>Z,TX_SIZE_LIMIT_BYTES:()=>j,buildAdapterRegisterInstruction:()=>ut,collectAltAddresses:()=>we,compileComposeV0:()=>Se,createSelfPayingComposeSend:()=>Y,createSolanaFinalVoucherV2ReservationVerifier:()=>et,createSolanaVaultAdapter:()=>Wt,deriveChannelId:()=>Ne,inspectSolanaFinalVoucherV2Reservation:()=>ue,passkeySignerFromP256Keypair:()=>st,verifySolanaFinalVoucherV2Reservation:()=>me});module.exports=ht(jt);var k=require("@solana/web3.js"),ct=te(require("bs58"),1);var D=class extends Error{constructor(o){super(`a LIVE session already exists for counterparty ${o.allowedCounterparty} (session ${o.sessionPubkeyHex.slice(0,16)}\u2026, expires ${o.expiresAtUnix}; on-chain spent=${o.spentAtomic}, crystallized=${o.crystallizedCumulativeAtomic}, frontier=${o.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=o;this.name="LiveSessionExistsError"}details};var N=require("@dexterai/vault/instructions"),ne=require("@dexterai/vault/precompile"),I=require("@dexterai/vault/constants");var _=require("@dexterai/vault/messages");var X=te(require("tweetnacl"),1),J=require("@solana/web3.js"),U=require("@dexterai/vault/messages"),Ke=require("@dexterai/vault/session");var Ue=require("@noble/hashes/sha256");function Te(){let e=X.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function Ee(e,t,o){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:o}}function Oe(e,t,o){if(o.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${o.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 n=BigInt(t.cumulativeAmount),i=BigInt(e.scope.maxAmountAtomic);if(n>i)throw new Error(`voucher cumulative ${n} exceeds session cap ${i}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let r=(0,_.voucherPayloadMessage)({channelId:o,cumulativeAmount:n,sequenceNumber:t.sequenceNumber}),a=X.default.sign.detached(r,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}var vt=/^[0-9a-f]{64}$/,At=(1n<<64n)-1n;function ye(e){return Buffer.from(e).toString("hex")}function bt(e){return Uint8Array.from(Buffer.from(e,"hex"))}function fe(e,t){if(e.length!==t.length)return!1;let o=0;for(let n=0;n<e.length;n+=1)o|=(e[n]??0)^(t[n]??0);return o===0}function Be(e){if(!vt.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>At)throw new Error("native_tab_v2_cumulative_amount_invalid");let o=new J.PublicKey(e.programId),n=new J.PublicKey(e.vaultPda),i=new J.PublicKey(e.sessionPda),s=new J.PublicKey(e.seller),[r]=(0,Ke.deriveSessionPda)(n,s,o);if(!i.equals(r))throw new Error("native_tab_v2_session_pda_mismatch");let a=e.sessionRegistration,c=new DataView(a.buffer,a.byteOffset,a.byteLength),m=c.getBigUint64(128,!0),d=c.getBigInt64(136,!0),v=c.getBigUint64(180,!0),g=e.nowUnixSeconds??Math.floor(Date.now()/1e3);if(!Number.isSafeInteger(g)||g<0)throw new Error("native_tab_v2_signing_time_invalid");if(!fe(a,(0,U.sessionRegisterMessage)({programId:o,vaultPda:n,sessionPubkey:e.sessionPublicKey,maxAmount:m,expiresAt:d,allowedCounterparty:s,nonce:e.sessionNonce,maxRevolvingCapacity:v})))throw new Error("native_tab_v2_registration_identity_mismatch");if(m===0n||v===0n||v>m||d<=BigInt(g)||d>0x7fffffffffffffffn-604800n||t>m)throw new Error("native_tab_v2_registration_semantics_invalid");(0,U.sessionVoucherV2AuthorizationNonce)(e.sessionNonce);let y=X.default.sign.keyPair.fromSeed(e.sessionPrivateKey.subarray(0,32)),f=!1;try{f=fe(y.publicKey,e.sessionPublicKey)&&fe(e.sessionPrivateKey.subarray(32,64),e.sessionPublicKey)}finally{y.secretKey.fill(0)}if(!f)throw new Error("native_tab_v2_session_key_mismatch");let h=(0,U.finalVoucherV2Sequence)(e.sequenceOrdinal),p=(0,U.contextBoundVoucherV2Message)({programId:o,vaultPda:n,sessionPda:i,seller:s,sessionNonce:e.sessionNonce,channelId:bt(e.channelId),cumulativeAmount:t,sequenceNumber:h}),R=X.default.sign.detached(p,e.sessionPrivateKey);return{channelId:e.channelId,cumulativeAmount:e.cumulativeAmountAtomic,sequenceNumber:h,sessionPublicKey:ye(e.sessionPublicKey),sessionSignature:ye(R),sessionRegistration:ye(a)}}function $(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function Ne(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let o=new TextEncoder().encode(e.sellerUrl),n=Ue.sha256.create();return n.update(e.vaultPda.toBytes()),n.update(o),n.update(t),n.digest()}var P=require("@dexterai/vault/session"),lt=require("@dexterai/vault/reader"),pe=require("@dexterai/vault");var wt=te(require("tweetnacl"),1),St=require("@noble/hashes/sha256"),Pt=require("@noble/curves/p256"),oe=require("@solana/web3.js");var ve=require("@dexterai/vault/session"),Ae=require("@dexterai/vault/messages"),he="OTS_SESSION_REGISTER_V2";var F=class extends Error{constructor(o,n){super(`Invalid registration: ${o}${n?` (${n})`:""}`);this.reason=o;this.name="InvalidRegistrationError"}reason};function ie(e){if(e.length!==188)throw new F("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,he.length));if(t!==he)throw new F("wrong_domain",`got "${t}"`);for(let v=he.length;v<32;v++)if(e[v]!==0)throw new F("wrong_domain",`non-NUL padding at byte ${v}`);let o=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new oe.PublicKey(e.slice(32,64)),i=new oe.PublicKey(e.slice(64,96)),s=e.slice(96,128),r=o.getBigUint64(128,!0),a=o.getBigInt64(136,!0),c=new oe.PublicKey(e.slice(144,176)),m=o.getUint32(176,!0),d=o.getBigUint64(180,!0);if(!n.equals(I.DEXTER_VAULT_PROGRAM_ID))throw new F("wrong_program",`${n.toBase58()} is not ${I.DEXTER_VAULT_PROGRAM_ID.toBase58()}`);if(r===0n)throw new F("cap_zero");return{programId:n,vaultPda:i,sessionPubkey:new Uint8Array(s),maxAmount:r,expiresAt:a,allowedCounterparty:c,nonce:m,maxRevolvingCapacity:d}}var Ve=require("@noble/hashes/sha256"),ge=require("@noble/hashes/utils");var T=require("@solana/web3.js"),j=1232,xt=40,$e=20,Fe=4,_t=20,re=1e4,Rt=1e6,se=4,M="[tab/solana/compose]";function we(e,t){let o=new Set,n=[],i=t.toBase58();for(let s of e)for(let r of s.keys){if(r.isSigner)continue;let a=r.pubkey.toBase58();a===i||o.has(a)||(o.add(a),n.push(r.pubkey))}return n}function Se(e,t,o,n){let i=new T.TransactionMessage({payerKey:t,recentBlockhash:o,instructions:e}).compileToV0Message([n]);return new T.VersionedTransaction(i)}async function ze(e){try{let t=(await e.getRecentPrioritizationFees()).map(n=>n.prioritizationFee).filter(n=>n>0).sort((n,i)=>n-i);if(t.length===0)return re;let o=t[Math.floor(.75*(t.length-1))]??re;return Math.max(re,Math.min(o,Rt))}catch{return re}}function Vt(e){let t=e,o=String(t?.message??e??""),n=Array.isArray(t?.logs)?t.logs.join(" "):"";return/already in use/i.test(o)||/already in use/i.test(n)}function Le(e){let t=e;return(Array.isArray(t?.logs)?t.logs:[]).length===0&&/block height exceeded|has expired|blockhash not found/i.test(String(t?.message??e))}var be=e=>new Promise(t=>setTimeout(t,e));function Y(e,t,o={}){let n=o.commitment??"confirmed",i=o.altWarmupPollMs??400,s=o.altReadbackPollMs??400,r=o.altCollisionPollMs??500,a=null,c=null;async function m(f,h){let p=await ze(e),R=[T.ComputeBudgetProgram.setComputeUnitPrice({microLamports:p}),...f],S;for(let b=0;b<se;b+=1){let{blockhash:A,lastValidBlockHeight:K}=await e.getLatestBlockhash(n),V=new T.Transaction().add(...R);V.feePayer=t.publicKey,V.recentBlockhash=A,V.sign(t);try{let u=await e.sendRawTransaction(V.serialize(),{skipPreflight:!1,maxRetries:5}),w=await e.confirmTransaction({signature:u,blockhash:A,lastValidBlockHeight:K},n);if(w.value.err)throw new Error(`${h} tx failed on-chain: ${JSON.stringify(w.value.err)}`);return u}catch(u){if(Le(u)&&b<se-1){console.warn(`${M} ${h} tx expired before landing (attempt ${b+1}) \u2014 rebroadcasting with a fresh blockhash`),S=u;continue}throw u}}throw S??new Error(`${h} tx did not land after rebroadcast attempts`)}async function d(f){for(let h=0;h<_t;h+=1){let p=await e.getSlot("finalized");if(p>f)return p;await be(r)}throw new Error(`ALT collision retry: finalized slot never advanced past ${f}`)}async function v(f){for(let h=0;h<xt;h+=1){if(await e.getSlot(n)>f)return;await be(i)}throw new Error(`ALT warmup timed out: preflight (${n}) slot never passed lastExtendedSlot ${f}`)}async function g(f){if(a)return a;let h=we(f,t.publicKey),p=null,R=null,S=-1;for(let A=0;A<Fe;A+=1){let K=S<0?await e.getSlot("finalized"):await d(S),[V,u]=T.AddressLookupTableProgram.createLookupTable({authority:t.publicKey,payer:t.publicKey,recentSlot:K}),w=T.AddressLookupTableProgram.extendLookupTable({payer:t.publicKey,authority:t.publicKey,lookupTable:u,addresses:h});try{R=await m([V,w],"ALT create/extend"),p=u;break}catch(L){if(Vt(L)&&A<Fe-1){S=K,console.warn(`${M} ALT address collision at slot ${K} (attempt ${A+1}) \u2014 retrying create with a fresh finalized slot`);continue}throw L}}if(!p||!R)throw new Error("ALT create exhausted retries after repeated address collisions");let b=await e.getAddressLookupTable(p);for(let A=0;A<$e&&!b.value;A+=1)await be(s),b=await e.getAddressLookupTable(p);if(!b.value)throw new Error(`ALT ${p.toBase58()} not visible after ${$e} read polls (${R})`);return await v(b.value.state.lastExtendedSlot),a=b.value,c=p,console.info(`${M} ephemeral compose ALT ready: ${p.toBase58()} (${h.length} addresses, createTx ${R})`),a}async function x(f){let h=await ze(e),p=[T.ComputeBudgetProgram.setComputeUnitPrice({microLamports:h}),...f],R=await g(p),S;for(let b=0;b<se;b+=1){let{blockhash:A,lastValidBlockHeight:K}=await e.getLatestBlockhash(n),V;try{let u=Se(p,t.publicKey,A,R);u.sign([t]),V=u.serialize()}catch(u){throw/overrun|too large/i.test(String(u?.message??u))?new Error(`composed revoke-then-register v0 tx exceeds the ${j}B wire cap \u2014 too many sibling PDAs outside the lookup table`):u}if(V.length>j)throw new Error(`composed revoke-then-register v0 tx ${V.length}B exceeds the ${j}B wire cap \u2014 too many sibling PDAs outside the lookup table`);try{let u=await e.sendRawTransaction(V,{skipPreflight:!1,maxRetries:5}),w=await e.confirmTransaction({signature:u,blockhash:A,lastValidBlockHeight:K},n);if(w.value.err)throw new Error(`composed tx failed on-chain: ${JSON.stringify(w.value.err)}`);return u}catch(u){if(Le(u)&&b<se-1){console.warn(`${M} compose tx expired before landing (attempt ${b+1}, priorityFee ${h}) \u2014 rebroadcasting with a fresh blockhash`),S=u;continue}let w=Array.isArray(u?.logs)?u.logs:[];throw w.length?new Error(`${u?.message??u} | ${w.join(" | ")}`):u}}throw S instanceof Error?S:new Error("compose tx did not land after rebroadcast attempts")}async function y(){if(c)try{let f=T.AddressLookupTableProgram.deactivateLookupTable({lookupTable:c,authority:t.publicKey}),h=await m([f],"ALT deactivate");console.info(`${M} ephemeral compose ALT deactivated: ${c.toBase58()} (${h}) \u2014 rent reclaimable via close_lookup_table after the deactivation cooldown`)}catch(f){console.warn(`${M} ALT deactivate failed for ${c?.toBase58()} \u2014 rent parks until a later cleanup retries (the compose already landed): ${String(f?.message??f)}`)}}return{send:x,getAltAddress:()=>c,deactivateAlt:y}}var B=require("@solana/web3.js"),le=require("@noble/hashes/utils"),H=require("@dexterai/vault/credit"),Q=require("@dexterai/vault/constants"),je=require("@dexterai/vault/instructions"),Ye=require("@dexterai/vault/reader"),G=require("@dexterai/vault/session");var _e=require("@noble/hashes/sha256"),z=require("@noble/hashes/utils"),De=/^[0-9a-f]{64}$/,Me=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,It=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,qe="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",He="dexter-native-tab-v2-reservation/v1",Ct=`${He}:`;function Pe(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(Pe);if(typeof e=="object")return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[o])=>t.localeCompare(o)).map(([t,o])=>[t,Pe(o)]));throw new Error("canonical_value_unsupported")}function Ge(e){return JSON.stringify(Pe(e))}function xe(e){if(e==="solana:mainnet"||e===qe)return qe;throw new Error("native_tab_v2_reservation_network_unsupported")}function We(e){return(0,z.bytesToHex)((0,_e.sha256)(new TextEncoder().encode(Ge({channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:(0,z.bytesToHex)(e.sessionPublicKey),sessionSignature:(0,z.bytesToHex)(e.sessionSignature),sessionRegistration:(0,z.bytesToHex)(e.sessionRegistration)}))))}function kt(e){return(0,z.bytesToHex)((0,_e.sha256)(new TextEncoder().encode(Ge({contract:He,network:xe(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 Kt(e){let t=We(e.voucher);return kt({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 Je(e){return`${Ct}${Kt(e)}`}function C(e){throw new Error(`native_tab_v2_reservation_receipt_invalid:${e}`)}function ae(e,t){(!Number.isSafeInteger(e)||e<0)&&C(t)}function Xe(e,t){(!t||typeof t!="object")&&C("missing");let o=We(e.voucher);(!De.test(e.voucherDigest)||e.voucherDigest!==o)&&C("input_voucher_digest"),e.idempotencyKey!==`native-tab-v2:${o}`&&C("input_idempotency_identity");let n=BigInt(e.voucher.payload.cumulativeAmount),i=BigInt(e.previousCumulativeAtomic),s=BigInt(e.reservationAmountAtomic);(n<=i||n-i!==s||s<=0n)&&C("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)&&C("input_voucher_identity"),t.contract!=="dexter-native-tab-open-receipt/v1"&&t.contract!=="dexter-native-tab-open-receipt/v2"&&C("contract"),De.test(t.operationId)||C("operation_id"),Me.test(t.callerOperationId)||C("caller_operation_id"),It.test(t.transaction)||C("transaction"),t.commitment!=="confirmed"&&t.commitment!=="finalized"&&C("commitment"),ae(t.confirmationSlot,"confirmation_slot"),ae(t.postStateSlot,"post_state_slot"),(t.confirmationSlot===0||t.postStateSlot<t.confirmationSlot)&&C("post_state_slot");let r,a;try{r=xe(e.network),a=xe(t.network)}catch{return C("network")}(a!==r||t.buyerSwigAddress!==e.buyerSwigAddress||t.vaultPda!==e.vaultPda||t.sessionPda!==e.sessionPda||t.seller!==e.seller||t.channelId!==e.channelId||t.sessionPublicKey!==(0,z.bytesToHex)(e.voucher.sessionPublicKey)||t.voucherDigest!==o||t.cumulativeAmountAtomic!==e.voucher.payload.cumulativeAmount||t.sequenceNumber!==e.voucher.payload.sequenceNumber||!Me.test(t.providerReceiptId)||t.reservationAmountAtomic!==e.reservationAmountAtomic||t.currentOutstandingBeforeAtomic!=="0"||t.currentOutstandingAfterAtomic!==e.reservationAmountAtomic)&&C("economic_identity"),ae(t.pendingVoucherCountBefore,"pending_voucher_count_before"),ae(t.pendingVoucherCountAfter,"pending_voucher_count_after"),t.contract==="dexter-native-tab-open-receipt/v1"?t.callerOperationId!==e.idempotencyKey&&C("idempotency_key"):(t.rootOperationId!==e.idempotencyKey||!Number.isSafeInteger(t.generation)||Number(t.generation)<2||!t.predecessorCallerOperationId||!t.predecessorLifecycleOperationId||!t.predecessorReleaseDigest||!t.stableReservationId||!t.economicEffectDigest)&&C("successor_identity")}var Tt=Uint8Array.from([56,67,4,209,238,143,0,129]),Et=74,Ze=new Set([1,2]),Ot=188,Qe=new B.PublicKey("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),Bt=(()=>{let e=Buffer.alloc(32);return e.write("OTS_SESSION_REGISTER_V2","ascii"),e})(),Z=class extends Error{constructor(o,n){super(`native_tab_v2_solana_reservation_invalid:${o}`+(n?`:${n}`:""));this.code=o;this.name="SolanaFinalVoucherV2ReservationError"}code};function l(e,t){throw new Z(e,t)}function E(e,t){try{return new B.PublicKey(e)}catch{return l(t)}}function ce(e,t){return e.length===t.length&&e.every((o,n)=>o===t[n])}async function Ut(e){let o=(await e.connection.getSignatureStatuses([e.signature],{searchTransactionHistory:!0})).value[0]??null;if(!o)return null;o.confirmationStatus!=="confirmed"&&o.confirmationStatus!=="finalized"&&l("transaction_commitment"),o.err!==null&&l("transaction_failed");let n=await e.connection.getTransaction(e.signature,{commitment:e.commitment,maxSupportedTransactionVersion:0});if(!n)return null;n.meta||l("transaction_meta_missing"),n.slot!==o.slot&&l("transaction_status_slot");let i=n.transaction.message,s=i.version===0?i.getAccountKeys({accountKeysFromLookups:n.meta.loadedAddresses??null}):i.getAccountKeys(),r=(a,c)=>{let m=s.get(a);return m||l(c),m};return{slot:n.slot,confirmationStatus:o.confirmationStatus,err:n.meta.err,signatures:[...n.transaction.signatures],accountKeys:Array.from({length:s.length},(a,c)=>({address:r(c,"transaction_account_key").toBase58(),signer:i.isAccountSigner(c),writable:i.isAccountWritable(c)})),instructions:i.compiledInstructions.map(a=>({programId:r(a.programIdIndex,"transaction_program_id").toBase58(),accounts:a.accountKeyIndexes.map(c=>r(c,"transaction_instruction_account").toBase58()),data:Uint8Array.from(a.data)}))}}function Nt(e,t,o,n){n.length!==Et&&l("binding_length"),ce(n.subarray(0,8),Tt)||l("binding_discriminator");let i=n.readUInt8(8),s=n.readUInt8(9);return Ze.has(i)||l("binding_version"),s!==t&&l("binding_bump"),{address:e.toBase58(),owner:o.toBase58(),version:i,bump:s,swig:new B.PublicKey(n.subarray(10,42)).toBase58(),vault:new B.PublicKey(n.subarray(42,74)).toBase58()}}async function $t(e){let t=E(e.input.programId,"program_id"),o=E(e.input.buyerSwigAddress,"buyer_swig"),n=E(e.input.vaultPda,"vault_pda"),i=E(e.input.seller,"seller"),[s,r]=(0,H.deriveSwigVaultBindingPda)(o,t),[a]=(0,G.deriveSessionPda)(n,i,t),c=await e.connection.getMultipleAccountsInfoAndContext([s,n,a],{commitment:e.commitment,minContextSlot:e.minimumSlot}),[m,d,v]=c.value;m||l("binding_missing"),d||l("vault_missing"),v||l("session_missing");let g,x;try{g=(0,Ye.decodeVaultFull)(Buffer.from(d.data)),x=(0,G.decodeSessionAccount)(a,v.data)}catch(f){return l("post_state_decode",f instanceof Error?f.message:String(f))}let y=x.session;return{contextSlot:c.context.slot,binding:Nt(s,r,m.owner,Buffer.from(m.data)),vault:{owner:d.owner.toBase58(),exists:g.exists,version:g.version,swigAddress:g.swigAddress,dexterAuthority:g.dexterAuthority,pendingVoucherCount:g.pendingVoucherCount},session:{owner:v.owner.toBase58(),version:x.version,bump:x.bump,vault:x.vault,sessionPublicKey:(0,le.bytesToHex)(y.sessionPubkey),maxAmount:y.maxAmount,expiresAt:y.expiresAt,seller:y.allowedCounterparty,nonce:y.nonce,spent:y.spent,currentOutstanding:y.currentOutstanding,maxRevolvingCapacity:y.maxRevolvingCapacity,crystallizedCumulative:y.crystallizedCumulative}}}function Ft(e){let t=Buffer.from(e.voucher.sessionRegistration);return t.length!==Ot&&l("registration_length"),ce(t.subarray(0,32),Bt)||l("registration_domain"),{programId:new B.PublicKey(t.subarray(32,64)).toBase58(),vaultPda:new B.PublicKey(t.subarray(64,96)).toBase58(),sessionPublicKey:(0,le.bytesToHex)(t.subarray(96,128)),maxAmount:t.readBigUInt64LE(128),expiresAt:t.readBigInt64LE(136),seller:new B.PublicKey(t.subarray(144,176)).toBase58(),nonce:t.readUInt32LE(176),maxRevolvingCapacity:t.readBigUInt64LE(180)}}function q(e,t,o){let n=e.accountKeys.filter(i=>i.address===t);return n.length!==1&&l(`${o}_account_key`),n[0]}function zt(e,t,o){(!Number.isSafeInteger(o.slot)||o.slot<=0)&&l("transaction_slot"),o.slot!==t.confirmationSlot&&l("transaction_confirmation_slot"),o.err!==null&&l("transaction_failed"),o.signatures[0]!==t.transaction&&l("transaction_signature"),o.instructions.length!==2&&l("transaction_instruction_count");let n=E(e.programId,"program_id"),i=E(e.buyerSwigAddress,"buyer_swig"),s=E(e.vaultPda,"vault_pda"),r=E(e.seller,"seller"),a=E(e.sessionPda,"session_pda"),[c]=(0,G.deriveSessionPda)(s,r,n),m=(0,H.deriveSwigVaultBindingPda)(i,n)[0],d=(0,je.deriveSwigWalletAddress)(i),v=(0,H.deriveGraphConfigPda)(n)[0];a.equals(c)||l("session_pda_derivation");let g=Buffer.from(Q.DISCRIMINATORS.settle_voucher),x=o.instructions.filter(u=>{if(u.programId!==e.programId)return!1;let w=u.data;return w.length>=g.length&&ce(w.subarray(0,g.length),g)});x.length!==1&&l("settle_voucher_instruction_count");let y=x[0];o.instructions[0]!==y&&l("settle_voucher_instruction_order");let f=Buffer.from(y.data);f.length!==49&&l("settle_voucher_instruction_length"),f.readBigUInt64LE(8).toString()!==e.reservationAmountAtomic&&l("settle_voucher_amount"),f.readUInt8(16)!==1&&l("settle_voucher_increment"),new B.PublicKey(f.subarray(17,49)).equals(r)||l("settle_voucher_seller"),y.accounts.length<8&&l("settle_voucher_accounts"),[s.toBase58(),null,a.toBase58(),null,i.toBase58(),d.toBase58(),m.toBase58(),v.toBase58()].forEach((u,w)=>{u!==null&&y.accounts[w]!==u&&l(`settle_voucher_account_${w}`)});let p=y.accounts[1];p||l("dexter_authority");let R=q(o,y.accounts[0],"vault"),S=q(o,p,"dexter_authority"),b=q(o,y.accounts[2],"session");(!R.writable||R.signer)&&l("vault_privileges"),S.signer||l("dexter_authority_signature"),(!b.writable||b.signer)&&l("session_privileges");for(let u=3;u<Math.min(y.accounts.length,8);u+=1)q(o,y.accounts[u],`account_${u}`).signer&&l(`settle_voucher_account_${u}_signer`);for(let u=8;u<y.accounts.length;u+=1){let w=q(o,y.accounts[u],`sibling_${u-8}`);(!w.writable||w.signer)&&l("settle_voucher_sibling_privileges")}let A=o.instructions[1];A.programId!==Qe.toBase58()&&l("reservation_memo_program"),(A.accounts.length!==1||A.accounts[0]!==p)&&l("reservation_memo_authority"),q(o,p,"reservation_memo_authority").signer||l("reservation_memo_authority_signature");let V=new TextEncoder().encode(Je(e));return ce(A.data,V)||l("reservation_memo_digest"),p}function Lt(e,t,o,n){let i=E(e.programId,"program_id"),s=E(e.buyerSwigAddress,"buyer_swig"),r=E(e.vaultPda,"vault_pda"),a=E(e.seller,"seller"),[c,m]=(0,H.deriveSwigVaultBindingPda)(s,i),[d,v]=(0,G.deriveSessionPda)(r,a,i);(!Number.isSafeInteger(n.contextSlot)||n.contextSlot<t)&&l("post_state_slot"),(n.binding.address!==c.toBase58()||n.binding.owner!==e.programId||n.binding.bump!==m||!Ze.has(n.binding.version)||n.binding.swig!==e.buyerSwigAddress||n.binding.vault!==e.vaultPda)&&l("binding_identity"),(n.vault.owner!==e.programId||!n.vault.exists||n.vault.version!==7||n.vault.swigAddress!==e.buyerSwigAddress||n.vault.dexterAuthority!==o)&&l("vault_post_state"),(e.sessionPda!==d.toBase58()||n.session.owner!==e.programId||n.session.version!==1||n.session.bump!==v||n.session.vault!==e.vaultPda||n.session.sessionPublicKey!==(0,le.bytesToHex)(e.voucher.sessionPublicKey)||n.session.seller!==e.seller||n.session.nonce!==e.sessionNonce||n.session.currentOutstanding.toString()!==e.reservationAmountAtomic)&&l("session_post_state");let g=Ft(e);(g.programId!==e.programId||g.vaultPda!==e.vaultPda||g.sessionPublicKey!==n.session.sessionPublicKey||g.seller!==e.seller||g.nonce!==e.sessionNonce||g.maxAmount!==n.session.maxAmount||g.expiresAt!==BigInt(n.session.expiresAt)||g.maxRevolvingCapacity!==n.session.maxRevolvingCapacity)&&l("registration_post_state");let x=n.session.spent>n.session.crystallizedCumulative?n.session.spent:n.session.crystallizedCumulative;return x.toString()!==e.previousCumulativeAtomic&&l("session_frontier"),{commitment:"confirmed",confirmationSlot:t,postStateSlot:n.contextSlot,sessionAccountVersion:n.session.version,wireVersion:2,frontierAtomic:x.toString(),spentAtomic:n.session.spent.toString(),currentOutstandingAtomic:n.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:n.session.crystallizedCumulative.toString()}}async function ue(e,t,o,n={}){try{Xe(t,o)}catch(a){return l("provider_receipt",a instanceof Error?a.message:String(a))}t.network!=="solana:mainnet"&&l("network"),t.programId!==Q.DEXTER_VAULT_PROGRAM_ID.toBase58()&&l("program_id");let i=await(n.readTransaction??Ut)({connection:e,signature:o.transaction,commitment:"confirmed"});i||l("transaction_missing"),i.confirmationStatus!=="confirmed"&&i.confirmationStatus!=="finalized"&&l("transaction_commitment");let s=zt(t,o,i),r=await(n.readPostState??$t)({connection:e,input:t,minimumSlot:i.slot,commitment:"confirmed"});return{...Lt(t,i.slot,s,r),commitment:i.confirmationStatus}}async function me(e,t,o,n={}){await ue(e,t,o,n)}function et(e,t={}){return async(o,n)=>{await ue(e,o,n,t)}}var tt=Q.DEXTER_VAULT_PROGRAM_ID,nt=Qe;var Re=require("@noble/curves/p256"),W=require("@noble/hashes/sha256"),de=require("@dexterai/vault"),it=require("@dexterai/vault/messages"),rt="dexter.cash";function Dt(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Mt(e,t=`https://${rt}`){let n={type:"webauthn.get",challenge:Dt(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(n))}function qt(e=1){let t=(0,W.sha256)(new TextEncoder().encode(rt)),o=new Uint8Array(37);return o.set(t,0),o[32]=5,new DataView(o.buffer).setUint32(33,e,!1),o}function ot(e,t){let o=Mt(t),n=qt(1),i=new Uint8Array(n.length+32);i.set(n,0),i.set((0,W.sha256)(o),n.length);let s=(0,W.sha256)(i);return{signature:Re.p256.sign(s,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:o,authenticatorData:n}}function st(e,t={}){return{credentialId:new Uint8Array(0),publicKey:e.publicKey,signOperation:async o=>{let n=t.resolveAuthorizationContext?await t.resolveAuthorizationContext(o.slice()):Ht(o);if(!n){if(t.allowLegacyOperationHash===!0)return ot(e,(0,W.sha256)(o));throw new Error("passkey_authorization_context_required")}let i=t.ceremonyNonce?t.ceremonyNonce():Re.p256.utils.randomPrivateKey();if(i.length!==32)throw new Error("ceremonyNonce must be exactly 32 bytes");let s=(0,de.buildPasskeyAuthorizationChallenge)({programId:n.programId,vault:n.vault,nonce:n.nonce,operationHash:(0,W.sha256)(o),ceremonyNonce:i});return ot(e,s)}}}function Ht(e){let t=(0,de.classifyPasskeyAuthorizationOperation)(e);return t.kind==="session_register_v2"?{programId:t.fields.programId,vault:t.fields.vault,nonce:BigInt((0,it.sessionVoucherV2AuthorizationNonce)(t.fields.registrationNonce))}:t.kind==="session_replace_v1"?{programId:t.fields.programId,vault:t.fields.vault,nonce:t.fields.authorizationNonce}:null}async function Gt({connection:e,vaultPda:t,allowedCounterparty:o,programId:n=I.DEXTER_VAULT_PROGRAM_ID,commitment:i="finalized"}){let[s]=(0,P.deriveSessionPda)(t,o,n),r=await e.getMultipleAccountsInfoAndContext([t,s],{commitment:i}),[a,c]=r.value;if(!a)throw new Error("close revocation: vault account not found");if(!a.owner.equals(n))throw new Error("close revocation: vault has the wrong owner");let m=(0,lt.decodeVaultFull)(Buffer.from(a.data));if(!m.exists||m.version!==7)throw new Error("close revocation: Vault V7 required");if(!c)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"absent"};if(!c.owner.equals(n))throw new Error("close revocation: session has the wrong owner");let d=(0,P.decodeSessionAccount)(s,c.data);if(d.version===0)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"cleared"};if(d.version!==1)throw new Error("close revocation: live SessionAccount required");if(d.vault!==t.toBase58())throw new Error("close revocation: session belongs to a different vault");if(d.session.allowedCounterparty!==o.toBase58())throw new Error("close revocation: session counterparty mismatch");return{kind:"live",snapshot:{contextSlot:r.context.slot,programId:new k.PublicKey(n),vaultPda:new k.PublicKey(t),sessionPda:s,sessionPubkey:Uint8Array.from(d.session.sessionPubkey),maxAmount:d.session.maxAmount,expiresAt:Buffer.from(c.data).readBigInt64LE(82),allowedCounterparty:new k.PublicKey(o),nonce:d.session.nonce,spent:d.session.spent,currentOutstanding:d.session.currentOutstanding,maxRevolvingCapacity:d.session.maxRevolvingCapacity,crystallizedCumulative:d.session.crystallizedCumulative,lastLockedSequence:d.session.lastLockedSequence,expectedPendingVoucherCount:m.pendingVoucherCount}}}function ut(e){return(0,N.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:e.vaultUsdcAta,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var Ie=class{network="solana:mainnet";sessionVoucherVersion=2;swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;seams;pendingCloseRevocations=new Map;completedCloseRevocations=new Map;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new k.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"},this.seams=t.seams??{}}closeRevocationKey(t){let o=ie(t.registration),[n]=(0,P.deriveSessionPda)(this.vaultPdaKey,o.allowedCounterparty,I.DEXTER_VAULT_PROGRAM_ID);return[n.toBase58(),(0,ge.bytesToHex)(o.sessionPubkey),o.nonce.toString()].join(":")}async readCloseTargetState(t){let o={connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:t,programId:I.DEXTER_VAULT_PROGRAM_ID,commitment:"finalized"};if(this.seams.readCloseRevocationTargetState)return this.seams.readCloseRevocationTargetState(o);if(this.seams.readCloseRevocationSnapshot)try{return{kind:"live",snapshot:await this.seams.readCloseRevocationSnapshot(o)}}catch{return null}return Gt(o)}targetInvalidated(t,o){if(t.kind==="invalidated")return!0;let n=t.snapshot,[i]=(0,P.deriveSessionPda)(this.vaultPdaKey,o.allowedCounterparty,I.DEXTER_VAULT_PROGRAM_ID);if(!n.programId.equals(I.DEXTER_VAULT_PROGRAM_ID)||!n.vaultPda.equals(this.vaultPdaKey)||!n.sessionPda.equals(i)||!n.allowedCounterparty.equals(o.allowedCounterparty))throw new Error("session revocation snapshot identity mismatch");if(!Buffer.from(n.sessionPubkey).equals(Buffer.from(o.sessionPubkey))||n.nonce!==o.nonce)return!0;if(n.maxAmount!==o.maxAmount||n.expiresAt!==o.expiresAt||n.maxRevolvingCapacity!==o.maxRevolvingCapacity)throw new Error("session revocation snapshot identity mismatch");return!1}rememberCompletedClose(t,o){let n=Uint8Array.from(o);return this.pendingCloseRevocations.delete(t),this.completedCloseRevocations.set(t,n),Uint8Array.from(n)}async reconcilePendingClose(t,o,n){let i=!1,s=null;try{let c=await this.connection.getSignatureStatuses([t.signature],{searchTransactionHistory:!0});if(i=!0,s=c.value[0]??null,s?.confirmationStatus==="finalized")return s.err===null?"complete":"fresh_allowed"}catch{}let r=!1;try{let c=await this.connection.getTransaction(t.signature,{commitment:"finalized",maxSupportedTransactionVersion:0});if(r=!0,c)return!c.meta||!Object.prototype.hasOwnProperty.call(c.meta,"err")?"unresolved":c.meta.err===null?"complete":"fresh_allowed"}catch{}let a=await this.readCloseTargetState(o.allowedCounterparty).catch(()=>null);if(a&&this.targetInvalidated(a,o))return"complete";if(n&&i&&s===null)try{if((await this.connection.isBlockhashValid(t.blockhash,{commitment:"confirmed"})).value)return await this.connection.sendRawTransaction(t.serializedTransaction,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment})!==t.signature?"unresolved":(await this.connection.confirmTransaction({signature:t.signature,blockhash:t.blockhash,lastValidBlockHeight:t.lastValidBlockHeight},"finalized")).value.err===null?"complete":"fresh_allowed"}catch{}if(i&&s!==null||!i||!r||t.finalizedHistoryFloorSlot===null)return"unresolved";try{let[c,m]=await Promise.all([this.connection.getBlockHeight("finalized"),this.connection.getMinimumLedgerSlot()]);if(c>t.lastValidBlockHeight&&m<=t.finalizedHistoryFloorSlot)return"fresh_allowed"}catch{}return"unresolved"}async authorizeSession(t,o){let n=new k.PublicKey(t.allowedCounterparty),i=$(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=await(this.seams.fetchSession??P.fetchSessionAccount)(this.connection,this.vaultPdaKey,n),a=r!==null&&(0,P.isSessionLive)(r);if(a&&(o?.onLiveSession??"error")!=="replace"){let h=r.session.spent,p=r.session.crystallizedCumulative;throw new D({allowedCounterparty:t.allowedCounterparty,sessionPubkeyHex:(0,ge.bytesToHex)(r.session.sessionPubkey),expiresAtUnix:r.session.expiresAt,spentAtomic:h.toString(),crystallizedCumulativeAtomic:p.toString(),currentOutstandingAtomic:r.session.currentOutstanding.toString(),frontierAtomic:(h>p?h:p).toString()})}let m=await(this.seams.fetchPasskeyAuthorization??pe.fetchPasskeyAuthorizationState)(this.connection,this.vaultPdaKey,I.DEXTER_VAULT_PROGRAM_ID);if(m===null||m.version!==1||!m.vault.equals(this.vaultPdaKey))throw new Error("passkey_authorization_guard_unavailable");let d=Te(),v=(0,_.sessionVoucherV2Nonce)(m.nonce),g=(0,_.sessionRegisterMessage)({programId:I.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:d.publicKey,maxAmount:$(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v}),x=a?(0,_.sessionReplaceV1Message)({programId:I.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPda:new k.PublicKey(r.address),authorizationNonce:m.nonce,retired:{sessionPubkey:r.session.sessionPubkey,maxAmount:r.session.maxAmount,expiresAt:BigInt(r.session.expiresAt),allowedCounterparty:new k.PublicKey(r.session.allowedCounterparty),nonce:r.session.nonce,spent:r.session.spent,currentOutstanding:r.session.currentOutstanding,maxRevolvingCapacity:r.session.maxRevolvingCapacity,crystallizedCumulative:r.session.crystallizedCumulative,lastLockedSequence:r.session.lastLockedSequence},replacement:{sessionPubkey:d.publicKey,maxAmount:$(t.maxAmountAtomic),expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v,maxRevolvingCapacity:i}}):g,y=await this.passkey.signOperation(x);if(a)await this.sendAtomicReplace(t,n,d.publicKey,v,i,y);else{if((0,pe.validatePasskeyAuthorizationClientData)({clientDataJSON:y.clientDataJSON,operationMessage:x,expectedVault:this.vaultPdaKey,expectedProgramId:I.DEXTER_VAULT_PROGRAM_ID}).nonce!==m.nonce)throw new Error("passkey_authorization_guard_changed");await this.sendBareRegister(t,n,d.publicKey,v,i,y)}return await(this.seams.waitForSession??P.waitForSession)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:d.publicKey,timeoutMs:2e4}),Ee(d,t,g)}async sendBareRegister(t,o,n,i,s,r){let{signature:a,clientDataJSON:c,authenticatorData:m}=r,d=at(m,(0,Ve.sha256)(c)),v=(0,ne.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,a,d),g=this.seams.fetchSessions??P.fetchVaultSessionAccounts,x=(0,P.sessionPdasOf)(await g(this.connection,this.vaultPdaKey)),f=await(this.seams.resolveUsdcAta??P.resolveVaultUsdcAta)(this.connection,new k.PublicKey(this.swigAddress)),h=ut({vaultPda:this.vaultPdaKey,swigAddress:new k.PublicKey(this.swigAddress),sessionPubkey:n,maxAmount:$(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:o,nonce:i,clientDataJSON:c,authenticatorData:m,payer:this.feePayer.publicKey,siblingSessionPdas:x,vaultUsdcAta:f}),p=new k.Transaction().add(v,h);p.feePayer=this.feePayer.publicKey;let{blockhash:R}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=R,p.sign(this.feePayer);let S;try{S=p.serialize()}catch(A){if(!/^Transaction too large: \d+ > 1232$/i.test(String(A?.message??A)))throw A;let K=this.seams.composeSend?{send:this.seams.composeSend,deactivateAlt:async()=>{}}:Y(this.connection,this.feePayer,{commitment:this.confirmOptions.commitment});try{await K.send([v,h])}finally{K.deactivateAlt()}return}let b=await this.connection.sendRawTransaction(S,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});await this.connection.confirmTransaction({signature:b,blockhash:R,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment)}async sendAtomicReplace(t,o,n,i,s,r){let c=await(this.seams.resolveUsdcAta??P.resolveVaultUsdcAta)(this.connection,new k.PublicKey(this.swigAddress)),m=this.seams.composeSend?{send:this.seams.composeSend,deactivateAlt:async()=>{}}:Y(this.connection,this.feePayer,{commitment:this.confirmOptions.commitment});try{await(0,P.composeRevokeThenRegister)({connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:o,registerArgs:{sessionPubkey:n,maxAmount:$(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),nonce:i,swigAddress:new k.PublicKey(this.swigAddress),vaultUsdcAta:c,payer:this.feePayer.publicKey},registerCeremony:{clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData,signature:r.signature},credentialPublicKey:this.passkey.publicKey,send:m.send,fetchSession:this.seams.fetchSession,fetchSessions:this.seams.fetchSessions,fetchPasskeyAuthorization:this.seams.fetchPasskeyAuthorization})}finally{m.deactivateAlt()}}async signWithSession(t,o){let n=await Jt(o.channelId),i=ie(t.registration);if((i.nonce&2147483648)!==0){let[s]=(0,P.deriveSessionPda)(i.vaultPda,i.allowedCounterparty,i.programId),r=Be({programId:i.programId.toBase58(),vaultPda:i.vaultPda.toBase58(),sessionPda:s.toBase58(),seller:i.allowedCounterparty.toBase58(),sessionNonce:i.nonce,channelId:(0,ge.bytesToHex)(n),cumulativeAmountAtomic:o.cumulativeAmount,sequenceOrdinal:o.sequenceNumber,sessionPrivateKey:t.privateKey,sessionPublicKey:t.publicKey,sessionRegistration:t.registration});return{payload:{channelId:r.channelId,cumulativeAmount:r.cumulativeAmount,sequenceNumber:r.sequenceNumber},sessionPublicKey:Uint8Array.from(Buffer.from(r.sessionPublicKey,"hex")),sessionSignature:Uint8Array.from(Buffer.from(r.sessionSignature,"hex")),sessionRegistration:Uint8Array.from(Buffer.from(r.sessionRegistration,"hex"))}}return Oe(t,o,n)}async signOpenTab(t,o){return t.registration}async verifyFinalVoucherV2Reservation(t,o){await me(this.connection,t,o)}async signCloseTab(t,o,n){let i=ie(t.registration);if(!i.vaultPda.equals(this.vaultPdaKey)||!Buffer.from(i.sessionPubkey).equals(Buffer.from(t.publicKey)))throw new Error("session registration identity mismatch");let s=this.closeRevocationKey(t),r=this.completedCloseRevocations.get(s);if(r)return Uint8Array.from(r);let a=this.pendingCloseRevocations.get(s);if(a){let O=await this.reconcilePendingClose(a,i,!0);if(O==="complete")return this.rememberCompletedClose(s,a.message);if(O==="unresolved")throw new Error(`session revoke finality unresolved for ${a.signature}; retry close`);this.pendingCloseRevocations.delete(s)}let c=await this.readCloseTargetState(i.allowedCounterparty);if(!c)throw new Error("close revocation target state unavailable");if(c.kind==="invalidated"||this.targetInvalidated(c,i))return this.rememberCompletedClose(s,t.registration);let m=c.snapshot,d=$(n);if((m.spent>m.crystallizedCumulative?m.spent:m.crystallizedCumulative)<d)throw new Error("session revocation snapshot is behind final settlement");let g=(0,_.sessionRevokeMessage)(m),{signature:x,clientDataJSON:y,authenticatorData:f}=await this.passkey.signOperation(g),h=at(f,(0,Ve.sha256)(y)),p=(0,ne.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,x,h),R=(0,N.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,allowedCounterparty:m.allowedCounterparty,expectedPendingVoucherCount:m.expectedPendingVoucherCount,clientDataJSON:y,authenticatorData:f}),S=new k.Transaction().add(p,R);S.feePayer=this.feePayer.publicKey;let b=null;try{let O=await this.connection.getSlot("finalized");b=Number.isSafeInteger(O)&&O>=0?O:null}catch{}let{blockhash:A,lastValidBlockHeight:K}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);if(S.recentBlockhash=A,S.sign(this.feePayer),!S.signature)throw new Error("session revoke transaction is unsigned");let V=Uint8Array.from(S.serialize()),u=ct.default.encode(S.signature),w={key:s,message:Uint8Array.from(g),serializedTransaction:V,signature:u,blockhash:A,lastValidBlockHeight:K,finalizedHistoryFloorSlot:b};this.pendingCloseRevocations.set(s,w);let L;try{let O=await this.connection.sendRawTransaction(V,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});if(O!==u)throw new Error(`session revoke signature mismatch expected=${u} returned=${O}`);L=await this.connection.confirmTransaction({signature:u,blockhash:A,lastValidBlockHeight:K},"finalized")}catch(O){let Ce=await this.reconcilePendingClose(w,i,!1);if(Ce==="complete")return this.rememberCompletedClose(s,g);throw Ce==="fresh_allowed"?(this.pendingCloseRevocations.delete(s),new Error("session revoke transaction finalized without effect; retry close",{cause:O})):new Error(`session revoke finality unresolved for ${u}; retry close`,{cause:O})}if(L.value.err)throw this.pendingCloseRevocations.delete(s),new Error(`session revoke transaction failed: ${JSON.stringify(L.value.err)}`);return this.rememberCompletedClose(s,g)}};function Wt(e){return new Ie(e)}function at(e,t){let o=new Uint8Array(e.length+t.length);return o.set(e,0),o.set(t,e.length),o}async function Jt(e){if(/^[0-9a-f]{64}$/i.test(e))return Xt(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function Xt(e){let t=new Uint8Array(e.length/2);for(let o=0;o<t.length;o++)t[o]=parseInt(e.substr(o*2,2),16);return t}0&&(module.exports={LiveSessionExistsError,SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID,SOLANA_FINAL_VOUCHER_V2_PROGRAM_ID,SolanaFinalVoucherV2ReservationError,TX_SIZE_LIMIT_BYTES,buildAdapterRegisterInstruction,collectAltAddresses,compileComposeV0,createSelfPayingComposeSend,createSolanaFinalVoucherV2ReservationVerifier,createSolanaVaultAdapter,deriveChannelId,inspectSolanaFinalVoucherV2Reservation,passkeySignerFromP256Keypair,verifySolanaFinalVoucherV2Reservation});
|
|
@@ -192,8 +192,9 @@ declare const SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID: PublicKey;
|
|
|
192
192
|
* table holding every non-signer account of the composed instructions
|
|
193
193
|
* (vault, target session PDA, vaultUsdcAta, swig, swig wallet PDA, sysvar,
|
|
194
194
|
* system program, sibling session PDAs) — 1166–1174 B on-chain-proven. The
|
|
195
|
-
* register-only (not-live) path stays on the adapter's legacy send
|
|
196
|
-
* and
|
|
195
|
+
* register-only (not-live) path stays on the adapter's legacy send while it
|
|
196
|
+
* fits and reuses this transport when required sibling accounts push it past
|
|
197
|
+
* the packet cap.
|
|
197
198
|
*
|
|
198
199
|
* SELF-PAYING vs SPONSORED: this is the buyer-side twin of dexter-api's
|
|
199
200
|
* sponsor-owned K-T4b transport (dexter-api src/vault/revokeRegisterCompose.ts,
|
|
@@ -192,8 +192,9 @@ declare const SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID: PublicKey;
|
|
|
192
192
|
* table holding every non-signer account of the composed instructions
|
|
193
193
|
* (vault, target session PDA, vaultUsdcAta, swig, swig wallet PDA, sysvar,
|
|
194
194
|
* system program, sibling session PDAs) — 1166–1174 B on-chain-proven. The
|
|
195
|
-
* register-only (not-live) path stays on the adapter's legacy send
|
|
196
|
-
* and
|
|
195
|
+
* register-only (not-live) path stays on the adapter's legacy send while it
|
|
196
|
+
* fits and reuses this transport when required sibling accounts push it past
|
|
197
|
+
* the packet cap.
|
|
197
198
|
*
|
|
198
199
|
* SELF-PAYING vs SPONSORED: this is the buyer-side twin of dexter-api's
|
|
199
200
|
* sponsor-owned K-T4b transport (dexter-api src/vault/revokeRegisterCompose.ts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PublicKey as K,Transaction as Je}from"@solana/web3.js";import Ht from"bs58";var F=class extends Error{constructor(o){super(`a LIVE session already exists for counterparty ${o.allowedCounterparty} (session ${o.sessionPubkeyHex.slice(0,16)}\u2026, expires ${o.expiresAtUnix}; on-chain spent=${o.spentAtomic}, crystallized=${o.crystallizedCumulativeAtomic}, frontier=${o.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=o;this.name="LiveSessionExistsError"}details};import{buildRegisterSessionKeyInstruction as fe,buildRevokeSessionKeyInstruction as he,deriveSwigWalletAddress as un}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as Y}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as V,SECP256R1_PROGRAM_ID as gn,INSTRUCTIONS_SYSVAR_ID as pn}from"@dexterai/vault/constants";import{sessionRegisterMessage as ve,sessionReplaceV1Message as Ae,sessionRevokeMessage as be,sessionVoucherV2Nonce as we,sessionVoucherV2AuthorizationNonce as hn,finalVoucherV2Sequence as vn,voucherV2SequenceOrdinal as An,voucherPayloadMessage as Z,buildVoucherMessage as bn}from"@dexterai/vault/messages";import D from"tweetnacl";import{PublicKey as L}from"@solana/web3.js";import{contextBoundVoucherV2Message as Ze,finalVoucherV2Sequence as Qe,sessionRegisterMessage as et,sessionVoucherV2AuthorizationNonce as tt}from"@dexterai/vault/messages";import{deriveSessionPda as nt}from"@dexterai/vault/session";import{sha256 as st}from"@noble/hashes/sha256";function Se(){let e=D.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function Pe(e,t,o){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:o}}function xe(e,t,o){if(o.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${o.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 n=BigInt(t.cumulativeAmount),i=BigInt(e.scope.maxAmountAtomic);if(n>i)throw new Error(`voucher cumulative ${n} exceeds session cap ${i}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let r=Z({channelId:o,cumulativeAmount:n,sequenceNumber:t.sequenceNumber}),a=D.sign.detached(r,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}var ot=/^[0-9a-f]{64}$/,it=(1n<<64n)-1n;function Q(e){return Buffer.from(e).toString("hex")}function rt(e){return Uint8Array.from(Buffer.from(e,"hex"))}function ee(e,t){if(e.length!==t.length)return!1;let o=0;for(let n=0;n<e.length;n+=1)o|=(e[n]??0)^(t[n]??0);return o===0}function _e(e){if(!ot.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>it)throw new Error("native_tab_v2_cumulative_amount_invalid");let o=new L(e.programId),n=new L(e.vaultPda),i=new L(e.sessionPda),s=new L(e.seller),[r]=nt(n,s,o);if(!i.equals(r))throw new Error("native_tab_v2_session_pda_mismatch");let a=e.sessionRegistration,c=new DataView(a.buffer,a.byteOffset,a.byteLength),m=c.getBigUint64(128,!0),d=c.getBigInt64(136,!0),v=c.getBigUint64(180,!0),g=e.nowUnixSeconds??Math.floor(Date.now()/1e3);if(!Number.isSafeInteger(g)||g<0)throw new Error("native_tab_v2_signing_time_invalid");if(!ee(a,et({programId:o,vaultPda:n,sessionPubkey:e.sessionPublicKey,maxAmount:m,expiresAt:d,allowedCounterparty:s,nonce:e.sessionNonce,maxRevolvingCapacity:v})))throw new Error("native_tab_v2_registration_identity_mismatch");if(m===0n||v===0n||v>m||d<=BigInt(g)||d>0x7fffffffffffffffn-604800n||t>m)throw new Error("native_tab_v2_registration_semantics_invalid");tt(e.sessionNonce);let y=D.sign.keyPair.fromSeed(e.sessionPrivateKey.subarray(0,32)),f=!1;try{f=ee(y.publicKey,e.sessionPublicKey)&&ee(e.sessionPrivateKey.subarray(32,64),e.sessionPublicKey)}finally{y.secretKey.fill(0)}if(!f)throw new Error("native_tab_v2_session_key_mismatch");let h=Qe(e.sequenceOrdinal),p=Ze({programId:o,vaultPda:n,sessionPda:i,seller:s,sessionNonce:e.sessionNonce,channelId:rt(e.channelId),cumulativeAmount:t,sequenceNumber:h}),x=D.sign.detached(p,e.sessionPrivateKey);return{channelId:e.channelId,cumulativeAmount:e.cumulativeAmountAtomic,sequenceNumber:h,sessionPublicKey:Q(e.sessionPublicKey),sessionSignature:Q(x),sessionRegistration:Q(a)}}function E(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function at(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let o=new TextEncoder().encode(e.sellerUrl),n=st.create();return n.update(e.vaultPda.toBytes()),n.update(o),n.update(t),n.digest()}import{fetchVaultSessionAccounts as Gt,fetchSessionAccount as Wt,decodeSessionAccount as Jt,deriveSessionPda as j,isSessionLive as Xt,sessionPdasOf as jt,waitForSession as Yt,resolveVaultUsdcAta as Xe,composeRevokeThenRegister as Zt}from"@dexterai/vault/session";import{decodeVaultFull as Qt}from"@dexterai/vault/reader";import{fetchPasskeyAuthorizationState as en,validatePasskeyAuthorizationClientData as tn}from"@dexterai/vault";import Cn from"tweetnacl";import{sha256 as Kn}from"@noble/hashes/sha256";import{p256 as En}from"@noble/curves/p256";import{PublicKey as te}from"@solana/web3.js";import{decodeSessionAccount as Fn,deriveSessionPda as zn,isSessionLive as Ln}from"@dexterai/vault/session";import{contextBoundVoucherV2Message as Mn,sessionVoucherV2AuthorizationNonce as qn,voucherV2SequenceOrdinal as Hn}from"@dexterai/vault/messages";var ne="OTS_SESSION_REGISTER_V2";var O=class extends Error{constructor(o,n){super(`Invalid registration: ${o}${n?` (${n})`:""}`);this.reason=o;this.name="InvalidRegistrationError"}reason};function M(e){if(e.length!==188)throw new O("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,ne.length));if(t!==ne)throw new O("wrong_domain",`got "${t}"`);for(let v=ne.length;v<32;v++)if(e[v]!==0)throw new O("wrong_domain",`non-NUL padding at byte ${v}`);let o=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new te(e.slice(32,64)),i=new te(e.slice(64,96)),s=e.slice(96,128),r=o.getBigUint64(128,!0),a=o.getBigInt64(136,!0),c=new te(e.slice(144,176)),m=o.getUint32(176,!0),d=o.getBigUint64(180,!0);if(!n.equals(V))throw new O("wrong_program",`${n.toBase58()} is not ${V.toBase58()}`);if(r===0n)throw new O("cap_zero");return{programId:n,vaultPda:i,sessionPubkey:new Uint8Array(s),maxAmount:r,expiresAt:a,allowedCounterparty:c,nonce:m,maxRevolvingCapacity:d}}import{sha256 as je}from"@noble/hashes/sha256";import{bytesToHex as ge}from"@noble/hashes/utils";import{AddressLookupTableProgram as oe,ComputeBudgetProgram as Re,Transaction as ct,TransactionMessage as lt,VersionedTransaction as ut}from"@solana/web3.js";var G=1232,mt=40,Ve=20,Ie=4,dt=20,q=1e4,gt=1e6,H=4,U="[tab/solana/compose]";function Ke(e,t){let o=new Set,n=[],i=t.toBase58();for(let s of e)for(let r of s.keys){if(r.isSigner)continue;let a=r.pubkey.toBase58();a===i||o.has(a)||(o.add(a),n.push(r.pubkey))}return n}function Te(e,t,o,n){let i=new lt({payerKey:t,recentBlockhash:o,instructions:e}).compileToV0Message([n]);return new ut(i)}async function Ce(e){try{let t=(await e.getRecentPrioritizationFees()).map(n=>n.prioritizationFee).filter(n=>n>0).sort((n,i)=>n-i);if(t.length===0)return q;let o=t[Math.floor(.75*(t.length-1))]??q;return Math.max(q,Math.min(o,gt))}catch{return q}}function pt(e){let t=e,o=String(t?.message??e??""),n=Array.isArray(t?.logs)?t.logs.join(" "):"";return/already in use/i.test(o)||/already in use/i.test(n)}function ke(e){let t=e;return(Array.isArray(t?.logs)?t.logs:[]).length===0&&/block height exceeded|has expired|blockhash not found/i.test(String(t?.message??e))}var ie=e=>new Promise(t=>setTimeout(t,e));function re(e,t,o={}){let n=o.commitment??"confirmed",i=o.altWarmupPollMs??400,s=o.altReadbackPollMs??400,r=o.altCollisionPollMs??500,a=null,c=null;async function m(f,h){let p=await Ce(e),x=[Re.setComputeUnitPrice({microLamports:p}),...f],S;for(let P=0;P<H;P+=1){let{blockhash:b,lastValidBlockHeight:k}=await e.getLatestBlockhash(n),_=new ct().add(...x);_.feePayer=t.publicKey,_.recentBlockhash=b,_.sign(t);try{let u=await e.sendRawTransaction(_.serialize(),{skipPreflight:!1,maxRetries:5}),A=await e.confirmTransaction({signature:u,blockhash:b,lastValidBlockHeight:k},n);if(A.value.err)throw new Error(`${h} tx failed on-chain: ${JSON.stringify(A.value.err)}`);return u}catch(u){if(ke(u)&&P<H-1){console.warn(`${U} ${h} tx expired before landing (attempt ${P+1}) \u2014 rebroadcasting with a fresh blockhash`),S=u;continue}throw u}}throw S??new Error(`${h} tx did not land after rebroadcast attempts`)}async function d(f){for(let h=0;h<dt;h+=1){let p=await e.getSlot("finalized");if(p>f)return p;await ie(r)}throw new Error(`ALT collision retry: finalized slot never advanced past ${f}`)}async function v(f){for(let h=0;h<mt;h+=1){if(await e.getSlot(n)>f)return;await ie(i)}throw new Error(`ALT warmup timed out: preflight (${n}) slot never passed lastExtendedSlot ${f}`)}async function g(f){if(a)return a;let h=Ke(f,t.publicKey),p=null,x=null,S=-1;for(let b=0;b<Ie;b+=1){let k=S<0?await e.getSlot("finalized"):await d(S),[_,u]=oe.createLookupTable({authority:t.publicKey,payer:t.publicKey,recentSlot:k}),A=oe.extendLookupTable({payer:t.publicKey,authority:t.publicKey,lookupTable:u,addresses:h});try{x=await m([_,A],"ALT create/extend"),p=u;break}catch(B){if(pt(B)&&b<Ie-1){S=k,console.warn(`${U} ALT address collision at slot ${k} (attempt ${b+1}) \u2014 retrying create with a fresh finalized slot`);continue}throw B}}if(!p||!x)throw new Error("ALT create exhausted retries after repeated address collisions");let P=await e.getAddressLookupTable(p);for(let b=0;b<Ve&&!P.value;b+=1)await ie(s),P=await e.getAddressLookupTable(p);if(!P.value)throw new Error(`ALT ${p.toBase58()} not visible after ${Ve} read polls (${x})`);return await v(P.value.state.lastExtendedSlot),a=P.value,c=p,console.info(`${U} ephemeral compose ALT ready: ${p.toBase58()} (${h.length} addresses, createTx ${x})`),a}async function w(f){let h=await Ce(e),p=[Re.setComputeUnitPrice({microLamports:h}),...f],x=await g(p),S;for(let P=0;P<H;P+=1){let{blockhash:b,lastValidBlockHeight:k}=await e.getLatestBlockhash(n),_;try{let u=Te(p,t.publicKey,b,x);u.sign([t]),_=u.serialize()}catch(u){throw/overrun|too large/i.test(String(u?.message??u))?new Error(`composed revoke-then-register v0 tx exceeds the ${G}B wire cap \u2014 too many sibling PDAs outside the lookup table`):u}if(_.length>G)throw new Error(`composed revoke-then-register v0 tx ${_.length}B exceeds the ${G}B wire cap \u2014 too many sibling PDAs outside the lookup table`);try{let u=await e.sendRawTransaction(_,{skipPreflight:!1,maxRetries:5}),A=await e.confirmTransaction({signature:u,blockhash:b,lastValidBlockHeight:k},n);if(A.value.err)throw new Error(`composed tx failed on-chain: ${JSON.stringify(A.value.err)}`);return u}catch(u){if(ke(u)&&P<H-1){console.warn(`${U} compose tx expired before landing (attempt ${P+1}, priorityFee ${h}) \u2014 rebroadcasting with a fresh blockhash`),S=u;continue}let A=Array.isArray(u?.logs)?u.logs:[];throw A.length?new Error(`${u?.message??u} | ${A.join(" | ")}`):u}}throw S instanceof Error?S:new Error("compose tx did not land after rebroadcast attempts")}async function y(){if(c)try{let f=oe.deactivateLookupTable({lookupTable:c,authority:t.publicKey}),h=await m([f],"ALT deactivate");console.info(`${U} ephemeral compose ALT deactivated: ${c.toBase58()} (${h}) \u2014 rent reclaimable via close_lookup_table after the deactivation cooldown`)}catch(f){console.warn(`${U} ALT deactivate failed for ${c?.toBase58()} \u2014 rent parks until a later cleanup retries (the compose already landed): ${String(f?.message??f)}`)}}return{send:w,getAltAddress:()=>c,deactivateAlt:y}}import{PublicKey as T}from"@solana/web3.js";import{bytesToHex as ce}from"@noble/hashes/utils";import{deriveGraphConfigPda as At,deriveSwigVaultBindingPda as le}from"@dexterai/vault/credit";import{DEXTER_VAULT_PROGRAM_ID as De,DISCRIMINATORS as bt}from"@dexterai/vault/constants";import{deriveSwigWalletAddress as wt}from"@dexterai/vault/instructions";import{decodeVaultFull as St}from"@dexterai/vault/reader";import{decodeSessionAccount as Pt,deriveSessionPda as ue}from"@dexterai/vault/session";import{sha256 as Ue}from"@noble/hashes/sha256";import{bytesToHex as N}from"@noble/hashes/utils";var Ee=/^[0-9a-f]{64}$/,Oe=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,yt=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,Be="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ne="dexter-native-tab-v2-reservation/v1",ft=`${Ne}:`;function se(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(se);if(typeof e=="object")return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[o])=>t.localeCompare(o)).map(([t,o])=>[t,se(o)]));throw new Error("canonical_value_unsupported")}function $e(e){return JSON.stringify(se(e))}function ae(e){if(e==="solana:mainnet"||e===Be)return Be;throw new Error("native_tab_v2_reservation_network_unsupported")}function Fe(e){return N(Ue(new TextEncoder().encode($e({channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:N(e.sessionPublicKey),sessionSignature:N(e.sessionSignature),sessionRegistration:N(e.sessionRegistration)}))))}function ht(e){return N(Ue(new TextEncoder().encode($e({contract:Ne,network:ae(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 vt(e){let t=Fe(e.voucher);return ht({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 ze(e){return`${ft}${vt(e)}`}function R(e){throw new Error(`native_tab_v2_reservation_receipt_invalid:${e}`)}function W(e,t){(!Number.isSafeInteger(e)||e<0)&&R(t)}function Le(e,t){(!t||typeof t!="object")&&R("missing");let o=Fe(e.voucher);(!Ee.test(e.voucherDigest)||e.voucherDigest!==o)&&R("input_voucher_digest"),e.idempotencyKey!==`native-tab-v2:${o}`&&R("input_idempotency_identity");let n=BigInt(e.voucher.payload.cumulativeAmount),i=BigInt(e.previousCumulativeAtomic),s=BigInt(e.reservationAmountAtomic);(n<=i||n-i!==s||s<=0n)&&R("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)&&R("input_voucher_identity"),t.contract!=="dexter-native-tab-open-receipt/v1"&&t.contract!=="dexter-native-tab-open-receipt/v2"&&R("contract"),Ee.test(t.operationId)||R("operation_id"),Oe.test(t.callerOperationId)||R("caller_operation_id"),yt.test(t.transaction)||R("transaction"),t.commitment!=="confirmed"&&t.commitment!=="finalized"&&R("commitment"),W(t.confirmationSlot,"confirmation_slot"),W(t.postStateSlot,"post_state_slot"),(t.confirmationSlot===0||t.postStateSlot<t.confirmationSlot)&&R("post_state_slot");let r,a;try{r=ae(e.network),a=ae(t.network)}catch{return R("network")}(a!==r||t.buyerSwigAddress!==e.buyerSwigAddress||t.vaultPda!==e.vaultPda||t.sessionPda!==e.sessionPda||t.seller!==e.seller||t.channelId!==e.channelId||t.sessionPublicKey!==N(e.voucher.sessionPublicKey)||t.voucherDigest!==o||t.cumulativeAmountAtomic!==e.voucher.payload.cumulativeAmount||t.sequenceNumber!==e.voucher.payload.sequenceNumber||!Oe.test(t.providerReceiptId)||t.reservationAmountAtomic!==e.reservationAmountAtomic||t.currentOutstandingBeforeAtomic!=="0"||t.currentOutstandingAfterAtomic!==e.reservationAmountAtomic)&&R("economic_identity"),W(t.pendingVoucherCountBefore,"pending_voucher_count_before"),W(t.pendingVoucherCountAfter,"pending_voucher_count_after"),t.contract==="dexter-native-tab-open-receipt/v1"?t.callerOperationId!==e.idempotencyKey&&R("idempotency_key"):(t.rootOperationId!==e.idempotencyKey||!Number.isSafeInteger(t.generation)||Number(t.generation)<2||!t.predecessorCallerOperationId||!t.predecessorLifecycleOperationId||!t.predecessorReleaseDigest||!t.stableReservationId||!t.economicEffectDigest)&&R("successor_identity")}var xt=Uint8Array.from([56,67,4,209,238,143,0,129]),_t=74,Me=new Set([1,2]),Rt=188,qe=new T("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),Vt=(()=>{let e=Buffer.alloc(32);return e.write("OTS_SESSION_REGISTER_V2","ascii"),e})(),J=class extends Error{constructor(o,n){super(`native_tab_v2_solana_reservation_invalid:${o}`+(n?`:${n}`:""));this.code=o;this.name="SolanaFinalVoucherV2ReservationError"}code};function l(e,t){throw new J(e,t)}function I(e,t){try{return new T(e)}catch{return l(t)}}function X(e,t){return e.length===t.length&&e.every((o,n)=>o===t[n])}async function It(e){let o=(await e.connection.getSignatureStatuses([e.signature],{searchTransactionHistory:!0})).value[0]??null;if(!o)return null;o.confirmationStatus!=="confirmed"&&o.confirmationStatus!=="finalized"&&l("transaction_commitment"),o.err!==null&&l("transaction_failed");let n=await e.connection.getTransaction(e.signature,{commitment:e.commitment,maxSupportedTransactionVersion:0});if(!n)return null;n.meta||l("transaction_meta_missing"),n.slot!==o.slot&&l("transaction_status_slot");let i=n.transaction.message,s=i.version===0?i.getAccountKeys({accountKeysFromLookups:n.meta.loadedAddresses??null}):i.getAccountKeys(),r=(a,c)=>{let m=s.get(a);return m||l(c),m};return{slot:n.slot,confirmationStatus:o.confirmationStatus,err:n.meta.err,signatures:[...n.transaction.signatures],accountKeys:Array.from({length:s.length},(a,c)=>({address:r(c,"transaction_account_key").toBase58(),signer:i.isAccountSigner(c),writable:i.isAccountWritable(c)})),instructions:i.compiledInstructions.map(a=>({programId:r(a.programIdIndex,"transaction_program_id").toBase58(),accounts:a.accountKeyIndexes.map(c=>r(c,"transaction_instruction_account").toBase58()),data:Uint8Array.from(a.data)}))}}function Ct(e,t,o,n){n.length!==_t&&l("binding_length"),X(n.subarray(0,8),xt)||l("binding_discriminator");let i=n.readUInt8(8),s=n.readUInt8(9);return Me.has(i)||l("binding_version"),s!==t&&l("binding_bump"),{address:e.toBase58(),owner:o.toBase58(),version:i,bump:s,swig:new T(n.subarray(10,42)).toBase58(),vault:new T(n.subarray(42,74)).toBase58()}}async function kt(e){let t=I(e.input.programId,"program_id"),o=I(e.input.buyerSwigAddress,"buyer_swig"),n=I(e.input.vaultPda,"vault_pda"),i=I(e.input.seller,"seller"),[s,r]=le(o,t),[a]=ue(n,i,t),c=await e.connection.getMultipleAccountsInfoAndContext([s,n,a],{commitment:e.commitment,minContextSlot:e.minimumSlot}),[m,d,v]=c.value;m||l("binding_missing"),d||l("vault_missing"),v||l("session_missing");let g,w;try{g=St(Buffer.from(d.data)),w=Pt(a,v.data)}catch(f){return l("post_state_decode",f instanceof Error?f.message:String(f))}let y=w.session;return{contextSlot:c.context.slot,binding:Ct(s,r,m.owner,Buffer.from(m.data)),vault:{owner:d.owner.toBase58(),exists:g.exists,version:g.version,swigAddress:g.swigAddress,dexterAuthority:g.dexterAuthority,pendingVoucherCount:g.pendingVoucherCount},session:{owner:v.owner.toBase58(),version:w.version,bump:w.bump,vault:w.vault,sessionPublicKey:ce(y.sessionPubkey),maxAmount:y.maxAmount,expiresAt:y.expiresAt,seller:y.allowedCounterparty,nonce:y.nonce,spent:y.spent,currentOutstanding:y.currentOutstanding,maxRevolvingCapacity:y.maxRevolvingCapacity,crystallizedCumulative:y.crystallizedCumulative}}}function Kt(e){let t=Buffer.from(e.voucher.sessionRegistration);return t.length!==Rt&&l("registration_length"),X(t.subarray(0,32),Vt)||l("registration_domain"),{programId:new T(t.subarray(32,64)).toBase58(),vaultPda:new T(t.subarray(64,96)).toBase58(),sessionPublicKey:ce(t.subarray(96,128)),maxAmount:t.readBigUInt64LE(128),expiresAt:t.readBigInt64LE(136),seller:new T(t.subarray(144,176)).toBase58(),nonce:t.readUInt32LE(176),maxRevolvingCapacity:t.readBigUInt64LE(180)}}function $(e,t,o){let n=e.accountKeys.filter(i=>i.address===t);return n.length!==1&&l(`${o}_account_key`),n[0]}function Tt(e,t,o){(!Number.isSafeInteger(o.slot)||o.slot<=0)&&l("transaction_slot"),o.slot!==t.confirmationSlot&&l("transaction_confirmation_slot"),o.err!==null&&l("transaction_failed"),o.signatures[0]!==t.transaction&&l("transaction_signature"),o.instructions.length!==2&&l("transaction_instruction_count");let n=I(e.programId,"program_id"),i=I(e.buyerSwigAddress,"buyer_swig"),s=I(e.vaultPda,"vault_pda"),r=I(e.seller,"seller"),a=I(e.sessionPda,"session_pda"),[c]=ue(s,r,n),m=le(i,n)[0],d=wt(i),v=At(n)[0];a.equals(c)||l("session_pda_derivation");let g=Buffer.from(bt.settle_voucher),w=o.instructions.filter(u=>{if(u.programId!==e.programId)return!1;let A=u.data;return A.length>=g.length&&X(A.subarray(0,g.length),g)});w.length!==1&&l("settle_voucher_instruction_count");let y=w[0];o.instructions[0]!==y&&l("settle_voucher_instruction_order");let f=Buffer.from(y.data);f.length!==49&&l("settle_voucher_instruction_length"),f.readBigUInt64LE(8).toString()!==e.reservationAmountAtomic&&l("settle_voucher_amount"),f.readUInt8(16)!==1&&l("settle_voucher_increment"),new T(f.subarray(17,49)).equals(r)||l("settle_voucher_seller"),y.accounts.length<8&&l("settle_voucher_accounts"),[s.toBase58(),null,a.toBase58(),null,i.toBase58(),d.toBase58(),m.toBase58(),v.toBase58()].forEach((u,A)=>{u!==null&&y.accounts[A]!==u&&l(`settle_voucher_account_${A}`)});let p=y.accounts[1];p||l("dexter_authority");let x=$(o,y.accounts[0],"vault"),S=$(o,p,"dexter_authority"),P=$(o,y.accounts[2],"session");(!x.writable||x.signer)&&l("vault_privileges"),S.signer||l("dexter_authority_signature"),(!P.writable||P.signer)&&l("session_privileges");for(let u=3;u<Math.min(y.accounts.length,8);u+=1)$(o,y.accounts[u],`account_${u}`).signer&&l(`settle_voucher_account_${u}_signer`);for(let u=8;u<y.accounts.length;u+=1){let A=$(o,y.accounts[u],`sibling_${u-8}`);(!A.writable||A.signer)&&l("settle_voucher_sibling_privileges")}let b=o.instructions[1];b.programId!==qe.toBase58()&&l("reservation_memo_program"),(b.accounts.length!==1||b.accounts[0]!==p)&&l("reservation_memo_authority"),$(o,p,"reservation_memo_authority").signer||l("reservation_memo_authority_signature");let _=new TextEncoder().encode(ze(e));return X(b.data,_)||l("reservation_memo_digest"),p}function Et(e,t,o,n){let i=I(e.programId,"program_id"),s=I(e.buyerSwigAddress,"buyer_swig"),r=I(e.vaultPda,"vault_pda"),a=I(e.seller,"seller"),[c,m]=le(s,i),[d,v]=ue(r,a,i);(!Number.isSafeInteger(n.contextSlot)||n.contextSlot<t)&&l("post_state_slot"),(n.binding.address!==c.toBase58()||n.binding.owner!==e.programId||n.binding.bump!==m||!Me.has(n.binding.version)||n.binding.swig!==e.buyerSwigAddress||n.binding.vault!==e.vaultPda)&&l("binding_identity"),(n.vault.owner!==e.programId||!n.vault.exists||n.vault.version!==7||n.vault.swigAddress!==e.buyerSwigAddress||n.vault.dexterAuthority!==o)&&l("vault_post_state"),(e.sessionPda!==d.toBase58()||n.session.owner!==e.programId||n.session.version!==1||n.session.bump!==v||n.session.vault!==e.vaultPda||n.session.sessionPublicKey!==ce(e.voucher.sessionPublicKey)||n.session.seller!==e.seller||n.session.nonce!==e.sessionNonce||n.session.currentOutstanding.toString()!==e.reservationAmountAtomic)&&l("session_post_state");let g=Kt(e);(g.programId!==e.programId||g.vaultPda!==e.vaultPda||g.sessionPublicKey!==n.session.sessionPublicKey||g.seller!==e.seller||g.nonce!==e.sessionNonce||g.maxAmount!==n.session.maxAmount||g.expiresAt!==BigInt(n.session.expiresAt)||g.maxRevolvingCapacity!==n.session.maxRevolvingCapacity)&&l("registration_post_state");let w=n.session.spent>n.session.crystallizedCumulative?n.session.spent:n.session.crystallizedCumulative;return w.toString()!==e.previousCumulativeAtomic&&l("session_frontier"),{commitment:"confirmed",confirmationSlot:t,postStateSlot:n.contextSlot,sessionAccountVersion:n.session.version,wireVersion:2,frontierAtomic:w.toString(),spentAtomic:n.session.spent.toString(),currentOutstandingAtomic:n.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:n.session.crystallizedCumulative.toString()}}async function me(e,t,o,n={}){try{Le(t,o)}catch(a){return l("provider_receipt",a instanceof Error?a.message:String(a))}t.network!=="solana:mainnet"&&l("network"),t.programId!==De.toBase58()&&l("program_id");let i=await(n.readTransaction??It)({connection:e,signature:o.transaction,commitment:"confirmed"});i||l("transaction_missing"),i.confirmationStatus!=="confirmed"&&i.confirmationStatus!=="finalized"&&l("transaction_commitment");let s=Tt(t,o,i),r=await(n.readPostState??kt)({connection:e,input:t,minimumSlot:i.slot,commitment:"confirmed"});return{...Et(t,i.slot,s,r),commitment:i.confirmationStatus}}async function de(e,t,o,n={}){await me(e,t,o,n)}function Ot(e,t={}){return async(o,n)=>{await me(e,o,n,t)}}var Bt=De,Ut=qe;import{p256 as Ge}from"@noble/curves/p256";import{sha256 as z}from"@noble/hashes/sha256";import{buildPasskeyAuthorizationChallenge as Nt,classifyPasskeyAuthorizationOperation as $t}from"@dexterai/vault";import{sessionVoucherV2AuthorizationNonce as Ft}from"@dexterai/vault/messages";var We="dexter.cash";function zt(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Lt(e,t=`https://${We}`){let n={type:"webauthn.get",challenge:zt(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(n))}function Dt(e=1){let t=z(new TextEncoder().encode(We)),o=new Uint8Array(37);return o.set(t,0),o[32]=5,new DataView(o.buffer).setUint32(33,e,!1),o}function He(e,t){let o=Lt(t),n=Dt(1),i=new Uint8Array(n.length+32);i.set(n,0),i.set(z(o),n.length);let s=z(i);return{signature:Ge.sign(s,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:o,authenticatorData:n}}function Mt(e,t={}){return{credentialId:new Uint8Array(0),publicKey:e.publicKey,signOperation:async o=>{let n=t.resolveAuthorizationContext?await t.resolveAuthorizationContext(o.slice()):qt(o);if(!n){if(t.allowLegacyOperationHash===!0)return He(e,z(o));throw new Error("passkey_authorization_context_required")}let i=t.ceremonyNonce?t.ceremonyNonce():Ge.utils.randomPrivateKey();if(i.length!==32)throw new Error("ceremonyNonce must be exactly 32 bytes");let s=Nt({programId:n.programId,vault:n.vault,nonce:n.nonce,operationHash:z(o),ceremonyNonce:i});return He(e,s)}}}function qt(e){let t=$t(e);return t.kind==="session_register_v2"?{programId:t.fields.programId,vault:t.fields.vault,nonce:BigInt(Ft(t.fields.registrationNonce))}:t.kind==="session_replace_v1"?{programId:t.fields.programId,vault:t.fields.vault,nonce:t.fields.authorizationNonce}:null}async function nn({connection:e,vaultPda:t,allowedCounterparty:o,programId:n=V,commitment:i="finalized"}){let[s]=j(t,o,n),r=await e.getMultipleAccountsInfoAndContext([t,s],{commitment:i}),[a,c]=r.value;if(!a)throw new Error("close revocation: vault account not found");if(!a.owner.equals(n))throw new Error("close revocation: vault has the wrong owner");let m=Qt(Buffer.from(a.data));if(!m.exists||m.version!==7)throw new Error("close revocation: Vault V7 required");if(!c)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"absent"};if(!c.owner.equals(n))throw new Error("close revocation: session has the wrong owner");let d=Jt(s,c.data);if(d.version===0)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"cleared"};if(d.version!==1)throw new Error("close revocation: live SessionAccount required");if(d.vault!==t.toBase58())throw new Error("close revocation: session belongs to a different vault");if(d.session.allowedCounterparty!==o.toBase58())throw new Error("close revocation: session counterparty mismatch");return{kind:"live",snapshot:{contextSlot:r.context.slot,programId:new K(n),vaultPda:new K(t),sessionPda:s,sessionPubkey:Uint8Array.from(d.session.sessionPubkey),maxAmount:d.session.maxAmount,expiresAt:Buffer.from(c.data).readBigInt64LE(82),allowedCounterparty:new K(o),nonce:d.session.nonce,spent:d.session.spent,currentOutstanding:d.session.currentOutstanding,maxRevolvingCapacity:d.session.maxRevolvingCapacity,crystallizedCumulative:d.session.crystallizedCumulative,lastLockedSequence:d.session.lastLockedSequence,expectedPendingVoucherCount:m.pendingVoucherCount}}}function on(e){return fe({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:e.vaultUsdcAta,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var pe=class{network="solana:mainnet";sessionVoucherVersion=2;swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;seams;pendingCloseRevocations=new Map;completedCloseRevocations=new Map;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new K(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"},this.seams=t.seams??{}}closeRevocationKey(t){let o=M(t.registration),[n]=j(this.vaultPdaKey,o.allowedCounterparty,V);return[n.toBase58(),ge(o.sessionPubkey),o.nonce.toString()].join(":")}async readCloseTargetState(t){let o={connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:t,programId:V,commitment:"finalized"};if(this.seams.readCloseRevocationTargetState)return this.seams.readCloseRevocationTargetState(o);if(this.seams.readCloseRevocationSnapshot)try{return{kind:"live",snapshot:await this.seams.readCloseRevocationSnapshot(o)}}catch{return null}return nn(o)}targetInvalidated(t,o){if(t.kind==="invalidated")return!0;let n=t.snapshot,[i]=j(this.vaultPdaKey,o.allowedCounterparty,V);if(!n.programId.equals(V)||!n.vaultPda.equals(this.vaultPdaKey)||!n.sessionPda.equals(i)||!n.allowedCounterparty.equals(o.allowedCounterparty))throw new Error("session revocation snapshot identity mismatch");if(!Buffer.from(n.sessionPubkey).equals(Buffer.from(o.sessionPubkey))||n.nonce!==o.nonce)return!0;if(n.maxAmount!==o.maxAmount||n.expiresAt!==o.expiresAt||n.maxRevolvingCapacity!==o.maxRevolvingCapacity)throw new Error("session revocation snapshot identity mismatch");return!1}rememberCompletedClose(t,o){let n=Uint8Array.from(o);return this.pendingCloseRevocations.delete(t),this.completedCloseRevocations.set(t,n),Uint8Array.from(n)}async reconcilePendingClose(t,o,n){let i=!1,s=null;try{let c=await this.connection.getSignatureStatuses([t.signature],{searchTransactionHistory:!0});if(i=!0,s=c.value[0]??null,s?.confirmationStatus==="finalized")return s.err===null?"complete":"fresh_allowed"}catch{}let r=!1;try{let c=await this.connection.getTransaction(t.signature,{commitment:"finalized",maxSupportedTransactionVersion:0});if(r=!0,c)return!c.meta||!Object.prototype.hasOwnProperty.call(c.meta,"err")?"unresolved":c.meta.err===null?"complete":"fresh_allowed"}catch{}let a=await this.readCloseTargetState(o.allowedCounterparty).catch(()=>null);if(a&&this.targetInvalidated(a,o))return"complete";if(n&&i&&s===null)try{if((await this.connection.isBlockhashValid(t.blockhash,{commitment:"confirmed"})).value)return await this.connection.sendRawTransaction(t.serializedTransaction,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment})!==t.signature?"unresolved":(await this.connection.confirmTransaction({signature:t.signature,blockhash:t.blockhash,lastValidBlockHeight:t.lastValidBlockHeight},"finalized")).value.err===null?"complete":"fresh_allowed"}catch{}if(i&&s!==null||!i||!r||t.finalizedHistoryFloorSlot===null)return"unresolved";try{let[c,m]=await Promise.all([this.connection.getBlockHeight("finalized"),this.connection.getMinimumLedgerSlot()]);if(c>t.lastValidBlockHeight&&m<=t.finalizedHistoryFloorSlot)return"fresh_allowed"}catch{}return"unresolved"}async authorizeSession(t,o){let n=new K(t.allowedCounterparty),i=E(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=await(this.seams.fetchSession??Wt)(this.connection,this.vaultPdaKey,n),a=r!==null&&Xt(r);if(a&&(o?.onLiveSession??"error")!=="replace"){let h=r.session.spent,p=r.session.crystallizedCumulative;throw new F({allowedCounterparty:t.allowedCounterparty,sessionPubkeyHex:ge(r.session.sessionPubkey),expiresAtUnix:r.session.expiresAt,spentAtomic:h.toString(),crystallizedCumulativeAtomic:p.toString(),currentOutstandingAtomic:r.session.currentOutstanding.toString(),frontierAtomic:(h>p?h:p).toString()})}let m=await(this.seams.fetchPasskeyAuthorization??en)(this.connection,this.vaultPdaKey,V);if(m===null||m.version!==1||!m.vault.equals(this.vaultPdaKey))throw new Error("passkey_authorization_guard_unavailable");let d=Se(),v=we(m.nonce),g=ve({programId:V,vaultPda:this.vaultPdaKey,sessionPubkey:d.publicKey,maxAmount:E(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v}),w=a?Ae({programId:V,vaultPda:this.vaultPdaKey,sessionPda:new K(r.address),authorizationNonce:m.nonce,retired:{sessionPubkey:r.session.sessionPubkey,maxAmount:r.session.maxAmount,expiresAt:BigInt(r.session.expiresAt),allowedCounterparty:new K(r.session.allowedCounterparty),nonce:r.session.nonce,spent:r.session.spent,currentOutstanding:r.session.currentOutstanding,maxRevolvingCapacity:r.session.maxRevolvingCapacity,crystallizedCumulative:r.session.crystallizedCumulative,lastLockedSequence:r.session.lastLockedSequence},replacement:{sessionPubkey:d.publicKey,maxAmount:E(t.maxAmountAtomic),expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v,maxRevolvingCapacity:i}}):g,y=await this.passkey.signOperation(w);if(a)await this.sendAtomicReplace(t,n,d.publicKey,v,i,y);else{if(tn({clientDataJSON:y.clientDataJSON,operationMessage:w,expectedVault:this.vaultPdaKey,expectedProgramId:V}).nonce!==m.nonce)throw new Error("passkey_authorization_guard_changed");await this.sendBareRegister(t,n,d.publicKey,v,i,y)}return await(this.seams.waitForSession??Yt)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:d.publicKey,timeoutMs:2e4}),Pe(d,t,g)}async sendBareRegister(t,o,n,i,s,r){let{signature:a,clientDataJSON:c,authenticatorData:m}=r,d=Ye(m,je(c)),v=Y(this.passkey.publicKey,a,d),g=this.seams.fetchSessions??Gt,w=jt(await g(this.connection,this.vaultPdaKey)),f=await(this.seams.resolveUsdcAta??Xe)(this.connection,new K(this.swigAddress)),h=on({vaultPda:this.vaultPdaKey,swigAddress:new K(this.swigAddress),sessionPubkey:n,maxAmount:E(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:o,nonce:i,clientDataJSON:c,authenticatorData:m,payer:this.feePayer.publicKey,siblingSessionPdas:w,vaultUsdcAta:f}),p=new Je().add(v,h);p.feePayer=this.feePayer.publicKey;let{blockhash:x}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=x,p.sign(this.feePayer);let S=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});await this.connection.confirmTransaction({signature:S,blockhash:x,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment)}async sendAtomicReplace(t,o,n,i,s,r){let c=await(this.seams.resolveUsdcAta??Xe)(this.connection,new K(this.swigAddress)),m=this.seams.composeSend?{send:this.seams.composeSend,deactivateAlt:async()=>{}}:re(this.connection,this.feePayer,{commitment:this.confirmOptions.commitment});try{await Zt({connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:o,registerArgs:{sessionPubkey:n,maxAmount:E(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),nonce:i,swigAddress:new K(this.swigAddress),vaultUsdcAta:c,payer:this.feePayer.publicKey},registerCeremony:{clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData,signature:r.signature},credentialPublicKey:this.passkey.publicKey,send:m.send,fetchSession:this.seams.fetchSession,fetchSessions:this.seams.fetchSessions,fetchPasskeyAuthorization:this.seams.fetchPasskeyAuthorization})}finally{m.deactivateAlt()}}async signWithSession(t,o){let n=await rn(o.channelId),i=M(t.registration);if((i.nonce&2147483648)!==0){let[s]=j(i.vaultPda,i.allowedCounterparty,i.programId),r=_e({programId:i.programId.toBase58(),vaultPda:i.vaultPda.toBase58(),sessionPda:s.toBase58(),seller:i.allowedCounterparty.toBase58(),sessionNonce:i.nonce,channelId:ge(n),cumulativeAmountAtomic:o.cumulativeAmount,sequenceOrdinal:o.sequenceNumber,sessionPrivateKey:t.privateKey,sessionPublicKey:t.publicKey,sessionRegistration:t.registration});return{payload:{channelId:r.channelId,cumulativeAmount:r.cumulativeAmount,sequenceNumber:r.sequenceNumber},sessionPublicKey:Uint8Array.from(Buffer.from(r.sessionPublicKey,"hex")),sessionSignature:Uint8Array.from(Buffer.from(r.sessionSignature,"hex")),sessionRegistration:Uint8Array.from(Buffer.from(r.sessionRegistration,"hex"))}}return xe(t,o,n)}async signOpenTab(t,o){return t.registration}async verifyFinalVoucherV2Reservation(t,o){await de(this.connection,t,o)}async signCloseTab(t,o,n){let i=M(t.registration);if(!i.vaultPda.equals(this.vaultPdaKey)||!Buffer.from(i.sessionPubkey).equals(Buffer.from(t.publicKey)))throw new Error("session registration identity mismatch");let s=this.closeRevocationKey(t),r=this.completedCloseRevocations.get(s);if(r)return Uint8Array.from(r);let a=this.pendingCloseRevocations.get(s);if(a){let C=await this.reconcilePendingClose(a,i,!0);if(C==="complete")return this.rememberCompletedClose(s,a.message);if(C==="unresolved")throw new Error(`session revoke finality unresolved for ${a.signature}; retry close`);this.pendingCloseRevocations.delete(s)}let c=await this.readCloseTargetState(i.allowedCounterparty);if(!c)throw new Error("close revocation target state unavailable");if(c.kind==="invalidated"||this.targetInvalidated(c,i))return this.rememberCompletedClose(s,t.registration);let m=c.snapshot,d=E(n);if((m.spent>m.crystallizedCumulative?m.spent:m.crystallizedCumulative)<d)throw new Error("session revocation snapshot is behind final settlement");let g=be(m),{signature:w,clientDataJSON:y,authenticatorData:f}=await this.passkey.signOperation(g),h=Ye(f,je(y)),p=Y(this.passkey.publicKey,w,h),x=he({vaultPda:this.vaultPdaKey,allowedCounterparty:m.allowedCounterparty,expectedPendingVoucherCount:m.expectedPendingVoucherCount,clientDataJSON:y,authenticatorData:f}),S=new Je().add(p,x);S.feePayer=this.feePayer.publicKey;let P=null;try{let C=await this.connection.getSlot("finalized");P=Number.isSafeInteger(C)&&C>=0?C:null}catch{}let{blockhash:b,lastValidBlockHeight:k}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);if(S.recentBlockhash=b,S.sign(this.feePayer),!S.signature)throw new Error("session revoke transaction is unsigned");let _=Uint8Array.from(S.serialize()),u=Ht.encode(S.signature),A={key:s,message:Uint8Array.from(g),serializedTransaction:_,signature:u,blockhash:b,lastValidBlockHeight:k,finalizedHistoryFloorSlot:P};this.pendingCloseRevocations.set(s,A);let B;try{let C=await this.connection.sendRawTransaction(_,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});if(C!==u)throw new Error(`session revoke signature mismatch expected=${u} returned=${C}`);B=await this.connection.confirmTransaction({signature:u,blockhash:b,lastValidBlockHeight:k},"finalized")}catch(C){let ye=await this.reconcilePendingClose(A,i,!1);if(ye==="complete")return this.rememberCompletedClose(s,g);throw ye==="fresh_allowed"?(this.pendingCloseRevocations.delete(s),new Error("session revoke transaction finalized without effect; retry close",{cause:C})):new Error(`session revoke finality unresolved for ${u}; retry close`,{cause:C})}if(B.value.err)throw this.pendingCloseRevocations.delete(s),new Error(`session revoke transaction failed: ${JSON.stringify(B.value.err)}`);return this.rememberCompletedClose(s,g)}};function Eo(e){return new pe(e)}function Ye(e,t){let o=new Uint8Array(e.length+t.length);return o.set(e,0),o.set(t,e.length),o}async function rn(e){if(/^[0-9a-f]{64}$/i.test(e))return sn(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function sn(e){let t=new Uint8Array(e.length/2);for(let o=0;o<t.length;o++)t[o]=parseInt(e.substr(o*2,2),16);return t}export{F as LiveSessionExistsError,Ut as SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID,Bt as SOLANA_FINAL_VOUCHER_V2_PROGRAM_ID,J as SolanaFinalVoucherV2ReservationError,G as TX_SIZE_LIMIT_BYTES,on as buildAdapterRegisterInstruction,Ke as collectAltAddresses,Te as compileComposeV0,re as createSelfPayingComposeSend,Ot as createSolanaFinalVoucherV2ReservationVerifier,Eo as createSolanaVaultAdapter,at as deriveChannelId,me as inspectSolanaFinalVoucherV2Reservation,Mt as passkeySignerFromP256Keypair,de as verifySolanaFinalVoucherV2Reservation};
|
|
1
|
+
import{PublicKey as K,Transaction as Je}from"@solana/web3.js";import Ht from"bs58";var F=class extends Error{constructor(o){super(`a LIVE session already exists for counterparty ${o.allowedCounterparty} (session ${o.sessionPubkeyHex.slice(0,16)}\u2026, expires ${o.expiresAtUnix}; on-chain spent=${o.spentAtomic}, crystallized=${o.crystallizedCumulativeAtomic}, frontier=${o.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=o;this.name="LiveSessionExistsError"}details};import{buildRegisterSessionKeyInstruction as fe,buildRevokeSessionKeyInstruction as he,deriveSwigWalletAddress as un}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as Z}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as I,SECP256R1_PROGRAM_ID as gn,INSTRUCTIONS_SYSVAR_ID as pn}from"@dexterai/vault/constants";import{sessionRegisterMessage as ve,sessionReplaceV1Message as Ae,sessionRevokeMessage as be,sessionVoucherV2Nonce as we,sessionVoucherV2AuthorizationNonce as hn,finalVoucherV2Sequence as vn,voucherV2SequenceOrdinal as An,voucherPayloadMessage as Q,buildVoucherMessage as bn}from"@dexterai/vault/messages";import D from"tweetnacl";import{PublicKey as L}from"@solana/web3.js";import{contextBoundVoucherV2Message as Ze,finalVoucherV2Sequence as Qe,sessionRegisterMessage as et,sessionVoucherV2AuthorizationNonce as tt}from"@dexterai/vault/messages";import{deriveSessionPda as nt}from"@dexterai/vault/session";import{sha256 as st}from"@noble/hashes/sha256";function Se(){let e=D.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function Pe(e,t,o){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:o}}function xe(e,t,o){if(o.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${o.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 n=BigInt(t.cumulativeAmount),i=BigInt(e.scope.maxAmountAtomic);if(n>i)throw new Error(`voucher cumulative ${n} exceeds session cap ${i}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let r=Q({channelId:o,cumulativeAmount:n,sequenceNumber:t.sequenceNumber}),a=D.sign.detached(r,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}var ot=/^[0-9a-f]{64}$/,it=(1n<<64n)-1n;function ee(e){return Buffer.from(e).toString("hex")}function rt(e){return Uint8Array.from(Buffer.from(e,"hex"))}function te(e,t){if(e.length!==t.length)return!1;let o=0;for(let n=0;n<e.length;n+=1)o|=(e[n]??0)^(t[n]??0);return o===0}function _e(e){if(!ot.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>it)throw new Error("native_tab_v2_cumulative_amount_invalid");let o=new L(e.programId),n=new L(e.vaultPda),i=new L(e.sessionPda),s=new L(e.seller),[r]=nt(n,s,o);if(!i.equals(r))throw new Error("native_tab_v2_session_pda_mismatch");let a=e.sessionRegistration,c=new DataView(a.buffer,a.byteOffset,a.byteLength),m=c.getBigUint64(128,!0),d=c.getBigInt64(136,!0),v=c.getBigUint64(180,!0),g=e.nowUnixSeconds??Math.floor(Date.now()/1e3);if(!Number.isSafeInteger(g)||g<0)throw new Error("native_tab_v2_signing_time_invalid");if(!te(a,et({programId:o,vaultPda:n,sessionPubkey:e.sessionPublicKey,maxAmount:m,expiresAt:d,allowedCounterparty:s,nonce:e.sessionNonce,maxRevolvingCapacity:v})))throw new Error("native_tab_v2_registration_identity_mismatch");if(m===0n||v===0n||v>m||d<=BigInt(g)||d>0x7fffffffffffffffn-604800n||t>m)throw new Error("native_tab_v2_registration_semantics_invalid");tt(e.sessionNonce);let y=D.sign.keyPair.fromSeed(e.sessionPrivateKey.subarray(0,32)),f=!1;try{f=te(y.publicKey,e.sessionPublicKey)&&te(e.sessionPrivateKey.subarray(32,64),e.sessionPublicKey)}finally{y.secretKey.fill(0)}if(!f)throw new Error("native_tab_v2_session_key_mismatch");let h=Qe(e.sequenceOrdinal),p=Ze({programId:o,vaultPda:n,sessionPda:i,seller:s,sessionNonce:e.sessionNonce,channelId:rt(e.channelId),cumulativeAmount:t,sequenceNumber:h}),x=D.sign.detached(p,e.sessionPrivateKey);return{channelId:e.channelId,cumulativeAmount:e.cumulativeAmountAtomic,sequenceNumber:h,sessionPublicKey:ee(e.sessionPublicKey),sessionSignature:ee(x),sessionRegistration:ee(a)}}function E(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function at(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let o=new TextEncoder().encode(e.sellerUrl),n=st.create();return n.update(e.vaultPda.toBytes()),n.update(o),n.update(t),n.digest()}import{fetchVaultSessionAccounts as Gt,fetchSessionAccount as Wt,decodeSessionAccount as Jt,deriveSessionPda as Y,isSessionLive as Xt,sessionPdasOf as jt,waitForSession as Yt,resolveVaultUsdcAta as Xe,composeRevokeThenRegister as Zt}from"@dexterai/vault/session";import{decodeVaultFull as Qt}from"@dexterai/vault/reader";import{fetchPasskeyAuthorizationState as en,validatePasskeyAuthorizationClientData as tn}from"@dexterai/vault";import Cn from"tweetnacl";import{sha256 as Kn}from"@noble/hashes/sha256";import{p256 as En}from"@noble/curves/p256";import{PublicKey as ne}from"@solana/web3.js";import{decodeSessionAccount as Fn,deriveSessionPda as zn,isSessionLive as Ln}from"@dexterai/vault/session";import{contextBoundVoucherV2Message as Mn,sessionVoucherV2AuthorizationNonce as qn,voucherV2SequenceOrdinal as Hn}from"@dexterai/vault/messages";var oe="OTS_SESSION_REGISTER_V2";var O=class extends Error{constructor(o,n){super(`Invalid registration: ${o}${n?` (${n})`:""}`);this.reason=o;this.name="InvalidRegistrationError"}reason};function M(e){if(e.length!==188)throw new O("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,oe.length));if(t!==oe)throw new O("wrong_domain",`got "${t}"`);for(let v=oe.length;v<32;v++)if(e[v]!==0)throw new O("wrong_domain",`non-NUL padding at byte ${v}`);let o=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new ne(e.slice(32,64)),i=new ne(e.slice(64,96)),s=e.slice(96,128),r=o.getBigUint64(128,!0),a=o.getBigInt64(136,!0),c=new ne(e.slice(144,176)),m=o.getUint32(176,!0),d=o.getBigUint64(180,!0);if(!n.equals(I))throw new O("wrong_program",`${n.toBase58()} is not ${I.toBase58()}`);if(r===0n)throw new O("cap_zero");return{programId:n,vaultPda:i,sessionPubkey:new Uint8Array(s),maxAmount:r,expiresAt:a,allowedCounterparty:c,nonce:m,maxRevolvingCapacity:d}}import{sha256 as je}from"@noble/hashes/sha256";import{bytesToHex as ge}from"@noble/hashes/utils";import{AddressLookupTableProgram as ie,ComputeBudgetProgram as Re,Transaction as ct,TransactionMessage as lt,VersionedTransaction as ut}from"@solana/web3.js";var G=1232,mt=40,Ve=20,Ie=4,dt=20,q=1e4,gt=1e6,H=4,U="[tab/solana/compose]";function Ke(e,t){let o=new Set,n=[],i=t.toBase58();for(let s of e)for(let r of s.keys){if(r.isSigner)continue;let a=r.pubkey.toBase58();a===i||o.has(a)||(o.add(a),n.push(r.pubkey))}return n}function Te(e,t,o,n){let i=new lt({payerKey:t,recentBlockhash:o,instructions:e}).compileToV0Message([n]);return new ut(i)}async function Ce(e){try{let t=(await e.getRecentPrioritizationFees()).map(n=>n.prioritizationFee).filter(n=>n>0).sort((n,i)=>n-i);if(t.length===0)return q;let o=t[Math.floor(.75*(t.length-1))]??q;return Math.max(q,Math.min(o,gt))}catch{return q}}function pt(e){let t=e,o=String(t?.message??e??""),n=Array.isArray(t?.logs)?t.logs.join(" "):"";return/already in use/i.test(o)||/already in use/i.test(n)}function ke(e){let t=e;return(Array.isArray(t?.logs)?t.logs:[]).length===0&&/block height exceeded|has expired|blockhash not found/i.test(String(t?.message??e))}var re=e=>new Promise(t=>setTimeout(t,e));function W(e,t,o={}){let n=o.commitment??"confirmed",i=o.altWarmupPollMs??400,s=o.altReadbackPollMs??400,r=o.altCollisionPollMs??500,a=null,c=null;async function m(f,h){let p=await Ce(e),x=[Re.setComputeUnitPrice({microLamports:p}),...f],S;for(let b=0;b<H;b+=1){let{blockhash:A,lastValidBlockHeight:V}=await e.getLatestBlockhash(n),_=new ct().add(...x);_.feePayer=t.publicKey,_.recentBlockhash=A,_.sign(t);try{let u=await e.sendRawTransaction(_.serialize(),{skipPreflight:!1,maxRetries:5}),w=await e.confirmTransaction({signature:u,blockhash:A,lastValidBlockHeight:V},n);if(w.value.err)throw new Error(`${h} tx failed on-chain: ${JSON.stringify(w.value.err)}`);return u}catch(u){if(ke(u)&&b<H-1){console.warn(`${U} ${h} tx expired before landing (attempt ${b+1}) \u2014 rebroadcasting with a fresh blockhash`),S=u;continue}throw u}}throw S??new Error(`${h} tx did not land after rebroadcast attempts`)}async function d(f){for(let h=0;h<dt;h+=1){let p=await e.getSlot("finalized");if(p>f)return p;await re(r)}throw new Error(`ALT collision retry: finalized slot never advanced past ${f}`)}async function v(f){for(let h=0;h<mt;h+=1){if(await e.getSlot(n)>f)return;await re(i)}throw new Error(`ALT warmup timed out: preflight (${n}) slot never passed lastExtendedSlot ${f}`)}async function g(f){if(a)return a;let h=Ke(f,t.publicKey),p=null,x=null,S=-1;for(let A=0;A<Ie;A+=1){let V=S<0?await e.getSlot("finalized"):await d(S),[_,u]=ie.createLookupTable({authority:t.publicKey,payer:t.publicKey,recentSlot:V}),w=ie.extendLookupTable({payer:t.publicKey,authority:t.publicKey,lookupTable:u,addresses:h});try{x=await m([_,w],"ALT create/extend"),p=u;break}catch(B){if(pt(B)&&A<Ie-1){S=V,console.warn(`${U} ALT address collision at slot ${V} (attempt ${A+1}) \u2014 retrying create with a fresh finalized slot`);continue}throw B}}if(!p||!x)throw new Error("ALT create exhausted retries after repeated address collisions");let b=await e.getAddressLookupTable(p);for(let A=0;A<Ve&&!b.value;A+=1)await re(s),b=await e.getAddressLookupTable(p);if(!b.value)throw new Error(`ALT ${p.toBase58()} not visible after ${Ve} read polls (${x})`);return await v(b.value.state.lastExtendedSlot),a=b.value,c=p,console.info(`${U} ephemeral compose ALT ready: ${p.toBase58()} (${h.length} addresses, createTx ${x})`),a}async function P(f){let h=await Ce(e),p=[Re.setComputeUnitPrice({microLamports:h}),...f],x=await g(p),S;for(let b=0;b<H;b+=1){let{blockhash:A,lastValidBlockHeight:V}=await e.getLatestBlockhash(n),_;try{let u=Te(p,t.publicKey,A,x);u.sign([t]),_=u.serialize()}catch(u){throw/overrun|too large/i.test(String(u?.message??u))?new Error(`composed revoke-then-register v0 tx exceeds the ${G}B wire cap \u2014 too many sibling PDAs outside the lookup table`):u}if(_.length>G)throw new Error(`composed revoke-then-register v0 tx ${_.length}B exceeds the ${G}B wire cap \u2014 too many sibling PDAs outside the lookup table`);try{let u=await e.sendRawTransaction(_,{skipPreflight:!1,maxRetries:5}),w=await e.confirmTransaction({signature:u,blockhash:A,lastValidBlockHeight:V},n);if(w.value.err)throw new Error(`composed tx failed on-chain: ${JSON.stringify(w.value.err)}`);return u}catch(u){if(ke(u)&&b<H-1){console.warn(`${U} compose tx expired before landing (attempt ${b+1}, priorityFee ${h}) \u2014 rebroadcasting with a fresh blockhash`),S=u;continue}let w=Array.isArray(u?.logs)?u.logs:[];throw w.length?new Error(`${u?.message??u} | ${w.join(" | ")}`):u}}throw S instanceof Error?S:new Error("compose tx did not land after rebroadcast attempts")}async function y(){if(c)try{let f=ie.deactivateLookupTable({lookupTable:c,authority:t.publicKey}),h=await m([f],"ALT deactivate");console.info(`${U} ephemeral compose ALT deactivated: ${c.toBase58()} (${h}) \u2014 rent reclaimable via close_lookup_table after the deactivation cooldown`)}catch(f){console.warn(`${U} ALT deactivate failed for ${c?.toBase58()} \u2014 rent parks until a later cleanup retries (the compose already landed): ${String(f?.message??f)}`)}}return{send:P,getAltAddress:()=>c,deactivateAlt:y}}import{PublicKey as T}from"@solana/web3.js";import{bytesToHex as ce}from"@noble/hashes/utils";import{deriveGraphConfigPda as At,deriveSwigVaultBindingPda as le}from"@dexterai/vault/credit";import{DEXTER_VAULT_PROGRAM_ID as De,DISCRIMINATORS as bt}from"@dexterai/vault/constants";import{deriveSwigWalletAddress as wt}from"@dexterai/vault/instructions";import{decodeVaultFull as St}from"@dexterai/vault/reader";import{decodeSessionAccount as Pt,deriveSessionPda as ue}from"@dexterai/vault/session";import{sha256 as Ue}from"@noble/hashes/sha256";import{bytesToHex as N}from"@noble/hashes/utils";var Ee=/^[0-9a-f]{64}$/,Oe=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,yt=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,Be="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ne="dexter-native-tab-v2-reservation/v1",ft=`${Ne}:`;function se(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(se);if(typeof e=="object")return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0).sort(([t],[o])=>t.localeCompare(o)).map(([t,o])=>[t,se(o)]));throw new Error("canonical_value_unsupported")}function $e(e){return JSON.stringify(se(e))}function ae(e){if(e==="solana:mainnet"||e===Be)return Be;throw new Error("native_tab_v2_reservation_network_unsupported")}function Fe(e){return N(Ue(new TextEncoder().encode($e({channelId:e.payload.channelId,cumulativeAmount:e.payload.cumulativeAmount,sequenceNumber:e.payload.sequenceNumber,sessionPublicKey:N(e.sessionPublicKey),sessionSignature:N(e.sessionSignature),sessionRegistration:N(e.sessionRegistration)}))))}function ht(e){return N(Ue(new TextEncoder().encode($e({contract:Ne,network:ae(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 vt(e){let t=Fe(e.voucher);return ht({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 ze(e){return`${ft}${vt(e)}`}function R(e){throw new Error(`native_tab_v2_reservation_receipt_invalid:${e}`)}function J(e,t){(!Number.isSafeInteger(e)||e<0)&&R(t)}function Le(e,t){(!t||typeof t!="object")&&R("missing");let o=Fe(e.voucher);(!Ee.test(e.voucherDigest)||e.voucherDigest!==o)&&R("input_voucher_digest"),e.idempotencyKey!==`native-tab-v2:${o}`&&R("input_idempotency_identity");let n=BigInt(e.voucher.payload.cumulativeAmount),i=BigInt(e.previousCumulativeAtomic),s=BigInt(e.reservationAmountAtomic);(n<=i||n-i!==s||s<=0n)&&R("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)&&R("input_voucher_identity"),t.contract!=="dexter-native-tab-open-receipt/v1"&&t.contract!=="dexter-native-tab-open-receipt/v2"&&R("contract"),Ee.test(t.operationId)||R("operation_id"),Oe.test(t.callerOperationId)||R("caller_operation_id"),yt.test(t.transaction)||R("transaction"),t.commitment!=="confirmed"&&t.commitment!=="finalized"&&R("commitment"),J(t.confirmationSlot,"confirmation_slot"),J(t.postStateSlot,"post_state_slot"),(t.confirmationSlot===0||t.postStateSlot<t.confirmationSlot)&&R("post_state_slot");let r,a;try{r=ae(e.network),a=ae(t.network)}catch{return R("network")}(a!==r||t.buyerSwigAddress!==e.buyerSwigAddress||t.vaultPda!==e.vaultPda||t.sessionPda!==e.sessionPda||t.seller!==e.seller||t.channelId!==e.channelId||t.sessionPublicKey!==N(e.voucher.sessionPublicKey)||t.voucherDigest!==o||t.cumulativeAmountAtomic!==e.voucher.payload.cumulativeAmount||t.sequenceNumber!==e.voucher.payload.sequenceNumber||!Oe.test(t.providerReceiptId)||t.reservationAmountAtomic!==e.reservationAmountAtomic||t.currentOutstandingBeforeAtomic!=="0"||t.currentOutstandingAfterAtomic!==e.reservationAmountAtomic)&&R("economic_identity"),J(t.pendingVoucherCountBefore,"pending_voucher_count_before"),J(t.pendingVoucherCountAfter,"pending_voucher_count_after"),t.contract==="dexter-native-tab-open-receipt/v1"?t.callerOperationId!==e.idempotencyKey&&R("idempotency_key"):(t.rootOperationId!==e.idempotencyKey||!Number.isSafeInteger(t.generation)||Number(t.generation)<2||!t.predecessorCallerOperationId||!t.predecessorLifecycleOperationId||!t.predecessorReleaseDigest||!t.stableReservationId||!t.economicEffectDigest)&&R("successor_identity")}var xt=Uint8Array.from([56,67,4,209,238,143,0,129]),_t=74,Me=new Set([1,2]),Rt=188,qe=new T("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),Vt=(()=>{let e=Buffer.alloc(32);return e.write("OTS_SESSION_REGISTER_V2","ascii"),e})(),X=class extends Error{constructor(o,n){super(`native_tab_v2_solana_reservation_invalid:${o}`+(n?`:${n}`:""));this.code=o;this.name="SolanaFinalVoucherV2ReservationError"}code};function l(e,t){throw new X(e,t)}function C(e,t){try{return new T(e)}catch{return l(t)}}function j(e,t){return e.length===t.length&&e.every((o,n)=>o===t[n])}async function It(e){let o=(await e.connection.getSignatureStatuses([e.signature],{searchTransactionHistory:!0})).value[0]??null;if(!o)return null;o.confirmationStatus!=="confirmed"&&o.confirmationStatus!=="finalized"&&l("transaction_commitment"),o.err!==null&&l("transaction_failed");let n=await e.connection.getTransaction(e.signature,{commitment:e.commitment,maxSupportedTransactionVersion:0});if(!n)return null;n.meta||l("transaction_meta_missing"),n.slot!==o.slot&&l("transaction_status_slot");let i=n.transaction.message,s=i.version===0?i.getAccountKeys({accountKeysFromLookups:n.meta.loadedAddresses??null}):i.getAccountKeys(),r=(a,c)=>{let m=s.get(a);return m||l(c),m};return{slot:n.slot,confirmationStatus:o.confirmationStatus,err:n.meta.err,signatures:[...n.transaction.signatures],accountKeys:Array.from({length:s.length},(a,c)=>({address:r(c,"transaction_account_key").toBase58(),signer:i.isAccountSigner(c),writable:i.isAccountWritable(c)})),instructions:i.compiledInstructions.map(a=>({programId:r(a.programIdIndex,"transaction_program_id").toBase58(),accounts:a.accountKeyIndexes.map(c=>r(c,"transaction_instruction_account").toBase58()),data:Uint8Array.from(a.data)}))}}function Ct(e,t,o,n){n.length!==_t&&l("binding_length"),j(n.subarray(0,8),xt)||l("binding_discriminator");let i=n.readUInt8(8),s=n.readUInt8(9);return Me.has(i)||l("binding_version"),s!==t&&l("binding_bump"),{address:e.toBase58(),owner:o.toBase58(),version:i,bump:s,swig:new T(n.subarray(10,42)).toBase58(),vault:new T(n.subarray(42,74)).toBase58()}}async function kt(e){let t=C(e.input.programId,"program_id"),o=C(e.input.buyerSwigAddress,"buyer_swig"),n=C(e.input.vaultPda,"vault_pda"),i=C(e.input.seller,"seller"),[s,r]=le(o,t),[a]=ue(n,i,t),c=await e.connection.getMultipleAccountsInfoAndContext([s,n,a],{commitment:e.commitment,minContextSlot:e.minimumSlot}),[m,d,v]=c.value;m||l("binding_missing"),d||l("vault_missing"),v||l("session_missing");let g,P;try{g=St(Buffer.from(d.data)),P=Pt(a,v.data)}catch(f){return l("post_state_decode",f instanceof Error?f.message:String(f))}let y=P.session;return{contextSlot:c.context.slot,binding:Ct(s,r,m.owner,Buffer.from(m.data)),vault:{owner:d.owner.toBase58(),exists:g.exists,version:g.version,swigAddress:g.swigAddress,dexterAuthority:g.dexterAuthority,pendingVoucherCount:g.pendingVoucherCount},session:{owner:v.owner.toBase58(),version:P.version,bump:P.bump,vault:P.vault,sessionPublicKey:ce(y.sessionPubkey),maxAmount:y.maxAmount,expiresAt:y.expiresAt,seller:y.allowedCounterparty,nonce:y.nonce,spent:y.spent,currentOutstanding:y.currentOutstanding,maxRevolvingCapacity:y.maxRevolvingCapacity,crystallizedCumulative:y.crystallizedCumulative}}}function Kt(e){let t=Buffer.from(e.voucher.sessionRegistration);return t.length!==Rt&&l("registration_length"),j(t.subarray(0,32),Vt)||l("registration_domain"),{programId:new T(t.subarray(32,64)).toBase58(),vaultPda:new T(t.subarray(64,96)).toBase58(),sessionPublicKey:ce(t.subarray(96,128)),maxAmount:t.readBigUInt64LE(128),expiresAt:t.readBigInt64LE(136),seller:new T(t.subarray(144,176)).toBase58(),nonce:t.readUInt32LE(176),maxRevolvingCapacity:t.readBigUInt64LE(180)}}function $(e,t,o){let n=e.accountKeys.filter(i=>i.address===t);return n.length!==1&&l(`${o}_account_key`),n[0]}function Tt(e,t,o){(!Number.isSafeInteger(o.slot)||o.slot<=0)&&l("transaction_slot"),o.slot!==t.confirmationSlot&&l("transaction_confirmation_slot"),o.err!==null&&l("transaction_failed"),o.signatures[0]!==t.transaction&&l("transaction_signature"),o.instructions.length!==2&&l("transaction_instruction_count");let n=C(e.programId,"program_id"),i=C(e.buyerSwigAddress,"buyer_swig"),s=C(e.vaultPda,"vault_pda"),r=C(e.seller,"seller"),a=C(e.sessionPda,"session_pda"),[c]=ue(s,r,n),m=le(i,n)[0],d=wt(i),v=At(n)[0];a.equals(c)||l("session_pda_derivation");let g=Buffer.from(bt.settle_voucher),P=o.instructions.filter(u=>{if(u.programId!==e.programId)return!1;let w=u.data;return w.length>=g.length&&j(w.subarray(0,g.length),g)});P.length!==1&&l("settle_voucher_instruction_count");let y=P[0];o.instructions[0]!==y&&l("settle_voucher_instruction_order");let f=Buffer.from(y.data);f.length!==49&&l("settle_voucher_instruction_length"),f.readBigUInt64LE(8).toString()!==e.reservationAmountAtomic&&l("settle_voucher_amount"),f.readUInt8(16)!==1&&l("settle_voucher_increment"),new T(f.subarray(17,49)).equals(r)||l("settle_voucher_seller"),y.accounts.length<8&&l("settle_voucher_accounts"),[s.toBase58(),null,a.toBase58(),null,i.toBase58(),d.toBase58(),m.toBase58(),v.toBase58()].forEach((u,w)=>{u!==null&&y.accounts[w]!==u&&l(`settle_voucher_account_${w}`)});let p=y.accounts[1];p||l("dexter_authority");let x=$(o,y.accounts[0],"vault"),S=$(o,p,"dexter_authority"),b=$(o,y.accounts[2],"session");(!x.writable||x.signer)&&l("vault_privileges"),S.signer||l("dexter_authority_signature"),(!b.writable||b.signer)&&l("session_privileges");for(let u=3;u<Math.min(y.accounts.length,8);u+=1)$(o,y.accounts[u],`account_${u}`).signer&&l(`settle_voucher_account_${u}_signer`);for(let u=8;u<y.accounts.length;u+=1){let w=$(o,y.accounts[u],`sibling_${u-8}`);(!w.writable||w.signer)&&l("settle_voucher_sibling_privileges")}let A=o.instructions[1];A.programId!==qe.toBase58()&&l("reservation_memo_program"),(A.accounts.length!==1||A.accounts[0]!==p)&&l("reservation_memo_authority"),$(o,p,"reservation_memo_authority").signer||l("reservation_memo_authority_signature");let _=new TextEncoder().encode(ze(e));return j(A.data,_)||l("reservation_memo_digest"),p}function Et(e,t,o,n){let i=C(e.programId,"program_id"),s=C(e.buyerSwigAddress,"buyer_swig"),r=C(e.vaultPda,"vault_pda"),a=C(e.seller,"seller"),[c,m]=le(s,i),[d,v]=ue(r,a,i);(!Number.isSafeInteger(n.contextSlot)||n.contextSlot<t)&&l("post_state_slot"),(n.binding.address!==c.toBase58()||n.binding.owner!==e.programId||n.binding.bump!==m||!Me.has(n.binding.version)||n.binding.swig!==e.buyerSwigAddress||n.binding.vault!==e.vaultPda)&&l("binding_identity"),(n.vault.owner!==e.programId||!n.vault.exists||n.vault.version!==7||n.vault.swigAddress!==e.buyerSwigAddress||n.vault.dexterAuthority!==o)&&l("vault_post_state"),(e.sessionPda!==d.toBase58()||n.session.owner!==e.programId||n.session.version!==1||n.session.bump!==v||n.session.vault!==e.vaultPda||n.session.sessionPublicKey!==ce(e.voucher.sessionPublicKey)||n.session.seller!==e.seller||n.session.nonce!==e.sessionNonce||n.session.currentOutstanding.toString()!==e.reservationAmountAtomic)&&l("session_post_state");let g=Kt(e);(g.programId!==e.programId||g.vaultPda!==e.vaultPda||g.sessionPublicKey!==n.session.sessionPublicKey||g.seller!==e.seller||g.nonce!==e.sessionNonce||g.maxAmount!==n.session.maxAmount||g.expiresAt!==BigInt(n.session.expiresAt)||g.maxRevolvingCapacity!==n.session.maxRevolvingCapacity)&&l("registration_post_state");let P=n.session.spent>n.session.crystallizedCumulative?n.session.spent:n.session.crystallizedCumulative;return P.toString()!==e.previousCumulativeAtomic&&l("session_frontier"),{commitment:"confirmed",confirmationSlot:t,postStateSlot:n.contextSlot,sessionAccountVersion:n.session.version,wireVersion:2,frontierAtomic:P.toString(),spentAtomic:n.session.spent.toString(),currentOutstandingAtomic:n.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:n.session.crystallizedCumulative.toString()}}async function me(e,t,o,n={}){try{Le(t,o)}catch(a){return l("provider_receipt",a instanceof Error?a.message:String(a))}t.network!=="solana:mainnet"&&l("network"),t.programId!==De.toBase58()&&l("program_id");let i=await(n.readTransaction??It)({connection:e,signature:o.transaction,commitment:"confirmed"});i||l("transaction_missing"),i.confirmationStatus!=="confirmed"&&i.confirmationStatus!=="finalized"&&l("transaction_commitment");let s=Tt(t,o,i),r=await(n.readPostState??kt)({connection:e,input:t,minimumSlot:i.slot,commitment:"confirmed"});return{...Et(t,i.slot,s,r),commitment:i.confirmationStatus}}async function de(e,t,o,n={}){await me(e,t,o,n)}function Ot(e,t={}){return async(o,n)=>{await me(e,o,n,t)}}var Bt=De,Ut=qe;import{p256 as Ge}from"@noble/curves/p256";import{sha256 as z}from"@noble/hashes/sha256";import{buildPasskeyAuthorizationChallenge as Nt,classifyPasskeyAuthorizationOperation as $t}from"@dexterai/vault";import{sessionVoucherV2AuthorizationNonce as Ft}from"@dexterai/vault/messages";var We="dexter.cash";function zt(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Lt(e,t=`https://${We}`){let n={type:"webauthn.get",challenge:zt(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(n))}function Dt(e=1){let t=z(new TextEncoder().encode(We)),o=new Uint8Array(37);return o.set(t,0),o[32]=5,new DataView(o.buffer).setUint32(33,e,!1),o}function He(e,t){let o=Lt(t),n=Dt(1),i=new Uint8Array(n.length+32);i.set(n,0),i.set(z(o),n.length);let s=z(i);return{signature:Ge.sign(s,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:o,authenticatorData:n}}function Mt(e,t={}){return{credentialId:new Uint8Array(0),publicKey:e.publicKey,signOperation:async o=>{let n=t.resolveAuthorizationContext?await t.resolveAuthorizationContext(o.slice()):qt(o);if(!n){if(t.allowLegacyOperationHash===!0)return He(e,z(o));throw new Error("passkey_authorization_context_required")}let i=t.ceremonyNonce?t.ceremonyNonce():Ge.utils.randomPrivateKey();if(i.length!==32)throw new Error("ceremonyNonce must be exactly 32 bytes");let s=Nt({programId:n.programId,vault:n.vault,nonce:n.nonce,operationHash:z(o),ceremonyNonce:i});return He(e,s)}}}function qt(e){let t=$t(e);return t.kind==="session_register_v2"?{programId:t.fields.programId,vault:t.fields.vault,nonce:BigInt(Ft(t.fields.registrationNonce))}:t.kind==="session_replace_v1"?{programId:t.fields.programId,vault:t.fields.vault,nonce:t.fields.authorizationNonce}:null}async function nn({connection:e,vaultPda:t,allowedCounterparty:o,programId:n=I,commitment:i="finalized"}){let[s]=Y(t,o,n),r=await e.getMultipleAccountsInfoAndContext([t,s],{commitment:i}),[a,c]=r.value;if(!a)throw new Error("close revocation: vault account not found");if(!a.owner.equals(n))throw new Error("close revocation: vault has the wrong owner");let m=Qt(Buffer.from(a.data));if(!m.exists||m.version!==7)throw new Error("close revocation: Vault V7 required");if(!c)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"absent"};if(!c.owner.equals(n))throw new Error("close revocation: session has the wrong owner");let d=Jt(s,c.data);if(d.version===0)return{kind:"invalidated",contextSlot:r.context.slot,sessionPda:s,reason:"cleared"};if(d.version!==1)throw new Error("close revocation: live SessionAccount required");if(d.vault!==t.toBase58())throw new Error("close revocation: session belongs to a different vault");if(d.session.allowedCounterparty!==o.toBase58())throw new Error("close revocation: session counterparty mismatch");return{kind:"live",snapshot:{contextSlot:r.context.slot,programId:new K(n),vaultPda:new K(t),sessionPda:s,sessionPubkey:Uint8Array.from(d.session.sessionPubkey),maxAmount:d.session.maxAmount,expiresAt:Buffer.from(c.data).readBigInt64LE(82),allowedCounterparty:new K(o),nonce:d.session.nonce,spent:d.session.spent,currentOutstanding:d.session.currentOutstanding,maxRevolvingCapacity:d.session.maxRevolvingCapacity,crystallizedCumulative:d.session.crystallizedCumulative,lastLockedSequence:d.session.lastLockedSequence,expectedPendingVoucherCount:m.pendingVoucherCount}}}function on(e){return fe({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:e.vaultUsdcAta,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var pe=class{network="solana:mainnet";sessionVoucherVersion=2;swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;seams;pendingCloseRevocations=new Map;completedCloseRevocations=new Map;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new K(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"},this.seams=t.seams??{}}closeRevocationKey(t){let o=M(t.registration),[n]=Y(this.vaultPdaKey,o.allowedCounterparty,I);return[n.toBase58(),ge(o.sessionPubkey),o.nonce.toString()].join(":")}async readCloseTargetState(t){let o={connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:t,programId:I,commitment:"finalized"};if(this.seams.readCloseRevocationTargetState)return this.seams.readCloseRevocationTargetState(o);if(this.seams.readCloseRevocationSnapshot)try{return{kind:"live",snapshot:await this.seams.readCloseRevocationSnapshot(o)}}catch{return null}return nn(o)}targetInvalidated(t,o){if(t.kind==="invalidated")return!0;let n=t.snapshot,[i]=Y(this.vaultPdaKey,o.allowedCounterparty,I);if(!n.programId.equals(I)||!n.vaultPda.equals(this.vaultPdaKey)||!n.sessionPda.equals(i)||!n.allowedCounterparty.equals(o.allowedCounterparty))throw new Error("session revocation snapshot identity mismatch");if(!Buffer.from(n.sessionPubkey).equals(Buffer.from(o.sessionPubkey))||n.nonce!==o.nonce)return!0;if(n.maxAmount!==o.maxAmount||n.expiresAt!==o.expiresAt||n.maxRevolvingCapacity!==o.maxRevolvingCapacity)throw new Error("session revocation snapshot identity mismatch");return!1}rememberCompletedClose(t,o){let n=Uint8Array.from(o);return this.pendingCloseRevocations.delete(t),this.completedCloseRevocations.set(t,n),Uint8Array.from(n)}async reconcilePendingClose(t,o,n){let i=!1,s=null;try{let c=await this.connection.getSignatureStatuses([t.signature],{searchTransactionHistory:!0});if(i=!0,s=c.value[0]??null,s?.confirmationStatus==="finalized")return s.err===null?"complete":"fresh_allowed"}catch{}let r=!1;try{let c=await this.connection.getTransaction(t.signature,{commitment:"finalized",maxSupportedTransactionVersion:0});if(r=!0,c)return!c.meta||!Object.prototype.hasOwnProperty.call(c.meta,"err")?"unresolved":c.meta.err===null?"complete":"fresh_allowed"}catch{}let a=await this.readCloseTargetState(o.allowedCounterparty).catch(()=>null);if(a&&this.targetInvalidated(a,o))return"complete";if(n&&i&&s===null)try{if((await this.connection.isBlockhashValid(t.blockhash,{commitment:"confirmed"})).value)return await this.connection.sendRawTransaction(t.serializedTransaction,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment})!==t.signature?"unresolved":(await this.connection.confirmTransaction({signature:t.signature,blockhash:t.blockhash,lastValidBlockHeight:t.lastValidBlockHeight},"finalized")).value.err===null?"complete":"fresh_allowed"}catch{}if(i&&s!==null||!i||!r||t.finalizedHistoryFloorSlot===null)return"unresolved";try{let[c,m]=await Promise.all([this.connection.getBlockHeight("finalized"),this.connection.getMinimumLedgerSlot()]);if(c>t.lastValidBlockHeight&&m<=t.finalizedHistoryFloorSlot)return"fresh_allowed"}catch{}return"unresolved"}async authorizeSession(t,o){let n=new K(t.allowedCounterparty),i=E(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=await(this.seams.fetchSession??Wt)(this.connection,this.vaultPdaKey,n),a=r!==null&&Xt(r);if(a&&(o?.onLiveSession??"error")!=="replace"){let h=r.session.spent,p=r.session.crystallizedCumulative;throw new F({allowedCounterparty:t.allowedCounterparty,sessionPubkeyHex:ge(r.session.sessionPubkey),expiresAtUnix:r.session.expiresAt,spentAtomic:h.toString(),crystallizedCumulativeAtomic:p.toString(),currentOutstandingAtomic:r.session.currentOutstanding.toString(),frontierAtomic:(h>p?h:p).toString()})}let m=await(this.seams.fetchPasskeyAuthorization??en)(this.connection,this.vaultPdaKey,I);if(m===null||m.version!==1||!m.vault.equals(this.vaultPdaKey))throw new Error("passkey_authorization_guard_unavailable");let d=Se(),v=we(m.nonce),g=ve({programId:I,vaultPda:this.vaultPdaKey,sessionPubkey:d.publicKey,maxAmount:E(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v}),P=a?Ae({programId:I,vaultPda:this.vaultPdaKey,sessionPda:new K(r.address),authorizationNonce:m.nonce,retired:{sessionPubkey:r.session.sessionPubkey,maxAmount:r.session.maxAmount,expiresAt:BigInt(r.session.expiresAt),allowedCounterparty:new K(r.session.allowedCounterparty),nonce:r.session.nonce,spent:r.session.spent,currentOutstanding:r.session.currentOutstanding,maxRevolvingCapacity:r.session.maxRevolvingCapacity,crystallizedCumulative:r.session.crystallizedCumulative,lastLockedSequence:r.session.lastLockedSequence},replacement:{sessionPubkey:d.publicKey,maxAmount:E(t.maxAmountAtomic),expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:v,maxRevolvingCapacity:i}}):g,y=await this.passkey.signOperation(P);if(a)await this.sendAtomicReplace(t,n,d.publicKey,v,i,y);else{if(tn({clientDataJSON:y.clientDataJSON,operationMessage:P,expectedVault:this.vaultPdaKey,expectedProgramId:I}).nonce!==m.nonce)throw new Error("passkey_authorization_guard_changed");await this.sendBareRegister(t,n,d.publicKey,v,i,y)}return await(this.seams.waitForSession??Yt)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:d.publicKey,timeoutMs:2e4}),Pe(d,t,g)}async sendBareRegister(t,o,n,i,s,r){let{signature:a,clientDataJSON:c,authenticatorData:m}=r,d=Ye(m,je(c)),v=Z(this.passkey.publicKey,a,d),g=this.seams.fetchSessions??Gt,P=jt(await g(this.connection,this.vaultPdaKey)),f=await(this.seams.resolveUsdcAta??Xe)(this.connection,new K(this.swigAddress)),h=on({vaultPda:this.vaultPdaKey,swigAddress:new K(this.swigAddress),sessionPubkey:n,maxAmount:E(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:o,nonce:i,clientDataJSON:c,authenticatorData:m,payer:this.feePayer.publicKey,siblingSessionPdas:P,vaultUsdcAta:f}),p=new Je().add(v,h);p.feePayer=this.feePayer.publicKey;let{blockhash:x}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=x,p.sign(this.feePayer);let S;try{S=p.serialize()}catch(A){if(!/^Transaction too large: \d+ > 1232$/i.test(String(A?.message??A)))throw A;let V=this.seams.composeSend?{send:this.seams.composeSend,deactivateAlt:async()=>{}}:W(this.connection,this.feePayer,{commitment:this.confirmOptions.commitment});try{await V.send([v,h])}finally{V.deactivateAlt()}return}let b=await this.connection.sendRawTransaction(S,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});await this.connection.confirmTransaction({signature:b,blockhash:x,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment)}async sendAtomicReplace(t,o,n,i,s,r){let c=await(this.seams.resolveUsdcAta??Xe)(this.connection,new K(this.swigAddress)),m=this.seams.composeSend?{send:this.seams.composeSend,deactivateAlt:async()=>{}}:W(this.connection,this.feePayer,{commitment:this.confirmOptions.commitment});try{await Zt({connection:this.connection,vaultPda:this.vaultPdaKey,allowedCounterparty:o,registerArgs:{sessionPubkey:n,maxAmount:E(t.maxAmountAtomic),maxRevolvingCapacity:s,expiresAt:BigInt(t.expiresAtUnix),nonce:i,swigAddress:new K(this.swigAddress),vaultUsdcAta:c,payer:this.feePayer.publicKey},registerCeremony:{clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData,signature:r.signature},credentialPublicKey:this.passkey.publicKey,send:m.send,fetchSession:this.seams.fetchSession,fetchSessions:this.seams.fetchSessions,fetchPasskeyAuthorization:this.seams.fetchPasskeyAuthorization})}finally{m.deactivateAlt()}}async signWithSession(t,o){let n=await rn(o.channelId),i=M(t.registration);if((i.nonce&2147483648)!==0){let[s]=Y(i.vaultPda,i.allowedCounterparty,i.programId),r=_e({programId:i.programId.toBase58(),vaultPda:i.vaultPda.toBase58(),sessionPda:s.toBase58(),seller:i.allowedCounterparty.toBase58(),sessionNonce:i.nonce,channelId:ge(n),cumulativeAmountAtomic:o.cumulativeAmount,sequenceOrdinal:o.sequenceNumber,sessionPrivateKey:t.privateKey,sessionPublicKey:t.publicKey,sessionRegistration:t.registration});return{payload:{channelId:r.channelId,cumulativeAmount:r.cumulativeAmount,sequenceNumber:r.sequenceNumber},sessionPublicKey:Uint8Array.from(Buffer.from(r.sessionPublicKey,"hex")),sessionSignature:Uint8Array.from(Buffer.from(r.sessionSignature,"hex")),sessionRegistration:Uint8Array.from(Buffer.from(r.sessionRegistration,"hex"))}}return xe(t,o,n)}async signOpenTab(t,o){return t.registration}async verifyFinalVoucherV2Reservation(t,o){await de(this.connection,t,o)}async signCloseTab(t,o,n){let i=M(t.registration);if(!i.vaultPda.equals(this.vaultPdaKey)||!Buffer.from(i.sessionPubkey).equals(Buffer.from(t.publicKey)))throw new Error("session registration identity mismatch");let s=this.closeRevocationKey(t),r=this.completedCloseRevocations.get(s);if(r)return Uint8Array.from(r);let a=this.pendingCloseRevocations.get(s);if(a){let k=await this.reconcilePendingClose(a,i,!0);if(k==="complete")return this.rememberCompletedClose(s,a.message);if(k==="unresolved")throw new Error(`session revoke finality unresolved for ${a.signature}; retry close`);this.pendingCloseRevocations.delete(s)}let c=await this.readCloseTargetState(i.allowedCounterparty);if(!c)throw new Error("close revocation target state unavailable");if(c.kind==="invalidated"||this.targetInvalidated(c,i))return this.rememberCompletedClose(s,t.registration);let m=c.snapshot,d=E(n);if((m.spent>m.crystallizedCumulative?m.spent:m.crystallizedCumulative)<d)throw new Error("session revocation snapshot is behind final settlement");let g=be(m),{signature:P,clientDataJSON:y,authenticatorData:f}=await this.passkey.signOperation(g),h=Ye(f,je(y)),p=Z(this.passkey.publicKey,P,h),x=he({vaultPda:this.vaultPdaKey,allowedCounterparty:m.allowedCounterparty,expectedPendingVoucherCount:m.expectedPendingVoucherCount,clientDataJSON:y,authenticatorData:f}),S=new Je().add(p,x);S.feePayer=this.feePayer.publicKey;let b=null;try{let k=await this.connection.getSlot("finalized");b=Number.isSafeInteger(k)&&k>=0?k:null}catch{}let{blockhash:A,lastValidBlockHeight:V}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);if(S.recentBlockhash=A,S.sign(this.feePayer),!S.signature)throw new Error("session revoke transaction is unsigned");let _=Uint8Array.from(S.serialize()),u=Ht.encode(S.signature),w={key:s,message:Uint8Array.from(g),serializedTransaction:_,signature:u,blockhash:A,lastValidBlockHeight:V,finalizedHistoryFloorSlot:b};this.pendingCloseRevocations.set(s,w);let B;try{let k=await this.connection.sendRawTransaction(_,{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});if(k!==u)throw new Error(`session revoke signature mismatch expected=${u} returned=${k}`);B=await this.connection.confirmTransaction({signature:u,blockhash:A,lastValidBlockHeight:V},"finalized")}catch(k){let ye=await this.reconcilePendingClose(w,i,!1);if(ye==="complete")return this.rememberCompletedClose(s,g);throw ye==="fresh_allowed"?(this.pendingCloseRevocations.delete(s),new Error("session revoke transaction finalized without effect; retry close",{cause:k})):new Error(`session revoke finality unresolved for ${u}; retry close`,{cause:k})}if(B.value.err)throw this.pendingCloseRevocations.delete(s),new Error(`session revoke transaction failed: ${JSON.stringify(B.value.err)}`);return this.rememberCompletedClose(s,g)}};function Eo(e){return new pe(e)}function Ye(e,t){let o=new Uint8Array(e.length+t.length);return o.set(e,0),o.set(t,e.length),o}async function rn(e){if(/^[0-9a-f]{64}$/i.test(e))return sn(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function sn(e){let t=new Uint8Array(e.length/2);for(let o=0;o<t.length;o++)t[o]=parseInt(e.substr(o*2,2),16);return t}export{F as LiveSessionExistsError,Ut as SOLANA_FINAL_VOUCHER_V2_MEMO_PROGRAM_ID,Bt as SOLANA_FINAL_VOUCHER_V2_PROGRAM_ID,X as SolanaFinalVoucherV2ReservationError,G as TX_SIZE_LIMIT_BYTES,on as buildAdapterRegisterInstruction,Ke as collectAltAddresses,Te as compileComposeV0,W as createSelfPayingComposeSend,Ot as createSolanaFinalVoucherV2ReservationVerifier,Eo as createSolanaVaultAdapter,at as deriveChannelId,me as inspectSolanaFinalVoucherV2Reservation,Mt as passkeySignerFromP256Keypair,de as verifySolanaFinalVoucherV2Reservation};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexterai/x402",
|
|
3
|
-
"version": "6.0.0-rc.
|
|
3
|
+
"version": "6.0.0-rc.5",
|
|
4
4
|
"description": "Full-stack x402 SDK - add paid API monetization to any endpoint. Express middleware, React hooks, Access Pass, dynamic pricing. Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, World Chain, Monad, Robinhood Chain, SKALE.",
|
|
5
5
|
"author": "Dexter",
|
|
6
6
|
"license": "MIT",
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"tweetnacl": "^1.0.3"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
|
-
"@dexterai/vault": "0.43.
|
|
95
|
+
"@dexterai/vault": "0.43.3-rc.1",
|
|
96
96
|
"@types/aws-lambda": "^8.10.161",
|
|
97
97
|
"@types/express": "^5.0.6",
|
|
98
98
|
"@types/node": "^22.10.0",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"vitest": "^2.1.8"
|
|
107
107
|
},
|
|
108
108
|
"peerDependencies": {
|
|
109
|
-
"@dexterai/vault": "0.43.
|
|
109
|
+
"@dexterai/vault": "0.43.3-rc.1",
|
|
110
110
|
"@solana/wallet-adapter-base": "^0.9.0",
|
|
111
111
|
"react": "^18.0.0 || ^19.0.0",
|
|
112
112
|
"stripe": "^20.0.0",
|