@dexterai/x402 6.0.4 → 6.0.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/dist/tab/seller/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var w=class extends Error{constructor(n,r){super(`Invalid voucher: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidVoucherError"}reason};import{promises as Q}from"fs";import{randomUUID as
|
|
1
|
+
var w=class extends Error{constructor(n,r){super(`Invalid voucher: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidVoucherError"}reason};import{promises as Q}from"fs";import{randomUUID as ut}from"crypto";import{join as Pn,dirname as Vn}from"path";var Xt=new Map;function E(t,e){let r=(Xt.get(t)??Promise.resolve()).then(()=>e(),()=>e());return Xt.set(t,r.then(()=>{},()=>{})),r}var D=class extends Error{code="channel_lease_lost";constructor(e){super(`channel lease lost for ${e}`),this.name="ChannelLeaseLostError"}};function J(t){if(!Number.isSafeInteger(t)||t<3||t>2147483647)throw new Error("channel lease TTL must be an integer from 3 to 2147483647 milliseconds");return t}function V(t){if(!/^[0-9a-f]{64}$/.test(t))throw new Error("channelId must be canonical lowercase 64-character hex")}function mt(t,e){return t!==void 0&&t.ownerToken===e.ownerToken&&t.fence===e.fence}function me(t,e,n){if(!e||!mt(e,n)||e.heldUntilUnixMs<=Date.now())throw new D(t)}var Ae=class{capabilities={adapter:"memory",restartSafe:!1,multiInstanceSafe:!1,conditionalWrites:!0,canonicalChannelIds:!0};map=new Map;leases=new Map;fences=new Map;async get(e){V(e);let n=this.map.get(e);return n?oe(ee(n)):null}async set(e,n,r){V(e),await E(e,async()=>{me(e,this.leases.get(e),r),this.map.set(e,oe(ee(n)))})}async update(e,n,r){return V(e),E(e,async()=>{me(e,this.leases.get(e),n);let i=this.map.get(e),o=r(i?oe(ee(i)):null),s=oe(ee(o));return this.map.set(e,s),oe(ee(s))})}async delete(e,n){V(e),await E(e,async()=>{me(e,this.leases.get(e),n),this.map.delete(e)})}async tryAcquireLease(e,n){return V(e),E(e,async()=>{let r=J(n),i=Date.now(),o=this.leases.get(e);if(o&&o.heldUntilUnixMs>i)return null;let s=(this.fences.get(e)??0n)+1n;this.fences.set(e,s);let c={ownerToken:ut(),fence:s.toString(),heldUntilUnixMs:i+r};return this.leases.set(e,c),{...c}})}async releaseLease(e,n){return V(e),E(e,async()=>{let r=this.leases.get(e);return!r||!mt(r,n)||r.heldUntilUnixMs<=Date.now()?!1:(this.leases.delete(e),!0)})}async renewLease(e,n,r){return V(e),E(e,async()=>{let i=J(r),o=this.leases.get(e);me(e,o,n);let s={...o,heldUntilUnixMs:Date.now()+i};return this.leases.set(e,s),{...s}})}};function ct(t){let e="";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}function lt(t){if(t.length%2!==0)throw new Error(`hex length must be even, got ${t.length}`);let e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n++)e[n]=parseInt(t.substr(n*2,2),16);return e}function pt(t){return ee(t)}function gt(t){return oe(t)}function ee(t){return{lastVoucher:t.lastVoucher?{payload:t.lastVoucher.payload,sessionPublicKey:ct(t.lastVoucher.sessionPublicKey),sessionRegistration:ct(t.lastVoucher.sessionRegistration),sessionSignature:ct(t.lastVoucher.sessionSignature)}:null,deliveredCumulativeAtomic:t.deliveredCumulativeAtomic,lastCrystallizedCumulativeAtomic:t.lastCrystallizedCumulativeAtomic,gateRefusedCumulativeAtomic:t.gateRefusedCumulativeAtomic,onChain:t.onChain}}function oe(t){return{lastVoucher:t.lastVoucher?{payload:t.lastVoucher.payload,sessionPublicKey:lt(t.lastVoucher.sessionPublicKey),sessionRegistration:lt(t.lastVoucher.sessionRegistration),sessionSignature:lt(t.lastVoucher.sessionSignature)}:null,deliveredCumulativeAtomic:t.deliveredCumulativeAtomic,lastCrystallizedCumulativeAtomic:t.lastCrystallizedCumulativeAtomic??"0",gateRefusedCumulativeAtomic:t.gateRefusedCumulativeAtomic,onChain:t.onChain}}var dt=class{constructor(e,n={}){this.dir=e;if(n===null||typeof n!="object"||Array.isArray(n))throw new Error("FileChannelLedger options must be an object");if(n.channelIdCutover!==void 0&&n.channelIdCutover!=="legacy-case-aliases-migrated-or-empty")throw new Error("invalid FileChannelLedger channelIdCutover acknowledgement");this.capabilities={adapter:"file",restartSafe:!0,multiInstanceSafe:!1,conditionalWrites:!0,canonicalChannelIds:n.channelIdCutover==="legacy-case-aliases-migrated-or-empty"}}dir;capabilities;pathFor(e,n=".json"){return V(e),Pn(this.dir,`${e}${n}`)}async writeAtomic(e,n){await Q.mkdir(Vn(e),{recursive:!0});let r=`${e}.${ut()}.tmp`;await Q.writeFile(r,n),await Q.rename(r,e)}async readLease(e){try{return JSON.parse(await Q.readFile(this.pathFor(e,".lease.json"),"utf8"))}catch(n){if(n?.code==="ENOENT")return;throw n}}async requireLease(e,n){me(e,await this.readLease(e),n)}async get(e){V(e);try{let n=await Q.readFile(this.pathFor(e),"utf8");return oe(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(e,n,r){V(e),await E(e,async()=>{await this.requireLease(e,r),await this.writeAtomic(this.pathFor(e),JSON.stringify(ee(n)))})}async update(e,n,r){return V(e),E(e,async()=>{await this.requireLease(e,n);let i=r(await this.get(e));return await this.writeAtomic(this.pathFor(e),JSON.stringify(ee(i))),i})}async delete(e,n){V(e),await E(e,async()=>{await this.requireLease(e,n);try{await Q.unlink(this.pathFor(e))}catch(r){if(r?.code!=="ENOENT")throw r}})}async tryAcquireLease(e,n){return V(e),E(e,async()=>{let r=J(n),i=Date.now(),o=await this.readLease(e);if(o&&o.heldUntilUnixMs>i)return null;let s=0n;try{s=BigInt(await Q.readFile(this.pathFor(e,".fence"),"utf8"))}catch(p){if(p?.code!=="ENOENT")throw p}let c=s+1n;await this.writeAtomic(this.pathFor(e,".fence"),c.toString());let l={ownerToken:ut(),fence:c.toString(),heldUntilUnixMs:i+r};return await this.writeAtomic(this.pathFor(e,".lease.json"),JSON.stringify(l)),l})}async releaseLease(e,n){return V(e),E(e,async()=>{let r=await this.readLease(e);return!r||!mt(r,n)||r.heldUntilUnixMs<=Date.now()?!1:(await Q.unlink(this.pathFor(e,".lease.json")),!0)})}async renewLease(e,n,r){return V(e),E(e,async()=>{let i=J(r),o=await this.readLease(e);me(e,o,n);let s={...o,heldUntilUnixMs:Date.now()+i};return await this.writeAtomic(this.pathFor(e,".lease.json"),JSON.stringify(s)),s})}};import{randomUUID as Tn}from"crypto";function Jt(t){if(t===null||typeof t!="object"||Array.isArray(t))return!1;let e=t;return e.persistence==="aof-always"&&e.failover==="no-data-loss"&&e.maxmemoryPolicy==="noeviction"&&e.isolation==="dedicated-instance"}var In=`
|
|
2
2
|
if redis.call("exists", KEYS[1]) == 1 then return false end
|
|
3
3
|
redis.call("incr", KEYS[2])
|
|
4
4
|
local fence = redis.call("get", KEYS[2])
|
|
@@ -19,9 +19,9 @@ return redis.call("del", KEYS[1])
|
|
|
19
19
|
if redis.call("get", KEYS[1]) ~= ARGV[1] then return 0 end
|
|
20
20
|
redis.call("pexpire", KEYS[1], ARGV[2])
|
|
21
21
|
return 1
|
|
22
|
-
`,Bn='return redis.call("get", KEYS[1])',ke=class extends Error{constructor(e){super(`legacy Redis seller state exists for channel ${e}; stop all legacy writers, migrate/delete the legacy ledger, lease, and fence keys, then retry cluster-v1`),this.name="RedisKeyspaceMigrationRequiredError"}};function Le(t){return`${t.ownerToken}:${t.fence}`}function Oe(t){return t===1||t==="1"}var pt=class{constructor(e,n="tab:"){this.client=e;if(typeof n!="string"&&(n===null||typeof n!="object"||Array.isArray(n)))throw new Error("RedisChannelLedger options must be a key prefix or options object");let r=typeof n=="string"?{keyPrefix:n}:n;if(r.keyPrefix!==void 0&&typeof r.keyPrefix!="string")throw new Error("RedisChannelLedger keyPrefix must be a string");if(this.keyPrefix=r.keyPrefix??"tab:",this.keyLayout=r.keyLayout??"legacy-v0",!["legacy-v0","cluster-v1"].includes(this.keyLayout))throw new Error(`invalid RedisChannelLedger keyLayout: ${String(this.keyLayout)}`);if(this.keyLayout==="cluster-v1"&&(this.keyPrefix.includes("{")||this.keyPrefix.includes("}")))throw new Error("cluster-v1 keyPrefix must not contain Redis hash-tag braces");if(r.writerCutover!==void 0&&r.writerCutover!=="all-legacy-writers-stopped")throw new Error("invalid RedisChannelLedger writerCutover acknowledgement");if(r.channelIdCutover!==void 0&&r.channelIdCutover!=="legacy-case-aliases-migrated-or-empty")throw new Error("invalid RedisChannelLedger channelIdCutover acknowledgement");if(this.keyLayout==="cluster-v1"&&r.keyspaceCutover!=="legacy-state-migrated-or-empty")throw new Error("cluster-v1 requires keyspaceCutover: legacy-state-migrated-or-empty");let i=r.durability;if(i!==void 0&&!Xt(i))throw new Error("RedisChannelLedger durability attestation must confirm aof-always, no-data-loss failover, noeviction, and dedicated-instance isolation");this.capabilities={adapter:"redis",restartSafe:Xt(i)&&r.writerCutover==="all-legacy-writers-stopped",multiInstanceSafe:!0,conditionalWrites:!0,canonicalChannelIds:r.channelIdCutover==="legacy-case-aliases-migrated-or-empty"}}client;capabilities;keyPrefix;keyLayout;assertChannelId(e){V(e)}legacyKey(e,n){return this.assertChannelId(e),`${this.keyPrefix}${n}:${e}`}channelKey(e,n){return this.assertChannelId(e),this.keyLayout==="cluster-v1"?`${this.keyPrefix}{${e}}:${n}`:this.legacyKey(e,n)}ledgerKey(e){return this.channelKey(e,"ledger")}leaseKey(e){return this.channelKey(e,"lease")}fenceKey(e){return this.channelKey(e,"fence")}async primaryGet(e){let n=await this.client.eval(Bn,1,e);if(n===null||n===!1)return null;if(typeof n!="string")throw new Error(`Redis primary GET returned invalid value type: ${typeof n}`);return n}async assertClusterCutover(e){if(this.keyLayout!=="cluster-v1")return;let n=await this.primaryGet(this.legacyKey(e,"ledger")),r=await this.primaryGet(this.legacyKey(e,"lease")),i=await this.primaryGet(this.legacyKey(e,"fence"));if(n!==null||r!==null||i!==null)throw new ke(e)}async get(e){this.assertChannelId(e),await this.assertClusterCutover(e);let n=await this.primaryGet(this.ledgerKey(e));return n===null?null:mt(JSON.parse(n))}async writeIfOwned(e,n,r){let i=dt(n),o=await this.client.eval(Nn,2,this.leaseKey(e),this.ledgerKey(e),Le(r),JSON.stringify(i));if(!Oe(o))throw new D(e)}async set(e,n,r){this.assertChannelId(e),await E(e,()=>this.writeIfOwned(e,n,r))}async update(e,n,r){return this.assertChannelId(e),E(e,async()=>{let i=r(await this.get(e));return await this.writeIfOwned(e,i,n),i})}async delete(e,n){this.assertChannelId(e),await E(e,async()=>{let r=await this.client.eval(Ln,2,this.leaseKey(e),this.ledgerKey(e),Le(n));if(!Oe(r))throw new D(e)})}async tryAcquireLease(e,n){return this.assertChannelId(e),E(e,async()=>{await this.assertClusterCutover(e);let r=Tn(),i=J(n),o=await this.client.eval(In,2,this.leaseKey(e),this.fenceKey(e),r,i);if(o===null||o===!1||o===0||o==="0")return null;let s=String(o);if(!/^[1-9][0-9]*$/.test(s))throw new Error(`Redis returned invalid channel fence: ${s}`);return{ownerToken:r,fence:s,heldUntilUnixMs:Date.now()+i}})}async releaseLease(e,n){return this.assertChannelId(e),E(e,async()=>{let r=await this.client.eval(On,1,this.leaseKey(e),Le(n));return Oe(r)})}async renewLease(e,n,r){return this.assertChannelId(e),E(e,async()=>{let i=J(r),o=await this.client.eval(kn,1,this.leaseKey(e),Le(n),i);if(!Oe(o))throw new D(e);return{...n,heldUntilUnixMs:Date.now()+i}})}};import{PublicKey as hr}from"@solana/web3.js";import Kn from"tweetnacl";import{sha256 as yi}from"@noble/hashes/sha256";import{p256 as Ai}from"@noble/curves/p256";import{PublicKey as ht}from"@solana/web3.js";import{sessionRegisterMessage as Un,sessionReplaceV1Message as Zr,sessionRevokeMessage as Qr,sessionVoucherV2Nonce as ei,sessionVoucherV2AuthorizationNonce as ti,finalVoucherV2Sequence as ni,voucherV2SequenceOrdinal as ri,voucherPayloadMessage as gt,buildVoucherMessage as ii}from"@dexterai/vault/messages";import{buildRegisterSessionKeyInstruction as ai,buildRevokeSessionKeyInstruction as ci,deriveSwigWalletAddress as li}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as di}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as Be,SECP256R1_PROGRAM_ID as pi,INSTRUCTIONS_SYSVAR_ID as gi}from"@dexterai/vault/constants";import{decodeSessionAccount as $n,deriveSessionPda as Yt,isSessionLive as Mn}from"@dexterai/vault/session";import{contextBoundVoucherV2Message as Dn,sessionVoucherV2AuthorizationNonce as Fn,voucherV2SequenceOrdinal as qn}from"@dexterai/vault/messages";var ft="OTS_SESSION_REGISTER_V2";function te(t){return t>=2147483648?2:1}var W=class extends Error{constructor(n,r){super(`Invalid registration: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidRegistrationError"}reason};function Ue(t){if(t.length!==188)throw new W("wrong_length",`expected 188, got ${t.length}`);let e=new TextDecoder().decode(t.slice(0,ft.length));if(e!==ft)throw new W("wrong_domain",`got "${e}"`);for(let v=ft.length;v<32;v++)if(t[v]!==0)throw new W("wrong_domain",`non-NUL padding at byte ${v}`);let n=new DataView(t.buffer,t.byteOffset,t.byteLength),r=new ht(t.slice(32,64)),i=new ht(t.slice(64,96)),o=t.slice(96,128),s=n.getBigUint64(128,!0),c=n.getBigInt64(136,!0),l=new ht(t.slice(144,176)),p=n.getUint32(176,!0),y=n.getBigUint64(180,!0);if(!r.equals(Be))throw new W("wrong_program",`${r.toBase58()} is not ${Be.toBase58()}`);if(s===0n)throw new W("cap_zero");return{programId:r,vaultPda:i,sessionPubkey:new Uint8Array(o),maxAmount:s,expiresAt:c,allowedCounterparty:l,nonce:p,maxRevolvingCapacity:y}}var $=class extends Error{constructor(n,r){super(`On-chain verification failed: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="OnChainVerificationError"}reason};async function yt(t,e){let[n]=Yt(e.vaultPda,e.allowedCounterparty,e.programId),r=await t.getAccountInfo(n,"finalized");if(!r)throw new $("session_not_active","no finalized SessionAccount PDA for this (vault, counterparty) \u2014 registration may be confirmed-only, revoked, expiry-swept, or never registered");if(!r.owner.equals(e.programId))throw new $("wrong_program",`SessionAccount owner ${r.owner.toBase58()} != ${e.programId.toBase58()}`);let i;try{i=$n(n,r.data)}catch(h){throw new $("registration_state_mismatch",`finalized SessionAccount decode failed: ${h instanceof Error?h.message:String(h)}`)}if(i.version===0)throw new $("session_not_active","finalized SessionAccount is cleared");if(!Mn(i))throw new $("session_not_active","SessionAccount PDA is present but expired");if(!Zt(i.session.sessionPubkey,e.sessionPubkey))throw new $("session_pubkey_mismatch",`on-chain ${Jt(i.session.sessionPubkey)} != registration ${Jt(e.sessionPubkey)}`);let o=te(e.nonce),s=te(i.session.nonce);if(s!==o)throw new $("wire_version_mismatch",`active SessionAccount is V${s}, voucher registration is V${o}`);let c=Number.isSafeInteger(i.session.expiresAt)&&BigInt(i.session.expiresAt)===e.expiresAt;if(!(i.address===n.toBase58()&&i.vault===e.vaultPda.toBase58()&&i.session.maxAmount===e.maxAmount&&c&&i.session.allowedCounterparty===e.allowedCounterparty.toBase58()&&i.session.nonce===e.nonce&&i.session.maxRevolvingCapacity===e.maxRevolvingCapacity))throw new $("registration_state_mismatch","188-byte registration does not exactly match the active SessionAccount immutable fields");let p=i.session.spent,y=i.session.crystallizedCumulative,v=p>y?p:y;return{sessionAccountVersion:i.version,wireVersion:s,frontierAtomic:v.toString(),spentAtomic:p.toString(),currentOutstandingAtomic:i.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:y.toString()}}var I=class extends Error{constructor(e){super(`Invalid voucher signature${e?`: ${e}`:""}`),this.name="InvalidVoucherSignatureError"}};function vt(t,e){if(e.length!==32)throw new I(`channelIdBytes must be 32 bytes, got ${e.length}`);if(t.sessionPublicKey.length!==32)throw new I(`sessionPublicKey must be 32 bytes, got ${t.sessionPublicKey.length}`);if(t.sessionSignature.length!==64)throw new I(`sessionSignature must be 64 bytes, got ${t.sessionSignature.length}`);let n=Ue(t.sessionRegistration);if(!Zt(n.sessionPubkey,t.sessionPublicKey))throw new I("registration session key does not match voucher session key");let r=n.nonce>=2147483648,i=te(n.nonce),o=te(t.payload.sequenceNumber);if(i!==o)throw new I(`voucher wire V${o} does not match registration wire V${i}`);let s;if(r){Fn(n.nonce),qn(t.payload.sequenceNumber);let[l]=Yt(n.vaultPda,n.allowedCounterparty,n.programId);s=Dn({programId:n.programId,vaultPda:n.vaultPda,sessionPda:l,seller:n.allowedCounterparty,sessionNonce:n.nonce,channelId:e,cumulativeAmount:BigInt(t.payload.cumulativeAmount),sequenceNumber:t.payload.sequenceNumber})}else s=gt({channelId:e,cumulativeAmount:BigInt(t.payload.cumulativeAmount),sequenceNumber:t.payload.sequenceNumber});if(!Kn.sign.detached.verify(s,t.sessionSignature,t.sessionPublicKey))throw new I("ed25519 verify rejected")}var L=class extends Error{constructor(n,r){super(`Scope violation: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="ScopeViolationError"}reason};function Ke(t){let e=BigInt(t.voucher.payload.cumulativeAmount);if(e>t.registration.maxAmount)throw new L("cumulative_exceeds_cap",`${e} > ${t.registration.maxAmount}`);let n=BigInt(Math.floor(Date.now()/1e3));if(n>=t.registration.expiresAt)throw new L("session_expired",`now=${n} >= expiresAt=${t.registration.expiresAt}`);if(!t.registration.allowedCounterparty.equals(t.expectedCounterparty))throw new L("wrong_counterparty",`${t.registration.allowedCounterparty.toBase58()} != ${t.expectedCounterparty.toBase58()}`);if(t.previousCumulativeAtomic!==void 0){let r=BigInt(t.previousCumulativeAtomic);if(e<=r)throw new L("non_monotonic",`cumulative=${e} not > previous=${r}`)}}function Zt(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}function Jt(t){let e="";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}import{PublicKey as Qi}from"@solana/web3.js";import{bytesToHex as to}from"@noble/hashes/utils";import Vi from"tweetnacl";import{PublicKey as Ii}from"@solana/web3.js";import{contextBoundVoucherV2Message as Li,finalVoucherV2Sequence as Oi,sessionRegisterMessage as ki,sessionVoucherV2AuthorizationNonce as Bi}from"@dexterai/vault/messages";import{deriveSessionPda as Ki}from"@dexterai/vault/session";import{sha256 as Fi}from"@noble/hashes/sha256";var Mi=(1n<<64n)-1n;import{sha256 as nn}from"@noble/hashes/sha256";import{bytesToHex as pe}from"@noble/hashes/utils";var Qt=/^[0-9a-f]{64}$/,en=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,zn=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,tn="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",rn="dexter-native-tab-v2-reservation/v1",Hn=`${rn}:`;function At(t){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number"){if(!Number.isFinite(t))throw new Error("canonical_non_finite_number");return t}if(typeof t=="bigint")return t.toString();if(Array.isArray(t))return t.map(At);if(typeof t=="object")return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,At(n)]));throw new Error("canonical_value_unsupported")}function on(t){return JSON.stringify(At(t))}function bt(t){if(t==="solana:mainnet"||t===tn)return tn;throw new Error("native_tab_v2_reservation_network_unsupported")}function wt(t){return pe(nn(new TextEncoder().encode(on({channelId:t.payload.channelId,cumulativeAmount:t.payload.cumulativeAmount,sequenceNumber:t.payload.sequenceNumber,sessionPublicKey:pe(t.sessionPublicKey),sessionSignature:pe(t.sessionSignature),sessionRegistration:pe(t.sessionRegistration)}))))}function St(t){let e=wt(t);return{voucherDigest:e,idempotencyKey:`native-tab-v2:${e}`}}function Wn(t){return pe(nn(new TextEncoder().encode(on({contract:rn,network:bt(t.network),programId:t.programId,buyerSwigAddress:t.buyerSwigAddress,vaultPda:t.vaultPda,sessionPda:t.sessionPda,seller:t.seller,channelId:t.channelId,sessionNonce:t.sessionNonce,reservationAmountAtomic:t.reservationAmountAtomic,previousCumulativeAtomic:t.previousCumulativeAtomic,voucherDigest:t.voucherDigest,cumulativeAmountAtomic:t.cumulativeAmountAtomic,sequenceNumber:t.sequenceNumber}))))}function Gn(t){let e=wt(t.voucher);return Wn({network:t.network,programId:t.programId,buyerSwigAddress:t.buyerSwigAddress,vaultPda:t.vaultPda,sessionPda:t.sessionPda,seller:t.seller,channelId:t.channelId,sessionNonce:t.sessionNonce,reservationAmountAtomic:t.reservationAmountAtomic,previousCumulativeAtomic:t.previousCumulativeAtomic,voucherDigest:e,cumulativeAmountAtomic:t.voucher.payload.cumulativeAmount,sequenceNumber:t.voucher.payload.sequenceNumber})}function sn(t){return`${Hn}${Gn(t)}`}function N(t){throw new Error(`native_tab_v2_reservation_receipt_invalid:${t}`)}function $e(t,e){(!Number.isSafeInteger(t)||t<0)&&N(e)}function _t(t,e){(!e||typeof e!="object")&&N("missing");let n=wt(t.voucher);(!Qt.test(t.voucherDigest)||t.voucherDigest!==n)&&N("input_voucher_digest"),t.idempotencyKey!==`native-tab-v2:${n}`&&N("input_idempotency_identity");let r=BigInt(t.voucher.payload.cumulativeAmount),i=BigInt(t.previousCumulativeAtomic),o=BigInt(t.reservationAmountAtomic);(r<=i||r-i!==o||o<=0n)&&N("input_reservation_delta"),(t.voucher.payload.channelId!==t.channelId||(t.voucher.payload.sequenceNumber&2147483648)===0||(t.sessionNonce&2147483648)===0||t.voucher.sessionPublicKey.length!==32||t.voucher.sessionSignature.length!==64||t.voucher.sessionRegistration.length!==188)&&N("input_voucher_identity"),e.contract!=="dexter-native-tab-open-receipt/v1"&&e.contract!=="dexter-native-tab-open-receipt/v2"&&N("contract"),Qt.test(e.operationId)||N("operation_id"),en.test(e.callerOperationId)||N("caller_operation_id"),zn.test(e.transaction)||N("transaction"),e.commitment!=="confirmed"&&e.commitment!=="finalized"&&N("commitment"),$e(e.confirmationSlot,"confirmation_slot"),$e(e.postStateSlot,"post_state_slot"),(e.confirmationSlot===0||e.postStateSlot<e.confirmationSlot)&&N("post_state_slot");let s,c;try{s=bt(t.network),c=bt(e.network)}catch{return N("network")}(c!==s||e.buyerSwigAddress!==t.buyerSwigAddress||e.vaultPda!==t.vaultPda||e.sessionPda!==t.sessionPda||e.seller!==t.seller||e.channelId!==t.channelId||e.sessionPublicKey!==pe(t.voucher.sessionPublicKey)||e.voucherDigest!==n||e.cumulativeAmountAtomic!==t.voucher.payload.cumulativeAmount||e.sequenceNumber!==t.voucher.payload.sequenceNumber||!en.test(e.providerReceiptId)||e.reservationAmountAtomic!==t.reservationAmountAtomic||e.currentOutstandingBeforeAtomic!=="0"||e.currentOutstandingAfterAtomic!==t.reservationAmountAtomic)&&N("economic_identity"),$e(e.pendingVoucherCountBefore,"pending_voucher_count_before"),$e(e.pendingVoucherCountAfter,"pending_voucher_count_after"),e.contract==="dexter-native-tab-open-receipt/v1"?e.callerOperationId!==t.idempotencyKey&&N("idempotency_key"):(e.rootOperationId!==t.idempotencyKey||!Number.isSafeInteger(e.generation)||Number(e.generation)<2||!e.predecessorCallerOperationId||!e.predecessorLifecycleOperationId||!e.predecessorReleaseDigest||!e.stableReservationId||!e.economicEffectDigest)&&N("successor_identity")}import{deriveSessionPda as so}from"@dexterai/vault/session";var an="https://x402.dexter.cash",cn=6;function H(t,e=cn){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let i=r.padEnd(e,"0"),o=`${n}${i}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function se(t,e=cn){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",i=n.slice(-e).replace(/0+$/,"");return i?`${r}.${i}`:r}import{PublicKey as ne}from"@solana/web3.js";import{bytesToHex as Ct}from"@noble/hashes/utils";import{deriveGraphConfigPda as jn,deriveSwigVaultBindingPda as xt}from"@dexterai/vault/credit";import{DEXTER_VAULT_PROGRAM_ID as Xn,DISCRIMINATORS as Jn,isSwigVaultBindingIdentityVersion as ln}from"@dexterai/vault/constants";import{deriveSwigWalletAddress as Yn}from"@dexterai/vault/instructions";import{decodeVaultFull as Zn}from"@dexterai/vault/reader";import{decodeSessionAccount as Qn,deriveSessionPda as Rt}from"@dexterai/vault/session";var er=Uint8Array.from([56,67,4,209,238,143,0,129]),tr=74,nr=188,rr=new ne("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),ir=(()=>{let t=Buffer.alloc(32);return t.write("OTS_SESSION_REGISTER_V2","ascii"),t})(),be=class extends Error{constructor(n,r){super(`native_tab_v2_solana_reservation_invalid:${n}`+(r?`:${r}`:""));this.code=n;this.name="SolanaFinalVoucherV2ReservationError"}code};function m(t,e){throw new be(t,e)}function M(t,e){try{return new ne(t)}catch{return m(e)}}function Me(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}async function or(t){let n=(await t.connection.getSignatureStatuses([t.signature],{searchTransactionHistory:!0})).value[0]??null;if(!n)return null;n.confirmationStatus!=="confirmed"&&n.confirmationStatus!=="finalized"&&m("transaction_commitment"),n.err!==null&&m("transaction_failed");let r=await t.connection.getTransaction(t.signature,{commitment:t.commitment,maxSupportedTransactionVersion:0});if(!r)return null;r.meta||m("transaction_meta_missing"),r.slot!==n.slot&&m("transaction_status_slot");let i=r.transaction.message,o=i.version===0?i.getAccountKeys({accountKeysFromLookups:r.meta.loadedAddresses??null}):i.getAccountKeys(),s=(c,l)=>{let p=o.get(c);return p||m(l),p};return{slot:r.slot,confirmationStatus:n.confirmationStatus,err:r.meta.err,signatures:[...r.transaction.signatures],accountKeys:Array.from({length:o.length},(c,l)=>({address:s(l,"transaction_account_key").toBase58(),signer:i.isAccountSigner(l),writable:i.isAccountWritable(l)})),instructions:i.compiledInstructions.map(c=>({programId:s(c.programIdIndex,"transaction_program_id").toBase58(),accounts:c.accountKeyIndexes.map(l=>s(l,"transaction_instruction_account").toBase58()),data:Uint8Array.from(c.data)}))}}function sr(t,e,n,r){r.length!==tr&&m("binding_length"),Me(r.subarray(0,8),er)||m("binding_discriminator");let i=r.readUInt8(8),o=r.readUInt8(9);return ln(i)||m("binding_version"),o!==e&&m("binding_bump"),{address:t.toBase58(),owner:n.toBase58(),version:i,bump:o,swig:new ne(r.subarray(10,42)).toBase58(),vault:new ne(r.subarray(42,74)).toBase58()}}async function ar(t){let e=M(t.input.programId,"program_id"),n=M(t.input.buyerSwigAddress,"buyer_swig"),r=M(t.input.vaultPda,"vault_pda"),i=M(t.input.seller,"seller"),[o,s]=xt(n,e),[c]=Rt(r,i,e),l=await t.connection.getMultipleAccountsInfoAndContext([o,r,c],{commitment:t.commitment,minContextSlot:t.minimumSlot}),[p,y,v]=l.value;p||m("binding_missing"),y||m("vault_missing"),v||m("session_missing");let h,f;try{h=Zn(Buffer.from(y.data)),f=Qn(c,v.data)}catch(S){return m("post_state_decode",S instanceof Error?S.message:String(S))}let g=f.session;return{contextSlot:l.context.slot,binding:sr(o,s,p.owner,Buffer.from(p.data)),vault:{owner:y.owner.toBase58(),exists:h.exists,version:h.version,swigAddress:h.swigAddress,dexterAuthority:h.dexterAuthority,pendingVoucherCount:h.pendingVoucherCount},session:{owner:v.owner.toBase58(),version:f.version,bump:f.bump,vault:f.vault,sessionPublicKey:Ct(g.sessionPubkey),maxAmount:g.maxAmount,expiresAt:g.expiresAt,seller:g.allowedCounterparty,nonce:g.nonce,spent:g.spent,currentOutstanding:g.currentOutstanding,maxRevolvingCapacity:g.maxRevolvingCapacity,crystallizedCumulative:g.crystallizedCumulative}}}function cr(t){let e=Buffer.from(t.voucher.sessionRegistration);return e.length!==nr&&m("registration_length"),Me(e.subarray(0,32),ir)||m("registration_domain"),{programId:new ne(e.subarray(32,64)).toBase58(),vaultPda:new ne(e.subarray(64,96)).toBase58(),sessionPublicKey:Ct(e.subarray(96,128)),maxAmount:e.readBigUInt64LE(128),expiresAt:e.readBigInt64LE(136),seller:new ne(e.subarray(144,176)).toBase58(),nonce:e.readUInt32LE(176),maxRevolvingCapacity:e.readBigUInt64LE(180)}}function ge(t,e,n){let r=t.accountKeys.filter(i=>i.address===e);return r.length!==1&&m(`${n}_account_key`),r[0]}function lr(t,e,n){(!Number.isSafeInteger(n.slot)||n.slot<=0)&&m("transaction_slot"),n.slot!==e.confirmationSlot&&m("transaction_confirmation_slot"),n.err!==null&&m("transaction_failed"),n.signatures[0]!==e.transaction&&m("transaction_signature"),n.instructions.length!==2&&m("transaction_instruction_count");let r=M(t.programId,"program_id"),i=M(t.buyerSwigAddress,"buyer_swig"),o=M(t.vaultPda,"vault_pda"),s=M(t.seller,"seller"),c=M(t.sessionPda,"session_pda"),[l]=Rt(o,s,r),p=xt(i,r)[0],y=Yn(i),v=jn(r)[0];c.equals(l)||m("session_pda_derivation");let h=Buffer.from(Jn.settle_voucher),f=n.instructions.filter(a=>{if(a.programId!==t.programId)return!1;let x=a.data;return x.length>=h.length&&Me(x.subarray(0,h.length),h)});f.length!==1&&m("settle_voucher_instruction_count");let g=f[0];n.instructions[0]!==g&&m("settle_voucher_instruction_order");let S=Buffer.from(g.data);S.length!==49&&m("settle_voucher_instruction_length"),S.readBigUInt64LE(8).toString()!==t.reservationAmountAtomic&&m("settle_voucher_amount"),S.readUInt8(16)!==1&&m("settle_voucher_increment"),new ne(S.subarray(17,49)).equals(s)||m("settle_voucher_seller"),g.accounts.length<8&&m("settle_voucher_accounts"),[o.toBase58(),null,c.toBase58(),null,i.toBase58(),y.toBase58(),p.toBase58(),v.toBase58()].forEach((a,x)=>{a!==null&&g.accounts[x]!==a&&m(`settle_voucher_account_${x}`)});let T=g.accounts[1];T||m("dexter_authority");let G=ge(n,g.accounts[0],"vault"),Z=ge(n,T,"dexter_authority"),re=ge(n,g.accounts[2],"session");(!G.writable||G.signer)&&m("vault_privileges"),Z.signer||m("dexter_authority_signature"),(!re.writable||re.signer)&&m("session_privileges");for(let a=3;a<Math.min(g.accounts.length,8);a+=1)ge(n,g.accounts[a],`account_${a}`).signer&&m(`settle_voucher_account_${a}_signer`);for(let a=8;a<g.accounts.length;a+=1){let x=ge(n,g.accounts[a],`sibling_${a-8}`);(!x.writable||x.signer)&&m("settle_voucher_sibling_privileges")}let F=n.instructions[1];F.programId!==rr.toBase58()&&m("reservation_memo_program"),(F.accounts.length!==1||F.accounts[0]!==T)&&m("reservation_memo_authority"),ge(n,T,"reservation_memo_authority").signer||m("reservation_memo_authority_signature");let d=new TextEncoder().encode(sn(t));return Me(F.data,d)||m("reservation_memo_digest"),T}function ur(t,e,n,r){let i=M(t.programId,"program_id"),o=M(t.buyerSwigAddress,"buyer_swig"),s=M(t.vaultPda,"vault_pda"),c=M(t.seller,"seller"),[l,p]=xt(o,i),[y,v]=Rt(s,c,i);(!Number.isSafeInteger(r.contextSlot)||r.contextSlot<e)&&m("post_state_slot"),(r.binding.address!==l.toBase58()||r.binding.owner!==t.programId||r.binding.bump!==p||!ln(r.binding.version)||r.binding.swig!==t.buyerSwigAddress||r.binding.vault!==t.vaultPda)&&m("binding_identity"),(r.vault.owner!==t.programId||!r.vault.exists||r.vault.version!==7||r.vault.swigAddress!==t.buyerSwigAddress||r.vault.dexterAuthority!==n)&&m("vault_post_state"),(t.sessionPda!==y.toBase58()||r.session.owner!==t.programId||r.session.version!==1||r.session.bump!==v||r.session.vault!==t.vaultPda||r.session.sessionPublicKey!==Ct(t.voucher.sessionPublicKey)||r.session.seller!==t.seller||r.session.nonce!==t.sessionNonce||r.session.currentOutstanding.toString()!==t.reservationAmountAtomic)&&m("session_post_state");let h=cr(t);(h.programId!==t.programId||h.vaultPda!==t.vaultPda||h.sessionPublicKey!==r.session.sessionPublicKey||h.seller!==t.seller||h.nonce!==t.sessionNonce||h.maxAmount!==r.session.maxAmount||h.expiresAt!==BigInt(r.session.expiresAt)||h.maxRevolvingCapacity!==r.session.maxRevolvingCapacity)&&m("registration_post_state");let f=r.session.spent>r.session.crystallizedCumulative?r.session.spent:r.session.crystallizedCumulative;return f.toString()!==t.previousCumulativeAtomic&&m("session_frontier"),{commitment:"confirmed",confirmationSlot:e,postStateSlot:r.contextSlot,sessionAccountVersion:r.session.version,wireVersion:2,frontierAtomic:f.toString(),spentAtomic:r.session.spent.toString(),currentOutstandingAtomic:r.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:r.session.crystallizedCumulative.toString()}}async function un(t,e,n,r={}){try{_t(e,n)}catch(c){return m("provider_receipt",c instanceof Error?c.message:String(c))}e.network!=="solana:mainnet"&&m("network"),e.programId!==Xn.toBase58()&&m("program_id");let i=await(r.readTransaction??or)({connection:t,signature:n.transaction,commitment:"confirmed"});i||m("transaction_missing"),i.confirmationStatus!=="confirmed"&&i.confirmationStatus!=="finalized"&&m("transaction_commitment");let o=lr(e,n,i),s=await(r.readPostState??ar)({connection:t,input:e,minimumSlot:i.slot,commitment:"confirmed"});return{...ur(e,i.slot,o,s),commitment:i.confirmationStatus}}import{deriveSessionPda as fr}from"@dexterai/vault/session";import{bytesToHex as Et}from"@noble/hashes/utils";var dr=15e3,mr=["claim_already_exists","non_monotonic_cumulative"],pr="below_lock_cadence";function De(t){return typeof t=="string"&&t.includes(pr)}function gr(t){return`${t.slice(0,16)}\u2026`}function dn(t,e,n,r){let i=gr(t);if(r.crystallized){console.info(`[tab/seller] crystallize OK channel=${i} cumulative=${e} seq=${n}${r.claimPda?` claimPda=${r.claimPda}`:""} \u2014 LockVoucher landed`);return}if(r.error){if(De(r.error)){console.warn(`[tab/seller] crystallize refused below the facilitator's cadence gate channel=${i} cumulative=${e} seq=${n}: ${r.error} \u2014 benign: this facilitator's cadence engine owns the protection cadence for the span; gate-refused watermark advanced, re-attempts after the next signed voucher`);return}if(mr.some(o=>r.error.includes(o))){console.warn(`[tab/seller] crystallize duplicate channel=${i} cumulative=${e} seq=${n}: ${r.error} \u2014 voucher already secured on-chain (benign, no action)`);return}console.error(`[tab/seller] crystallize FAILED channel=${i} cumulative=${e} seq=${n}: ${r.error} \u2014 lock NOT secured (degraded: best-effort path, no watermark advance, retries at next threshold/close; seller exposure stays unsecured until it lands)`)}}async function Pt(t,e,n,r,i=fetch){let o=t.lastVoucher;if(!o)return{crystallized:!1};if(o.payload.channelId!==e){let c={crystallized:!1,error:"channel_id_mismatch"};return dn(e,o.payload.cumulativeAmount,o.payload.sequenceNumber,c),c}let s=c=>(dn(e,o.payload.cumulativeAmount,o.payload.sequenceNumber,c),c);try{let c=`${n.replace(/\/$/,"")}/tab/lock`,l={channelId:o.payload.channelId,cumulativeAmount:o.payload.cumulativeAmount,sequenceNumber:o.payload.sequenceNumber,sessionPublicKey:Et(o.sessionPublicKey),sessionSignature:Et(o.sessionSignature),sessionRegistration:Et(o.sessionRegistration),network:r},p=await i(c,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(l),signal:AbortSignal.timeout(dr)}),y=await p.text();if(!p.ok)return s({crystallized:!1,error:`tab lock ${p.status}: ${y.slice(0,200)}`});let v;try{let h=JSON.parse(y);h&&typeof h.claimPda=="string"&&(v=h.claimPda)}catch{}return s({crystallized:!0,claimPda:v})}catch(c){return s({crystallized:!1,error:String(c?.message??c)})}}async function mn(t,e,n,r,i,o={}){let s=BigInt(t.deliveredCumulativeAtomic),c=BigInt(t.lastCrystallizedCumulativeAtomic??"0"),l=BigInt(i.thresholdAtomic);if(s-c<l)return{crystallized:!1};let p=t.lastVoucher?.payload.cumulativeAmount,y=t.gateRefusedCumulativeAtomic;if(p!==void 0&&y!==void 0&&BigInt(p)<=BigInt(y))return{crystallized:!1};let v=await Pt(t,e,n,r,o.fetchImpl);return v.crystallized&&p!==void 0?(t.lastCrystallizedCumulativeAtomic=p,t.gateRefusedCumulativeAtomic=void 0):De(v.error)&&p!==void 0&&(t.gateRefusedCumulativeAtomic=p),v}var ce="x-tab-voucher",ze=class extends Error{constructor(){super("response terminated before tab admission completed"),this.name="ResponseTerminatedError"}};function yr(t){if(t!==void 0)return t;if(process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development")return"development";throw new Error("tab seller ledgerSafetyMode must be explicit outside NODE_ENV=test/development; choose production-single-instance or production-multi-instance for deployment")}function vr(t,e){if(!["development","production-single-instance","production-multi-instance"].includes(e))throw new Error(`invalid tab seller ledgerSafetyMode: ${String(e)}`);let n=t.capabilities;if(!n||n.conditionalWrites!==!0)throw new Error("tab seller ledger must declare conditional owner-token/fence writes");if(e!=="development"&&!n.restartSafe)throw new Error(`tab seller ${e} requires restart-safe durable ledger state; ${n.adapter} is not restart-safe`);if(e!=="development"&&!n.canonicalChannelIds)throw new Error(`tab seller ${e} requires the legacy channel-id alias migration or an empty-store proof; ${n.adapter} has no canonical channel-id cutover acknowledgement`);if(e==="production-multi-instance"&&!n.multiInstanceSafe)throw new Error(`tab seller production-multi-instance requires cross-process atomic fencing; ${n.adapter} is single-instance only`)}var Vt=class{map=new Map;get(e){return this.map.get(e)}set(e,n){this.map.set(e,n)}deleteIfSame(e,n){this.map.get(e)===n&&this.map.delete(e)}update(e,n){let r=this.map.get(e);r&&(r.lastCumulativeAtomic=n)}delete(e){this.map.delete(e)}},Tt=class{constructor(e,n,r,i,o,s){this.recordDeliveredImpl=o;this.chargeImpl=s;this.channelId=e,this.network=n,this.cumulativeAtomic=r,this.deliveredBaselineAtomic=i}recordDeliveredImpl;chargeImpl;channelId;network;sessionPublicKey=null;cumulativeAtomic;deliveredBaselineAtomic;cumulative(){return se(this.cumulativeAtomic.toString())}deliveredCumulative(){return se(this.deliveredBaselineAtomic.toString())}async recordDelivered(e){return this.recordDeliveredImpl(e)}bumpCumulative(e){this.cumulativeAtomic=e}setSessionPublicKey(e){this.sessionPublicKey=e}async charge(e){return this.chargeImpl(e)}};function Ar(t){if(typeof t!="string"||t.length===0)throw new w("signature_invalid",`missing ${ce} header`);let e;try{e=Buffer.from(t,"base64").toString("utf8")}catch{throw new w("signature_invalid","malformed base64")}let n;try{n=JSON.parse(e)}catch{throw new w("signature_invalid","malformed JSON")}if(!n||typeof n!="object"||!n.payload||!n.sessionPublicKey)throw new w("signature_invalid","missing required fields");return{voucher:{payload:n.payload,sessionPublicKey:qe(n.sessionPublicKey),sessionRegistration:qe(n.sessionRegistration),sessionSignature:qe(n.sessionSignature)},reservationReceipt:n.reservationReceipt}}function qe(t){if(typeof t!="string"||t.length%2!==0)throw new w("signature_invalid",`bad hex: ${typeof t}`);let e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n++)e[n]=parseInt(t.substr(n*2,2),16);return e}function br(t){if(!/^[0-9a-f]{64}$/.test(t))throw new w("signature_invalid",`channelId must be canonical lowercase 64-char hex, got "${t}"`);return qe(t)}function It(t){let e=t.ledger??new Ae,n=yr(t.ledgerSafetyMode);vr(e,n);let r=J(t.leaseTtlMs??3e5),i=new Vt,o=typeof t.sellerPubkey=="string"?new hr(t.sellerPubkey):t.sellerPubkey,s=t.maxPerVoucherAtomic?BigInt(t.maxPerVoucherAtomic):BigInt(H(t.perUnit))*100n,c=t.facilitatorUrl??an,l={thresholdAtomic:t.lockCadence?.thresholdAtomic??H("0.10"),onClose:t.lockCadence?.onClose??!0};return async(p,y,v)=>{let h=null,f=null,g=null,S=null,P=null,T=!1,G=async()=>{if(P)throw P},Z=async()=>{if(!f||f.releaseStarted)return;let _=f;_.releaseStarted=!0,g&&(clearInterval(g),g=null),S&&await S.catch(()=>{});try{await e.releaseLease(_.channelId,f?.lease??_.lease)}catch(d){throw _.releaseStarted=!1,d}},re=()=>{T||(T=!0,setImmediate(()=>{Z().catch(_=>{console.error("[tab/seller] failed to release channel lease on response termination:",_)})}))},F=()=>{if(T)throw new ze};y.on("close",re),y.on("finish",re);try{let _=Ar(p.headers[ce]),d=_.voucher,a=d.payload.channelId,x=br(a),A=i.get(a),O=null,K,nt=!1;if(A){if(!ae(A.registrationBytes,d.sessionRegistration))throw new I("voucher registration does not match the channel's verified registration")}else{nt=!0;let u=Ue(d.sessionRegistration);te(u.nonce)===1&&(K=await yt(t.connection,u),O=K?.frontierAtomic??null);let C=await e.get(a);A={registration:u,registrationBytes:d.sessionRegistration.slice(),lastCumulativeAtomic:C?.lastVoucher?.payload.cumulativeAmount??"0"}}let q=te(A.registration.nonce),Bt=te(d.payload.sequenceNumber);if(Bt!==q)throw new w("wire_version_mismatch",`voucher is V${Bt}, active registration is V${q}`);let he;if(q===2){if(_.reservationReceipt===void 0)throw new w("reservation_proof_missing","Native Tab V2 requires the verified reservation receipt in the voucher envelope");if(_.reservationReceipt===null||typeof _.reservationReceipt!="object"||Array.isArray(_.reservationReceipt))throw new w("reservation_proof_invalid","reservationReceipt must be an object");he=_.reservationReceipt}vt(d,x);let k=BigInt(d.payload.cumulativeAmount),j=BigInt(A.lastCumulativeAtomic),fe=null,X=null,rt=null;if(q===2){if(!he)throw new w("reservation_proof_missing","Native Tab V2 reservation proof was not carried through admission");if(X=Fe(he.reservationAmountAtomic,"receipt.reservationAmountAtomic"),X<=0n||X>k)throw new w("reservation_mismatch","reservation amount does not fit the voucher cumulative");let u=k-X,[C]=fr(A.registration.vaultPda,A.registration.allowedCounterparty,A.registration.programId),R=St(d);try{let U=await un(t.connection,{network:t.network,programId:A.registration.programId.toBase58(),buyerSwigAddress:he.buyerSwigAddress,vaultPda:A.registration.vaultPda.toBase58(),sessionPda:C.toBase58(),seller:A.registration.allowedCounterparty.toBase58(),channelId:a,sessionNonce:A.registration.nonce,reservationAmountAtomic:X.toString(),previousCumulativeAtomic:u.toString(),...R,voucher:d},he);K=U,O=U.frontierAtomic}catch(U){throw U instanceof be?new w("reservation_proof_invalid",U.message):U}if(K?.wireVersion!==2)throw new w("wire_version_mismatch",`active SessionAccount is V${K?.wireVersion??"unknown"}, voucher is V2`);if(K.sessionAccountVersion!==1||O===null||K.currentOutstandingAtomic===void 0)throw new w("reservation_mismatch","authoritative V2 SessionAccount reservation evidence is incomplete");let b=Fe(O,"frontierAtomic");if(b>j&&(j=b),k<=j)throw new w("voucher_already_covered",`cumulative ${k} is not above covered frontier ${j}`);fe=k-j;let B=Fe(K.currentOutstandingAtomic,"currentOutstandingAtomic");if(rt=B,B!==fe)throw new w("reservation_mismatch",`currentOutstanding ${B} does not equal voucher delta ${fe}`);if(X!==fe)throw new w("reservation_mismatch",`receipt reservation ${X} does not equal voucher delta ${fe}`)}let Cn=q===1&&k===j;Ke({registration:A.registration,voucher:d,expectedCounterparty:o,previousCumulativeAtomic:Cn?void 0:j.toString()});let ie=k-j;if(ie>s)throw new L("cumulative_exceeds_cap",`single voucher increment ${ie} exceeds maxPerVoucherAtomic ${s}`);if(nt){let u=i.get(a);if(u){if(!ae(u.registrationBytes,A.registrationBytes))throw new I("voucher registration lost the channel admission race to a different verified registration");if(BigInt(u.lastCumulativeAtomic)>BigInt(A.lastCumulativeAtomic))throw new L("non_monotonic","channel admission advanced while reservation proof was in flight");A=u}}F();let ye=await e.tryAcquireLease(a,r);if(!ye)throw new w("channel_busy","another stream is live on this channel; tabs serve one stream at a time");f={channelId:a,lease:ye,releaseStarted:!1},F();let Ut=Math.max(1,Math.floor(r/3)),Kt=async()=>{if(P)throw P;if(!f||f.releaseStarted)throw new D(a);return S||(S=(async()=>{let u=await e.renewLease(a,f.lease,r);f&&!f.releaseStarted&&(f.lease=u)})().catch(u=>{let C=u instanceof Error?u:new Error(String(u));throw P=C,console.error(`[tab/seller] channel lease renewal FAILED channel=${a.slice(0,16)}\u2026; stream terminated before further delivery:`,C),typeof y.destroy=="function"&&y.destroy(C),C}).finally(()=>{S=null}),S)};G=async()=>{if(P)throw P;if(!f||f.releaseStarted)throw new D(a);f.lease.heldUntilUnixMs-Date.now()<=Ut&&await Kt()},g=setInterval(()=>{Kt().catch(()=>{})},Ut),g.unref?.();let ve=await e.get(a);if(F(),ve?.lastVoucher&&!ae(ve.lastVoucher.sessionRegistration,d.sessionRegistration))throw new I("durable channel registration changed while reservation proof was in flight");let $t=BigInt(ve?.lastVoucher?.payload.cumulativeAmount??"0"),z=BigInt(A.lastCumulativeAtomic);if($t>z&&(z=$t),q===2&&O!==null){let u=Fe(O,"frontierAtomic");u>z&&(z=u)}let Mt=q===1&&k===z;if(k<z||q===2&&k===z)throw new w(q===2?"voucher_already_covered":"non_monotonic",`cumulative ${k} is not above post-lease covered frontier ${z}`);if(Mt){let u=ve?.lastVoucher;if(!u||BigInt(u.payload.cumulativeAmount)!==k||d.payload.sequenceNumber<=u.payload.sequenceNumber)throw new w("non_monotonic","same-cumulative V1 reconnect requires a strictly newer sequence than the durable voucher")}if(Ke({registration:A.registration,voucher:d,expectedCounterparty:o,previousCumulativeAtomic:Mt?void 0:z.toString()}),ie=k-z,ie>s)throw new L("cumulative_exceeds_cap",`post-lease voucher increment ${ie} exceeds maxPerVoucherAtomic ${s}`);if(q===2&&(X===null||rt===null||X!==ie||rt!==ie))throw new w("reservation_mismatch","durable channel frontier advanced while reservation proof was in flight");if(j=z,nt){let u=i.get(a);if(u){if(!ae(u.registrationBytes,A.registrationBytes))throw await Z(),new I("voucher registration lost the channel lease race to a different verified registration");A=u}else i.set(a,A),h={channelId:a,entry:A}}let it=async u=>{try{return await e.update(a,ye,u)}catch(C){if(!(C instanceof D))throw C;let R=await e.tryAcquireLease(a,Math.min(r,15e3));if(!R)throw C;try{return await e.update(a,R,u)}finally{await e.releaseLease(a,R)}}},xn=async u=>{let C=u.lastCrystallizedCumulativeAtomic??"0",R=u.gateRefusedCumulativeAtomic;await mn(u,a,c,t.network,l),(u.lastCrystallizedCumulativeAtomic!==C||u.gateRefusedCumulativeAtomic!==R)&&await it(b=>{if(!b)throw new Error("channel ledger entry missing during crystallize persist");let B=BigInt(b.lastCrystallizedCumulativeAtomic??"0")>=BigInt(u.lastCrystallizedCumulativeAtomic??"0")?b.lastCrystallizedCumulativeAtomic??"0":u.lastCrystallizedCumulativeAtomic??"0",ue=[b.gateRefusedCumulativeAtomic,u.gateRefusedCumulativeAtomic].filter(de=>de!==void 0).reduce((de,Gt)=>de===void 0||BigInt(Gt)>BigInt(de)?Gt:de,void 0);return{...b,lastCrystallizedCumulativeAtomic:B,gateRefusedCumulativeAtomic:ue!==void 0&&BigInt(ue)>BigInt(B)?ue:void 0}}).catch(b=>{console.error(`[tab/seller] crystallize watermark persist FAILED channel=${a.slice(0,16)}\u2026 (expect a benign duplicate/below-cadence warn on the next request):`,b)})},Dt=Promise.resolve(),Ft=u=>{let C=Dt.then(u,u);return Dt=C.catch(()=>{}),C},qt=!1,zt=()=>{!l.onClose||qt||(qt=!0,Ft(async()=>{let u=await e.get(a);if(!u||!u.lastVoucher)return;let C=u.lastVoucher.payload.cumulativeAmount;if(u.gateRefusedCumulativeAtomic!==void 0&&BigInt(C)<=BigInt(u.gateRefusedCumulativeAtomic))return;let R=await Pt(u,a,c,t.network);R.crystallized?await it(b=>{if(!b)throw new Error("channel ledger entry missing during close crystallize");let B=BigInt(b.lastCrystallizedCumulativeAtomic??"0")>=BigInt(C)?b.lastCrystallizedCumulativeAtomic??"0":C;return{...b,lastCrystallizedCumulativeAtomic:B,gateRefusedCumulativeAtomic:b.gateRefusedCumulativeAtomic!==void 0&&BigInt(b.gateRefusedCumulativeAtomic)>BigInt(B)?b.gateRefusedCumulativeAtomic:void 0}}):De(R.error)&&await it(b=>{if(!b)throw new Error("channel ledger entry missing during close refusal persist");let B=BigInt(b.lastCrystallizedCumulativeAtomic??"0"),U=b.gateRefusedCumulativeAtomic!==void 0&&BigInt(b.gateRefusedCumulativeAtomic)>=BigInt(C)?b.gateRefusedCumulativeAtomic:C;return{...b,gateRefusedCumulativeAtomic:BigInt(U)>B?U:void 0}})}).catch(u=>{console.error(`[tab/seller] close-path crystallize CRASHED channel=${a.slice(0,16)}\u2026 (final voucher NOT locked; exposure unsecured until the next request retries):`,u)}))};y.on("close",zt),y.on("finish",zt);let Ne=ve,Ht=BigInt(Ne?.deliveredCumulativeAtomic??"0"),Rn=!Ne?.lastVoucher&&Ht===0n,ot=O===null?null:BigInt(O),le=ot!==null&&ot>Ht&&(q===2||Rn)?ot.toString():null;le!==null&&console.info(`[tab/seller] channel ${a.slice(0,16)}\u2026 resumed: seeding delivered baseline from chain frontier ${le} (session already settled/locked up to it \u2014 that span is not deliverable budget)`);let En=le!==null?BigInt(le):Ne?BigInt(Ne.deliveredCumulativeAtomic):0n;await e.update(a,ye,u=>({...u??{},lastVoucher:d,deliveredCumulativeAtomic:le??(u?u.deliveredCumulativeAtomic:"0"),lastCrystallizedCumulativeAtomic:le??u?.lastCrystallizedCumulativeAtomic??"0"})),h=null,F(),i.update(a,d.payload.cumulativeAmount);let Wt=new Tt(a,t.network,k,En,async u=>{await G();let C=null;C=await e.update(a,ye,R=>{if(!R?.lastVoucher||!wr(R.lastVoucher,d))throw new I("durable voucher identity changed before delivery accounting");let b=BigInt(R.deliveredCumulativeAtomic),B=BigInt(u),U=B>0n?b+B:b,ue=BigInt(R.lastVoucher.payload.cumulativeAmount);if(U>ue)throw new L("cumulative_exceeds_cap",`durable delivered cumulative ${U} exceeds signed cumulative ${ue}`);return{...R,lastVoucher:R.lastVoucher,deliveredCumulativeAtomic:U.toString(),lastCrystallizedCumulativeAtomic:R.lastCrystallizedCumulativeAtomic??"0"}}),C&&Ft(async()=>{let R=await e.get(a);R&&await xn(R)}).catch(R=>{console.error(`[tab/seller] crystallize cadence CRASHED channel=${a.slice(0,16)}\u2026 (threshold lock not attempted; retries at the next delivery):`,R)})},async u=>{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.")});Wt.setSessionPublicKey(d.sessionPublicKey),p.tab=Wt,v()}catch(_){if(f&&!f.releaseStarted&&await Z().catch(d=>{console.error("[tab/seller] failed to release channel lease after request error:",d)}),h&&i.deleteIfSame(h.channelId,h.entry),_ instanceof ze)return;if(_ instanceof w||_ instanceof W||_ instanceof $||_ instanceof I||_ instanceof L){y.status(402).json({error:"invalid_voucher",reason:_.reason??"unknown",detail:_.message});return}v(_)}}}function ae(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r+=1)n|=t[r]^e[r];return n===0}function wr(t,e){return t.payload.channelId===e.payload.channelId&&t.payload.cumulativeAmount===e.payload.cumulativeAmount&&t.payload.sequenceNumber===e.payload.sequenceNumber&&ae(t.sessionPublicKey,e.sessionPublicKey)&&ae(t.sessionRegistration,e.sessionRegistration)&&ae(t.sessionSignature,e.sessionSignature)}function Fe(t,e){if(!/^(0|[1-9][0-9]*)$/.test(t))throw new w("reservation_mismatch",`authoritative ${e} is not a canonical atomic amount`);return BigInt(t)}function Sr(t){if(!t.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return t.tab}function _r(t,e){if(!e.tab)throw new Error("openSse requires options.tab");t.headersSent||(t.setHeader("Content-Type","text/event-stream"),t.setHeader("Cache-Control","no-cache"),t.setHeader("Connection","keep-alive"),typeof t.flushHeaders=="function"&&t.flushHeaders());let n=e.tab,r=BigInt(H(n.cumulative())),i=BigInt(H(n.deliveredCumulative())),o=r-i;o<0n&&(o=0n);let s=e.perUnit?BigInt(H(e.perUnit)):null,c=0n,l=!1,p=0,y=Promise.resolve();t.prependListener("close",()=>{l||(l=!0)});function v(g=1){if(l)return Promise.reject(new Error("meter ended"));if(s===null)return Promise.reject(new Error("charge() needs options.perUnit"));if(!Number.isSafeInteger(g)||g<=0)return Promise.reject(new Error("charge() units must be a positive safe integer"));let S=s*BigInt(g);p+=1;let P=y.then(async()=>{if(l)throw new Error("meter ended");let T=c+S;if(T>o)throw l=!0,new L("cumulative_exceeds_cap",`chunk would push delivered to ${se((i+T).toString())} beyond signed cumulative ${se(r.toString())} (per-request budget ${se(o.toString())})`);try{await n.recordDelivered(S.toString()),c=T}catch(G){throw l=!0,G}});return y=P.catch(()=>{}),P.finally(()=>{p-=1})}function h(g){if(l)throw new Error("meter ended");if(p>0)throw new Error("charge still pending; await meter.charge() before send()");let P=(typeof g=="string"?g:Buffer.from(g).toString("utf8")).replace(/\\/g,"\\\\").replace(/\n/g,"\\n");t.write(`data: ${P}
|
|
22
|
+
`,Bn='return redis.call("get", KEYS[1])',Be=class extends Error{constructor(e){super(`legacy Redis seller state exists for channel ${e}; stop all legacy writers, migrate/delete the legacy ledger, lease, and fence keys, then retry cluster-v1`),this.name="RedisKeyspaceMigrationRequiredError"}};function Oe(t){return`${t.ownerToken}:${t.fence}`}function ke(t){return t===1||t==="1"}var ht=class{constructor(e,n="tab:"){this.client=e;if(typeof n!="string"&&(n===null||typeof n!="object"||Array.isArray(n)))throw new Error("RedisChannelLedger options must be a key prefix or options object");let r=typeof n=="string"?{keyPrefix:n}:n;if(r.keyPrefix!==void 0&&typeof r.keyPrefix!="string")throw new Error("RedisChannelLedger keyPrefix must be a string");if(this.keyPrefix=r.keyPrefix??"tab:",this.keyLayout=r.keyLayout??"legacy-v0",!["legacy-v0","cluster-v1"].includes(this.keyLayout))throw new Error(`invalid RedisChannelLedger keyLayout: ${String(this.keyLayout)}`);if(this.keyLayout==="cluster-v1"&&(this.keyPrefix.includes("{")||this.keyPrefix.includes("}")))throw new Error("cluster-v1 keyPrefix must not contain Redis hash-tag braces");if(r.writerCutover!==void 0&&r.writerCutover!=="all-legacy-writers-stopped")throw new Error("invalid RedisChannelLedger writerCutover acknowledgement");if(r.channelIdCutover!==void 0&&r.channelIdCutover!=="legacy-case-aliases-migrated-or-empty")throw new Error("invalid RedisChannelLedger channelIdCutover acknowledgement");if(this.keyLayout==="cluster-v1"&&r.keyspaceCutover!=="legacy-state-migrated-or-empty")throw new Error("cluster-v1 requires keyspaceCutover: legacy-state-migrated-or-empty");let i=r.durability;if(i!==void 0&&!Jt(i))throw new Error("RedisChannelLedger durability attestation must confirm aof-always, no-data-loss failover, noeviction, and dedicated-instance isolation");this.capabilities={adapter:"redis",restartSafe:Jt(i)&&r.writerCutover==="all-legacy-writers-stopped",multiInstanceSafe:!0,conditionalWrites:!0,canonicalChannelIds:r.channelIdCutover==="legacy-case-aliases-migrated-or-empty"}}client;capabilities;keyPrefix;keyLayout;assertChannelId(e){V(e)}legacyKey(e,n){return this.assertChannelId(e),`${this.keyPrefix}${n}:${e}`}channelKey(e,n){return this.assertChannelId(e),this.keyLayout==="cluster-v1"?`${this.keyPrefix}{${e}}:${n}`:this.legacyKey(e,n)}ledgerKey(e){return this.channelKey(e,"ledger")}leaseKey(e){return this.channelKey(e,"lease")}fenceKey(e){return this.channelKey(e,"fence")}async primaryGet(e){let n=await this.client.eval(Bn,1,e);if(n===null||n===!1)return null;if(typeof n!="string")throw new Error(`Redis primary GET returned invalid value type: ${typeof n}`);return n}async assertClusterCutover(e){if(this.keyLayout!=="cluster-v1")return;let n=await this.primaryGet(this.legacyKey(e,"ledger")),r=await this.primaryGet(this.legacyKey(e,"lease")),i=await this.primaryGet(this.legacyKey(e,"fence"));if(n!==null||r!==null||i!==null)throw new Be(e)}async get(e){this.assertChannelId(e),await this.assertClusterCutover(e);let n=await this.primaryGet(this.ledgerKey(e));return n===null?null:gt(JSON.parse(n))}async writeIfOwned(e,n,r){let i=pt(n),o=await this.client.eval(Nn,2,this.leaseKey(e),this.ledgerKey(e),Oe(r),JSON.stringify(i));if(!ke(o))throw new D(e)}async set(e,n,r){this.assertChannelId(e),await E(e,()=>this.writeIfOwned(e,n,r))}async update(e,n,r){return this.assertChannelId(e),E(e,async()=>{let i=r(await this.get(e));return await this.writeIfOwned(e,i,n),i})}async delete(e,n){this.assertChannelId(e),await E(e,async()=>{let r=await this.client.eval(Ln,2,this.leaseKey(e),this.ledgerKey(e),Oe(n));if(!ke(r))throw new D(e)})}async tryAcquireLease(e,n){return this.assertChannelId(e),E(e,async()=>{await this.assertClusterCutover(e);let r=Tn(),i=J(n),o=await this.client.eval(In,2,this.leaseKey(e),this.fenceKey(e),r,i);if(o===null||o===!1||o===0||o==="0")return null;let s=String(o);if(!/^[1-9][0-9]*$/.test(s))throw new Error(`Redis returned invalid channel fence: ${s}`);return{ownerToken:r,fence:s,heldUntilUnixMs:Date.now()+i}})}async releaseLease(e,n){return this.assertChannelId(e),E(e,async()=>{let r=await this.client.eval(On,1,this.leaseKey(e),Oe(n));return ke(r)})}async renewLease(e,n,r){return this.assertChannelId(e),E(e,async()=>{let i=J(r),o=await this.client.eval(kn,1,this.leaseKey(e),Oe(n),i);if(!ke(o))throw new D(e);return{...n,heldUntilUnixMs:Date.now()+i}})}};import{PublicKey as hr}from"@solana/web3.js";import Kn from"tweetnacl";import{sha256 as yi}from"@noble/hashes/sha256";import{p256 as Ai}from"@noble/curves/p256";import{PublicKey as yt}from"@solana/web3.js";import{sessionRegisterMessage as Un,sessionReplaceV1Message as Zr,sessionRevokeMessage as Qr,sessionVoucherV2Nonce as ei,sessionVoucherV2AuthorizationNonce as ti,finalVoucherV2Sequence as ni,voucherV2SequenceOrdinal as ri,voucherPayloadMessage as ft,buildVoucherMessage as ii}from"@dexterai/vault/messages";import{buildRegisterSessionKeyInstruction as ai,buildRevokeSessionKeyInstruction as ci,deriveSwigWalletAddress as li}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as di}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as Ue,SECP256R1_PROGRAM_ID as pi,INSTRUCTIONS_SYSVAR_ID as gi}from"@dexterai/vault/constants";import{decodeSessionAccount as $n,deriveSessionPda as Zt,isSessionLive as Mn}from"@dexterai/vault/session";import{contextBoundVoucherV2Message as Dn,sessionVoucherV2AuthorizationNonce as Fn,voucherV2SequenceOrdinal as qn}from"@dexterai/vault/messages";var vt="OTS_SESSION_REGISTER_V2";function te(t){return t>=2147483648?2:1}var W=class extends Error{constructor(n,r){super(`Invalid registration: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="InvalidRegistrationError"}reason};function Ke(t){if(t.length!==188)throw new W("wrong_length",`expected 188, got ${t.length}`);let e=new TextDecoder().decode(t.slice(0,vt.length));if(e!==vt)throw new W("wrong_domain",`got "${e}"`);for(let v=vt.length;v<32;v++)if(t[v]!==0)throw new W("wrong_domain",`non-NUL padding at byte ${v}`);let n=new DataView(t.buffer,t.byteOffset,t.byteLength),r=new yt(t.slice(32,64)),i=new yt(t.slice(64,96)),o=t.slice(96,128),s=n.getBigUint64(128,!0),c=n.getBigInt64(136,!0),l=new yt(t.slice(144,176)),p=n.getUint32(176,!0),y=n.getBigUint64(180,!0);if(!r.equals(Ue))throw new W("wrong_program",`${r.toBase58()} is not ${Ue.toBase58()}`);if(s===0n)throw new W("cap_zero");return{programId:r,vaultPda:i,sessionPubkey:new Uint8Array(o),maxAmount:s,expiresAt:c,allowedCounterparty:l,nonce:p,maxRevolvingCapacity:y}}var $=class extends Error{constructor(n,r){super(`On-chain verification failed: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="OnChainVerificationError"}reason};async function At(t,e){let[n]=Zt(e.vaultPda,e.allowedCounterparty,e.programId),r=await t.getAccountInfo(n,"finalized");if(!r)throw new $("session_not_active","no finalized SessionAccount PDA for this (vault, counterparty) \u2014 registration may be confirmed-only, revoked, expiry-swept, or never registered");if(!r.owner.equals(e.programId))throw new $("wrong_program",`SessionAccount owner ${r.owner.toBase58()} != ${e.programId.toBase58()}`);let i;try{i=$n(n,r.data)}catch(h){throw new $("registration_state_mismatch",`finalized SessionAccount decode failed: ${h instanceof Error?h.message:String(h)}`)}if(i.version===0)throw new $("session_not_active","finalized SessionAccount is cleared");if(!Mn(i))throw new $("session_not_active","SessionAccount PDA is present but expired");if(!Qt(i.session.sessionPubkey,e.sessionPubkey))throw new $("session_pubkey_mismatch",`on-chain ${Yt(i.session.sessionPubkey)} != registration ${Yt(e.sessionPubkey)}`);let o=te(e.nonce),s=te(i.session.nonce);if(s!==o)throw new $("wire_version_mismatch",`active SessionAccount is V${s}, voucher registration is V${o}`);let c=Number.isSafeInteger(i.session.expiresAt)&&BigInt(i.session.expiresAt)===e.expiresAt;if(!(i.address===n.toBase58()&&i.vault===e.vaultPda.toBase58()&&i.session.maxAmount===e.maxAmount&&c&&i.session.allowedCounterparty===e.allowedCounterparty.toBase58()&&i.session.nonce===e.nonce&&i.session.maxRevolvingCapacity===e.maxRevolvingCapacity))throw new $("registration_state_mismatch","188-byte registration does not exactly match the active SessionAccount immutable fields");let p=i.session.spent,y=i.session.crystallizedCumulative,v=p>y?p:y;return{sessionAccountVersion:i.version,wireVersion:s,frontierAtomic:v.toString(),spentAtomic:p.toString(),currentOutstandingAtomic:i.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:y.toString()}}var I=class extends Error{constructor(e){super(`Invalid voucher signature${e?`: ${e}`:""}`),this.name="InvalidVoucherSignatureError"}};function bt(t,e){if(e.length!==32)throw new I(`channelIdBytes must be 32 bytes, got ${e.length}`);if(t.sessionPublicKey.length!==32)throw new I(`sessionPublicKey must be 32 bytes, got ${t.sessionPublicKey.length}`);if(t.sessionSignature.length!==64)throw new I(`sessionSignature must be 64 bytes, got ${t.sessionSignature.length}`);let n=Ke(t.sessionRegistration);if(!Qt(n.sessionPubkey,t.sessionPublicKey))throw new I("registration session key does not match voucher session key");let r=n.nonce>=2147483648,i=te(n.nonce),o=te(t.payload.sequenceNumber);if(i!==o)throw new I(`voucher wire V${o} does not match registration wire V${i}`);let s;if(r){Fn(n.nonce),qn(t.payload.sequenceNumber);let[l]=Zt(n.vaultPda,n.allowedCounterparty,n.programId);s=Dn({programId:n.programId,vaultPda:n.vaultPda,sessionPda:l,seller:n.allowedCounterparty,sessionNonce:n.nonce,channelId:e,cumulativeAmount:BigInt(t.payload.cumulativeAmount),sequenceNumber:t.payload.sequenceNumber})}else s=ft({channelId:e,cumulativeAmount:BigInt(t.payload.cumulativeAmount),sequenceNumber:t.payload.sequenceNumber});if(!Kn.sign.detached.verify(s,t.sessionSignature,t.sessionPublicKey))throw new I("ed25519 verify rejected")}var L=class extends Error{constructor(n,r){super(`Scope violation: ${n}${r?` (${r})`:""}`);this.reason=n;this.name="ScopeViolationError"}reason};function $e(t){let e=BigInt(t.voucher.payload.cumulativeAmount);if(e>t.registration.maxAmount)throw new L("cumulative_exceeds_cap",`${e} > ${t.registration.maxAmount}`);let n=BigInt(Math.floor(Date.now()/1e3));if(n>=t.registration.expiresAt)throw new L("session_expired",`now=${n} >= expiresAt=${t.registration.expiresAt}`);if(!t.registration.allowedCounterparty.equals(t.expectedCounterparty))throw new L("wrong_counterparty",`${t.registration.allowedCounterparty.toBase58()} != ${t.expectedCounterparty.toBase58()}`);if(t.previousCumulativeAtomic!==void 0){let r=BigInt(t.previousCumulativeAtomic);if(e<=r)throw new L("non_monotonic",`cumulative=${e} not > previous=${r}`)}}function Qt(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}function Yt(t){let e="";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}import{PublicKey as Qi}from"@solana/web3.js";import{bytesToHex as to}from"@noble/hashes/utils";import Vi from"tweetnacl";import{PublicKey as Ii}from"@solana/web3.js";import{contextBoundVoucherV2Message as Li,finalVoucherV2Sequence as Oi,sessionRegisterMessage as ki,sessionVoucherV2AuthorizationNonce as Bi}from"@dexterai/vault/messages";import{deriveSessionPda as Ki}from"@dexterai/vault/session";import{sha256 as Fi}from"@noble/hashes/sha256";var Mi=(1n<<64n)-1n;import{sha256 as nn}from"@noble/hashes/sha256";import{bytesToHex as pe}from"@noble/hashes/utils";var en=/^[0-9a-f]{64}$/,tn=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,199}$/,zn=/^[1-9A-HJ-NP-Za-km-z]{32,100}$/,De="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",rn="dexter-native-tab-v2-reservation/v1",Hn=`${rn}:`;function wt(t){if(t===null||typeof t=="string"||typeof t=="boolean")return t;if(typeof t=="number"){if(!Number.isFinite(t))throw new Error("canonical_non_finite_number");return t}if(typeof t=="bigint")return t.toString();if(Array.isArray(t))return t.map(wt);if(typeof t=="object")return Object.fromEntries(Object.entries(t).filter(([,e])=>e!==void 0).sort(([e],[n])=>e.localeCompare(n)).map(([e,n])=>[e,wt(n)]));throw new Error("canonical_value_unsupported")}function on(t){return JSON.stringify(wt(t))}function be(t){if(t==="solana:mainnet"||t===De)return De;throw new Error("native_tab_v2_reservation_network_unsupported")}function St(t){return pe(nn(new TextEncoder().encode(on({channelId:t.payload.channelId,cumulativeAmount:t.payload.cumulativeAmount,sequenceNumber:t.payload.sequenceNumber,sessionPublicKey:pe(t.sessionPublicKey),sessionSignature:pe(t.sessionSignature),sessionRegistration:pe(t.sessionRegistration)}))))}function _t(t){let e=St(t);return{voucherDigest:e,idempotencyKey:`native-tab-v2:${e}`}}function Wn(t){return pe(nn(new TextEncoder().encode(on({contract:rn,network:be(t.network),programId:t.programId,buyerSwigAddress:t.buyerSwigAddress,vaultPda:t.vaultPda,sessionPda:t.sessionPda,seller:t.seller,channelId:t.channelId,sessionNonce:t.sessionNonce,reservationAmountAtomic:t.reservationAmountAtomic,previousCumulativeAtomic:t.previousCumulativeAtomic,voucherDigest:t.voucherDigest,cumulativeAmountAtomic:t.cumulativeAmountAtomic,sequenceNumber:t.sequenceNumber}))))}function Gn(t){let e=St(t.voucher);return Wn({network:t.network,programId:t.programId,buyerSwigAddress:t.buyerSwigAddress,vaultPda:t.vaultPda,sessionPda:t.sessionPda,seller:t.seller,channelId:t.channelId,sessionNonce:t.sessionNonce,reservationAmountAtomic:t.reservationAmountAtomic,previousCumulativeAtomic:t.previousCumulativeAtomic,voucherDigest:e,cumulativeAmountAtomic:t.voucher.payload.cumulativeAmount,sequenceNumber:t.voucher.payload.sequenceNumber})}function sn(t){return`${Hn}${Gn(t)}`}function N(t){throw new Error(`native_tab_v2_reservation_receipt_invalid:${t}`)}function Me(t,e){(!Number.isSafeInteger(t)||t<0)&&N(e)}function Ct(t,e){(!e||typeof e!="object")&&N("missing");let n=St(t.voucher);(!en.test(t.voucherDigest)||t.voucherDigest!==n)&&N("input_voucher_digest"),t.idempotencyKey!==`native-tab-v2:${n}`&&N("input_idempotency_identity");let r=BigInt(t.voucher.payload.cumulativeAmount),i=BigInt(t.previousCumulativeAtomic),o=BigInt(t.reservationAmountAtomic);(r<=i||r-i!==o||o<=0n)&&N("input_reservation_delta"),(t.voucher.payload.channelId!==t.channelId||(t.voucher.payload.sequenceNumber&2147483648)===0||(t.sessionNonce&2147483648)===0||t.voucher.sessionPublicKey.length!==32||t.voucher.sessionSignature.length!==64||t.voucher.sessionRegistration.length!==188)&&N("input_voucher_identity"),e.contract!=="dexter-native-tab-open-receipt/v1"&&e.contract!=="dexter-native-tab-open-receipt/v2"&&N("contract"),en.test(e.operationId)||N("operation_id"),tn.test(e.callerOperationId)||N("caller_operation_id"),zn.test(e.transaction)||N("transaction"),e.commitment!=="confirmed"&&e.commitment!=="finalized"&&N("commitment"),Me(e.confirmationSlot,"confirmation_slot"),Me(e.postStateSlot,"post_state_slot"),(e.confirmationSlot===0||e.postStateSlot<e.confirmationSlot)&&N("post_state_slot");let s,c;try{s=be(t.network),c=be(e.network)}catch{return N("network")}(c!==s||e.buyerSwigAddress!==t.buyerSwigAddress||e.vaultPda!==t.vaultPda||e.sessionPda!==t.sessionPda||e.seller!==t.seller||e.channelId!==t.channelId||e.sessionPublicKey!==pe(t.voucher.sessionPublicKey)||e.voucherDigest!==n||e.cumulativeAmountAtomic!==t.voucher.payload.cumulativeAmount||e.sequenceNumber!==t.voucher.payload.sequenceNumber||!tn.test(e.providerReceiptId)||e.reservationAmountAtomic!==t.reservationAmountAtomic||e.currentOutstandingBeforeAtomic!=="0"||e.currentOutstandingAfterAtomic!==t.reservationAmountAtomic)&&N("economic_identity"),Me(e.pendingVoucherCountBefore,"pending_voucher_count_before"),Me(e.pendingVoucherCountAfter,"pending_voucher_count_after"),e.contract==="dexter-native-tab-open-receipt/v1"?e.callerOperationId!==t.idempotencyKey&&N("idempotency_key"):(e.rootOperationId!==t.idempotencyKey||!Number.isSafeInteger(e.generation)||Number(e.generation)<2||!e.predecessorCallerOperationId||!e.predecessorLifecycleOperationId||!e.predecessorReleaseDigest||!e.stableReservationId||!e.economicEffectDigest)&&N("successor_identity")}import{deriveSessionPda as so}from"@dexterai/vault/session";var an="https://x402.dexter.cash",cn=6;function H(t,e=cn){if(!/^\d+(\.\d+)?$/.test(t))throw new Error(`amount must be a non-negative decimal string, got "${t}"`);let[n,r=""]=t.split(".");if(r.length>e)throw new Error(`amount "${t}" has more than ${e} decimals`);let i=r.padEnd(e,"0"),o=`${n}${i}`.replace(/^0+(?=\d)/,"");return o===""?"0":o}function se(t,e=cn){if(!/^\d+$/.test(t))throw new Error(`atomic must be a non-negative integer string, got "${t}"`);let n=t.padStart(e+1,"0"),r=n.slice(0,-e).replace(/^0+(?=\d)/,"")||"0",i=n.slice(-e).replace(/0+$/,"");return i?`${r}.${i}`:r}import{PublicKey as ne}from"@solana/web3.js";import{bytesToHex as xt}from"@noble/hashes/utils";import{deriveGraphConfigPda as jn,deriveSwigVaultBindingPda as Rt}from"@dexterai/vault/credit";import{DEXTER_VAULT_PROGRAM_ID as Xn,DISCRIMINATORS as Jn,isSwigVaultBindingIdentityVersion as ln}from"@dexterai/vault/constants";import{deriveSwigWalletAddress as Yn}from"@dexterai/vault/instructions";import{decodeVaultFull as Zn}from"@dexterai/vault/reader";import{decodeSessionAccount as Qn,deriveSessionPda as Et}from"@dexterai/vault/session";var er=Uint8Array.from([56,67,4,209,238,143,0,129]),tr=74,nr=188,rr=new ne("MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"),ir=(()=>{let t=Buffer.alloc(32);return t.write("OTS_SESSION_REGISTER_V2","ascii"),t})(),we=class extends Error{constructor(n,r){super(`native_tab_v2_solana_reservation_invalid:${n}`+(r?`:${r}`:""));this.code=n;this.name="SolanaFinalVoucherV2ReservationError"}code};function m(t,e){throw new we(t,e)}function M(t,e){try{return new ne(t)}catch{return m(e)}}function Fe(t,e){return t.length===e.length&&t.every((n,r)=>n===e[r])}async function or(t){let n=(await t.connection.getSignatureStatuses([t.signature],{searchTransactionHistory:!0})).value[0]??null;if(!n)return null;n.confirmationStatus!=="confirmed"&&n.confirmationStatus!=="finalized"&&m("transaction_commitment"),n.err!==null&&m("transaction_failed");let r=await t.connection.getTransaction(t.signature,{commitment:t.commitment,maxSupportedTransactionVersion:0});if(!r)return null;r.meta||m("transaction_meta_missing"),r.slot!==n.slot&&m("transaction_status_slot");let i=r.transaction.message,o=i.version===0?i.getAccountKeys({accountKeysFromLookups:r.meta.loadedAddresses??null}):i.getAccountKeys(),s=(c,l)=>{let p=o.get(c);return p||m(l),p};return{slot:r.slot,confirmationStatus:n.confirmationStatus,err:r.meta.err,signatures:[...r.transaction.signatures],accountKeys:Array.from({length:o.length},(c,l)=>({address:s(l,"transaction_account_key").toBase58(),signer:i.isAccountSigner(l),writable:i.isAccountWritable(l)})),instructions:i.compiledInstructions.map(c=>({programId:s(c.programIdIndex,"transaction_program_id").toBase58(),accounts:c.accountKeyIndexes.map(l=>s(l,"transaction_instruction_account").toBase58()),data:Uint8Array.from(c.data)}))}}function sr(t,e,n,r){r.length!==tr&&m("binding_length"),Fe(r.subarray(0,8),er)||m("binding_discriminator");let i=r.readUInt8(8),o=r.readUInt8(9);return ln(i)||m("binding_version"),o!==e&&m("binding_bump"),{address:t.toBase58(),owner:n.toBase58(),version:i,bump:o,swig:new ne(r.subarray(10,42)).toBase58(),vault:new ne(r.subarray(42,74)).toBase58()}}async function ar(t){let e=M(t.input.programId,"program_id"),n=M(t.input.buyerSwigAddress,"buyer_swig"),r=M(t.input.vaultPda,"vault_pda"),i=M(t.input.seller,"seller"),[o,s]=Rt(n,e),[c]=Et(r,i,e),l=await t.connection.getMultipleAccountsInfoAndContext([o,r,c],{commitment:t.commitment,minContextSlot:t.minimumSlot}),[p,y,v]=l.value;p||m("binding_missing"),y||m("vault_missing"),v||m("session_missing");let h,f;try{h=Zn(Buffer.from(y.data)),f=Qn(c,v.data)}catch(S){return m("post_state_decode",S instanceof Error?S.message:String(S))}let g=f.session;return{contextSlot:l.context.slot,binding:sr(o,s,p.owner,Buffer.from(p.data)),vault:{owner:y.owner.toBase58(),exists:h.exists,version:h.version,swigAddress:h.swigAddress,dexterAuthority:h.dexterAuthority,pendingVoucherCount:h.pendingVoucherCount},session:{owner:v.owner.toBase58(),version:f.version,bump:f.bump,vault:f.vault,sessionPublicKey:xt(g.sessionPubkey),maxAmount:g.maxAmount,expiresAt:g.expiresAt,seller:g.allowedCounterparty,nonce:g.nonce,spent:g.spent,currentOutstanding:g.currentOutstanding,maxRevolvingCapacity:g.maxRevolvingCapacity,crystallizedCumulative:g.crystallizedCumulative}}}function cr(t){let e=Buffer.from(t.voucher.sessionRegistration);return e.length!==nr&&m("registration_length"),Fe(e.subarray(0,32),ir)||m("registration_domain"),{programId:new ne(e.subarray(32,64)).toBase58(),vaultPda:new ne(e.subarray(64,96)).toBase58(),sessionPublicKey:xt(e.subarray(96,128)),maxAmount:e.readBigUInt64LE(128),expiresAt:e.readBigInt64LE(136),seller:new ne(e.subarray(144,176)).toBase58(),nonce:e.readUInt32LE(176),maxRevolvingCapacity:e.readBigUInt64LE(180)}}function ge(t,e,n){let r=t.accountKeys.filter(i=>i.address===e);return r.length!==1&&m(`${n}_account_key`),r[0]}function lr(t,e,n){(!Number.isSafeInteger(n.slot)||n.slot<=0)&&m("transaction_slot"),n.slot!==e.confirmationSlot&&m("transaction_confirmation_slot"),n.err!==null&&m("transaction_failed"),n.signatures[0]!==e.transaction&&m("transaction_signature"),n.instructions.length!==2&&m("transaction_instruction_count");let r=M(t.programId,"program_id"),i=M(t.buyerSwigAddress,"buyer_swig"),o=M(t.vaultPda,"vault_pda"),s=M(t.seller,"seller"),c=M(t.sessionPda,"session_pda"),[l]=Et(o,s,r),p=Rt(i,r)[0],y=Yn(i),v=jn(r)[0];c.equals(l)||m("session_pda_derivation");let h=Buffer.from(Jn.settle_voucher),f=n.instructions.filter(a=>{if(a.programId!==t.programId)return!1;let x=a.data;return x.length>=h.length&&Fe(x.subarray(0,h.length),h)});f.length!==1&&m("settle_voucher_instruction_count");let g=f[0];n.instructions[0]!==g&&m("settle_voucher_instruction_order");let S=Buffer.from(g.data);S.length!==49&&m("settle_voucher_instruction_length"),S.readBigUInt64LE(8).toString()!==t.reservationAmountAtomic&&m("settle_voucher_amount"),S.readUInt8(16)!==1&&m("settle_voucher_increment"),new ne(S.subarray(17,49)).equals(s)||m("settle_voucher_seller"),g.accounts.length<8&&m("settle_voucher_accounts"),[o.toBase58(),null,c.toBase58(),null,i.toBase58(),y.toBase58(),p.toBase58(),v.toBase58()].forEach((a,x)=>{a!==null&&g.accounts[x]!==a&&m(`settle_voucher_account_${x}`)});let T=g.accounts[1];T||m("dexter_authority");let G=ge(n,g.accounts[0],"vault"),Z=ge(n,T,"dexter_authority"),re=ge(n,g.accounts[2],"session");(!G.writable||G.signer)&&m("vault_privileges"),Z.signer||m("dexter_authority_signature"),(!re.writable||re.signer)&&m("session_privileges");for(let a=3;a<Math.min(g.accounts.length,8);a+=1)ge(n,g.accounts[a],`account_${a}`).signer&&m(`settle_voucher_account_${a}_signer`);for(let a=8;a<g.accounts.length;a+=1){let x=ge(n,g.accounts[a],`sibling_${a-8}`);(!x.writable||x.signer)&&m("settle_voucher_sibling_privileges")}let F=n.instructions[1];F.programId!==rr.toBase58()&&m("reservation_memo_program"),(F.accounts.length!==1||F.accounts[0]!==T)&&m("reservation_memo_authority"),ge(n,T,"reservation_memo_authority").signer||m("reservation_memo_authority_signature");let d=new TextEncoder().encode(sn(t));return Fe(F.data,d)||m("reservation_memo_digest"),T}function ur(t,e,n,r){let i=M(t.programId,"program_id"),o=M(t.buyerSwigAddress,"buyer_swig"),s=M(t.vaultPda,"vault_pda"),c=M(t.seller,"seller"),[l,p]=Rt(o,i),[y,v]=Et(s,c,i);(!Number.isSafeInteger(r.contextSlot)||r.contextSlot<e)&&m("post_state_slot"),(r.binding.address!==l.toBase58()||r.binding.owner!==t.programId||r.binding.bump!==p||!ln(r.binding.version)||r.binding.swig!==t.buyerSwigAddress||r.binding.vault!==t.vaultPda)&&m("binding_identity"),(r.vault.owner!==t.programId||!r.vault.exists||r.vault.version!==7||r.vault.swigAddress!==t.buyerSwigAddress||r.vault.dexterAuthority!==n)&&m("vault_post_state"),(t.sessionPda!==y.toBase58()||r.session.owner!==t.programId||r.session.version!==1||r.session.bump!==v||r.session.vault!==t.vaultPda||r.session.sessionPublicKey!==xt(t.voucher.sessionPublicKey)||r.session.seller!==t.seller||r.session.nonce!==t.sessionNonce||r.session.currentOutstanding.toString()!==t.reservationAmountAtomic)&&m("session_post_state");let h=cr(t);(h.programId!==t.programId||h.vaultPda!==t.vaultPda||h.sessionPublicKey!==r.session.sessionPublicKey||h.seller!==t.seller||h.nonce!==t.sessionNonce||h.maxAmount!==r.session.maxAmount||h.expiresAt!==BigInt(r.session.expiresAt)||h.maxRevolvingCapacity!==r.session.maxRevolvingCapacity)&&m("registration_post_state");let f=r.session.spent>r.session.crystallizedCumulative?r.session.spent:r.session.crystallizedCumulative;return f.toString()!==t.previousCumulativeAtomic&&m("session_frontier"),{commitment:"confirmed",confirmationSlot:e,postStateSlot:r.contextSlot,sessionAccountVersion:r.session.version,wireVersion:2,frontierAtomic:f.toString(),spentAtomic:r.session.spent.toString(),currentOutstandingAtomic:r.session.currentOutstanding.toString(),crystallizedCumulativeAtomic:r.session.crystallizedCumulative.toString()}}async function un(t,e,n,r={}){try{Ct(e,n)}catch(c){return m("provider_receipt",c instanceof Error?c.message:String(c))}be(e.network)!==De&&m("network"),e.programId!==Xn.toBase58()&&m("program_id");let i=await(r.readTransaction??or)({connection:t,signature:n.transaction,commitment:"confirmed"});i||m("transaction_missing"),i.confirmationStatus!=="confirmed"&&i.confirmationStatus!=="finalized"&&m("transaction_commitment");let o=lr(e,n,i),s=await(r.readPostState??ar)({connection:t,input:e,minimumSlot:i.slot,commitment:"confirmed"});return{...ur(e,i.slot,o,s),commitment:i.confirmationStatus}}import{deriveSessionPda as fr}from"@dexterai/vault/session";import{bytesToHex as Pt}from"@noble/hashes/utils";var dr=15e3,mr=["claim_already_exists","non_monotonic_cumulative"],pr="below_lock_cadence";function qe(t){return typeof t=="string"&&t.includes(pr)}function gr(t){return`${t.slice(0,16)}\u2026`}function dn(t,e,n,r){let i=gr(t);if(r.crystallized){console.info(`[tab/seller] crystallize OK channel=${i} cumulative=${e} seq=${n}${r.claimPda?` claimPda=${r.claimPda}`:""} \u2014 LockVoucher landed`);return}if(r.error){if(qe(r.error)){console.warn(`[tab/seller] crystallize refused below the facilitator's cadence gate channel=${i} cumulative=${e} seq=${n}: ${r.error} \u2014 benign: this facilitator's cadence engine owns the protection cadence for the span; gate-refused watermark advanced, re-attempts after the next signed voucher`);return}if(mr.some(o=>r.error.includes(o))){console.warn(`[tab/seller] crystallize duplicate channel=${i} cumulative=${e} seq=${n}: ${r.error} \u2014 voucher already secured on-chain (benign, no action)`);return}console.error(`[tab/seller] crystallize FAILED channel=${i} cumulative=${e} seq=${n}: ${r.error} \u2014 lock NOT secured (degraded: best-effort path, no watermark advance, retries at next threshold/close; seller exposure stays unsecured until it lands)`)}}async function Vt(t,e,n,r,i=fetch){let o=t.lastVoucher;if(!o)return{crystallized:!1};if(o.payload.channelId!==e){let c={crystallized:!1,error:"channel_id_mismatch"};return dn(e,o.payload.cumulativeAmount,o.payload.sequenceNumber,c),c}let s=c=>(dn(e,o.payload.cumulativeAmount,o.payload.sequenceNumber,c),c);try{let c=`${n.replace(/\/$/,"")}/tab/lock`,l={channelId:o.payload.channelId,cumulativeAmount:o.payload.cumulativeAmount,sequenceNumber:o.payload.sequenceNumber,sessionPublicKey:Pt(o.sessionPublicKey),sessionSignature:Pt(o.sessionSignature),sessionRegistration:Pt(o.sessionRegistration),network:r},p=await i(c,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(l),signal:AbortSignal.timeout(dr)}),y=await p.text();if(!p.ok)return s({crystallized:!1,error:`tab lock ${p.status}: ${y.slice(0,200)}`});let v;try{let h=JSON.parse(y);h&&typeof h.claimPda=="string"&&(v=h.claimPda)}catch{}return s({crystallized:!0,claimPda:v})}catch(c){return s({crystallized:!1,error:String(c?.message??c)})}}async function mn(t,e,n,r,i,o={}){let s=BigInt(t.deliveredCumulativeAtomic),c=BigInt(t.lastCrystallizedCumulativeAtomic??"0"),l=BigInt(i.thresholdAtomic);if(s-c<l)return{crystallized:!1};let p=t.lastVoucher?.payload.cumulativeAmount,y=t.gateRefusedCumulativeAtomic;if(p!==void 0&&y!==void 0&&BigInt(p)<=BigInt(y))return{crystallized:!1};let v=await Vt(t,e,n,r,o.fetchImpl);return v.crystallized&&p!==void 0?(t.lastCrystallizedCumulativeAtomic=p,t.gateRefusedCumulativeAtomic=void 0):qe(v.error)&&p!==void 0&&(t.gateRefusedCumulativeAtomic=p),v}var ce="x-tab-voucher",We=class extends Error{constructor(){super("response terminated before tab admission completed"),this.name="ResponseTerminatedError"}};function yr(t){if(t!==void 0)return t;if(process.env.NODE_ENV==="test"||process.env.NODE_ENV==="development")return"development";throw new Error("tab seller ledgerSafetyMode must be explicit outside NODE_ENV=test/development; choose production-single-instance or production-multi-instance for deployment")}function vr(t,e){if(!["development","production-single-instance","production-multi-instance"].includes(e))throw new Error(`invalid tab seller ledgerSafetyMode: ${String(e)}`);let n=t.capabilities;if(!n||n.conditionalWrites!==!0)throw new Error("tab seller ledger must declare conditional owner-token/fence writes");if(e!=="development"&&!n.restartSafe)throw new Error(`tab seller ${e} requires restart-safe durable ledger state; ${n.adapter} is not restart-safe`);if(e!=="development"&&!n.canonicalChannelIds)throw new Error(`tab seller ${e} requires the legacy channel-id alias migration or an empty-store proof; ${n.adapter} has no canonical channel-id cutover acknowledgement`);if(e==="production-multi-instance"&&!n.multiInstanceSafe)throw new Error(`tab seller production-multi-instance requires cross-process atomic fencing; ${n.adapter} is single-instance only`)}var Tt=class{map=new Map;get(e){return this.map.get(e)}set(e,n){this.map.set(e,n)}deleteIfSame(e,n){this.map.get(e)===n&&this.map.delete(e)}update(e,n){let r=this.map.get(e);r&&(r.lastCumulativeAtomic=n)}delete(e){this.map.delete(e)}},It=class{constructor(e,n,r,i,o,s){this.recordDeliveredImpl=o;this.chargeImpl=s;this.channelId=e,this.network=n,this.cumulativeAtomic=r,this.deliveredBaselineAtomic=i}recordDeliveredImpl;chargeImpl;channelId;network;sessionPublicKey=null;cumulativeAtomic;deliveredBaselineAtomic;cumulative(){return se(this.cumulativeAtomic.toString())}deliveredCumulative(){return se(this.deliveredBaselineAtomic.toString())}async recordDelivered(e){return this.recordDeliveredImpl(e)}bumpCumulative(e){this.cumulativeAtomic=e}setSessionPublicKey(e){this.sessionPublicKey=e}async charge(e){return this.chargeImpl(e)}};function Ar(t){if(typeof t!="string"||t.length===0)throw new w("signature_invalid",`missing ${ce} header`);let e;try{e=Buffer.from(t,"base64").toString("utf8")}catch{throw new w("signature_invalid","malformed base64")}let n;try{n=JSON.parse(e)}catch{throw new w("signature_invalid","malformed JSON")}if(!n||typeof n!="object"||!n.payload||!n.sessionPublicKey)throw new w("signature_invalid","missing required fields");return{voucher:{payload:n.payload,sessionPublicKey:He(n.sessionPublicKey),sessionRegistration:He(n.sessionRegistration),sessionSignature:He(n.sessionSignature)},reservationReceipt:n.reservationReceipt}}function He(t){if(typeof t!="string"||t.length%2!==0)throw new w("signature_invalid",`bad hex: ${typeof t}`);let e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n++)e[n]=parseInt(t.substr(n*2,2),16);return e}function br(t){if(!/^[0-9a-f]{64}$/.test(t))throw new w("signature_invalid",`channelId must be canonical lowercase 64-char hex, got "${t}"`);return He(t)}function Nt(t){let e=t.ledger??new Ae,n=yr(t.ledgerSafetyMode);vr(e,n);let r=J(t.leaseTtlMs??3e5),i=new Tt,o=typeof t.sellerPubkey=="string"?new hr(t.sellerPubkey):t.sellerPubkey,s=t.maxPerVoucherAtomic?BigInt(t.maxPerVoucherAtomic):BigInt(H(t.perUnit))*100n,c=t.facilitatorUrl??an,l={thresholdAtomic:t.lockCadence?.thresholdAtomic??H("0.10"),onClose:t.lockCadence?.onClose??!0};return async(p,y,v)=>{let h=null,f=null,g=null,S=null,P=null,T=!1,G=async()=>{if(P)throw P},Z=async()=>{if(!f||f.releaseStarted)return;let _=f;_.releaseStarted=!0,g&&(clearInterval(g),g=null),S&&await S.catch(()=>{});try{await e.releaseLease(_.channelId,f?.lease??_.lease)}catch(d){throw _.releaseStarted=!1,d}},re=()=>{T||(T=!0,setImmediate(()=>{Z().catch(_=>{console.error("[tab/seller] failed to release channel lease on response termination:",_)})}))},F=()=>{if(T)throw new We};y.on("close",re),y.on("finish",re);try{let _=Ar(p.headers[ce]),d=_.voucher,a=d.payload.channelId,x=br(a),A=i.get(a),O=null,K,it=!1;if(A){if(!ae(A.registrationBytes,d.sessionRegistration))throw new I("voucher registration does not match the channel's verified registration")}else{it=!0;let u=Ke(d.sessionRegistration);te(u.nonce)===1&&(K=await At(t.connection,u),O=K?.frontierAtomic??null);let C=await e.get(a);A={registration:u,registrationBytes:d.sessionRegistration.slice(),lastCumulativeAtomic:C?.lastVoucher?.payload.cumulativeAmount??"0"}}let q=te(A.registration.nonce),Ut=te(d.payload.sequenceNumber);if(Ut!==q)throw new w("wire_version_mismatch",`voucher is V${Ut}, active registration is V${q}`);let he;if(q===2){if(_.reservationReceipt===void 0)throw new w("reservation_proof_missing","Native Tab V2 requires the verified reservation receipt in the voucher envelope");if(_.reservationReceipt===null||typeof _.reservationReceipt!="object"||Array.isArray(_.reservationReceipt))throw new w("reservation_proof_invalid","reservationReceipt must be an object");he=_.reservationReceipt}bt(d,x);let k=BigInt(d.payload.cumulativeAmount),j=BigInt(A.lastCumulativeAtomic),fe=null,X=null,ot=null;if(q===2){if(!he)throw new w("reservation_proof_missing","Native Tab V2 reservation proof was not carried through admission");if(X=ze(he.reservationAmountAtomic,"receipt.reservationAmountAtomic"),X<=0n||X>k)throw new w("reservation_mismatch","reservation amount does not fit the voucher cumulative");let u=k-X,[C]=fr(A.registration.vaultPda,A.registration.allowedCounterparty,A.registration.programId),R=_t(d);try{let U=await un(t.connection,{network:t.network,programId:A.registration.programId.toBase58(),buyerSwigAddress:he.buyerSwigAddress,vaultPda:A.registration.vaultPda.toBase58(),sessionPda:C.toBase58(),seller:A.registration.allowedCounterparty.toBase58(),channelId:a,sessionNonce:A.registration.nonce,reservationAmountAtomic:X.toString(),previousCumulativeAtomic:u.toString(),...R,voucher:d},he);K=U,O=U.frontierAtomic}catch(U){throw U instanceof we?new w("reservation_proof_invalid",U.message):U}if(K?.wireVersion!==2)throw new w("wire_version_mismatch",`active SessionAccount is V${K?.wireVersion??"unknown"}, voucher is V2`);if(K.sessionAccountVersion!==1||O===null||K.currentOutstandingAtomic===void 0)throw new w("reservation_mismatch","authoritative V2 SessionAccount reservation evidence is incomplete");let b=ze(O,"frontierAtomic");if(b>j&&(j=b),k<=j)throw new w("voucher_already_covered",`cumulative ${k} is not above covered frontier ${j}`);fe=k-j;let B=ze(K.currentOutstandingAtomic,"currentOutstandingAtomic");if(ot=B,B!==fe)throw new w("reservation_mismatch",`currentOutstanding ${B} does not equal voucher delta ${fe}`);if(X!==fe)throw new w("reservation_mismatch",`receipt reservation ${X} does not equal voucher delta ${fe}`)}let Cn=q===1&&k===j;$e({registration:A.registration,voucher:d,expectedCounterparty:o,previousCumulativeAtomic:Cn?void 0:j.toString()});let ie=k-j;if(ie>s)throw new L("cumulative_exceeds_cap",`single voucher increment ${ie} exceeds maxPerVoucherAtomic ${s}`);if(it){let u=i.get(a);if(u){if(!ae(u.registrationBytes,A.registrationBytes))throw new I("voucher registration lost the channel admission race to a different verified registration");if(BigInt(u.lastCumulativeAtomic)>BigInt(A.lastCumulativeAtomic))throw new L("non_monotonic","channel admission advanced while reservation proof was in flight");A=u}}F();let ye=await e.tryAcquireLease(a,r);if(!ye)throw new w("channel_busy","another stream is live on this channel; tabs serve one stream at a time");f={channelId:a,lease:ye,releaseStarted:!1},F();let Kt=Math.max(1,Math.floor(r/3)),$t=async()=>{if(P)throw P;if(!f||f.releaseStarted)throw new D(a);return S||(S=(async()=>{let u=await e.renewLease(a,f.lease,r);f&&!f.releaseStarted&&(f.lease=u)})().catch(u=>{let C=u instanceof Error?u:new Error(String(u));throw P=C,console.error(`[tab/seller] channel lease renewal FAILED channel=${a.slice(0,16)}\u2026; stream terminated before further delivery:`,C),typeof y.destroy=="function"&&y.destroy(C),C}).finally(()=>{S=null}),S)};G=async()=>{if(P)throw P;if(!f||f.releaseStarted)throw new D(a);f.lease.heldUntilUnixMs-Date.now()<=Kt&&await $t()},g=setInterval(()=>{$t().catch(()=>{})},Kt),g.unref?.();let ve=await e.get(a);if(F(),ve?.lastVoucher&&!ae(ve.lastVoucher.sessionRegistration,d.sessionRegistration))throw new I("durable channel registration changed while reservation proof was in flight");let Mt=BigInt(ve?.lastVoucher?.payload.cumulativeAmount??"0"),z=BigInt(A.lastCumulativeAtomic);if(Mt>z&&(z=Mt),q===2&&O!==null){let u=ze(O,"frontierAtomic");u>z&&(z=u)}let Dt=q===1&&k===z;if(k<z||q===2&&k===z)throw new w(q===2?"voucher_already_covered":"non_monotonic",`cumulative ${k} is not above post-lease covered frontier ${z}`);if(Dt){let u=ve?.lastVoucher;if(!u||BigInt(u.payload.cumulativeAmount)!==k||d.payload.sequenceNumber<=u.payload.sequenceNumber)throw new w("non_monotonic","same-cumulative V1 reconnect requires a strictly newer sequence than the durable voucher")}if($e({registration:A.registration,voucher:d,expectedCounterparty:o,previousCumulativeAtomic:Dt?void 0:z.toString()}),ie=k-z,ie>s)throw new L("cumulative_exceeds_cap",`post-lease voucher increment ${ie} exceeds maxPerVoucherAtomic ${s}`);if(q===2&&(X===null||ot===null||X!==ie||ot!==ie))throw new w("reservation_mismatch","durable channel frontier advanced while reservation proof was in flight");if(j=z,it){let u=i.get(a);if(u){if(!ae(u.registrationBytes,A.registrationBytes))throw await Z(),new I("voucher registration lost the channel lease race to a different verified registration");A=u}else i.set(a,A),h={channelId:a,entry:A}}let st=async u=>{try{return await e.update(a,ye,u)}catch(C){if(!(C instanceof D))throw C;let R=await e.tryAcquireLease(a,Math.min(r,15e3));if(!R)throw C;try{return await e.update(a,R,u)}finally{await e.releaseLease(a,R)}}},xn=async u=>{let C=u.lastCrystallizedCumulativeAtomic??"0",R=u.gateRefusedCumulativeAtomic;await mn(u,a,c,t.network,l),(u.lastCrystallizedCumulativeAtomic!==C||u.gateRefusedCumulativeAtomic!==R)&&await st(b=>{if(!b)throw new Error("channel ledger entry missing during crystallize persist");let B=BigInt(b.lastCrystallizedCumulativeAtomic??"0")>=BigInt(u.lastCrystallizedCumulativeAtomic??"0")?b.lastCrystallizedCumulativeAtomic??"0":u.lastCrystallizedCumulativeAtomic??"0",ue=[b.gateRefusedCumulativeAtomic,u.gateRefusedCumulativeAtomic].filter(de=>de!==void 0).reduce((de,jt)=>de===void 0||BigInt(jt)>BigInt(de)?jt:de,void 0);return{...b,lastCrystallizedCumulativeAtomic:B,gateRefusedCumulativeAtomic:ue!==void 0&&BigInt(ue)>BigInt(B)?ue:void 0}}).catch(b=>{console.error(`[tab/seller] crystallize watermark persist FAILED channel=${a.slice(0,16)}\u2026 (expect a benign duplicate/below-cadence warn on the next request):`,b)})},Ft=Promise.resolve(),qt=u=>{let C=Ft.then(u,u);return Ft=C.catch(()=>{}),C},zt=!1,Ht=()=>{!l.onClose||zt||(zt=!0,qt(async()=>{let u=await e.get(a);if(!u||!u.lastVoucher)return;let C=u.lastVoucher.payload.cumulativeAmount;if(u.gateRefusedCumulativeAtomic!==void 0&&BigInt(C)<=BigInt(u.gateRefusedCumulativeAtomic))return;let R=await Vt(u,a,c,t.network);R.crystallized?await st(b=>{if(!b)throw new Error("channel ledger entry missing during close crystallize");let B=BigInt(b.lastCrystallizedCumulativeAtomic??"0")>=BigInt(C)?b.lastCrystallizedCumulativeAtomic??"0":C;return{...b,lastCrystallizedCumulativeAtomic:B,gateRefusedCumulativeAtomic:b.gateRefusedCumulativeAtomic!==void 0&&BigInt(b.gateRefusedCumulativeAtomic)>BigInt(B)?b.gateRefusedCumulativeAtomic:void 0}}):qe(R.error)&&await st(b=>{if(!b)throw new Error("channel ledger entry missing during close refusal persist");let B=BigInt(b.lastCrystallizedCumulativeAtomic??"0"),U=b.gateRefusedCumulativeAtomic!==void 0&&BigInt(b.gateRefusedCumulativeAtomic)>=BigInt(C)?b.gateRefusedCumulativeAtomic:C;return{...b,gateRefusedCumulativeAtomic:BigInt(U)>B?U:void 0}})}).catch(u=>{console.error(`[tab/seller] close-path crystallize CRASHED channel=${a.slice(0,16)}\u2026 (final voucher NOT locked; exposure unsecured until the next request retries):`,u)}))};y.on("close",Ht),y.on("finish",Ht);let Le=ve,Wt=BigInt(Le?.deliveredCumulativeAtomic??"0"),Rn=!Le?.lastVoucher&&Wt===0n,at=O===null?null:BigInt(O),le=at!==null&&at>Wt&&(q===2||Rn)?at.toString():null;le!==null&&console.info(`[tab/seller] channel ${a.slice(0,16)}\u2026 resumed: seeding delivered baseline from chain frontier ${le} (session already settled/locked up to it \u2014 that span is not deliverable budget)`);let En=le!==null?BigInt(le):Le?BigInt(Le.deliveredCumulativeAtomic):0n;await e.update(a,ye,u=>({...u??{},lastVoucher:d,deliveredCumulativeAtomic:le??(u?u.deliveredCumulativeAtomic:"0"),lastCrystallizedCumulativeAtomic:le??u?.lastCrystallizedCumulativeAtomic??"0"})),h=null,F(),i.update(a,d.payload.cumulativeAmount);let Gt=new It(a,t.network,k,En,async u=>{await G();let C=null;C=await e.update(a,ye,R=>{if(!R?.lastVoucher||!wr(R.lastVoucher,d))throw new I("durable voucher identity changed before delivery accounting");let b=BigInt(R.deliveredCumulativeAtomic),B=BigInt(u),U=B>0n?b+B:b,ue=BigInt(R.lastVoucher.payload.cumulativeAmount);if(U>ue)throw new L("cumulative_exceeds_cap",`durable delivered cumulative ${U} exceeds signed cumulative ${ue}`);return{...R,lastVoucher:R.lastVoucher,deliveredCumulativeAtomic:U.toString(),lastCrystallizedCumulativeAtomic:R.lastCrystallizedCumulativeAtomic??"0"}}),C&&qt(async()=>{let R=await e.get(a);R&&await xn(R)}).catch(R=>{console.error(`[tab/seller] crystallize cadence CRASHED channel=${a.slice(0,16)}\u2026 (threshold lock not attempted; retries at the next delivery):`,R)})},async u=>{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.")});Gt.setSessionPublicKey(d.sessionPublicKey),p.tab=Gt,v()}catch(_){if(f&&!f.releaseStarted&&await Z().catch(d=>{console.error("[tab/seller] failed to release channel lease after request error:",d)}),h&&i.deleteIfSame(h.channelId,h.entry),_ instanceof We)return;if(_ instanceof w||_ instanceof W||_ instanceof $||_ instanceof I||_ instanceof L){y.status(402).json({error:"invalid_voucher",reason:_.reason??"unknown",detail:_.message});return}v(_)}}}function ae(t,e){if(t.length!==e.length)return!1;let n=0;for(let r=0;r<t.length;r+=1)n|=t[r]^e[r];return n===0}function wr(t,e){return t.payload.channelId===e.payload.channelId&&t.payload.cumulativeAmount===e.payload.cumulativeAmount&&t.payload.sequenceNumber===e.payload.sequenceNumber&&ae(t.sessionPublicKey,e.sessionPublicKey)&&ae(t.sessionRegistration,e.sessionRegistration)&&ae(t.sessionSignature,e.sessionSignature)}function ze(t,e){if(!/^(0|[1-9][0-9]*)$/.test(t))throw new w("reservation_mismatch",`authoritative ${e} is not a canonical atomic amount`);return BigInt(t)}function Sr(t){if(!t.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return t.tab}function _r(t,e){if(!e.tab)throw new Error("openSse requires options.tab");t.headersSent||(t.setHeader("Content-Type","text/event-stream"),t.setHeader("Cache-Control","no-cache"),t.setHeader("Connection","keep-alive"),typeof t.flushHeaders=="function"&&t.flushHeaders());let n=e.tab,r=BigInt(H(n.cumulative())),i=BigInt(H(n.deliveredCumulative())),o=r-i;o<0n&&(o=0n);let s=e.perUnit?BigInt(H(e.perUnit)):null,c=0n,l=!1,p=0,y=Promise.resolve();t.prependListener("close",()=>{l||(l=!0)});function v(g=1){if(l)return Promise.reject(new Error("meter ended"));if(s===null)return Promise.reject(new Error("charge() needs options.perUnit"));if(!Number.isSafeInteger(g)||g<=0)return Promise.reject(new Error("charge() units must be a positive safe integer"));let S=s*BigInt(g);p+=1;let P=y.then(async()=>{if(l)throw new Error("meter ended");let T=c+S;if(T>o)throw l=!0,new L("cumulative_exceeds_cap",`chunk would push delivered to ${se((i+T).toString())} beyond signed cumulative ${se(r.toString())} (per-request budget ${se(o.toString())})`);try{await n.recordDelivered(S.toString()),c=T}catch(G){throw l=!0,G}});return y=P.catch(()=>{}),P.finally(()=>{p-=1})}function h(g){if(l)throw new Error("meter ended");if(p>0)throw new Error("charge still pending; await meter.charge() before send()");let P=(typeof g=="string"?g:Buffer.from(g).toString("utf8")).replace(/\\/g,"\\\\").replace(/\n/g,"\\n");t.write(`data: ${P}
|
|
23
23
|
|
|
24
24
|
`)}async function f(){l||(l=!0,t.write(`event: end
|
|
25
25
|
data: {"chargedAtomic":"${c}"}
|
|
26
26
|
|
|
27
|
-
`),t.end())}return{charge:v,send:h,end:f}}import{promises as we}from"fs";import{join as Cr,dirname as xr}from"path";function Rr(t){return{payload:t.payload,sessionPublicKey:Nt(t.sessionPublicKey),sessionRegistration:Nt(t.sessionRegistration),sessionSignature:Nt(t.sessionSignature)}}function Er(t){return{payload:t.payload,sessionPublicKey:Lt(t.sessionPublicKey),sessionRegistration:Lt(t.sessionRegistration),sessionSignature:Lt(t.sessionSignature)}}function Nt(t){let e="";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}function Lt(t){if(t.length%2!==0)throw new Error(`hex length must be even, got ${t.length}`);let e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n++)e[n]=parseInt(t.substr(n*2,2),16);return e}var Ot=class{map=new Map;async get(e){return this.map.get(e)??null}async set(e,n){this.map.set(e,n)}async delete(e){this.map.delete(e)}},kt=class{constructor(e){this.dir=e}dir;pathFor(e){if(!/^[a-z0-9_-]+$/i.test(e))throw new Error(`unsafe channelId for filesystem: ${e}`);return Cr(this.dir,`${e}.json`)}async get(e){try{let n=await we.readFile(this.pathFor(e),"utf8");return Er(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(e,n){let r=this.pathFor(e);await we.mkdir(xr(r),{recursive:!0});let i=`${r}.tmp`;await we.writeFile(i,JSON.stringify(Rr(n))),await we.rename(i,r)}async delete(e){try{await we.unlink(this.pathFor(e))}catch(n){if(n?.code!=="ENOENT")throw n}}};import{PublicKey as kr}from"@solana/web3.js";var Y="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",pn="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",gn="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var Se="eip155:8453",He="eip155:84532",We="eip155:42161",Ge="eip155:137",je="eip155:10",Xe="eip155:43114",Je="eip155:56",_e="eip155:480",Ce="eip155:143",xe="eip155:4663",Re="eip155:1187947933",Ee="eip155:324705682",Ye="eip155:1";var Ze="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var hn="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Pr="0x55d398326f99059fF775485246999027B3197955",fn="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Vr="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",yn={[Je]:fn,[Se]:hn,[He]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[We]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Ge]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[je]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[Xe]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[_e]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[Ce]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[xe]:Vr,[Re]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Ee]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Ye]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},vn={[Pr]:{symbol:"USDT",decimals:18},[fn]:{symbol:"USDC",decimals:18}};var Mo={[_e]:{name:"USDC",version:"2"},[Ce]:{name:"USDC",version:"2"},[xe]:{name:"Global Dollar",version:"1"},[Re]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Ee]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}};var Do={[Je]:56,[Se]:8453,[He]:84532,[We]:42161,[Ge]:137,[je]:10,[Xe]:43114,[_e]:480,[Ce]:143,[xe]:4663,[Re]:1187947933,[Ee]:324705682,[Ye]:1},Fo={[Y]:"https://api.dexter.cash/api/solana/rpc",[pn]:"https://api.devnet.solana.com",[gn]:"https://api.testnet.solana.com"},Tr={[Je]:"https://api.dexter.cash/api/evm/bsc/rpc",[Se]:"https://api.dexter.cash/api/base/rpc",[He]:"https://sepolia.base.org",[We]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Ge]:"https://api.dexter.cash/api/evm/polygon/rpc",[je]:"https://api.dexter.cash/api/evm/optimism/rpc",[Xe]:"https://api.dexter.cash/api/evm/avalanche/rpc",[_e]:"https://worldchain-mainnet.g.alchemy.com/public",[Ce]:"https://rpc.monad.xyz",[xe]:"https://rpc.mainnet.chain.robinhood.com",[Re]:"https://skale-base.skalenodes.com/v1/base",[Ee]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Ye]:"https://eth.llamarpc.com"},Pe="https://x402.dexter.cash";var An="dexter-tab-hosted-pay-before-delivery/v1",bn="pay_before_delivery_seller_2xx",wn="x-tab-voucher",Sn="base64(188-byte sessionRegisterMessage)";function Qe(t){return t.startsWith("solana:")||t==="solana"}function Ir(t){if(typeof Buffer<"u")return Buffer.from(t,"utf-8").toString("base64");let e=new TextEncoder().encode(t),n="";for(let r=0;r<e.length;r++)n+=String.fromCharCode(e[r]);return btoa(n)}function Nr(t){if(typeof Buffer<"u")return Buffer.from(t,"base64").toString("utf-8");let e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r++)n[r]=e.charCodeAt(r);return new TextDecoder().decode(n)}function et(t){return Ir(JSON.stringify(t))}function Ve(t){return JSON.parse(Nr(t))}function Lr(t){if(t instanceof TypeError)return!0;if(t&&typeof t=="object"&&"status"in t){let e=t.status;return e>=500&&e<600}return!1}var Te=class extends Error{status;body;constructor(e,n){super(`HTTP ${e}`),this.status=e,this.body=n}},tt=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(e=Pe,n){this.facilitatorUrl=e.replace(/\/$/,""),this.timeoutMs=n?.timeoutMs??1e4,this.maxRetries=n?.maxRetries??3,this.retryBaseMs=n?.retryBaseMs??500}async fetchWithTimeout(e,n){let r=new AbortController,i=setTimeout(()=>r.abort(),this.timeoutMs);try{return await fetch(e,{...n,signal:r.signal})}finally{clearTimeout(i)}}async fetchWithRetry(e,n){let r;for(let i=0;i<this.maxRetries;i++)try{let o=await this.fetchWithTimeout(e,n);if(!o.ok&&o.status>=500)throw new Te(o.status,await o.text());return o}catch(o){if(r=o,i<this.maxRetries-1&&Lr(o)){let s=this.retryBaseMs*Math.pow(2,i);await new Promise(c=>setTimeout(c,s));continue}throw o}throw r}async getSupported(){let e=Date.now();if(this.cachedSupported&&e-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let n=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!n.ok)throw new Error(`Facilitator /supported returned ${n.status}`);return this.cachedSupported=await n.json(),this.cacheTime=e,this.cachedSupported}async getFeePayer(e){let r=(await this.getSupported()).kinds.find(i=>i.x402Version===2&&(i.scheme==="exact"||i.scheme==="exact-approval")&&i.network===e);if(!r)throw new Error(`Facilitator does not support network "${e}" with a recognized scheme`);return r.extra?.feePayer}async getNetworkExtra(e){return(await this.getSupported()).kinds.find(i=>i.x402Version===2&&(i.scheme==="exact"||i.scheme==="exact-approval"||i.scheme==="batch-settlement")&&i.network===e)?.extra}async verifyPayment(e,n){try{let r=Ve(e),i=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return i.ok?await i.json():{isValid:!1,invalidReason:`facilitator_error_${i.status}`}}catch(r){return{isValid:!1,invalidReason:r instanceof Te?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_verify_error"}}}async settlePayment(e,n){try{let r=Ve(e),i=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return i.ok?{...await i.json(),network:n.network}:{success:!1,network:n.network,errorReason:`facilitator_error_${i.status}`}}catch(r){let i=r instanceof Te?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_settle_error";return{success:!1,network:n.network,errorReason:i}}}};function Or(t){if(Qe(t))return{address:Ze,decimals:6};let e=yn[t];if(e){let n=vn[e]?.decimals??6;return{address:e,decimals:n}}return{address:Ze,decimals:6}}function _n(t){try{let e=Ve(t);return e?.accepted?.amount??e?.accepted?.maxAmountRequired}catch{return}}function Ie(t){let{payTo:e,facilitatorUrl:n=Pe,network:r=Y,defaultTimeoutSeconds:i=60}=t,o=t.asset??Or(r),s=t.scheme??"exact";if(s==="tab"&&!Qe(r))throw new Error(`scheme 'tab' is SVM-only; got network "${r}"`);let c=new tt(n),l=null,p=new Map,y=3e4,v=Date.now();function h(d){let a=(d.maxTimeoutSeconds||i)*1e3;if(p.set(d.payTo,{accept:d,expiresAt:Date.now()+a}),Date.now()-v>y){let x=Date.now();for(let[A,O]of p)O.expiresAt<x&&p.delete(A);v=x}}function f(d){let a=p.get(d);if(a){if(a.expiresAt<Date.now()){p.delete(d);return}return a.accept}}async function g(d){return typeof e=="string"?e:e(d||{})}async function S(){if(l||(l=await c.getNetworkExtra(r)),Qe(r)&&!l?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${r}"`);return{...l?.feePayer?{feePayer:l.feePayer}:{},decimals:l?.decimals??o.decimals,name:l?.name,version:l?.version,...s==="batch-settlement"&&l?.receiverAuthorizer?{receiverAuthorizer:l.receiverAuthorizer}:{},...s==="tab"?{voucherHeader:wn,registrationEncoding:Sn,termsVersion:An,acceptanceRule:bn}:{}}}async function P(d,a){let{amountAtomic:x,timeoutSeconds:A=i}=a,O=await S(),K={scheme:s,network:r,amount:x,maxAmountRequired:x,asset:o.address,payTo:d,maxTimeoutSeconds:A,extra:O};return h(K),K}async function T(d){let a=await g({amountAtomic:d.amountAtomic,resourceUrl:d.resourceUrl});return P(a,d)}async function G(d){let{resourceUrl:a,description:x,mimeType:A="application/json"}=d,O={url:a,description:x,mimeType:A},K=await T(d);return{x402Version:2,resource:O,accepts:[K],error:"Payment required"}}function Z(d){return et(d)}function re(d){return{status:402,headers:{"PAYMENT-REQUIRED":Z(d)},body:{}}}async function F(d,a){if(!a){let x=await g({paymentHeader:d});a=f(x),a||(a=await P(x,{amountAtomic:_n(d)??"0",resourceUrl:""}))}return c.verifyPayment(d,a)}async function _(d,a){if(!a){let x=await g({paymentHeader:d});a=f(x),a||(a=await P(x,{amountAtomic:_n(d)??"0",resourceUrl:""}))}return c.settlePayment(d,a)}return{buildRequirements:G,encodeRequirements:Z,create402Response:re,verifyPayment:F,settlePayment:_,getPaymentAccept:T,network:r,assetDecimals:o.decimals,facilitator:c}}var Br={"solana:mainnet":Y};function Ur(t){let e=Br[t.network];if(!e)throw new Error(`tabChallengeMiddleware: unsupported network "${t.network}"`);let n=typeof t.sellerPubkey=="string"?t.sellerPubkey:t.sellerPubkey.toBase58();new kr(n);let r=Ie({payTo:n,network:e,scheme:"tab",facilitatorUrl:t.facilitatorUrl}),i=H(t.perUnit);return async(o,s,c)=>{if(o.headers[ce])return c();try{let l=`${o.protocol}://${o.get("host")}${o.originalUrl}`,p=await r.buildRequirements({amountAtomic:i,resourceUrl:l,description:t.description}),y=r.create402Response(p);s.set(y.headers).status(y.status).json(y.body)}catch(l){let p=l?.message??String(l);s.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:p})}}}import{PublicKey as Kr}from"@solana/web3.js";var $r={"solana:mainnet":Y};function Mr(t){let e=$r[t.network];if(!e)throw new Error(`tabOrExactMiddleware: unsupported network "${t.network}"`);let n=typeof t.sellerPubkey=="string"?t.sellerPubkey:t.sellerPubkey.toBase58();new Kr(n);let r=Ie({payTo:n,network:e,scheme:"tab",facilitatorUrl:t.facilitatorUrl}),i=Ie({payTo:n,network:e,scheme:"exact",facilitatorUrl:t.facilitatorUrl}),o=H(t.perUnit),s=It({connection:t.connection,sellerPubkey:n,network:t.network,perUnit:t.perUnit,settle:"on-close",facilitatorUrl:t.facilitatorUrl,ledger:t.ledger,ledgerSafetyMode:t.ledgerSafetyMode,leaseTtlMs:t.leaseTtlMs,lockCadence:t.lockCadence});return async(c,l,p)=>{if(c.headers[ce])return s(c,l,p);let y=`${c.protocol}://${c.get("host")}${c.originalUrl}`,v=c.headers["payment-signature"];if(v){let h;try{h=await i.getPaymentAccept({amountAtomic:o,resourceUrl:y,description:t.description})}catch(f){let g=f?.message??String(f);l.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:g});return}try{let f=await i.verifyPayment(v,h);if(!f.isValid){l.status(402).json({error:"Payment verification failed",reason:f.invalidReason});return}let g=await i.settlePayment(v,h);if(!g.success){l.status(402).json({error:"Payment settlement failed",reason:g.errorReason});return}return c.x402={transaction:g.transaction,payer:f.payer??"",network:g.network||e},l.setHeader("PAYMENT-RESPONSE",et({success:!0,transaction:g.transaction,network:g.network||e,payer:f.payer??""})),p()}catch{l.status(500).json({error:"Payment processing error"});return}}try{let h={amountAtomic:o,resourceUrl:y,description:t.description},[f,g]=await Promise.all([r.buildRequirements(h),i.buildRequirements(h)]),S={...f,accepts:[...f.accepts,...g.accepts]};l.set({"PAYMENT-REQUIRED":r.encodeRequirements(S)}).status(402).json({error:"Payment required",accepts:S.accepts,resource:S.resource})}catch(h){let f=h?.message??String(h);l.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:f})}}}export{D as ChannelLeaseLostError,lt as FileChannelLedger,kt as FileVoucherStore,Ae as InMemoryChannelLedger,Ot as InMemoryVoucherStore,W as InvalidRegistrationError,w as InvalidVoucherError,I as InvalidVoucherSignatureError,$ as OnChainVerificationError,pt as RedisChannelLedger,ke as RedisKeyspaceMigrationRequiredError,L as ScopeViolationError,ce as TAB_VOUCHER_HEADER,mt as deserializeChannelLedgerEntry,Ke as enforceScope,_r as openSse,Ue as parseRegistration,Sr as requireTab,dt as serializeChannelLedgerEntry,Ur as tabChallengeMiddleware,It as tabMiddleware,Mr as tabOrExactMiddleware,yt as verifyRegistrationOnChain,vt as verifyVoucherSignature};
|
|
27
|
+
`),t.end())}return{charge:v,send:h,end:f}}import{promises as Se}from"fs";import{join as Cr,dirname as xr}from"path";function Rr(t){return{payload:t.payload,sessionPublicKey:Lt(t.sessionPublicKey),sessionRegistration:Lt(t.sessionRegistration),sessionSignature:Lt(t.sessionSignature)}}function Er(t){return{payload:t.payload,sessionPublicKey:Ot(t.sessionPublicKey),sessionRegistration:Ot(t.sessionRegistration),sessionSignature:Ot(t.sessionSignature)}}function Lt(t){let e="";for(let n of t)e+=n.toString(16).padStart(2,"0");return e}function Ot(t){if(t.length%2!==0)throw new Error(`hex length must be even, got ${t.length}`);let e=new Uint8Array(t.length/2);for(let n=0;n<e.length;n++)e[n]=parseInt(t.substr(n*2,2),16);return e}var kt=class{map=new Map;async get(e){return this.map.get(e)??null}async set(e,n){this.map.set(e,n)}async delete(e){this.map.delete(e)}},Bt=class{constructor(e){this.dir=e}dir;pathFor(e){if(!/^[a-z0-9_-]+$/i.test(e))throw new Error(`unsafe channelId for filesystem: ${e}`);return Cr(this.dir,`${e}.json`)}async get(e){try{let n=await Se.readFile(this.pathFor(e),"utf8");return Er(JSON.parse(n))}catch(n){if(n?.code==="ENOENT")return null;throw n}}async set(e,n){let r=this.pathFor(e);await Se.mkdir(xr(r),{recursive:!0});let i=`${r}.tmp`;await Se.writeFile(i,JSON.stringify(Rr(n))),await Se.rename(i,r)}async delete(e){try{await Se.unlink(this.pathFor(e))}catch(n){if(n?.code!=="ENOENT")throw n}}};import{PublicKey as kr}from"@solana/web3.js";var Y="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",pn="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",gn="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var _e="eip155:8453",Ge="eip155:84532",je="eip155:42161",Xe="eip155:137",Je="eip155:10",Ye="eip155:43114",Ze="eip155:56",Ce="eip155:480",xe="eip155:143",Re="eip155:4663",Ee="eip155:1187947933",Pe="eip155:324705682",Qe="eip155:1";var et="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var hn="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Pr="0x55d398326f99059fF775485246999027B3197955",fn="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Vr="0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168",yn={[Ze]:fn,[_e]:hn,[Ge]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[je]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Xe]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[Je]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[Ye]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[Ce]:"0x79A02482A880bCE3F13e09Da970dC34db4CD24d1",[xe]:"0x754704Bc059F8C67012fEd69BC8A327a5aafb603",[Re]:Vr,[Ee]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[Pe]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[Qe]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},vn={[Pr]:{symbol:"USDT",decimals:18},[fn]:{symbol:"USDC",decimals:18}};var Mo={[Ce]:{name:"USDC",version:"2"},[xe]:{name:"USDC",version:"2"},[Re]:{name:"Global Dollar",version:"1"},[Ee]:{name:"Bridged USDC (SKALE Bridge)",version:"2"},[Pe]:{name:"Bridged USDC (SKALE Bridge)",version:"2"}};var Do={[Ze]:56,[_e]:8453,[Ge]:84532,[je]:42161,[Xe]:137,[Je]:10,[Ye]:43114,[Ce]:480,[xe]:143,[Re]:4663,[Ee]:1187947933,[Pe]:324705682,[Qe]:1},Fo={[Y]:"https://api.dexter.cash/api/solana/rpc",[pn]:"https://api.devnet.solana.com",[gn]:"https://api.testnet.solana.com"},Tr={[Ze]:"https://api.dexter.cash/api/evm/bsc/rpc",[_e]:"https://api.dexter.cash/api/base/rpc",[Ge]:"https://sepolia.base.org",[je]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Xe]:"https://api.dexter.cash/api/evm/polygon/rpc",[Je]:"https://api.dexter.cash/api/evm/optimism/rpc",[Ye]:"https://api.dexter.cash/api/evm/avalanche/rpc",[Ce]:"https://worldchain-mainnet.g.alchemy.com/public",[xe]:"https://rpc.monad.xyz",[Re]:"https://rpc.mainnet.chain.robinhood.com",[Ee]:"https://skale-base.skalenodes.com/v1/base",[Pe]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[Qe]:"https://eth.llamarpc.com"},Ve="https://x402.dexter.cash";var An="dexter-tab-hosted-pay-before-delivery/v1",bn="pay_before_delivery_seller_2xx",wn="x-tab-voucher",Sn="base64(188-byte sessionRegisterMessage)";function tt(t){return t.startsWith("solana:")||t==="solana"}function Ir(t){if(typeof Buffer<"u")return Buffer.from(t,"utf-8").toString("base64");let e=new TextEncoder().encode(t),n="";for(let r=0;r<e.length;r++)n+=String.fromCharCode(e[r]);return btoa(n)}function Nr(t){if(typeof Buffer<"u")return Buffer.from(t,"base64").toString("utf-8");let e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r++)n[r]=e.charCodeAt(r);return new TextDecoder().decode(n)}function nt(t){return Ir(JSON.stringify(t))}function Te(t){return JSON.parse(Nr(t))}function Lr(t){if(t instanceof TypeError)return!0;if(t&&typeof t=="object"&&"status"in t){let e=t.status;return e>=500&&e<600}return!1}var Ie=class extends Error{status;body;constructor(e,n){super(`HTTP ${e}`),this.status=e,this.body=n}},rt=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(e=Ve,n){this.facilitatorUrl=e.replace(/\/$/,""),this.timeoutMs=n?.timeoutMs??1e4,this.maxRetries=n?.maxRetries??3,this.retryBaseMs=n?.retryBaseMs??500}async fetchWithTimeout(e,n){let r=new AbortController,i=setTimeout(()=>r.abort(),this.timeoutMs);try{return await fetch(e,{...n,signal:r.signal})}finally{clearTimeout(i)}}async fetchWithRetry(e,n){let r;for(let i=0;i<this.maxRetries;i++)try{let o=await this.fetchWithTimeout(e,n);if(!o.ok&&o.status>=500)throw new Ie(o.status,await o.text());return o}catch(o){if(r=o,i<this.maxRetries-1&&Lr(o)){let s=this.retryBaseMs*Math.pow(2,i);await new Promise(c=>setTimeout(c,s));continue}throw o}throw r}async getSupported(){let e=Date.now();if(this.cachedSupported&&e-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let n=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!n.ok)throw new Error(`Facilitator /supported returned ${n.status}`);return this.cachedSupported=await n.json(),this.cacheTime=e,this.cachedSupported}async getFeePayer(e){let r=(await this.getSupported()).kinds.find(i=>i.x402Version===2&&(i.scheme==="exact"||i.scheme==="exact-approval")&&i.network===e);if(!r)throw new Error(`Facilitator does not support network "${e}" with a recognized scheme`);return r.extra?.feePayer}async getNetworkExtra(e){return(await this.getSupported()).kinds.find(i=>i.x402Version===2&&(i.scheme==="exact"||i.scheme==="exact-approval"||i.scheme==="batch-settlement")&&i.network===e)?.extra}async verifyPayment(e,n){try{let r=Te(e),i=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return i.ok?await i.json():{isValid:!1,invalidReason:`facilitator_error_${i.status}`}}catch(r){return{isValid:!1,invalidReason:r instanceof Ie?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_verify_error"}}}async settlePayment(e,n){try{let r=Te(e),i=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:r,paymentRequirements:n})});return i.ok?{...await i.json(),network:n.network}:{success:!1,network:n.network,errorReason:`facilitator_error_${i.status}`}}catch(r){let i=r instanceof Ie?`facilitator_error_${r.status}`:r instanceof Error&&r.name==="AbortError"?"facilitator_timeout":r instanceof Error?r.message:"unexpected_settle_error";return{success:!1,network:n.network,errorReason:i}}}};function Or(t){if(tt(t))return{address:et,decimals:6};let e=yn[t];if(e){let n=vn[e]?.decimals??6;return{address:e,decimals:n}}return{address:et,decimals:6}}function _n(t){try{let e=Te(t);return e?.accepted?.amount??e?.accepted?.maxAmountRequired}catch{return}}function Ne(t){let{payTo:e,facilitatorUrl:n=Ve,network:r=Y,defaultTimeoutSeconds:i=60}=t,o=t.asset??Or(r),s=t.scheme??"exact";if(s==="tab"&&!tt(r))throw new Error(`scheme 'tab' is SVM-only; got network "${r}"`);let c=new rt(n),l=null,p=new Map,y=3e4,v=Date.now();function h(d){let a=(d.maxTimeoutSeconds||i)*1e3;if(p.set(d.payTo,{accept:d,expiresAt:Date.now()+a}),Date.now()-v>y){let x=Date.now();for(let[A,O]of p)O.expiresAt<x&&p.delete(A);v=x}}function f(d){let a=p.get(d);if(a){if(a.expiresAt<Date.now()){p.delete(d);return}return a.accept}}async function g(d){return typeof e=="string"?e:e(d||{})}async function S(){if(l||(l=await c.getNetworkExtra(r)),tt(r)&&!l?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${r}"`);return{...l?.feePayer?{feePayer:l.feePayer}:{},decimals:l?.decimals??o.decimals,name:l?.name,version:l?.version,...s==="batch-settlement"&&l?.receiverAuthorizer?{receiverAuthorizer:l.receiverAuthorizer}:{},...s==="tab"?{voucherHeader:wn,registrationEncoding:Sn,termsVersion:An,acceptanceRule:bn}:{}}}async function P(d,a){let{amountAtomic:x,timeoutSeconds:A=i}=a,O=await S(),K={scheme:s,network:r,amount:x,maxAmountRequired:x,asset:o.address,payTo:d,maxTimeoutSeconds:A,extra:O};return h(K),K}async function T(d){let a=await g({amountAtomic:d.amountAtomic,resourceUrl:d.resourceUrl});return P(a,d)}async function G(d){let{resourceUrl:a,description:x,mimeType:A="application/json"}=d,O={url:a,description:x,mimeType:A},K=await T(d);return{x402Version:2,resource:O,accepts:[K],error:"Payment required"}}function Z(d){return nt(d)}function re(d){return{status:402,headers:{"PAYMENT-REQUIRED":Z(d)},body:{}}}async function F(d,a){if(!a){let x=await g({paymentHeader:d});a=f(x),a||(a=await P(x,{amountAtomic:_n(d)??"0",resourceUrl:""}))}return c.verifyPayment(d,a)}async function _(d,a){if(!a){let x=await g({paymentHeader:d});a=f(x),a||(a=await P(x,{amountAtomic:_n(d)??"0",resourceUrl:""}))}return c.settlePayment(d,a)}return{buildRequirements:G,encodeRequirements:Z,create402Response:re,verifyPayment:F,settlePayment:_,getPaymentAccept:T,network:r,assetDecimals:o.decimals,facilitator:c}}var Br={"solana:mainnet":Y};function Ur(t){let e=Br[t.network];if(!e)throw new Error(`tabChallengeMiddleware: unsupported network "${t.network}"`);let n=typeof t.sellerPubkey=="string"?t.sellerPubkey:t.sellerPubkey.toBase58();new kr(n);let r=Ne({payTo:n,network:e,scheme:"tab",facilitatorUrl:t.facilitatorUrl}),i=H(t.perUnit);return async(o,s,c)=>{if(o.headers[ce])return c();try{let l=`${o.protocol}://${o.get("host")}${o.originalUrl}`,p=await r.buildRequirements({amountAtomic:i,resourceUrl:l,description:t.description}),y=r.create402Response(p);s.set(y.headers).status(y.status).json(y.body)}catch(l){let p=l?.message??String(l);s.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:p})}}}import{PublicKey as Kr}from"@solana/web3.js";var $r={"solana:mainnet":Y};function Mr(t){let e=$r[t.network];if(!e)throw new Error(`tabOrExactMiddleware: unsupported network "${t.network}"`);let n=typeof t.sellerPubkey=="string"?t.sellerPubkey:t.sellerPubkey.toBase58();new Kr(n);let r=Ne({payTo:n,network:e,scheme:"tab",facilitatorUrl:t.facilitatorUrl}),i=Ne({payTo:n,network:e,scheme:"exact",facilitatorUrl:t.facilitatorUrl}),o=H(t.perUnit),s=Nt({connection:t.connection,sellerPubkey:n,network:t.network,perUnit:t.perUnit,settle:"on-close",facilitatorUrl:t.facilitatorUrl,ledger:t.ledger,ledgerSafetyMode:t.ledgerSafetyMode,leaseTtlMs:t.leaseTtlMs,lockCadence:t.lockCadence});return async(c,l,p)=>{if(c.headers[ce])return s(c,l,p);let y=`${c.protocol}://${c.get("host")}${c.originalUrl}`,v=c.headers["payment-signature"];if(v){let h;try{h=await i.getPaymentAccept({amountAtomic:o,resourceUrl:y,description:t.description})}catch(f){let g=f?.message??String(f);l.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:g});return}try{let f=await i.verifyPayment(v,h);if(!f.isValid){l.status(402).json({error:"Payment verification failed",reason:f.invalidReason});return}let g=await i.settlePayment(v,h);if(!g.success){l.status(402).json({error:"Payment settlement failed",reason:g.errorReason});return}return c.x402={transaction:g.transaction,payer:f.payer??"",network:g.network||e},l.setHeader("PAYMENT-RESPONSE",nt({success:!0,transaction:g.transaction,network:g.network||e,payer:f.payer??""})),p()}catch{l.status(500).json({error:"Payment processing error"});return}}try{let h={amountAtomic:o,resourceUrl:y,description:t.description},[f,g]=await Promise.all([r.buildRequirements(h),i.buildRequirements(h)]),S={...f,accepts:[...f.accepts,...g.accepts]};l.set({"PAYMENT-REQUIRED":r.encodeRequirements(S)}).status(402).json({error:"Payment required",accepts:S.accepts,resource:S.resource})}catch(h){let f=h?.message??String(h);l.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:f})}}}export{D as ChannelLeaseLostError,dt as FileChannelLedger,Bt as FileVoucherStore,Ae as InMemoryChannelLedger,kt as InMemoryVoucherStore,W as InvalidRegistrationError,w as InvalidVoucherError,I as InvalidVoucherSignatureError,$ as OnChainVerificationError,ht as RedisChannelLedger,Be as RedisKeyspaceMigrationRequiredError,L as ScopeViolationError,ce as TAB_VOUCHER_HEADER,gt as deserializeChannelLedgerEntry,$e as enforceScope,_r as openSse,Ke as parseRegistration,Sr as requireTab,pt as serializeChannelLedgerEntry,Ur as tabChallengeMiddleware,Nt as tabMiddleware,Mr as tabOrExactMiddleware,At as verifyRegistrationOnChain,bt as verifyVoucherSignature};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexterai/x402",
|
|
3
|
-
"version": "6.0.
|
|
3
|
+
"version": "6.0.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",
|