@dexterai/x402 3.14.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- "use strict";var q=Object.create;var h=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var X=Object.getOwnPropertyNames;var Y=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var Z=(e,t)=>{for(var n in t)h(e,n,{get:t[n],enumerable:!0})},N=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of X(t))!j.call(e,r)&&r!==n&&h(e,r,{get:()=>t[r],enumerable:!(i=G(t,r))||i.enumerable});return e};var U=(e,t,n)=>(n=e!=null?q(Y(e)):{},N(t||!e||!e.__esModule?h(n,"default",{value:e,enumerable:!0}):n,e)),Q=e=>N(h({},"__esModule",{value:!0}),e);var me={};Z(me,{buildAdapterRegisterInstruction:()=>$,createSolanaVaultAdapter:()=>pe,deriveChannelId:()=>W,passkeySignerFromP256Keypair:()=>ce});module.exports=Q(me);var y=require("@solana/web3.js"),H=require("@solana/spl-token");var ee="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",te="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",ne="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var P="eip155:8453",E="eip155:84532",b="eip155:42161",K="eip155:137",v="eip155:10",w="eip155:43114",O="eip155:56",R="eip155:1187947933",T="eip155:324705682",C="eip155:1";var I="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var ie="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",re="0x55d398326f99059fF775485246999027B3197955",k="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ae={[O]:k,[P]:ie,[E]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[b]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[K]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[v]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[w]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[R]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[T]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[C]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},he={[re]:{symbol:"USDT",decimals:18},[k]:{symbol:"USDC",decimals:18}};var Se={[O]:56,[P]:8453,[E]:84532,[b]:42161,[K]:137,[v]:10,[w]:43114,[R]:1187947933,[T]:324705682,[C]:1},fe={[ee]:"https://api.dexter.cash/api/solana/rpc",[te]:"https://api.devnet.solana.com",[ne]:"https://api.testnet.solana.com"},xe={[O]:"https://api.dexter.cash/api/evm/bsc/rpc",[P]:"https://api.dexter.cash/api/base/rpc",[E]:"https://sepolia.base.org",[b]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[K]:"https://api.dexter.cash/api/evm/polygon/rpc",[v]:"https://api.dexter.cash/api/evm/optimism/rpc",[w]:"https://api.dexter.cash/api/evm/avalanche/rpc",[R]:"https://skale-base.skalenodes.com/v1/base",[T]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[C]:"https://eth.llamarpc.com"};var u=require("@dexterai/vault/instructions"),S=require("@dexterai/vault/precompile"),m=require("@dexterai/vault/constants");var a=require("@dexterai/vault/messages");var _=U(require("tweetnacl"),1);var L=require("@noble/hashes/sha256");function B(){let e=_.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function M(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function V(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),r=BigInt(e.scope.maxAmountAtomic);if(i>r)throw new Error(`voucher cumulative ${i} exceeds session cap ${r}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let c=(0,a.voucherPayloadMessage)({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),o=_.default.sign.detached(c,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:o}}function f(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function W(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=L.sha256.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}var F=require("@noble/curves/p256"),A=require("@noble/hashes/sha256"),J="dexter.cash";function se(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function oe(e,t=`https://${J}`){let i={type:"webauthn.get",challenge:se(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function ae(e=1){let t=(0,A.sha256)(new TextEncoder().encode(J)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function z(e,t){let n=(0,A.sha256)(t),i=oe(n),r=ae(1),s=new Uint8Array(r.length+32);s.set(r,0),s.set((0,A.sha256)(i),r.length);let c=(0,A.sha256)(s),p=F.p256.sign(c,e.privateKey,{lowS:!0}).toCompactRawBytes();return{clientDataJSON:i,authenticatorData:r,precompileMessage:s,signature:p}}function ce(e){return{publicKey:e.publicKey,signOperation:async t=>z(e,t)}}function $(e){let t=(0,u.deriveSwigWalletAddress)(e.swigAddress),n=(0,H.getAssociatedTokenAddressSync)(new y.PublicKey(I),t,!0);return(0,u.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData})}var D=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new y.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new y.PublicKey(t.allowedCounterparty),i=f(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=B(),s=le(),c=(0,a.sessionRegisterMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:r.publicKey,maxAmount:f(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:s}),o=await this.passkey.signOperation(c),p=(0,S.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,o.signature,o.precompileMessage),g=$({vaultPda:this.vaultPdaKey,swigAddress:new y.PublicKey(this.swigAddress),sessionPubkey:r.publicKey,maxAmount:f(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:s,clientDataJSON:o.clientDataJSON,authenticatorData:o.authenticatorData}),l=new y.Transaction().add(p,g);l.feePayer=this.feePayer.publicKey;let{blockhash:d}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);l.recentBlockhash=d,l.sign(this.feePayer);let x=await this.connection.sendRawTransaction(l.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:x,blockhash:d,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await this.waitForActiveSessionFinalized(r.publicKey),M(r,t,c)}async signWithSession(t,n){let i=await ue(n.channelId);return V(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let r=(0,a.sessionRevokeMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),s=await this.passkey.signOperation(r),c=(0,S.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,s.signature,s.precompileMessage),o=(0,u.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,clientDataJSON:s.clientDataJSON,authenticatorData:s.authenticatorData}),p=new y.Transaction().add(c,o);p.feePayer=this.feePayer.publicKey;let{blockhash:g,lastValidBlockHeight:l}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=g,p.sign(this.feePayer);let d=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:d,blockhash:g,lastValidBlockHeight:l},this.confirmOptions.commitment),r}async waitForActiveSessionFinalized(t,n=2e4){let i=Date.now()+n;for(;Date.now()<i;){let r=await this.connection.getAccountInfo(this.vaultPdaKey,"finalized");if(r){let s=r.data,l=84+(s[83]===1?48:0)+32+32;if(s[l]===1){let d=l+1,x=s.slice(d,d+32);if(ye(x,t))return}}await new Promise(s=>setTimeout(s,500))}throw new Error(`register_session_key did not become finalized-visible within ${n}ms`)}};function pe(e){return new D(e)}function le(){return Math.floor(Math.random()*4294967295)>>>0}async function ue(e){if(/^[0-9a-f]{64}$/i.test(e))return de(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function ye(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function de(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}0&&(module.exports={buildAdapterRegisterInstruction,createSolanaVaultAdapter,deriveChannelId,passkeySignerFromP256Keypair});
1
+ "use strict";var Y=Object.create;var h=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var ee=(e,t)=>{for(var n in t)h(e,n,{get:t[n],enumerable:!0})},U=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of j(t))!Q.call(e,s)&&s!==n&&h(e,s,{get:()=>t[s],enumerable:!(i=z(t,s))||i.enumerable});return e};var I=(e,t,n)=>(n=e!=null?Y(Z(e)):{},U(t||!e||!e.__esModule?h(n,"default",{value:e,enumerable:!0}):n,e)),te=e=>U(h({},"__esModule",{value:!0}),e);var ge={};ee(ge,{buildAdapterRegisterInstruction:()=>q,createSolanaVaultAdapter:()=>ue,deriveChannelId:()=>F,passkeySignerFromP256Keypair:()=>le});module.exports=te(ge);var p=require("@solana/web3.js"),$=require("@solana/spl-token");var ne="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",ie="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",se="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var P="eip155:8453",b="eip155:84532",E="eip155:42161",K="eip155:137",v="eip155:10",w="eip155:43114",O="eip155:56",R="eip155:1187947933",C="eip155:324705682",T="eip155:1";var k="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var re="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",oe="0x55d398326f99059fF775485246999027B3197955",B="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",he={[O]:B,[P]:re,[b]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[E]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[K]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[v]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[w]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[R]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[C]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[T]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Se={[oe]:{symbol:"USDT",decimals:18},[B]:{symbol:"USDC",decimals:18}};var fe={[O]:56,[P]:8453,[b]:84532,[E]:42161,[K]:137,[v]:10,[w]:43114,[R]:1187947933,[C]:324705682,[T]:1},xe={[ne]:"https://api.dexter.cash/api/solana/rpc",[ie]:"https://api.devnet.solana.com",[se]:"https://api.testnet.solana.com"},Pe={[O]:"https://api.dexter.cash/api/evm/bsc/rpc",[P]:"https://api.dexter.cash/api/base/rpc",[b]:"https://sepolia.base.org",[E]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[K]:"https://api.dexter.cash/api/evm/polygon/rpc",[v]:"https://api.dexter.cash/api/evm/optimism/rpc",[w]:"https://api.dexter.cash/api/evm/avalanche/rpc",[R]:"https://skale-base.skalenodes.com/v1/base",[C]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[T]:"https://eth.llamarpc.com"};var c=require("@dexterai/vault/instructions"),S=require("@dexterai/vault/precompile"),m=require("@dexterai/vault/constants");var o=require("@dexterai/vault/messages");var _=I(require("tweetnacl"),1);var W=require("@noble/hashes/sha256");function M(){let e=_.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function V(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function L(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),s=BigInt(e.scope.maxAmountAtomic);if(i>s)throw new Error(`voucher cumulative ${i} exceeds session cap ${s}`);let r=Math.floor(Date.now()/1e3);if(r>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${r}`);let l=(0,o.voucherPayloadMessage)({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),a=_.default.sign.detached(l,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}function f(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function F(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=W.sha256.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}var d=require("@dexterai/vault/session");var J=require("@noble/curves/p256"),g=require("@noble/hashes/sha256"),H="dexter.cash";function ae(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ce(e,t=`https://${H}`){let i={type:"webauthn.get",challenge:ae(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function pe(e=1){let t=(0,g.sha256)(new TextEncoder().encode(H)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function G(e,t){let n=(0,g.sha256)(t),i=ce(n),s=pe(1),r=new Uint8Array(s.length+32);r.set(s,0),r.set((0,g.sha256)(i),s.length);let l=(0,g.sha256)(r),u=J.p256.sign(l,e.privateKey,{lowS:!0}).toCompactRawBytes();return{clientDataJSON:i,authenticatorData:s,precompileMessage:r,signature:u}}function le(e){return{publicKey:e.publicKey,signOperation:async t=>G(e,t)}}function q(e){let t=(0,c.deriveSwigWalletAddress)(e.swigAddress),n=(0,$.getAssociatedTokenAddressSync)(new p.PublicKey(k),t,!0);return(0,c.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var N=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new p.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new p.PublicKey(t.allowedCounterparty),i=f(t.revolvingCapacityAtomic??t.maxAmountAtomic),s=M(),r=ye(),l=(0,o.sessionRegisterMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:s.publicKey,maxAmount:f(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r}),a=await this.passkey.signOperation(l),u=(0,S.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,a.signature,a.precompileMessage),A=(0,d.sessionPdasOf)(await(0,d.fetchVaultSessionAccounts)(this.connection,this.vaultPdaKey)),x=q({vaultPda:this.vaultPdaKey,swigAddress:new p.PublicKey(this.swigAddress),sessionPubkey:s.publicKey,maxAmount:f(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r,clientDataJSON:a.clientDataJSON,authenticatorData:a.authenticatorData,payer:this.feePayer.publicKey,siblingSessionPdas:A}),y=new p.Transaction().add(u,x);y.feePayer=this.feePayer.publicKey;let{blockhash:D}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);y.recentBlockhash=D,y.sign(this.feePayer);let X=await this.connection.sendRawTransaction(y.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:X,blockhash:D,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await(0,d.waitForSession)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:s.publicKey,timeoutMs:2e4}),V(s,t,l)}async signWithSession(t,n){let i=await me(n.channelId);return L(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let s=(0,o.sessionRevokeMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),r=await this.passkey.signOperation(s),l=(0,S.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,r.signature,r.precompileMessage),a=(0,c.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,allowedCounterparty:new p.PublicKey(t.scope.allowedCounterparty),clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData}),u=new p.Transaction().add(l,a);u.feePayer=this.feePayer.publicKey;let{blockhash:A,lastValidBlockHeight:x}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);u.recentBlockhash=A,u.sign(this.feePayer);let y=await this.connection.sendRawTransaction(u.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:y,blockhash:A,lastValidBlockHeight:x},this.confirmOptions.commitment),s}};function ue(e){return new N(e)}function ye(){return Math.floor(Math.random()*4294967295)>>>0}async function me(e){if(/^[0-9a-f]{64}$/i.test(e))return de(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function de(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}0&&(module.exports={buildAdapterRegisterInstruction,createSolanaVaultAdapter,deriveChannelId,passkeySignerFromP256Keypair});
@@ -112,6 +112,10 @@ interface AdapterRegisterIxParams {
112
112
  nonce: number;
113
113
  clientDataJSON: Uint8Array;
114
114
  authenticatorData: Uint8Array;
115
+ /** V6: rent payer for the init_if_needed session PDA (the buyer's fee payer). */
116
+ payer: PublicKey;
117
+ /** V6: existing session PDAs for this vault — the overcommit aggregate gate. */
118
+ siblingSessionPdas: PublicKey[];
115
119
  }
116
120
  declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): _solana_web3_js.TransactionInstruction;
117
121
  /** Factory entry point. */
@@ -112,6 +112,10 @@ interface AdapterRegisterIxParams {
112
112
  nonce: number;
113
113
  clientDataJSON: Uint8Array;
114
114
  authenticatorData: Uint8Array;
115
+ /** V6: rent payer for the init_if_needed session PDA (the buyer's fee payer). */
116
+ payer: PublicKey;
117
+ /** V6: existing session PDAs for this vault — the overcommit aggregate gate. */
118
+ siblingSessionPdas: PublicKey[];
115
119
  }
116
120
  declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): _solana_web3_js.TransactionInstruction;
117
121
  /** Factory entry point. */
@@ -1 +1 @@
1
- import{PublicKey as m,Transaction as J}from"@solana/web3.js";import{getAssociatedTokenAddressSync as te}from"@solana/spl-token";var z="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",H="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",$="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var A="eip155:8453",h="eip155:84532",S="eip155:42161",f="eip155:137",x="eip155:10",P="eip155:43114",E="eip155:56",b="eip155:1187947933",K="eip155:324705682",v="eip155:1";var T="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var q="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",G="0x55d398326f99059fF775485246999027B3197955",C="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",ae={[E]:C,[A]:q,[h]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[S]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[f]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[x]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[P]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[b]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[K]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[v]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ce={[G]:{symbol:"USDT",decimals:18},[C]:{symbol:"USDC",decimals:18}};var pe={[E]:56,[A]:8453,[h]:84532,[S]:42161,[f]:137,[x]:10,[P]:43114,[b]:1187947933,[K]:324705682,[v]:1},le={[z]:"https://api.dexter.cash/api/solana/rpc",[H]:"https://api.devnet.solana.com",[$]:"https://api.testnet.solana.com"},ue={[E]:"https://api.dexter.cash/api/evm/bsc/rpc",[A]:"https://api.dexter.cash/api/base/rpc",[h]:"https://sepolia.base.org",[S]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[f]:"https://api.dexter.cash/api/evm/polygon/rpc",[x]:"https://api.dexter.cash/api/evm/optimism/rpc",[P]:"https://api.dexter.cash/api/evm/avalanche/rpc",[b]:"https://skale-base.skalenodes.com/v1/base",[K]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[v]:"https://eth.llamarpc.com"};import{buildRegisterSessionKeyInstruction as _,buildRevokeSessionKeyInstruction as D,deriveSwigWalletAddress as N}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as w}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as O,SECP256R1_PROGRAM_ID as he,INSTRUCTIONS_SYSVAR_ID as Se}from"@dexterai/vault/constants";import{sessionRegisterMessage as U,sessionRevokeMessage as I,voucherPayloadMessage as k,buildVoucherMessage as Pe}from"@dexterai/vault/messages";import B from"tweetnacl";import{sha256 as X}from"@noble/hashes/sha256";function M(){let e=B.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function V(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function L(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),s=BigInt(e.scope.maxAmountAtomic);if(i>s)throw new Error(`voucher cumulative ${i} exceeds session cap ${s}`);let r=Math.floor(Date.now()/1e3);if(r>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${r}`);let a=k({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),o=B.sign.detached(a,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:o}}function y(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function Y(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=X.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}import{p256 as j}from"@noble/curves/p256";import{sha256 as d}from"@noble/hashes/sha256";var W="dexter.cash";function Z(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function Q(e,t=`https://${W}`){let i={type:"webauthn.get",challenge:Z(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function ee(e=1){let t=d(new TextEncoder().encode(W)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function F(e,t){let n=d(t),i=Q(n),s=ee(1),r=new Uint8Array(s.length+32);r.set(s,0),r.set(d(i),s.length);let a=d(r),c=j.sign(a,e.privateKey,{lowS:!0}).toCompactRawBytes();return{clientDataJSON:i,authenticatorData:s,precompileMessage:r,signature:c}}function Be(e){return{publicKey:e.publicKey,signOperation:async t=>F(e,t)}}function ne(e){let t=N(e.swigAddress),n=te(new m(T),t,!0);return _({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData})}var R=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new m(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new m(t.allowedCounterparty),i=y(t.revolvingCapacityAtomic??t.maxAmountAtomic),s=M(),r=ie(),a=U({programId:O,vaultPda:this.vaultPdaKey,sessionPubkey:s.publicKey,maxAmount:y(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r}),o=await this.passkey.signOperation(a),c=w(this.passkey.publicKey,o.signature,o.precompileMessage),u=ne({vaultPda:this.vaultPdaKey,swigAddress:new m(this.swigAddress),sessionPubkey:s.publicKey,maxAmount:y(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r,clientDataJSON:o.clientDataJSON,authenticatorData:o.authenticatorData}),p=new J().add(c,u);p.feePayer=this.feePayer.publicKey;let{blockhash:l}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=l,p.sign(this.feePayer);let g=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:g,blockhash:l,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await this.waitForActiveSessionFinalized(s.publicKey),V(s,t,a)}async signWithSession(t,n){let i=await re(n.channelId);return L(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let s=I({programId:O,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),r=await this.passkey.signOperation(s),a=w(this.passkey.publicKey,r.signature,r.precompileMessage),o=D({vaultPda:this.vaultPdaKey,clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData}),c=new J().add(a,o);c.feePayer=this.feePayer.publicKey;let{blockhash:u,lastValidBlockHeight:p}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);c.recentBlockhash=u,c.sign(this.feePayer);let l=await this.connection.sendRawTransaction(c.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:l,blockhash:u,lastValidBlockHeight:p},this.confirmOptions.commitment),s}async waitForActiveSessionFinalized(t,n=2e4){let i=Date.now()+n;for(;Date.now()<i;){let s=await this.connection.getAccountInfo(this.vaultPdaKey,"finalized");if(s){let r=s.data,p=84+(r[83]===1?48:0)+32+32;if(r[p]===1){let l=p+1,g=r.slice(l,l+32);if(se(g,t))return}}await new Promise(r=>setTimeout(r,500))}throw new Error(`register_session_key did not become finalized-visible within ${n}ms`)}};function Me(e){return new R(e)}function ie(){return Math.floor(Math.random()*4294967295)>>>0}async function re(e){if(/^[0-9a-f]{64}$/i.test(e))return oe(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function se(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function oe(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}export{ne as buildAdapterRegisterInstruction,Me as createSolanaVaultAdapter,Y as deriveChannelId,Be as passkeySignerFromP256Keypair};
1
+ import{PublicKey as l,Transaction as J}from"@solana/web3.js";import{getAssociatedTokenAddressSync as ne}from"@solana/spl-token";var G="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",$="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",q="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var g="eip155:8453",A="eip155:84532",h="eip155:42161",S="eip155:137",f="eip155:10",x="eip155:43114",P="eip155:56",b="eip155:1187947933",E="eip155:324705682",K="eip155:1";var C="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var X="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Y="0x55d398326f99059fF775485246999027B3197955",T="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",le={[P]:T,[g]:X,[A]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[h]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[S]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[f]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[x]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[b]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[E]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[K]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ue={[Y]:{symbol:"USDT",decimals:18},[T]:{symbol:"USDC",decimals:18}};var ye={[P]:56,[g]:8453,[A]:84532,[h]:42161,[S]:137,[f]:10,[x]:43114,[b]:1187947933,[E]:324705682,[K]:1},me={[G]:"https://api.dexter.cash/api/solana/rpc",[$]:"https://api.devnet.solana.com",[q]:"https://api.testnet.solana.com"},de={[P]:"https://api.dexter.cash/api/evm/bsc/rpc",[g]:"https://api.dexter.cash/api/base/rpc",[A]:"https://sepolia.base.org",[h]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[S]:"https://api.dexter.cash/api/evm/polygon/rpc",[f]:"https://api.dexter.cash/api/evm/optimism/rpc",[x]:"https://api.dexter.cash/api/evm/avalanche/rpc",[b]:"https://skale-base.skalenodes.com/v1/base",[E]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[K]:"https://eth.llamarpc.com"};import{buildRegisterSessionKeyInstruction as _,buildRevokeSessionKeyInstruction as N,deriveSwigWalletAddress as D}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as v}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as w,SECP256R1_PROGRAM_ID as xe,INSTRUCTIONS_SYSVAR_ID as Pe}from"@dexterai/vault/constants";import{sessionRegisterMessage as U,sessionRevokeMessage as I,voucherPayloadMessage as k,buildVoucherMessage as Ke}from"@dexterai/vault/messages";import B from"tweetnacl";import{sha256 as z}from"@noble/hashes/sha256";function M(){let e=B.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function V(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function L(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),s=BigInt(e.scope.maxAmountAtomic);if(i>s)throw new Error(`voucher cumulative ${i} exceeds session cap ${s}`);let r=Math.floor(Date.now()/1e3);if(r>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${r}`);let a=k({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),o=B.sign.detached(a,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:o}}function y(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function j(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=z.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}import{fetchVaultSessionAccounts as ie,sessionPdasOf as se,waitForSession as re}from"@dexterai/vault/session";import{p256 as Z}from"@noble/curves/p256";import{sha256 as m}from"@noble/hashes/sha256";var W="dexter.cash";function Q(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ee(e,t=`https://${W}`){let i={type:"webauthn.get",challenge:Q(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function te(e=1){let t=m(new TextEncoder().encode(W)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function F(e,t){let n=m(t),i=ee(n),s=te(1),r=new Uint8Array(s.length+32);r.set(s,0),r.set(m(i),s.length);let a=m(r),c=Z.sign(a,e.privateKey,{lowS:!0}).toCompactRawBytes();return{clientDataJSON:i,authenticatorData:s,precompileMessage:r,signature:c}}function We(e){return{publicKey:e.publicKey,signOperation:async t=>F(e,t)}}function oe(e){let t=D(e.swigAddress),n=ne(new l(C),t,!0);return _({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var O=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new l(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new l(t.allowedCounterparty),i=y(t.revolvingCapacityAtomic??t.maxAmountAtomic),s=M(),r=ae(),a=U({programId:w,vaultPda:this.vaultPdaKey,sessionPubkey:s.publicKey,maxAmount:y(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r}),o=await this.passkey.signOperation(a),c=v(this.passkey.publicKey,o.signature,o.precompileMessage),u=se(await ie(this.connection,this.vaultPdaKey)),d=oe({vaultPda:this.vaultPdaKey,swigAddress:new l(this.swigAddress),sessionPubkey:s.publicKey,maxAmount:y(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r,clientDataJSON:o.clientDataJSON,authenticatorData:o.authenticatorData,payer:this.feePayer.publicKey,siblingSessionPdas:u}),p=new J().add(c,d);p.feePayer=this.feePayer.publicKey;let{blockhash:R}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=R,p.sign(this.feePayer);let H=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:H,blockhash:R,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await re(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:s.publicKey,timeoutMs:2e4}),V(s,t,a)}async signWithSession(t,n){let i=await ce(n.channelId);return L(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let s=I({programId:w,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),r=await this.passkey.signOperation(s),a=v(this.passkey.publicKey,r.signature,r.precompileMessage),o=N({vaultPda:this.vaultPdaKey,allowedCounterparty:new l(t.scope.allowedCounterparty),clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData}),c=new J().add(a,o);c.feePayer=this.feePayer.publicKey;let{blockhash:u,lastValidBlockHeight:d}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);c.recentBlockhash=u,c.sign(this.feePayer);let p=await this.connection.sendRawTransaction(c.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:p,blockhash:u,lastValidBlockHeight:d},this.confirmOptions.commitment),s}};function Fe(e){return new O(e)}function ae(){return Math.floor(Math.random()*4294967295)>>>0}async function ce(e){if(/^[0-9a-f]{64}$/i.test(e))return pe(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function pe(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}export{oe as buildAdapterRegisterInstruction,Fe as createSolanaVaultAdapter,j as deriveChannelId,We as passkeySignerFromP256Keypair};
@@ -1,6 +1,6 @@
1
- "use strict";var te=Object.create;var P=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var re=Object.getOwnPropertyNames;var oe=Object.getPrototypeOf,ie=Object.prototype.hasOwnProperty;var se=(e,t)=>{for(var n in t)P(e,n,{get:t[n],enumerable:!0})},L=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of re(t))!ie.call(e,o)&&o!==n&&P(e,o,{get:()=>t[o],enumerable:!(r=ne(t,o))||r.enumerable});return e};var j=(e,t,n)=>(n=e!=null?te(oe(e)):{},L(t||!e||!e.__esModule?P(n,"default",{value:e,enumerable:!0}):n,e)),ae=e=>L(P({},"__esModule",{value:!0}),e);var Se={};se(Se,{FileVoucherStore:()=>C,InMemoryVoucherStore:()=>A,InvalidRegistrationError:()=>d,InvalidVoucherError:()=>m,InvalidVoucherSignatureError:()=>h,OnChainVerificationError:()=>y,ScopeViolationError:()=>c,TAB_VOUCHER_HEADER:()=>R,enforceScope:()=>_,openSse:()=>Q,parseRegistration:()=>I,readVaultState:()=>N,requireTab:()=>Z,tabMiddleware:()=>Y,verifyRegistrationOnChain:()=>V,verifyVoucherSignature:()=>k});module.exports=ae(Se);var m=class extends Error{constructor(n,r){super(`Invalid voucher: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidVoucherError"}};var X=require("@solana/web3.js");var G=j(require("tweetnacl"),1),ce=require("@noble/hashes/sha256"),le=require("@noble/curves/p256"),T=require("@solana/web3.js");var w=require("@dexterai/vault/messages");var K=require("@dexterai/vault/instructions"),ue=require("@dexterai/vault/precompile"),b=require("@dexterai/vault/constants");var O="OTS_SESSION_REGISTER_V2",d=class extends Error{constructor(n,r){super(`Invalid registration: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidRegistrationError"}};function I(e){if(e.length!==188)throw new d("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,O.length));if(t!==O)throw new d("wrong_domain",`got "${t}"`);for(let a=O.length;a<32;a++)if(e[a]!==0)throw new d("wrong_domain",`non-NUL padding at byte ${a}`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=new T.PublicKey(e.slice(32,64)),o=new T.PublicKey(e.slice(64,96)),l=e.slice(96,128),p=n.getBigUint64(128,!0),f=n.getBigInt64(136,!0),i=new T.PublicKey(e.slice(144,176)),u=n.getUint32(176,!0),g=n.getBigUint64(180,!0);if(!r.equals(b.DEXTER_VAULT_PROGRAM_ID))throw new d("wrong_program",`${r.toBase58()} is not ${b.DEXTER_VAULT_PROGRAM_ID.toBase58()}`);if(p===0n)throw new d("cap_zero");let s=BigInt(Math.floor(Date.now()/1e3));if(f<=s)throw new d("expiry_in_past",`expires_at=${f}, now=${s}`);return{programId:r,vaultPda:o,sessionPubkey:new Uint8Array(l),maxAmount:p,expiresAt:f,allowedCounterparty:i,nonce:u,maxRevolvingCapacity:g}}var F=10,y=class extends Error{constructor(n,r){super(`On-chain verification failed: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="OnChainVerificationError"}};async function N(e,t){let n=await e.getAccountInfo(t,"finalized");if(!n)throw new y("vault_not_found",t.toBase58());if(!n.owner.equals(b.DEXTER_VAULT_PROGRAM_ID))throw new y("wrong_program",`owner ${n.owner.toBase58()} is not the vault program`);let r=n.data,o=new Uint8Array(r.slice(F,F+33)),u=84+(r[83]===1?48:0)+32+32;if(r[u]!==1)return{passkeyPubkey:o,activeSessionPubkey:null};let s=u+1,a=new Uint8Array(r.slice(s,s+32));return{passkeyPubkey:o,activeSessionPubkey:a}}async function V(e,t){let n=await N(e,t.vaultPda);if(n.activeSessionPubkey===null)throw new y("session_not_active","vault has no active_session \u2014 was it revoked?");if(!me(n.activeSessionPubkey,t.sessionPubkey))throw new y("session_pubkey_mismatch",`on-chain ${J(n.activeSessionPubkey)} != registration ${J(t.sessionPubkey)}`);return{passkeyPubkey:n.passkeyPubkey}}var h=class extends Error{constructor(t){super(`Invalid voucher signature${t?`: ${t}`:""}`),this.name="InvalidVoucherSignatureError"}};function k(e,t){if(t.length!==32)throw new h(`channelIdBytes must be 32 bytes, got ${t.length}`);if(e.sessionPublicKey.length!==32)throw new h(`sessionPublicKey must be 32 bytes, got ${e.sessionPublicKey.length}`);if(e.sessionSignature.length!==64)throw new h(`sessionSignature must be 64 bytes, got ${e.sessionSignature.length}`);let n=(0,w.voucherPayloadMessage)({channelId:t,cumulativeAmount:BigInt(e.payload.cumulativeAmount),sequenceNumber:e.payload.sequenceNumber});if(!G.default.sign.detached.verify(n,e.sessionSignature,e.sessionPublicKey))throw new h("ed25519 verify rejected")}var c=class extends Error{constructor(n,r){super(`Scope violation: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="ScopeViolationError"}};function _(e){let t=BigInt(e.voucher.payload.cumulativeAmount);if(t>e.registration.maxAmount)throw new c("cumulative_exceeds_cap",`${t} > ${e.registration.maxAmount}`);let n=BigInt(Math.floor(Date.now()/1e3));if(n>=e.registration.expiresAt)throw new c("session_expired",`now=${n} >= expiresAt=${e.registration.expiresAt}`);if(!e.registration.allowedCounterparty.equals(e.expectedCounterparty))throw new c("wrong_counterparty",`${e.registration.allowedCounterparty.toBase58()} != ${e.expectedCounterparty.toBase58()}`);if(e.previousCumulativeAtomic!==void 0){let r=BigInt(e.previousCumulativeAtomic);if(t<=r)throw new c("non_monotonic",`cumulative=${t} not > previous=${r}`)}}function me(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function J(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}var S=require("fs"),U=require("path");function de(e){return{payload:e.payload,sessionPublicKey:H(e.sessionPublicKey),sessionRegistration:H(e.sessionRegistration),sessionSignature:H(e.sessionSignature)}}function pe(e){return{payload:e.payload,sessionPublicKey:B(e.sessionPublicKey),sessionRegistration:B(e.sessionRegistration),sessionSignature:B(e.sessionSignature)}}function H(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}function B(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}var A=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,n){this.map.set(t,n)}async delete(t){this.map.delete(t)}},C=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return(0,U.join)(this.dir,`${t}.json`)}async get(t){try{let n=await S.promises.readFile(this.pathFor(t),"utf8");return pe(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(t,n){let r=this.pathFor(t);await S.promises.mkdir((0,U.dirname)(r),{recursive:!0});let o=`${r}.tmp`;await S.promises.writeFile(o,JSON.stringify(de(n))),await S.promises.rename(o,r)}async delete(t){try{await S.promises.unlink(this.pathFor(t))}catch(n){if(n?.code!=="ENOENT")throw n}}};var ye=require("@solana/web3.js"),fe=require("@noble/hashes/utils");var ge=j(require("tweetnacl"),1);var he=require("@noble/hashes/sha256");var W=6;function v(e,t=W){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[n,r=""]=e.split(".");if(r.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let o=r.padEnd(t,"0"),l=`${n}${o}`.replace(/^0+(?=\d)/,"");return l===""?"0":l}function x(e,t=W){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let n=e.padStart(t+1,"0"),r=n.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",o=n.slice(-t).replace(/0+$/,"");return o?`${r}.${o}`:r}var R="x-tab-voucher",M=class{map=new Map;get(t){return this.map.get(t)}set(t,n){this.map.set(t,n)}update(t,n){let r=this.map.get(t);r&&(r.lastCumulativeAtomic=n)}delete(t){this.map.delete(t)}},q=class{constructor(t,n,r,o){this.chargeImpl=o;this.channelId=t,this.network=n,this.cumulativeAtomic=r}channelId;network;sessionPublicKey=null;cumulativeAtomic;cumulative(){return x(this.cumulativeAtomic.toString())}bumpCumulative(t){this.cumulativeAtomic=t}setSessionPublicKey(t){this.sessionPublicKey=t}async charge(t){return this.chargeImpl(t)}};function we(e){if(typeof e!="string"||e.length===0)throw new m("signature_invalid",`missing ${R} header`);let t;try{t=Buffer.from(e,"base64").toString("utf8")}catch{throw new m("signature_invalid","malformed base64")}let n;try{n=JSON.parse(t)}catch{throw new m("signature_invalid","malformed JSON")}if(!n||typeof n!="object"||!n.payload||!n.sessionPublicKey)throw new m("signature_invalid","missing required fields");return{payload:n.payload,sessionPublicKey:$(n.sessionPublicKey),sessionRegistration:$(n.sessionRegistration),sessionSignature:$(n.sessionSignature)}}function $(e){if(typeof e!="string"||e.length%2!==0)throw new m("signature_invalid",`bad hex: ${typeof e}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}function be(e){if(!/^[0-9a-f]{64}$/i.test(e))throw new m("signature_invalid",`channelId must be 64-char hex, got "${e}"`);return $(e)}function Y(e){let t=e.store??new A,n=new M,r=typeof e.sellerPubkey=="string"?new X.PublicKey(e.sellerPubkey):e.sellerPubkey,o=e.maxPerVoucherAtomic?BigInt(e.maxPerVoucherAtomic):BigInt(v(e.perUnit))*100n;return async(l,p,f)=>{try{let i=we(l.headers[R]),u=i.payload.channelId,g=be(u),s=n.get(u);if(!s){let E=I(i.sessionRegistration);await V(e.connection,E),s={registration:E,lastCumulativeAtomic:"0"},n.set(u,s)}k(i,g),_({registration:s.registration,voucher:i,expectedCounterparty:r,previousCumulativeAtomic:s.lastCumulativeAtomic});let a=BigInt(i.payload.cumulativeAmount),ee=BigInt(s.lastCumulativeAtomic),D=a-ee;if(D>o)throw new c("cumulative_exceeds_cap",`single voucher increment ${D} exceeds maxPerVoucherAtomic ${o}`);await t.set(u,i),n.update(u,i.payload.cumulativeAmount);let z=new q(u,e.network,a,async E=>{throw new Error("SellerTab.charge() is not driven by the route handler; the buyer presents a fresh voucher per chunk. Use openSse(res, tab) for the metered-stream pattern.")});z.setSessionPublicKey(i.sessionPublicKey),l.tab=z,f()}catch(i){if(i instanceof m||i instanceof d||i instanceof y||i instanceof h||i instanceof c){p.status(402).json({error:"invalid_voucher",reason:i.reason??"unknown",detail:i.message});return}f(i)}}}function Z(e){if(!e.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return e.tab}function Q(e,t){if(!t.tab)throw new Error("openSse requires options.tab");e.headersSent||(e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive"),typeof e.flushHeaders=="function"&&e.flushHeaders());let n=t.tab,r=BigInt(v(n.cumulative())),o=t.perUnit?BigInt(v(t.perUnit)):null,l=0n,p=!1;function f(g=1){if(p)return Promise.reject(new Error("meter ended"));if(o===null)return Promise.reject(new Error("charge() needs options.perUnit"));let s=o*BigInt(g),a=l+s;return a>r?Promise.reject(new c("cumulative_exceeds_cap",`chunk would push request total to ${x(a.toString())} beyond voucher-authorized budget ${x(r.toString())}`)):(l=a,Promise.resolve())}function i(g){if(p)throw new Error("meter ended");let a=(typeof g=="string"?g:Buffer.from(g).toString("utf8")).replace(/\n/g,"\\n");e.write(`data: ${a}
1
+ "use strict";var ee=Object.create;var P=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty;var ie=(e,t)=>{for(var n in t)P(e,n,{get:t[n],enumerable:!0})},j=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ne(t))!oe.call(e,o)&&o!==n&&P(e,o,{get:()=>t[o],enumerable:!(r=te(t,o))||r.enumerable});return e};var z=(e,t,n)=>(n=e!=null?ee(re(e)):{},j(t||!e||!e.__esModule?P(n,"default",{value:e,enumerable:!0}):n,e)),se=e=>j(P({},"__esModule",{value:!0}),e);var be={};ie(be,{FileVoucherStore:()=>R,InMemoryVoucherStore:()=>S,InvalidRegistrationError:()=>l,InvalidVoucherError:()=>c,InvalidVoucherSignatureError:()=>p,OnChainVerificationError:()=>y,ScopeViolationError:()=>a,TAB_VOUCHER_HEADER:()=>E,enforceScope:()=>C,openSse:()=>Z,parseRegistration:()=>V,requireTab:()=>Y,tabMiddleware:()=>X,verifyRegistrationOnChain:()=>_,verifyVoucherSignature:()=>$});module.exports=se(be);var c=class extends Error{constructor(n,r){super(`Invalid voucher: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidVoucherError"}};var W=require("@solana/web3.js");var J=z(require("tweetnacl"),1),ue=require("@noble/hashes/sha256"),ce=require("@noble/curves/p256"),T=require("@solana/web3.js");var w=require("@dexterai/vault/messages");var N=require("@dexterai/vault/instructions"),ae=require("@dexterai/vault/precompile"),b=require("@dexterai/vault/constants");var I=require("@dexterai/vault/session"),O="OTS_SESSION_REGISTER_V2",l=class extends Error{constructor(n,r){super(`Invalid registration: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidRegistrationError"}};function V(e){if(e.length!==188)throw new l("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,O.length));if(t!==O)throw new l("wrong_domain",`got "${t}"`);for(let s=O.length;s<32;s++)if(e[s]!==0)throw new l("wrong_domain",`non-NUL padding at byte ${s}`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=new T.PublicKey(e.slice(32,64)),o=new T.PublicKey(e.slice(64,96)),m=e.slice(96,128),g=n.getBigUint64(128,!0),f=n.getBigInt64(136,!0),i=new T.PublicKey(e.slice(144,176)),d=n.getUint32(176,!0),h=n.getBigUint64(180,!0);if(!r.equals(b.DEXTER_VAULT_PROGRAM_ID))throw new l("wrong_program",`${r.toBase58()} is not ${b.DEXTER_VAULT_PROGRAM_ID.toBase58()}`);if(g===0n)throw new l("cap_zero");let u=BigInt(Math.floor(Date.now()/1e3));if(f<=u)throw new l("expiry_in_past",`expires_at=${f}, now=${u}`);return{programId:r,vaultPda:o,sessionPubkey:new Uint8Array(m),maxAmount:g,expiresAt:f,allowedCounterparty:i,nonce:d,maxRevolvingCapacity:h}}var y=class extends Error{constructor(n,r){super(`On-chain verification failed: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="OnChainVerificationError"}};async function _(e,t){let n=await(0,I.fetchSessionAccount)(e,t.vaultPda,t.allowedCounterparty);if(!n||n.version===0)throw new y("session_not_active","no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!(0,I.isSessionLive)(n))throw new y("session_not_active","SessionAccount PDA is present but expired");if(!le(n.session.sessionPubkey,t.sessionPubkey))throw new y("session_pubkey_mismatch",`on-chain ${F(n.session.sessionPubkey)} != registration ${F(t.sessionPubkey)}`)}var p=class extends Error{constructor(t){super(`Invalid voucher signature${t?`: ${t}`:""}`),this.name="InvalidVoucherSignatureError"}};function $(e,t){if(t.length!==32)throw new p(`channelIdBytes must be 32 bytes, got ${t.length}`);if(e.sessionPublicKey.length!==32)throw new p(`sessionPublicKey must be 32 bytes, got ${e.sessionPublicKey.length}`);if(e.sessionSignature.length!==64)throw new p(`sessionSignature must be 64 bytes, got ${e.sessionSignature.length}`);let n=(0,w.voucherPayloadMessage)({channelId:t,cumulativeAmount:BigInt(e.payload.cumulativeAmount),sequenceNumber:e.payload.sequenceNumber});if(!J.default.sign.detached.verify(n,e.sessionSignature,e.sessionPublicKey))throw new p("ed25519 verify rejected")}var a=class extends Error{constructor(n,r){super(`Scope violation: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="ScopeViolationError"}};function C(e){let t=BigInt(e.voucher.payload.cumulativeAmount);if(t>e.registration.maxAmount)throw new a("cumulative_exceeds_cap",`${t} > ${e.registration.maxAmount}`);let n=BigInt(Math.floor(Date.now()/1e3));if(n>=e.registration.expiresAt)throw new a("session_expired",`now=${n} >= expiresAt=${e.registration.expiresAt}`);if(!e.registration.allowedCounterparty.equals(e.expectedCounterparty))throw new a("wrong_counterparty",`${e.registration.allowedCounterparty.toBase58()} != ${e.expectedCounterparty.toBase58()}`);if(e.previousCumulativeAtomic!==void 0){let r=BigInt(e.previousCumulativeAtomic);if(t<=r)throw new a("non_monotonic",`cumulative=${t} not > previous=${r}`)}}function le(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function F(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}var A=require("fs"),U=require("path");function me(e){return{payload:e.payload,sessionPublicKey:H(e.sessionPublicKey),sessionRegistration:H(e.sessionRegistration),sessionSignature:H(e.sessionSignature)}}function de(e){return{payload:e.payload,sessionPublicKey:B(e.sessionPublicKey),sessionRegistration:B(e.sessionRegistration),sessionSignature:B(e.sessionSignature)}}function H(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}function B(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}var S=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,n){this.map.set(t,n)}async delete(t){this.map.delete(t)}},R=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return(0,U.join)(this.dir,`${t}.json`)}async get(t){try{let n=await A.promises.readFile(this.pathFor(t),"utf8");return de(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(t,n){let r=this.pathFor(t);await A.promises.mkdir((0,U.dirname)(r),{recursive:!0});let o=`${r}.tmp`;await A.promises.writeFile(o,JSON.stringify(me(n))),await A.promises.rename(o,r)}async delete(t){try{await A.promises.unlink(this.pathFor(t))}catch(n){if(n?.code!=="ENOENT")throw n}}};var he=require("@solana/web3.js"),ye=require("@noble/hashes/utils");var pe=z(require("tweetnacl"),1);var ge=require("@noble/hashes/sha256");var G=6;function v(e,t=G){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[n,r=""]=e.split(".");if(r.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let o=r.padEnd(t,"0"),m=`${n}${o}`.replace(/^0+(?=\d)/,"");return m===""?"0":m}function x(e,t=G){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let n=e.padStart(t+1,"0"),r=n.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",o=n.slice(-t).replace(/0+$/,"");return o?`${r}.${o}`:r}var E="x-tab-voucher",M=class{map=new Map;get(t){return this.map.get(t)}set(t,n){this.map.set(t,n)}update(t,n){let r=this.map.get(t);r&&(r.lastCumulativeAtomic=n)}delete(t){this.map.delete(t)}},q=class{constructor(t,n,r,o){this.chargeImpl=o;this.channelId=t,this.network=n,this.cumulativeAtomic=r}channelId;network;sessionPublicKey=null;cumulativeAtomic;cumulative(){return x(this.cumulativeAtomic.toString())}bumpCumulative(t){this.cumulativeAtomic=t}setSessionPublicKey(t){this.sessionPublicKey=t}async charge(t){return this.chargeImpl(t)}};function fe(e){if(typeof e!="string"||e.length===0)throw new c("signature_invalid",`missing ${E} header`);let t;try{t=Buffer.from(e,"base64").toString("utf8")}catch{throw new c("signature_invalid","malformed base64")}let n;try{n=JSON.parse(t)}catch{throw new c("signature_invalid","malformed JSON")}if(!n||typeof n!="object"||!n.payload||!n.sessionPublicKey)throw new c("signature_invalid","missing required fields");return{payload:n.payload,sessionPublicKey:k(n.sessionPublicKey),sessionRegistration:k(n.sessionRegistration),sessionSignature:k(n.sessionSignature)}}function k(e){if(typeof e!="string"||e.length%2!==0)throw new c("signature_invalid",`bad hex: ${typeof e}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}function we(e){if(!/^[0-9a-f]{64}$/i.test(e))throw new c("signature_invalid",`channelId must be 64-char hex, got "${e}"`);return k(e)}function X(e){let t=e.store??new S,n=new M,r=typeof e.sellerPubkey=="string"?new W.PublicKey(e.sellerPubkey):e.sellerPubkey,o=e.maxPerVoucherAtomic?BigInt(e.maxPerVoucherAtomic):BigInt(v(e.perUnit))*100n;return async(m,g,f)=>{try{let i=fe(m.headers[E]),d=i.payload.channelId,h=we(d),u=n.get(d);if(!u){let K=V(i.sessionRegistration);await _(e.connection,K),u={registration:K,lastCumulativeAtomic:"0"},n.set(d,u)}$(i,h),C({registration:u.registration,voucher:i,expectedCounterparty:r,previousCumulativeAtomic:u.lastCumulativeAtomic});let s=BigInt(i.payload.cumulativeAmount),Q=BigInt(u.lastCumulativeAtomic),D=s-Q;if(D>o)throw new a("cumulative_exceeds_cap",`single voucher increment ${D} exceeds maxPerVoucherAtomic ${o}`);await t.set(d,i),n.update(d,i.payload.cumulativeAmount);let L=new q(d,e.network,s,async K=>{throw new Error("SellerTab.charge() is not driven by the route handler; the buyer presents a fresh voucher per chunk. Use openSse(res, tab) for the metered-stream pattern.")});L.setSessionPublicKey(i.sessionPublicKey),m.tab=L,f()}catch(i){if(i instanceof c||i instanceof l||i instanceof y||i instanceof p||i instanceof a){g.status(402).json({error:"invalid_voucher",reason:i.reason??"unknown",detail:i.message});return}f(i)}}}function Y(e){if(!e.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return e.tab}function Z(e,t){if(!t.tab)throw new Error("openSse requires options.tab");e.headersSent||(e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive"),typeof e.flushHeaders=="function"&&e.flushHeaders());let n=t.tab,r=BigInt(v(n.cumulative())),o=t.perUnit?BigInt(v(t.perUnit)):null,m=0n,g=!1;function f(h=1){if(g)return Promise.reject(new Error("meter ended"));if(o===null)return Promise.reject(new Error("charge() needs options.perUnit"));let u=o*BigInt(h),s=m+u;return s>r?Promise.reject(new a("cumulative_exceeds_cap",`chunk would push request total to ${x(s.toString())} beyond voucher-authorized budget ${x(r.toString())}`)):(m=s,Promise.resolve())}function i(h){if(g)throw new Error("meter ended");let s=(typeof h=="string"?h:Buffer.from(h).toString("utf8")).replace(/\n/g,"\\n");e.write(`data: ${s}
2
2
 
3
- `)}function u(){p||(p=!0,e.write(`event: end
4
- data: {"chargedAtomic":"${l}"}
3
+ `)}function d(){g||(g=!0,e.write(`event: end
4
+ data: {"chargedAtomic":"${m}"}
5
5
 
6
- `),e.end())}return{charge:f,send:i,end:u}}0&&(module.exports={FileVoucherStore,InMemoryVoucherStore,InvalidRegistrationError,InvalidVoucherError,InvalidVoucherSignatureError,OnChainVerificationError,ScopeViolationError,TAB_VOUCHER_HEADER,enforceScope,openSse,parseRegistration,readVaultState,requireTab,tabMiddleware,verifyRegistrationOnChain,verifyVoucherSignature});
6
+ `),e.end())}return{charge:f,send:i,end:d}}0&&(module.exports={FileVoucherStore,InMemoryVoucherStore,InvalidRegistrationError,InvalidVoucherError,InvalidVoucherSignatureError,OnChainVerificationError,ScopeViolationError,TAB_VOUCHER_HEADER,enforceScope,openSse,parseRegistration,requireTab,tabMiddleware,verifyRegistrationOnChain,verifyVoucherSignature});
@@ -231,38 +231,26 @@ declare class InvalidRegistrationError extends Error {
231
231
  * passkey signature check is a separate on-chain step.
232
232
  */
233
233
  declare function parseRegistration(registration: Uint8Array): ParsedRegistration;
234
- interface OnChainVaultState {
235
- passkeyPubkey: Uint8Array;
236
- activeSessionPubkey: Uint8Array | null;
237
- }
238
234
  declare class OnChainVerificationError extends Error {
239
235
  readonly reason: 'vault_not_found' | 'session_not_active' | 'session_pubkey_mismatch' | 'wrong_program';
240
236
  constructor(reason: 'vault_not_found' | 'session_not_active' | 'session_pubkey_mismatch' | 'wrong_program', detail?: string);
241
237
  }
242
238
  /**
243
- * Read the vault account and extract passkey + active session.
239
+ * Verify a registration against on-chain state. Throws on any mismatch.
244
240
  *
245
- * Reads at `finalized` commitment to avoid the read-replica race that
246
- * shows up when the buyer just confirmed register_session_key at
247
- * `confirmed` and the seller's RPC replica hasn't propagated the write
248
- * yet. This is the same lesson as the dexter-vault test suite — see
249
- * reference_anchor_test_commitment in repo memory.
250
- */
251
- declare function readVaultState(connection: Connection, vaultPda: PublicKey): Promise<OnChainVaultState>;
252
- /**
253
- * Verify a registration against on-chain state. Returns the vault's
254
- * passkey pubkey (caller can cache it). Throws on any mismatch.
241
+ * V6: a session is its own PDA ([b"session", vault, allowed_counterparty]),
242
+ * NOT an inline field on the vault. We read that SessionAccount and confirm it
243
+ * is live (version 1 + unexpired) AND carries the same session pubkey the
244
+ * registration claims. If the program accepted the register_session_key tx
245
+ * (which is what wrote the PDA), the passkey signature was already verified by
246
+ * the secp256r1 precompile inside that tx — the seller just confirms the
247
+ * on-chain witness still holds.
255
248
  *
256
- * The "verification" here is structural: the active_session on chain MUST
257
- * carry the same session pubkey the registration claims. If the program
258
- * accepted the register_session_key tx (which is what set active_session
259
- * in the first place), then the passkey signature was verified by the
260
- * secp256r1 precompile inside that tx. The seller doesn't need to redo
261
- * that work; they just need to confirm the on-chain witness still holds.
249
+ * fetchSessionAccount reads at the connection's commitment; pass a connection
250
+ * configured at the commitment the buyer's registration was confirmed to (the
251
+ * adapter waits for visibility before openTab returns).
262
252
  */
263
- declare function verifyRegistrationOnChain(connection: Connection, registration: ParsedRegistration): Promise<{
264
- passkeyPubkey: Uint8Array;
265
- }>;
253
+ declare function verifyRegistrationOnChain(connection: Connection, registration: ParsedRegistration): Promise<void>;
266
254
  declare class InvalidVoucherSignatureError extends Error {
267
255
  constructor(detail?: string);
268
256
  }
@@ -289,4 +277,4 @@ declare function enforceScope(args: {
289
277
  previousCumulativeAtomic?: AtomicAmount;
290
278
  }): void;
291
279
 
292
- export { FileVoucherStore, InMemoryVoucherStore, InvalidRegistrationError, InvalidVoucherError, InvalidVoucherSignatureError, type OnChainVaultState, OnChainVerificationError, type OpenSseOptions, type ParsedRegistration, ScopeViolationError, type SellerTab, type SseMeter, TAB_VOUCHER_HEADER, type TabMiddlewareConfig, type TabMiddlewareOptions, type VoucherStore, enforceScope, openSse, parseRegistration, readVaultState, requireTab, tabMiddleware, verifyRegistrationOnChain, verifyVoucherSignature };
280
+ export { FileVoucherStore, InMemoryVoucherStore, InvalidRegistrationError, InvalidVoucherError, InvalidVoucherSignatureError, OnChainVerificationError, type OpenSseOptions, type ParsedRegistration, ScopeViolationError, type SellerTab, type SseMeter, TAB_VOUCHER_HEADER, type TabMiddlewareConfig, type TabMiddlewareOptions, type VoucherStore, enforceScope, openSse, parseRegistration, requireTab, tabMiddleware, verifyRegistrationOnChain, verifyVoucherSignature };
@@ -231,38 +231,26 @@ declare class InvalidRegistrationError extends Error {
231
231
  * passkey signature check is a separate on-chain step.
232
232
  */
233
233
  declare function parseRegistration(registration: Uint8Array): ParsedRegistration;
234
- interface OnChainVaultState {
235
- passkeyPubkey: Uint8Array;
236
- activeSessionPubkey: Uint8Array | null;
237
- }
238
234
  declare class OnChainVerificationError extends Error {
239
235
  readonly reason: 'vault_not_found' | 'session_not_active' | 'session_pubkey_mismatch' | 'wrong_program';
240
236
  constructor(reason: 'vault_not_found' | 'session_not_active' | 'session_pubkey_mismatch' | 'wrong_program', detail?: string);
241
237
  }
242
238
  /**
243
- * Read the vault account and extract passkey + active session.
239
+ * Verify a registration against on-chain state. Throws on any mismatch.
244
240
  *
245
- * Reads at `finalized` commitment to avoid the read-replica race that
246
- * shows up when the buyer just confirmed register_session_key at
247
- * `confirmed` and the seller's RPC replica hasn't propagated the write
248
- * yet. This is the same lesson as the dexter-vault test suite — see
249
- * reference_anchor_test_commitment in repo memory.
250
- */
251
- declare function readVaultState(connection: Connection, vaultPda: PublicKey): Promise<OnChainVaultState>;
252
- /**
253
- * Verify a registration against on-chain state. Returns the vault's
254
- * passkey pubkey (caller can cache it). Throws on any mismatch.
241
+ * V6: a session is its own PDA ([b"session", vault, allowed_counterparty]),
242
+ * NOT an inline field on the vault. We read that SessionAccount and confirm it
243
+ * is live (version 1 + unexpired) AND carries the same session pubkey the
244
+ * registration claims. If the program accepted the register_session_key tx
245
+ * (which is what wrote the PDA), the passkey signature was already verified by
246
+ * the secp256r1 precompile inside that tx — the seller just confirms the
247
+ * on-chain witness still holds.
255
248
  *
256
- * The "verification" here is structural: the active_session on chain MUST
257
- * carry the same session pubkey the registration claims. If the program
258
- * accepted the register_session_key tx (which is what set active_session
259
- * in the first place), then the passkey signature was verified by the
260
- * secp256r1 precompile inside that tx. The seller doesn't need to redo
261
- * that work; they just need to confirm the on-chain witness still holds.
249
+ * fetchSessionAccount reads at the connection's commitment; pass a connection
250
+ * configured at the commitment the buyer's registration was confirmed to (the
251
+ * adapter waits for visibility before openTab returns).
262
252
  */
263
- declare function verifyRegistrationOnChain(connection: Connection, registration: ParsedRegistration): Promise<{
264
- passkeyPubkey: Uint8Array;
265
- }>;
253
+ declare function verifyRegistrationOnChain(connection: Connection, registration: ParsedRegistration): Promise<void>;
266
254
  declare class InvalidVoucherSignatureError extends Error {
267
255
  constructor(detail?: string);
268
256
  }
@@ -289,4 +277,4 @@ declare function enforceScope(args: {
289
277
  previousCumulativeAtomic?: AtomicAmount;
290
278
  }): void;
291
279
 
292
- export { FileVoucherStore, InMemoryVoucherStore, InvalidRegistrationError, InvalidVoucherError, InvalidVoucherSignatureError, type OnChainVaultState, OnChainVerificationError, type OpenSseOptions, type ParsedRegistration, ScopeViolationError, type SellerTab, type SseMeter, TAB_VOUCHER_HEADER, type TabMiddlewareConfig, type TabMiddlewareOptions, type VoucherStore, enforceScope, openSse, parseRegistration, readVaultState, requireTab, tabMiddleware, verifyRegistrationOnChain, verifyVoucherSignature };
280
+ export { FileVoucherStore, InMemoryVoucherStore, InvalidRegistrationError, InvalidVoucherError, InvalidVoucherSignatureError, OnChainVerificationError, type OpenSseOptions, type ParsedRegistration, ScopeViolationError, type SellerTab, type SseMeter, TAB_VOUCHER_HEADER, type TabMiddlewareConfig, type TabMiddlewareOptions, type VoucherStore, enforceScope, openSse, parseRegistration, requireTab, tabMiddleware, verifyRegistrationOnChain, verifyVoucherSignature };
@@ -1,6 +1,6 @@
1
- var m=class extends Error{constructor(n,r){super(`Invalid voucher: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidVoucherError"}};import{PublicKey as Y}from"@solana/web3.js";import j from"tweetnacl";import{sha256 as Ae}from"@noble/hashes/sha256";import{p256 as xe}from"@noble/curves/p256";import{PublicKey as I}from"@solana/web3.js";import{sessionRegisterMessage as se,sessionRevokeMessage as ae,voucherPayloadMessage as T,buildVoucherMessage as ue}from"@dexterai/vault/messages";import{buildRegisterSessionKeyInstruction as me,buildRevokeSessionKeyInstruction as de,deriveSwigWalletAddress as pe}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as he}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as v,SECP256R1_PROGRAM_ID as fe,INSTRUCTIONS_SYSVAR_ID as we}from"@dexterai/vault/constants";var V="OTS_SESSION_REGISTER_V2",d=class extends Error{constructor(n,r){super(`Invalid registration: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidRegistrationError"}};function k(e){if(e.length!==188)throw new d("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,V.length));if(t!==V)throw new d("wrong_domain",`got "${t}"`);for(let a=V.length;a<32;a++)if(e[a]!==0)throw new d("wrong_domain",`non-NUL padding at byte ${a}`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=new I(e.slice(32,64)),i=new I(e.slice(64,96)),c=e.slice(96,128),p=n.getBigUint64(128,!0),h=n.getBigInt64(136,!0),o=new I(e.slice(144,176)),u=n.getUint32(176,!0),g=n.getBigUint64(180,!0);if(!r.equals(v))throw new d("wrong_program",`${r.toBase58()} is not ${v.toBase58()}`);if(p===0n)throw new d("cap_zero");let s=BigInt(Math.floor(Date.now()/1e3));if(h<=s)throw new d("expiry_in_past",`expires_at=${h}, now=${s}`);return{programId:r,vaultPda:i,sessionPubkey:new Uint8Array(c),maxAmount:p,expiresAt:h,allowedCounterparty:o,nonce:u,maxRevolvingCapacity:g}}var M=10,f=class extends Error{constructor(n,r){super(`On-chain verification failed: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="OnChainVerificationError"}};async function D(e,t){let n=await e.getAccountInfo(t,"finalized");if(!n)throw new f("vault_not_found",t.toBase58());if(!n.owner.equals(v))throw new f("wrong_program",`owner ${n.owner.toBase58()} is not the vault program`);let r=n.data,i=new Uint8Array(r.slice(M,M+33)),u=84+(r[83]===1?48:0)+32+32;if(r[u]!==1)return{passkeyPubkey:i,activeSessionPubkey:null};let s=u+1,a=new Uint8Array(r.slice(s,s+32));return{passkeyPubkey:i,activeSessionPubkey:a}}async function _(e,t){let n=await D(e,t.vaultPda);if(n.activeSessionPubkey===null)throw new f("session_not_active","vault has no active_session \u2014 was it revoked?");if(!F(n.activeSessionPubkey,t.sessionPubkey))throw new f("session_pubkey_mismatch",`on-chain ${q(n.activeSessionPubkey)} != registration ${q(t.sessionPubkey)}`);return{passkeyPubkey:n.passkeyPubkey}}var y=class extends Error{constructor(t){super(`Invalid voucher signature${t?`: ${t}`:""}`),this.name="InvalidVoucherSignatureError"}};function C(e,t){if(t.length!==32)throw new y(`channelIdBytes must be 32 bytes, got ${t.length}`);if(e.sessionPublicKey.length!==32)throw new y(`sessionPublicKey must be 32 bytes, got ${e.sessionPublicKey.length}`);if(e.sessionSignature.length!==64)throw new y(`sessionSignature must be 64 bytes, got ${e.sessionSignature.length}`);let n=T({channelId:t,cumulativeAmount:BigInt(e.payload.cumulativeAmount),sequenceNumber:e.payload.sequenceNumber});if(!j.sign.detached.verify(n,e.sessionSignature,e.sessionPublicKey))throw new y("ed25519 verify rejected")}var l=class extends Error{constructor(n,r){super(`Scope violation: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="ScopeViolationError"}};function U(e){let t=BigInt(e.voucher.payload.cumulativeAmount);if(t>e.registration.maxAmount)throw new l("cumulative_exceeds_cap",`${t} > ${e.registration.maxAmount}`);let n=BigInt(Math.floor(Date.now()/1e3));if(n>=e.registration.expiresAt)throw new l("session_expired",`now=${n} >= expiresAt=${e.registration.expiresAt}`);if(!e.registration.allowedCounterparty.equals(e.expectedCounterparty))throw new l("wrong_counterparty",`${e.registration.allowedCounterparty.toBase58()} != ${e.expectedCounterparty.toBase58()}`);if(e.previousCumulativeAtomic!==void 0){let r=BigInt(e.previousCumulativeAtomic);if(t<=r)throw new l("non_monotonic",`cumulative=${t} not > previous=${r}`)}}function F(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function q(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}import{promises as w}from"fs";import{join as J,dirname as G}from"path";function W(e){return{payload:e.payload,sessionPublicKey:$(e.sessionPublicKey),sessionRegistration:$(e.sessionRegistration),sessionSignature:$(e.sessionSignature)}}function X(e){return{payload:e.payload,sessionPublicKey:R(e.sessionPublicKey),sessionRegistration:R(e.sessionRegistration),sessionSignature:R(e.sessionSignature)}}function $(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}function R(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}var b=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,n){this.map.set(t,n)}async delete(t){this.map.delete(t)}},E=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return J(this.dir,`${t}.json`)}async get(t){try{let n=await w.readFile(this.pathFor(t),"utf8");return X(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(t,n){let r=this.pathFor(t);await w.mkdir(G(r),{recursive:!0});let i=`${r}.tmp`;await w.writeFile(i,JSON.stringify(W(n))),await w.rename(i,r)}async delete(t){try{await w.unlink(this.pathFor(t))}catch(n){if(n?.code!=="ENOENT")throw n}}};import{PublicKey as Le}from"@solana/web3.js";import{bytesToHex as Fe}from"@noble/hashes/utils";import Ee from"tweetnacl";import{sha256 as Ne}from"@noble/hashes/sha256";var z=6;function S(e,t=z){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[n,r=""]=e.split(".");if(r.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let i=r.padEnd(t,"0"),c=`${n}${i}`.replace(/^0+(?=\d)/,"");return c===""?"0":c}function A(e,t=z){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let n=e.padStart(t+1,"0"),r=n.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",i=n.slice(-t).replace(/0+$/,"");return i?`${r}.${i}`:r}var N="x-tab-voucher",K=class{map=new Map;get(t){return this.map.get(t)}set(t,n){this.map.set(t,n)}update(t,n){let r=this.map.get(t);r&&(r.lastCumulativeAtomic=n)}delete(t){this.map.delete(t)}},O=class{constructor(t,n,r,i){this.chargeImpl=i;this.channelId=t,this.network=n,this.cumulativeAtomic=r}channelId;network;sessionPublicKey=null;cumulativeAtomic;cumulative(){return A(this.cumulativeAtomic.toString())}bumpCumulative(t){this.cumulativeAtomic=t}setSessionPublicKey(t){this.sessionPublicKey=t}async charge(t){return this.chargeImpl(t)}};function Z(e){if(typeof e!="string"||e.length===0)throw new m("signature_invalid",`missing ${N} header`);let t;try{t=Buffer.from(e,"base64").toString("utf8")}catch{throw new m("signature_invalid","malformed base64")}let n;try{n=JSON.parse(t)}catch{throw new m("signature_invalid","malformed JSON")}if(!n||typeof n!="object"||!n.payload||!n.sessionPublicKey)throw new m("signature_invalid","missing required fields");return{payload:n.payload,sessionPublicKey:x(n.sessionPublicKey),sessionRegistration:x(n.sessionRegistration),sessionSignature:x(n.sessionSignature)}}function x(e){if(typeof e!="string"||e.length%2!==0)throw new m("signature_invalid",`bad hex: ${typeof e}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}function Q(e){if(!/^[0-9a-f]{64}$/i.test(e))throw new m("signature_invalid",`channelId must be 64-char hex, got "${e}"`);return x(e)}function ee(e){let t=e.store??new b,n=new K,r=typeof e.sellerPubkey=="string"?new Y(e.sellerPubkey):e.sellerPubkey,i=e.maxPerVoucherAtomic?BigInt(e.maxPerVoucherAtomic):BigInt(S(e.perUnit))*100n;return async(c,p,h)=>{try{let o=Z(c.headers[N]),u=o.payload.channelId,g=Q(u),s=n.get(u);if(!s){let P=k(o.sessionRegistration);await _(e.connection,P),s={registration:P,lastCumulativeAtomic:"0"},n.set(u,s)}C(o,g),U({registration:s.registration,voucher:o,expectedCounterparty:r,previousCumulativeAtomic:s.lastCumulativeAtomic});let a=BigInt(o.payload.cumulativeAmount),L=BigInt(s.lastCumulativeAtomic),H=a-L;if(H>i)throw new l("cumulative_exceeds_cap",`single voucher increment ${H} exceeds maxPerVoucherAtomic ${i}`);await t.set(u,o),n.update(u,o.payload.cumulativeAmount);let B=new O(u,e.network,a,async P=>{throw new Error("SellerTab.charge() is not driven by the route handler; the buyer presents a fresh voucher per chunk. Use openSse(res, tab) for the metered-stream pattern.")});B.setSessionPublicKey(o.sessionPublicKey),c.tab=B,h()}catch(o){if(o instanceof m||o instanceof d||o instanceof f||o instanceof y||o instanceof l){p.status(402).json({error:"invalid_voucher",reason:o.reason??"unknown",detail:o.message});return}h(o)}}}function te(e){if(!e.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return e.tab}function ne(e,t){if(!t.tab)throw new Error("openSse requires options.tab");e.headersSent||(e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive"),typeof e.flushHeaders=="function"&&e.flushHeaders());let n=t.tab,r=BigInt(S(n.cumulative())),i=t.perUnit?BigInt(S(t.perUnit)):null,c=0n,p=!1;function h(g=1){if(p)return Promise.reject(new Error("meter ended"));if(i===null)return Promise.reject(new Error("charge() needs options.perUnit"));let s=i*BigInt(g),a=c+s;return a>r?Promise.reject(new l("cumulative_exceeds_cap",`chunk would push request total to ${A(a.toString())} beyond voucher-authorized budget ${A(r.toString())}`)):(c=a,Promise.resolve())}function o(g){if(p)throw new Error("meter ended");let a=(typeof g=="string"?g:Buffer.from(g).toString("utf8")).replace(/\n/g,"\\n");e.write(`data: ${a}
1
+ var l=class extends Error{constructor(n,r){super(`Invalid voucher: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidVoucherError"}};import{PublicKey as Y}from"@solana/web3.js";import L from"tweetnacl";import{sha256 as Se}from"@noble/hashes/sha256";import{p256 as xe}from"@noble/curves/p256";import{PublicKey as I}from"@solana/web3.js";import{sessionRegisterMessage as se,sessionRevokeMessage as ae,voucherPayloadMessage as P,buildVoucherMessage as ue}from"@dexterai/vault/messages";import{buildRegisterSessionKeyInstruction as me,buildRevokeSessionKeyInstruction as de,deriveSwigWalletAddress as pe}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as he}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as T,SECP256R1_PROGRAM_ID as fe,INSTRUCTIONS_SYSVAR_ID as we}from"@dexterai/vault/constants";import{fetchSessionAccount as j,isSessionLive as z}from"@dexterai/vault/session";var V="OTS_SESSION_REGISTER_V2",m=class extends Error{constructor(n,r){super(`Invalid registration: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidRegistrationError"}};function _(e){if(e.length!==188)throw new m("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,V.length));if(t!==V)throw new m("wrong_domain",`got "${t}"`);for(let s=V.length;s<32;s++)if(e[s]!==0)throw new m("wrong_domain",`non-NUL padding at byte ${s}`);let n=new DataView(e.buffer,e.byteOffset,e.byteLength),r=new I(e.slice(32,64)),i=new I(e.slice(64,96)),c=e.slice(96,128),p=n.getBigUint64(128,!0),y=n.getBigInt64(136,!0),o=new I(e.slice(144,176)),d=n.getUint32(176,!0),g=n.getBigUint64(180,!0);if(!r.equals(T))throw new m("wrong_program",`${r.toBase58()} is not ${T.toBase58()}`);if(p===0n)throw new m("cap_zero");let a=BigInt(Math.floor(Date.now()/1e3));if(y<=a)throw new m("expiry_in_past",`expires_at=${y}, now=${a}`);return{programId:r,vaultPda:i,sessionPubkey:new Uint8Array(c),maxAmount:p,expiresAt:y,allowedCounterparty:o,nonce:d,maxRevolvingCapacity:g}}var f=class extends Error{constructor(n,r){super(`On-chain verification failed: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="OnChainVerificationError"}};async function $(e,t){let n=await j(e,t.vaultPda,t.allowedCounterparty);if(!n||n.version===0)throw new f("session_not_active","no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!z(n))throw new f("session_not_active","SessionAccount PDA is present but expired");if(!F(n.session.sessionPubkey,t.sessionPubkey))throw new f("session_pubkey_mismatch",`on-chain ${M(n.session.sessionPubkey)} != registration ${M(t.sessionPubkey)}`)}var h=class extends Error{constructor(t){super(`Invalid voucher signature${t?`: ${t}`:""}`),this.name="InvalidVoucherSignatureError"}};function C(e,t){if(t.length!==32)throw new h(`channelIdBytes must be 32 bytes, got ${t.length}`);if(e.sessionPublicKey.length!==32)throw new h(`sessionPublicKey must be 32 bytes, got ${e.sessionPublicKey.length}`);if(e.sessionSignature.length!==64)throw new h(`sessionSignature must be 64 bytes, got ${e.sessionSignature.length}`);let n=P({channelId:t,cumulativeAmount:BigInt(e.payload.cumulativeAmount),sequenceNumber:e.payload.sequenceNumber});if(!L.sign.detached.verify(n,e.sessionSignature,e.sessionPublicKey))throw new h("ed25519 verify rejected")}var u=class extends Error{constructor(n,r){super(`Scope violation: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="ScopeViolationError"}};function R(e){let t=BigInt(e.voucher.payload.cumulativeAmount);if(t>e.registration.maxAmount)throw new u("cumulative_exceeds_cap",`${t} > ${e.registration.maxAmount}`);let n=BigInt(Math.floor(Date.now()/1e3));if(n>=e.registration.expiresAt)throw new u("session_expired",`now=${n} >= expiresAt=${e.registration.expiresAt}`);if(!e.registration.allowedCounterparty.equals(e.expectedCounterparty))throw new u("wrong_counterparty",`${e.registration.allowedCounterparty.toBase58()} != ${e.expectedCounterparty.toBase58()}`);if(e.previousCumulativeAtomic!==void 0){let r=BigInt(e.previousCumulativeAtomic);if(t<=r)throw new u("non_monotonic",`cumulative=${t} not > previous=${r}`)}}function F(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function M(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}import{promises as w}from"fs";import{join as J,dirname as G}from"path";function W(e){return{payload:e.payload,sessionPublicKey:U(e.sessionPublicKey),sessionRegistration:U(e.sessionRegistration),sessionSignature:U(e.sessionSignature)}}function X(e){return{payload:e.payload,sessionPublicKey:k(e.sessionPublicKey),sessionRegistration:k(e.sessionRegistration),sessionSignature:k(e.sessionSignature)}}function U(e){let t="";for(let n of e)t+=n.toString(16).padStart(2,"0");return t}function k(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}var b=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,n){this.map.set(t,n)}async delete(t){this.map.delete(t)}},E=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return J(this.dir,`${t}.json`)}async get(t){try{let n=await w.readFile(this.pathFor(t),"utf8");return X(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(t,n){let r=this.pathFor(t);await w.mkdir(G(r),{recursive:!0});let i=`${r}.tmp`;await w.writeFile(i,JSON.stringify(W(n))),await w.rename(i,r)}async delete(t){try{await w.unlink(this.pathFor(t))}catch(n){if(n?.code!=="ENOENT")throw n}}};import{PublicKey as ze}from"@solana/web3.js";import{bytesToHex as Je}from"@noble/hashes/utils";import Ke from"tweetnacl";import{sha256 as He}from"@noble/hashes/sha256";var q=6;function A(e,t=q){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[n,r=""]=e.split(".");if(r.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let i=r.padEnd(t,"0"),c=`${n}${i}`.replace(/^0+(?=\d)/,"");return c===""?"0":c}function S(e,t=q){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let n=e.padStart(t+1,"0"),r=n.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",i=n.slice(-t).replace(/0+$/,"");return i?`${r}.${i}`:r}var O="x-tab-voucher",K=class{map=new Map;get(t){return this.map.get(t)}set(t,n){this.map.set(t,n)}update(t,n){let r=this.map.get(t);r&&(r.lastCumulativeAtomic=n)}delete(t){this.map.delete(t)}},N=class{constructor(t,n,r,i){this.chargeImpl=i;this.channelId=t,this.network=n,this.cumulativeAtomic=r}channelId;network;sessionPublicKey=null;cumulativeAtomic;cumulative(){return S(this.cumulativeAtomic.toString())}bumpCumulative(t){this.cumulativeAtomic=t}setSessionPublicKey(t){this.sessionPublicKey=t}async charge(t){return this.chargeImpl(t)}};function Z(e){if(typeof e!="string"||e.length===0)throw new l("signature_invalid",`missing ${O} header`);let t;try{t=Buffer.from(e,"base64").toString("utf8")}catch{throw new l("signature_invalid","malformed base64")}let n;try{n=JSON.parse(t)}catch{throw new l("signature_invalid","malformed JSON")}if(!n||typeof n!="object"||!n.payload||!n.sessionPublicKey)throw new l("signature_invalid","missing required fields");return{payload:n.payload,sessionPublicKey:v(n.sessionPublicKey),sessionRegistration:v(n.sessionRegistration),sessionSignature:v(n.sessionSignature)}}function v(e){if(typeof e!="string"||e.length%2!==0)throw new l("signature_invalid",`bad hex: ${typeof e}`);let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}function Q(e){if(!/^[0-9a-f]{64}$/i.test(e))throw new l("signature_invalid",`channelId must be 64-char hex, got "${e}"`);return v(e)}function ee(e){let t=e.store??new b,n=new K,r=typeof e.sellerPubkey=="string"?new Y(e.sellerPubkey):e.sellerPubkey,i=e.maxPerVoucherAtomic?BigInt(e.maxPerVoucherAtomic):BigInt(A(e.perUnit))*100n;return async(c,p,y)=>{try{let o=Z(c.headers[O]),d=o.payload.channelId,g=Q(d),a=n.get(d);if(!a){let x=_(o.sessionRegistration);await $(e.connection,x),a={registration:x,lastCumulativeAtomic:"0"},n.set(d,a)}C(o,g),R({registration:a.registration,voucher:o,expectedCounterparty:r,previousCumulativeAtomic:a.lastCumulativeAtomic});let s=BigInt(o.payload.cumulativeAmount),D=BigInt(a.lastCumulativeAtomic),H=s-D;if(H>i)throw new u("cumulative_exceeds_cap",`single voucher increment ${H} exceeds maxPerVoucherAtomic ${i}`);await t.set(d,o),n.update(d,o.payload.cumulativeAmount);let B=new N(d,e.network,s,async x=>{throw new Error("SellerTab.charge() is not driven by the route handler; the buyer presents a fresh voucher per chunk. Use openSse(res, tab) for the metered-stream pattern.")});B.setSessionPublicKey(o.sessionPublicKey),c.tab=B,y()}catch(o){if(o instanceof l||o instanceof m||o instanceof f||o instanceof h||o instanceof u){p.status(402).json({error:"invalid_voucher",reason:o.reason??"unknown",detail:o.message});return}y(o)}}}function te(e){if(!e.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return e.tab}function ne(e,t){if(!t.tab)throw new Error("openSse requires options.tab");e.headersSent||(e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive"),typeof e.flushHeaders=="function"&&e.flushHeaders());let n=t.tab,r=BigInt(A(n.cumulative())),i=t.perUnit?BigInt(A(t.perUnit)):null,c=0n,p=!1;function y(g=1){if(p)return Promise.reject(new Error("meter ended"));if(i===null)return Promise.reject(new Error("charge() needs options.perUnit"));let a=i*BigInt(g),s=c+a;return s>r?Promise.reject(new u("cumulative_exceeds_cap",`chunk would push request total to ${S(s.toString())} beyond voucher-authorized budget ${S(r.toString())}`)):(c=s,Promise.resolve())}function o(g){if(p)throw new Error("meter ended");let s=(typeof g=="string"?g:Buffer.from(g).toString("utf8")).replace(/\n/g,"\\n");e.write(`data: ${s}
2
2
 
3
- `)}function u(){p||(p=!0,e.write(`event: end
3
+ `)}function d(){p||(p=!0,e.write(`event: end
4
4
  data: {"chargedAtomic":"${c}"}
5
5
 
6
- `),e.end())}return{charge:h,send:o,end:u}}export{E as FileVoucherStore,b as InMemoryVoucherStore,d as InvalidRegistrationError,m as InvalidVoucherError,y as InvalidVoucherSignatureError,f as OnChainVerificationError,l as ScopeViolationError,N as TAB_VOUCHER_HEADER,U as enforceScope,ne as openSse,k as parseRegistration,D as readVaultState,te as requireTab,ee as tabMiddleware,_ as verifyRegistrationOnChain,C as verifyVoucherSignature};
6
+ `),e.end())}return{charge:y,send:o,end:d}}export{E as FileVoucherStore,b as InMemoryVoucherStore,m as InvalidRegistrationError,l as InvalidVoucherError,h as InvalidVoucherSignatureError,f as OnChainVerificationError,u as ScopeViolationError,O as TAB_VOUCHER_HEADER,R as enforceScope,ne as openSse,_ as parseRegistration,te as requireTab,ee as tabMiddleware,$ as verifyRegistrationOnChain,C as verifyVoucherSignature};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexterai/x402",
3
- "version": "3.14.0",
3
+ "version": "3.15.0",
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, SKALE.",
5
5
  "author": "Dexter",
6
6
  "license": "MIT",
@@ -76,7 +76,7 @@
76
76
  "release:major": "npm version major && npm publish --access public"
77
77
  },
78
78
  "dependencies": {
79
- "@dexterai/vault": "^0.4.2",
79
+ "@dexterai/vault": "^0.9.0",
80
80
  "@dexterai/x402-ads-types": "^0.2.0",
81
81
  "@dexterai/x402-core": "^1.4.0",
82
82
  "@noble/curves": "^1.9.7",