@dexterai/x402 5.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +1 -1
- package/dist/tab/adapters/solana/index.d.cts +1 -1
- package/dist/tab/adapters/solana/index.d.ts +1 -1
- package/dist/tab/index.cjs +5 -5
- package/dist/tab/index.d.cts +121 -4
- package/dist/tab/index.d.ts +121 -4
- package/dist/tab/index.js +5 -5
- package/dist/tab/seller/index.cjs +2 -2
- package/dist/tab/seller/index.js +2 -2
- package/dist/{types-DMzS_Rh2.d.cts → types-CWYzWTwF.d.cts} +1 -1
- package/dist/{types-DuoL3s8n.d.cts → types-D5eKDMvo.d.cts} +17 -2
- package/dist/{types-DuoL3s8n.d.ts → types-D5eKDMvo.d.ts} +17 -2
- package/dist/{types-BL9QW1gf.d.ts → types-rSrCtwS2.d.ts} +1 -1
- package/package.json +1 -1
package/dist/tab/seller/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var S=class extends Error{constructor(r,n){super(`Invalid voucher: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="InvalidVoucherError"}};import{promises as V}from"fs";import{join as qe,dirname as ze}from"path";var Ne=new Map;function P(e,t){let n=(Ne.get(e)??Promise.resolve()).then(()=>t(),()=>t());return Ne.set(e,n.then(()=>{},()=>{})),n}var $=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,r){this.map.set(t,r)}async delete(t){this.map.delete(t)}async tryAcquireLease(t,r){return P(t,async()=>{let n=this.map.get(t),s=Date.now();if(n?.lease&&n.lease.heldUntilUnixMs>s)return!1;let i=n??{lastVoucher:null,deliveredCumulativeAtomic:"0",lastCrystallizedCumulativeAtomic:"0"};return this.map.set(t,{...i,lease:{heldUntilUnixMs:s+r}}),!0})}async releaseLease(t){await P(t,async()=>{let r=this.map.get(t);r&&this.map.set(t,{...r,lease:void 0})})}};function ce(e){let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function le(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let r=0;r<t.length;r++)t[r]=parseInt(e.substr(r*2,2),16);return t}function We(e){return{lastVoucher:e.lastVoucher?{payload:e.lastVoucher.payload,sessionPublicKey:ce(e.lastVoucher.sessionPublicKey),sessionRegistration:ce(e.lastVoucher.sessionRegistration),sessionSignature:ce(e.lastVoucher.sessionSignature)}:null,deliveredCumulativeAtomic:e.deliveredCumulativeAtomic,lastCrystallizedCumulativeAtomic:e.lastCrystallizedCumulativeAtomic,onChain:e.onChain,lease:e.lease}}function Fe(e){return{lastVoucher:e.lastVoucher?{payload:e.lastVoucher.payload,sessionPublicKey:le(e.lastVoucher.sessionPublicKey),sessionRegistration:le(e.lastVoucher.sessionRegistration),sessionSignature:le(e.lastVoucher.sessionSignature)}:null,deliveredCumulativeAtomic:e.deliveredCumulativeAtomic,lastCrystallizedCumulativeAtomic:e.lastCrystallizedCumulativeAtomic??"0",onChain:e.onChain,lease:e.lease}}var ue=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return qe(this.dir,`${t}.json`)}async get(t){try{let r=await V.readFile(this.pathFor(t),"utf8");return Fe(JSON.parse(r))}catch(r){if(r?.code==="ENOENT")return null;throw r}}async set(t,r){let n=this.pathFor(t);await V.mkdir(ze(n),{recursive:!0});let s=`${n}.tmp`;await V.writeFile(s,JSON.stringify(We(r))),await V.rename(s,n)}async delete(t){try{await V.unlink(this.pathFor(t))}catch(r){if(r?.code!=="ENOENT")throw r}}async tryAcquireLease(t,r){return P(t,async()=>{let n=await this.get(t),s=Date.now();if(n?.lease&&n.lease.heldUntilUnixMs>s)return!1;let i=n??{lastVoucher:null,deliveredCumulativeAtomic:"0",lastCrystallizedCumulativeAtomic:"0"};return await this.set(t,{...i,lease:{heldUntilUnixMs:s+r}}),!0})}async releaseLease(t){await P(t,async()=>{let r=await this.get(t);r&&await this.set(t,{...r,lease:void 0})})}};import{PublicKey as Ze}from"@solana/web3.js";import je from"tweetnacl";import{sha256 as Mt}from"@noble/hashes/sha256";import{p256 as Dt}from"@noble/curves/p256";import{PublicKey as de}from"@solana/web3.js";import{sessionRegisterMessage as Et,sessionRevokeMessage as Ct,voucherPayloadMessage as me,buildVoucherMessage as Pt}from"@dexterai/vault/messages";import{buildRegisterSessionKeyInstruction as _t,buildRevokeSessionKeyInstruction as Nt,deriveSwigWalletAddress as It}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as Ot}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as pe,SECP256R1_PROGRAM_ID as Vt,INSTRUCTIONS_SYSVAR_ID as $t}from"@dexterai/vault/constants";import{fetchSessionAccount as Xe,isSessionLive as Je}from"@dexterai/vault/session";var ge="OTS_SESSION_REGISTER_V2",E=class extends Error{constructor(r,n){super(`Invalid registration: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="InvalidRegistrationError"}};function he(e){if(e.length!==188)throw new E("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,ge.length));if(t!==ge)throw new E("wrong_domain",`got "${t}"`);for(let y=ge.length;y<32;y++)if(e[y]!==0)throw new E("wrong_domain",`non-NUL padding at byte ${y}`);let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new de(e.slice(32,64)),s=new de(e.slice(64,96)),i=e.slice(96,128),p=r.getBigUint64(128,!0),u=r.getBigInt64(136,!0),o=new de(e.slice(144,176)),d=r.getUint32(176,!0),c=r.getBigUint64(180,!0);if(!n.equals(pe))throw new E("wrong_program",`${n.toBase58()} is not ${pe.toBase58()}`);if(p===0n)throw new E("cap_zero");let a=BigInt(Math.floor(Date.now()/1e3));if(u<=a)throw new E("expiry_in_past",`expires_at=${u}, now=${a}`);return{programId:n,vaultPda:s,sessionPubkey:new Uint8Array(i),maxAmount:p,expiresAt:u,allowedCounterparty:o,nonce:d,maxRevolvingCapacity:c}}var _=class extends Error{constructor(r,n){super(`On-chain verification failed: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="OnChainVerificationError"}};async function ye(e,t){let r=await Xe(e,t.vaultPda,t.allowedCounterparty);if(!r||r.version===0)throw new _("session_not_active","no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!Je(r))throw new _("session_not_active","SessionAccount PDA is present but expired");if(!Ye(r.session.sessionPubkey,t.sessionPubkey))throw new _("session_pubkey_mismatch",`on-chain ${Ie(r.session.sessionPubkey)} != registration ${Ie(t.sessionPubkey)}`)}var T=class extends Error{constructor(t){super(`Invalid voucher signature${t?`: ${t}`:""}`),this.name="InvalidVoucherSignatureError"}};function fe(e,t){if(t.length!==32)throw new T(`channelIdBytes must be 32 bytes, got ${t.length}`);if(e.sessionPublicKey.length!==32)throw new T(`sessionPublicKey must be 32 bytes, got ${e.sessionPublicKey.length}`);if(e.sessionSignature.length!==64)throw new T(`sessionSignature must be 64 bytes, got ${e.sessionSignature.length}`);let r=me({channelId:t,cumulativeAmount:BigInt(e.payload.cumulativeAmount),sequenceNumber:e.payload.sequenceNumber});if(!je.sign.detached.verify(r,e.sessionSignature,e.sessionPublicKey))throw new T("ed25519 verify rejected")}var x=class extends Error{constructor(r,n){super(`Scope violation: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="ScopeViolationError"}};function Ae(e){let t=BigInt(e.voucher.payload.cumulativeAmount);if(t>e.registration.maxAmount)throw new x("cumulative_exceeds_cap",`${t} > ${e.registration.maxAmount}`);let r=BigInt(Math.floor(Date.now()/1e3));if(r>=e.registration.expiresAt)throw new x("session_expired",`now=${r} >= expiresAt=${e.registration.expiresAt}`);if(!e.registration.allowedCounterparty.equals(e.expectedCounterparty))throw new x("wrong_counterparty",`${e.registration.allowedCounterparty.toBase58()} != ${e.expectedCounterparty.toBase58()}`);if(e.previousCumulativeAtomic!==void 0){let n=BigInt(e.previousCumulativeAtomic);if(t<=n)throw new x("non_monotonic",`cumulative=${t} not > previous=${n}`)}}function Ye(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}function Ie(e){let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}import{PublicKey as or}from"@solana/web3.js";import{bytesToHex as cr}from"@noble/hashes/utils";import Yt from"tweetnacl";import{sha256 as Qt}from"@noble/hashes/sha256";var Ue="https://x402.dexter.cash",Oe=6;function C(e,t=Oe){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[r,n=""]=e.split(".");if(n.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let s=n.padEnd(t,"0"),i=`${r}${s}`.replace(/^0+(?=\d)/,"");return i===""?"0":i}function N(e,t=Oe){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let r=e.padStart(t+1,"0"),n=r.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",s=r.slice(-t).replace(/0+$/,"");return s?`${n}.${s}`:n}import{bytesToHex as be}from"@noble/hashes/utils";var Ge=15e3;async function we(e,t,r,n,s=fetch){let i=e.lastVoucher;if(!i)return{crystallized:!1};if(i.payload.channelId!==t)return{crystallized:!1,error:"channel_id_mismatch"};try{let p=`${r.replace(/\/$/,"")}/tab/lock`,u={channelId:i.payload.channelId,cumulativeAmount:i.payload.cumulativeAmount,sequenceNumber:i.payload.sequenceNumber,sessionPublicKey:be(i.sessionPublicKey),sessionSignature:be(i.sessionSignature),sessionRegistration:be(i.sessionRegistration),network:n},o=await s(p,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(u),signal:AbortSignal.timeout(Ge)}),d=await o.text();if(!o.ok)return{crystallized:!1,error:`tab lock ${o.status}: ${d.slice(0,200)}`};let c;try{let a=JSON.parse(d);a&&typeof a.claimPda=="string"&&(c=a.claimPda)}catch{}return{crystallized:!0,claimPda:c}}catch(p){return{crystallized:!1,error:String(p?.message??p)}}}async function ke(e,t,r,n,s,i={}){let p=BigInt(e.deliveredCumulativeAtomic),u=BigInt(e.lastCrystallizedCumulativeAtomic??"0"),o=BigInt(s.thresholdAtomic);if(p-u<o)return{crystallized:!1};let d=e.lastVoucher?.payload.cumulativeAmount,c=await we(e,t,r,n,i.fetchImpl);return c.crystallized&&d!==void 0&&(e.lastCrystallizedCumulativeAtomic=d),c}var I="x-tab-voucher",ve=class{map=new Map;get(t){return this.map.get(t)}set(t,r){this.map.set(t,r)}update(t,r){let n=this.map.get(t);n&&(n.lastCumulativeAtomic=r)}delete(t){this.map.delete(t)}},Se=class{constructor(t,r,n,s,i,p){this.recordDeliveredImpl=i;this.chargeImpl=p;this.channelId=t,this.network=r,this.cumulativeAtomic=n,this.deliveredBaselineAtomic=s}channelId;network;sessionPublicKey=null;cumulativeAtomic;deliveredBaselineAtomic;cumulative(){return N(this.cumulativeAtomic.toString())}deliveredCumulative(){return N(this.deliveredBaselineAtomic.toString())}async recordDelivered(t){return this.recordDeliveredImpl(t)}bumpCumulative(t){this.cumulativeAtomic=t}setSessionPublicKey(t){this.sessionPublicKey=t}async charge(t){return this.chargeImpl(t)}};function Qe(e){if(typeof e!="string"||e.length===0)throw new S("signature_invalid",`missing ${I} header`);let t;try{t=Buffer.from(e,"base64").toString("utf8")}catch{throw new S("signature_invalid","malformed base64")}let r;try{r=JSON.parse(t)}catch{throw new S("signature_invalid","malformed JSON")}if(!r||typeof r!="object"||!r.payload||!r.sessionPublicKey)throw new S("signature_invalid","missing required fields");return{payload:r.payload,sessionPublicKey:j(r.sessionPublicKey),sessionRegistration:j(r.sessionRegistration),sessionSignature:j(r.sessionSignature)}}function j(e){if(typeof e!="string"||e.length%2!==0)throw new S("signature_invalid",`bad hex: ${typeof e}`);let t=new Uint8Array(e.length/2);for(let r=0;r<t.length;r++)t[r]=parseInt(e.substr(r*2,2),16);return t}function et(e){if(!/^[0-9a-f]{64}$/i.test(e))throw new S("signature_invalid",`channelId must be 64-char hex, got "${e}"`);return j(e)}function xe(e){let t=e.ledger??new $,r=new ve,n=typeof e.sellerPubkey=="string"?new Ze(e.sellerPubkey):e.sellerPubkey,s=e.maxPerVoucherAtomic?BigInt(e.maxPerVoucherAtomic):BigInt(C(e.perUnit))*100n,i=e.facilitatorUrl??Ue,p={thresholdAtomic:e.lockCadence?.thresholdAtomic??C("0.10"),onClose:e.lockCadence?.onClose??!0};return async(u,o,d)=>{try{let c=Qe(u.headers[I]),a=c.payload.channelId,y=et(a),m=r.get(a);if(!m){let g=he(c.sessionRegistration);await ye(e.connection,g),m={registration:g,lastCumulativeAtomic:"0"},r.set(a,m)}fe(c,y),Ae({registration:m.registration,voucher:c,expectedCounterparty:n,previousCumulativeAtomic:m.lastCumulativeAtomic});let f=BigInt(c.payload.cumulativeAmount),w=BigInt(m.lastCumulativeAtomic),U=f-w;if(U>s)throw new x("cumulative_exceeds_cap",`single voucher increment ${U} exceeds maxPerVoucherAtomic ${s}`);let q=e.leaseTtlMs??3e5;if(!await t.tryAcquireLease(a,q))throw new S("channel_busy","another stream is live on this channel; tabs serve one stream at a time");let z=!1,O=()=>{z||(z=!0,t.releaseLease(a).catch(g=>{console.error("[tab/seller] failed to release channel lease:",g)}))};o.on("close",O),o.on("finish",O);let ae=async g=>{let v=g.lastCrystallizedCumulativeAtomic??"0";await ke(g,a,i,e.network,p),g.lastCrystallizedCumulativeAtomic!==v&&await P(a,async()=>{let b=await t.get(a);b&&await t.set(a,{...b,lastCrystallizedCumulativeAtomic:g.lastCrystallizedCumulativeAtomic})}).catch(()=>{})},W=!1,F=()=>{!p.onClose||W||(W=!0,(async()=>{let g=await t.get(a);if(!g||!g.lastVoucher)return;let v=g.lastVoucher.payload.cumulativeAmount;(await we(g,a,i,e.network)).crystallized&&await P(a,async()=>{let k=await t.get(a);k&&await t.set(a,{...k,lastCrystallizedCumulativeAtomic:v})})})().catch(()=>{}))};o.on("close",F),o.on("finish",F);let l=await t.get(a),h=l?BigInt(l.deliveredCumulativeAtomic):0n;await P(a,async()=>{let g=await t.get(a);await t.set(a,{...g,lastVoucher:c,deliveredCumulativeAtomic:g?g.deliveredCumulativeAtomic:"0"})}),r.update(a,c.payload.cumulativeAmount);let A=new Se(a,e.network,f,h,async g=>{let v=null;await P(a,async()=>{let b=await t.get(a),k=b?BigInt(b.deliveredCumulativeAtomic):0n,Re=BigInt(g),He=Re>0n?k+Re:k,_e={...b,lastVoucher:b?.lastVoucher??c,deliveredCumulativeAtomic:He.toString(),lastCrystallizedCumulativeAtomic:b?.lastCrystallizedCumulativeAtomic??"0"};await t.set(a,_e),v=_e}),v&&ae(v).catch(()=>{})},async g=>{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.")});A.setSessionPublicKey(c.sessionPublicKey),u.tab=A,d()}catch(c){if(c instanceof S||c instanceof E||c instanceof _||c instanceof T||c instanceof x){o.status(402).json({error:"invalid_voucher",reason:c.reason??"unknown",detail:c.message});return}d(c)}}}function tt(e){if(!e.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return e.tab}function rt(e,t){if(!t.tab)throw new Error("openSse requires options.tab");e.headersSent||(e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive"),typeof e.flushHeaders=="function"&&e.flushHeaders());let r=t.tab,n=BigInt(C(r.cumulative())),s=BigInt(C(r.deliveredCumulative())),i=n-s;i<0n&&(i=0n);let p=t.perUnit?BigInt(C(t.perUnit)):null,u=0n,o=!1;async function d(){await r.recordDelivered(u.toString())}e.on("close",()=>{o||(o=!0,d().catch(m=>{console.error("[tab/seller] terminal persist failed on disconnect:",m)}))});async function c(m=1){if(o)throw new Error("meter ended");if(p===null)throw new Error("charge() needs options.perUnit");let f=p*BigInt(m),w=u+f;if(w>i)throw o=!0,await d(),new x("cumulative_exceeds_cap",`chunk would push delivered to ${N((s+w).toString())} beyond signed cumulative ${N(n.toString())} (per-request budget ${N(i.toString())})`);u=w}function a(m){if(o)throw new Error("meter ended");let w=(typeof m=="string"?m:Buffer.from(m).toString("utf8")).replace(/\n/g,"\\n");e.write(`data: ${w}
|
|
1
|
+
var S=class extends Error{constructor(r,n){super(`Invalid voucher: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="InvalidVoucherError"}};import{promises as V}from"fs";import{join as qe,dirname as ze}from"path";var Ne=new Map;function P(e,t){let n=(Ne.get(e)??Promise.resolve()).then(()=>t(),()=>t());return Ne.set(e,n.then(()=>{},()=>{})),n}var $=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,r){this.map.set(t,r)}async delete(t){this.map.delete(t)}async tryAcquireLease(t,r){return P(t,async()=>{let n=this.map.get(t),i=Date.now();if(n?.lease&&n.lease.heldUntilUnixMs>i)return!1;let s=n??{lastVoucher:null,deliveredCumulativeAtomic:"0",lastCrystallizedCumulativeAtomic:"0"};return this.map.set(t,{...s,lease:{heldUntilUnixMs:i+r}}),!0})}async releaseLease(t){await P(t,async()=>{let r=this.map.get(t);r&&this.map.set(t,{...r,lease:void 0})})}};function ce(e){let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function le(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let r=0;r<t.length;r++)t[r]=parseInt(e.substr(r*2,2),16);return t}function We(e){return{lastVoucher:e.lastVoucher?{payload:e.lastVoucher.payload,sessionPublicKey:ce(e.lastVoucher.sessionPublicKey),sessionRegistration:ce(e.lastVoucher.sessionRegistration),sessionSignature:ce(e.lastVoucher.sessionSignature)}:null,deliveredCumulativeAtomic:e.deliveredCumulativeAtomic,lastCrystallizedCumulativeAtomic:e.lastCrystallizedCumulativeAtomic,onChain:e.onChain,lease:e.lease}}function Fe(e){return{lastVoucher:e.lastVoucher?{payload:e.lastVoucher.payload,sessionPublicKey:le(e.lastVoucher.sessionPublicKey),sessionRegistration:le(e.lastVoucher.sessionRegistration),sessionSignature:le(e.lastVoucher.sessionSignature)}:null,deliveredCumulativeAtomic:e.deliveredCumulativeAtomic,lastCrystallizedCumulativeAtomic:e.lastCrystallizedCumulativeAtomic??"0",onChain:e.onChain,lease:e.lease}}var ue=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return qe(this.dir,`${t}.json`)}async get(t){try{let r=await V.readFile(this.pathFor(t),"utf8");return Fe(JSON.parse(r))}catch(r){if(r?.code==="ENOENT")return null;throw r}}async set(t,r){let n=this.pathFor(t);await V.mkdir(ze(n),{recursive:!0});let i=`${n}.tmp`;await V.writeFile(i,JSON.stringify(We(r))),await V.rename(i,n)}async delete(t){try{await V.unlink(this.pathFor(t))}catch(r){if(r?.code!=="ENOENT")throw r}}async tryAcquireLease(t,r){return P(t,async()=>{let n=await this.get(t),i=Date.now();if(n?.lease&&n.lease.heldUntilUnixMs>i)return!1;let s=n??{lastVoucher:null,deliveredCumulativeAtomic:"0",lastCrystallizedCumulativeAtomic:"0"};return await this.set(t,{...s,lease:{heldUntilUnixMs:i+r}}),!0})}async releaseLease(t){await P(t,async()=>{let r=await this.get(t);r&&await this.set(t,{...r,lease:void 0})})}};import{PublicKey as Ze}from"@solana/web3.js";import je from"tweetnacl";import{sha256 as Mt}from"@noble/hashes/sha256";import{p256 as Dt}from"@noble/curves/p256";import{PublicKey as de}from"@solana/web3.js";import{sessionRegisterMessage as Et,sessionRevokeMessage as Ct,voucherPayloadMessage as me,buildVoucherMessage as Pt}from"@dexterai/vault/messages";import{buildRegisterSessionKeyInstruction as _t,buildRevokeSessionKeyInstruction as Nt,deriveSwigWalletAddress as It}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as kt}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as pe,SECP256R1_PROGRAM_ID as Vt,INSTRUCTIONS_SYSVAR_ID as $t}from"@dexterai/vault/constants";import{fetchSessionAccount as Xe,isSessionLive as Je}from"@dexterai/vault/session";var ge="OTS_SESSION_REGISTER_V2",E=class extends Error{constructor(r,n){super(`Invalid registration: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="InvalidRegistrationError"}};function he(e){if(e.length!==188)throw new E("wrong_length",`expected 188, got ${e.length}`);let t=new TextDecoder().decode(e.slice(0,ge.length));if(t!==ge)throw new E("wrong_domain",`got "${t}"`);for(let y=ge.length;y<32;y++)if(e[y]!==0)throw new E("wrong_domain",`non-NUL padding at byte ${y}`);let r=new DataView(e.buffer,e.byteOffset,e.byteLength),n=new de(e.slice(32,64)),i=new de(e.slice(64,96)),s=e.slice(96,128),p=r.getBigUint64(128,!0),u=r.getBigInt64(136,!0),o=new de(e.slice(144,176)),d=r.getUint32(176,!0),c=r.getBigUint64(180,!0);if(!n.equals(pe))throw new E("wrong_program",`${n.toBase58()} is not ${pe.toBase58()}`);if(p===0n)throw new E("cap_zero");let a=BigInt(Math.floor(Date.now()/1e3));if(u<=a)throw new E("expiry_in_past",`expires_at=${u}, now=${a}`);return{programId:n,vaultPda:i,sessionPubkey:new Uint8Array(s),maxAmount:p,expiresAt:u,allowedCounterparty:o,nonce:d,maxRevolvingCapacity:c}}var _=class extends Error{constructor(r,n){super(`On-chain verification failed: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="OnChainVerificationError"}};async function ye(e,t){let r=await Xe(e,t.vaultPda,t.allowedCounterparty);if(!r||r.version===0)throw new _("session_not_active","no live SessionAccount PDA for this (vault, counterparty) \u2014 revoked, expiry-swept, or never registered");if(!Je(r))throw new _("session_not_active","SessionAccount PDA is present but expired");if(!Ye(r.session.sessionPubkey,t.sessionPubkey))throw new _("session_pubkey_mismatch",`on-chain ${Ie(r.session.sessionPubkey)} != registration ${Ie(t.sessionPubkey)}`)}var T=class extends Error{constructor(t){super(`Invalid voucher signature${t?`: ${t}`:""}`),this.name="InvalidVoucherSignatureError"}};function fe(e,t){if(t.length!==32)throw new T(`channelIdBytes must be 32 bytes, got ${t.length}`);if(e.sessionPublicKey.length!==32)throw new T(`sessionPublicKey must be 32 bytes, got ${e.sessionPublicKey.length}`);if(e.sessionSignature.length!==64)throw new T(`sessionSignature must be 64 bytes, got ${e.sessionSignature.length}`);let r=me({channelId:t,cumulativeAmount:BigInt(e.payload.cumulativeAmount),sequenceNumber:e.payload.sequenceNumber});if(!je.sign.detached.verify(r,e.sessionSignature,e.sessionPublicKey))throw new T("ed25519 verify rejected")}var x=class extends Error{constructor(r,n){super(`Scope violation: ${r}${n?` (${n})`:""}`);this.reason=r;this.name="ScopeViolationError"}};function Ae(e){let t=BigInt(e.voucher.payload.cumulativeAmount);if(t>e.registration.maxAmount)throw new x("cumulative_exceeds_cap",`${t} > ${e.registration.maxAmount}`);let r=BigInt(Math.floor(Date.now()/1e3));if(r>=e.registration.expiresAt)throw new x("session_expired",`now=${r} >= expiresAt=${e.registration.expiresAt}`);if(!e.registration.allowedCounterparty.equals(e.expectedCounterparty))throw new x("wrong_counterparty",`${e.registration.allowedCounterparty.toBase58()} != ${e.expectedCounterparty.toBase58()}`);if(e.previousCumulativeAtomic!==void 0){let n=BigInt(e.previousCumulativeAtomic);if(t<=n)throw new x("non_monotonic",`cumulative=${t} not > previous=${n}`)}}function Ye(e,t){if(e.length!==t.length)return!1;for(let r=0;r<e.length;r++)if(e[r]!==t[r])return!1;return!0}function Ie(e){let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}import{PublicKey as or}from"@solana/web3.js";import{bytesToHex as cr}from"@noble/hashes/utils";import Yt from"tweetnacl";import{sha256 as Qt}from"@noble/hashes/sha256";var Ue="https://x402.dexter.cash",ke=6;function C(e,t=ke){if(!/^\d+(\.\d+)?$/.test(e))throw new Error(`amount must be a non-negative decimal string, got "${e}"`);let[r,n=""]=e.split(".");if(n.length>t)throw new Error(`amount "${e}" has more than ${t} decimals`);let i=n.padEnd(t,"0"),s=`${r}${i}`.replace(/^0+(?=\d)/,"");return s===""?"0":s}function N(e,t=ke){if(!/^\d+$/.test(e))throw new Error(`atomic must be a non-negative integer string, got "${e}"`);let r=e.padStart(t+1,"0"),n=r.slice(0,-t).replace(/^0+(?=\d)/,"")||"0",i=r.slice(-t).replace(/0+$/,"");return i?`${n}.${i}`:n}import{bytesToHex as be}from"@noble/hashes/utils";var Ge=15e3;async function we(e,t,r,n,i=fetch){let s=e.lastVoucher;if(!s)return{crystallized:!1};if(s.payload.channelId!==t)return{crystallized:!1,error:"channel_id_mismatch"};try{let p=`${r.replace(/\/$/,"")}/tab/lock`,u={channelId:s.payload.channelId,cumulativeAmount:s.payload.cumulativeAmount,sequenceNumber:s.payload.sequenceNumber,sessionPublicKey:be(s.sessionPublicKey),sessionSignature:be(s.sessionSignature),sessionRegistration:be(s.sessionRegistration),network:n},o=await i(p,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(u),signal:AbortSignal.timeout(Ge)}),d=await o.text();if(!o.ok)return{crystallized:!1,error:`tab lock ${o.status}: ${d.slice(0,200)}`};let c;try{let a=JSON.parse(d);a&&typeof a.claimPda=="string"&&(c=a.claimPda)}catch{}return{crystallized:!0,claimPda:c}}catch(p){return{crystallized:!1,error:String(p?.message??p)}}}async function Oe(e,t,r,n,i,s={}){let p=BigInt(e.deliveredCumulativeAtomic),u=BigInt(e.lastCrystallizedCumulativeAtomic??"0"),o=BigInt(i.thresholdAtomic);if(p-u<o)return{crystallized:!1};let d=e.lastVoucher?.payload.cumulativeAmount,c=await we(e,t,r,n,s.fetchImpl);return c.crystallized&&d!==void 0&&(e.lastCrystallizedCumulativeAtomic=d),c}var I="x-tab-voucher",ve=class{map=new Map;get(t){return this.map.get(t)}set(t,r){this.map.set(t,r)}update(t,r){let n=this.map.get(t);n&&(n.lastCumulativeAtomic=r)}delete(t){this.map.delete(t)}},Se=class{constructor(t,r,n,i,s,p){this.recordDeliveredImpl=s;this.chargeImpl=p;this.channelId=t,this.network=r,this.cumulativeAtomic=n,this.deliveredBaselineAtomic=i}channelId;network;sessionPublicKey=null;cumulativeAtomic;deliveredBaselineAtomic;cumulative(){return N(this.cumulativeAtomic.toString())}deliveredCumulative(){return N(this.deliveredBaselineAtomic.toString())}async recordDelivered(t){return this.recordDeliveredImpl(t)}bumpCumulative(t){this.cumulativeAtomic=t}setSessionPublicKey(t){this.sessionPublicKey=t}async charge(t){return this.chargeImpl(t)}};function Qe(e){if(typeof e!="string"||e.length===0)throw new S("signature_invalid",`missing ${I} header`);let t;try{t=Buffer.from(e,"base64").toString("utf8")}catch{throw new S("signature_invalid","malformed base64")}let r;try{r=JSON.parse(t)}catch{throw new S("signature_invalid","malformed JSON")}if(!r||typeof r!="object"||!r.payload||!r.sessionPublicKey)throw new S("signature_invalid","missing required fields");return{payload:r.payload,sessionPublicKey:j(r.sessionPublicKey),sessionRegistration:j(r.sessionRegistration),sessionSignature:j(r.sessionSignature)}}function j(e){if(typeof e!="string"||e.length%2!==0)throw new S("signature_invalid",`bad hex: ${typeof e}`);let t=new Uint8Array(e.length/2);for(let r=0;r<t.length;r++)t[r]=parseInt(e.substr(r*2,2),16);return t}function et(e){if(!/^[0-9a-f]{64}$/i.test(e))throw new S("signature_invalid",`channelId must be 64-char hex, got "${e}"`);return j(e)}function xe(e){let t=e.ledger??new $,r=new ve,n=typeof e.sellerPubkey=="string"?new Ze(e.sellerPubkey):e.sellerPubkey,i=e.maxPerVoucherAtomic?BigInt(e.maxPerVoucherAtomic):BigInt(C(e.perUnit))*100n,s=e.facilitatorUrl??Ue,p={thresholdAtomic:e.lockCadence?.thresholdAtomic??C("0.10"),onClose:e.lockCadence?.onClose??!0};return async(u,o,d)=>{try{let c=Qe(u.headers[I]),a=c.payload.channelId,y=et(a),m=r.get(a);if(!m){let g=he(c.sessionRegistration);await ye(e.connection,g),m={registration:g,lastCumulativeAtomic:"0"},r.set(a,m)}fe(c,y),Ae({registration:m.registration,voucher:c,expectedCounterparty:n,previousCumulativeAtomic:m.lastCumulativeAtomic});let f=BigInt(c.payload.cumulativeAmount),w=BigInt(m.lastCumulativeAtomic),U=f-w;if(U>i)throw new x("cumulative_exceeds_cap",`single voucher increment ${U} exceeds maxPerVoucherAtomic ${i}`);let q=e.leaseTtlMs??3e5;if(!await t.tryAcquireLease(a,q))throw new S("channel_busy","another stream is live on this channel; tabs serve one stream at a time");let z=!1,k=()=>{z||(z=!0,t.releaseLease(a).catch(g=>{console.error("[tab/seller] failed to release channel lease:",g)}))};o.on("close",k),o.on("finish",k);let ae=async g=>{let v=g.lastCrystallizedCumulativeAtomic??"0";await Oe(g,a,s,e.network,p),g.lastCrystallizedCumulativeAtomic!==v&&await P(a,async()=>{let b=await t.get(a);b&&await t.set(a,{...b,lastCrystallizedCumulativeAtomic:g.lastCrystallizedCumulativeAtomic})}).catch(()=>{})},W=!1,F=()=>{!p.onClose||W||(W=!0,(async()=>{let g=await t.get(a);if(!g||!g.lastVoucher)return;let v=g.lastVoucher.payload.cumulativeAmount;(await we(g,a,s,e.network)).crystallized&&await P(a,async()=>{let O=await t.get(a);O&&await t.set(a,{...O,lastCrystallizedCumulativeAtomic:v})})})().catch(()=>{}))};o.on("close",F),o.on("finish",F);let l=await t.get(a),h=l?BigInt(l.deliveredCumulativeAtomic):0n;await P(a,async()=>{let g=await t.get(a);await t.set(a,{...g,lastVoucher:c,deliveredCumulativeAtomic:g?g.deliveredCumulativeAtomic:"0"})}),r.update(a,c.payload.cumulativeAmount);let A=new Se(a,e.network,f,h,async g=>{let v=null;await P(a,async()=>{let b=await t.get(a),O=b?BigInt(b.deliveredCumulativeAtomic):0n,Re=BigInt(g),He=Re>0n?O+Re:O,_e={...b,lastVoucher:b?.lastVoucher??c,deliveredCumulativeAtomic:He.toString(),lastCrystallizedCumulativeAtomic:b?.lastCrystallizedCumulativeAtomic??"0"};await t.set(a,_e),v=_e}),v&&ae(v).catch(()=>{})},async g=>{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.")});A.setSessionPublicKey(c.sessionPublicKey),u.tab=A,d()}catch(c){if(c instanceof S||c instanceof E||c instanceof _||c instanceof T||c instanceof x){o.status(402).json({error:"invalid_voucher",reason:c.reason??"unknown",detail:c.message});return}d(c)}}}function tt(e){if(!e.tab)throw new Error("req.tab is missing \u2014 did tabMiddleware run on this route?");return e.tab}function rt(e,t){if(!t.tab)throw new Error("openSse requires options.tab");e.headersSent||(e.setHeader("Content-Type","text/event-stream"),e.setHeader("Cache-Control","no-cache"),e.setHeader("Connection","keep-alive"),typeof e.flushHeaders=="function"&&e.flushHeaders());let r=t.tab,n=BigInt(C(r.cumulative())),i=BigInt(C(r.deliveredCumulative())),s=n-i;s<0n&&(s=0n);let p=t.perUnit?BigInt(C(t.perUnit)):null,u=0n,o=!1;async function d(){await r.recordDelivered(u.toString())}e.on("close",()=>{o||(o=!0,d().catch(m=>{console.error("[tab/seller] terminal persist failed on disconnect:",m)}))});async function c(m=1){if(o)throw new Error("meter ended");if(p===null)throw new Error("charge() needs options.perUnit");let f=p*BigInt(m),w=u+f;if(w>s)throw o=!0,await d(),new x("cumulative_exceeds_cap",`chunk would push delivered to ${N((i+w).toString())} beyond signed cumulative ${N(n.toString())} (per-request budget ${N(s.toString())})`);u=w}function a(m){if(o)throw new Error("meter ended");let w=(typeof m=="string"?m:Buffer.from(m).toString("utf8")).replace(/\n/g,"\\n");e.write(`data: ${w}
|
|
2
2
|
|
|
3
3
|
`)}async function y(){o||(o=!0,await d(),e.write(`event: end
|
|
4
4
|
data: {"chargedAtomic":"${u}"}
|
|
5
5
|
|
|
6
|
-
`),e.end())}return{charge:c,send:a,end:y}}import{promises as B}from"fs";import{join as nt,dirname as st}from"path";function it(e){return{payload:e.payload,sessionPublicKey:Ee(e.sessionPublicKey),sessionRegistration:Ee(e.sessionRegistration),sessionSignature:Ee(e.sessionSignature)}}function ot(e){return{payload:e.payload,sessionPublicKey:Ce(e.sessionPublicKey),sessionRegistration:Ce(e.sessionRegistration),sessionSignature:Ce(e.sessionSignature)}}function Ee(e){let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function Ce(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let r=0;r<t.length;r++)t[r]=parseInt(e.substr(r*2,2),16);return t}var Pe=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,r){this.map.set(t,r)}async delete(t){this.map.delete(t)}},Te=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return nt(this.dir,`${t}.json`)}async get(t){try{let r=await B.readFile(this.pathFor(t),"utf8");return ot(JSON.parse(r))}catch(r){if(r?.code==="ENOENT")return null;throw r}}async set(t,r){let n=this.pathFor(t);await B.mkdir(st(n),{recursive:!0});let s=`${n}.tmp`;await B.writeFile(s,JSON.stringify(it(r))),await B.rename(s,n)}async delete(t){try{await B.unlink(this.pathFor(t))}catch(r){if(r?.code!=="ENOENT")throw r}}};import{PublicKey as pt}from"@solana/web3.js";var R="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ve="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",$e="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var K="eip155:8453",X="eip155:84532",J="eip155:42161",Y="eip155:137",G="eip155:10",Z="eip155:43114",Q="eip155:56",ee="eip155:1187947933",te="eip155:324705682",re="eip155:1";var ne="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var Be="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",at="0x55d398326f99059fF775485246999027B3197955",Ke="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Me={[Q]:Ke,[K]:Be,[X]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[J]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Y]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[G]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[Z]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[ee]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[te]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[re]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Le={[at]:{symbol:"USDT",decimals:18},[Ke]:{symbol:"USDC",decimals:18}};var Rr={[Q]:56,[K]:8453,[X]:84532,[J]:42161,[Y]:137,[G]:10,[Z]:43114,[ee]:1187947933,[te]:324705682,[re]:1},_r={[R]:"https://api.dexter.cash/api/solana/rpc",[Ve]:"https://api.devnet.solana.com",[$e]:"https://api.testnet.solana.com"},Nr={[Q]:"https://api.dexter.cash/api/evm/bsc/rpc",[K]:"https://api.dexter.cash/api/base/rpc",[X]:"https://sepolia.base.org",[J]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Y]:"https://api.dexter.cash/api/evm/polygon/rpc",[G]:"https://api.dexter.cash/api/evm/optimism/rpc",[Z]:"https://api.dexter.cash/api/evm/avalanche/rpc",[ee]:"https://skale-base.skalenodes.com/v1/base",[te]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[re]:"https://eth.llamarpc.com"},M="https://x402.dexter.cash";function se(e){return e.startsWith("solana:")||e==="solana"}function ct(e){if(typeof Buffer<"u")return Buffer.from(e,"utf-8").toString("base64");let t=new TextEncoder().encode(e),r="";for(let n=0;n<t.length;n++)r+=String.fromCharCode(t[n]);return btoa(r)}function lt(e){if(typeof Buffer<"u")return Buffer.from(e,"base64").toString("utf-8");let t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return new TextDecoder().decode(r)}function ie(e){return ct(JSON.stringify(e))}function L(e){return JSON.parse(lt(e))}function ut(e){if(e instanceof TypeError)return!0;if(e&&typeof e=="object"&&"status"in e){let t=e.status;return t>=500&&t<600}return!1}var D=class extends Error{status;body;constructor(t,r){super(`HTTP ${t}`),this.status=t,this.body=r}},oe=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(t=M,r){this.facilitatorUrl=t.replace(/\/$/,""),this.timeoutMs=r?.timeoutMs??1e4,this.maxRetries=r?.maxRetries??3,this.retryBaseMs=r?.retryBaseMs??500}async fetchWithTimeout(t,r){let n=new AbortController,s=setTimeout(()=>n.abort(),this.timeoutMs);try{return await fetch(t,{...r,signal:n.signal})}finally{clearTimeout(s)}}async fetchWithRetry(t,r){let n;for(let s=0;s<this.maxRetries;s++)try{let i=await this.fetchWithTimeout(t,r);if(!i.ok&&i.status>=500)throw new D(i.status,await i.text());return i}catch(i){if(n=i,s<this.maxRetries-1&&ut(i)){let p=this.retryBaseMs*Math.pow(2,s);await new Promise(u=>setTimeout(u,p));continue}throw i}throw n}async getSupported(){let t=Date.now();if(this.cachedSupported&&t-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let r=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!r.ok)throw new Error(`Facilitator /supported returned ${r.status}`);return this.cachedSupported=await r.json(),this.cacheTime=t,this.cachedSupported}async getFeePayer(t){let n=(await this.getSupported()).kinds.find(s=>s.x402Version===2&&(s.scheme==="exact"||s.scheme==="exact-approval")&&s.network===t);if(!n)throw new Error(`Facilitator does not support network "${t}" with a recognized scheme`);return n.extra?.feePayer}async getNetworkExtra(t){return(await this.getSupported()).kinds.find(s=>s.x402Version===2&&(s.scheme==="exact"||s.scheme==="exact-approval"||s.scheme==="batch-settlement")&&s.network===t)?.extra}async verifyPayment(t,r){try{let n=L(t),s=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:n,paymentRequirements:r})});return s.ok?await s.json():{isValid:!1,invalidReason:`facilitator_error_${s.status}`}}catch(n){return{isValid:!1,invalidReason:n instanceof D?`facilitator_error_${n.status}`:n instanceof Error&&n.name==="AbortError"?"facilitator_timeout":n instanceof Error?n.message:"unexpected_verify_error"}}}async settlePayment(t,r){try{let n=L(t),s=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:n,paymentRequirements:r})});return s.ok?{...await s.json(),network:r.network}:{success:!1,network:r.network,errorReason:`facilitator_error_${s.status}`}}catch(n){let s=n instanceof D?`facilitator_error_${n.status}`:n instanceof Error&&n.name==="AbortError"?"facilitator_timeout":n instanceof Error?n.message:"unexpected_settle_error";return{success:!1,network:r.network,errorReason:s}}}};function mt(e){if(se(e))return{address:ne,decimals:6};let t=Me[e];if(t){let r=Le[t]?.decimals??6;return{address:t,decimals:r}}return{address:ne,decimals:6}}function De(e){try{let t=L(e);return t?.accepted?.amount??t?.accepted?.maxAmountRequired}catch{return}}function H(e){let{payTo:t,facilitatorUrl:r=M,network:n=R,defaultTimeoutSeconds:s=60}=e,i=e.asset??mt(n),p=e.scheme??"exact";if(p==="tab"&&!se(n))throw new Error(`scheme 'tab' is SVM-only; got network "${n}"`);let u=new oe(r),o=null,d=new Map,c=3e4,a=Date.now();function y(l){let h=(l.maxTimeoutSeconds||s)*1e3;if(d.set(l.payTo,{accept:l,expiresAt:Date.now()+h}),Date.now()-a>c){let A=Date.now();for(let[g,v]of d)v.expiresAt<A&&d.delete(g);a=A}}function m(l){let h=d.get(l);if(h){if(h.expiresAt<Date.now()){d.delete(l);return}return h.accept}}async function f(l){return typeof t=="string"?t:t(l||{})}async function w(){if(o||(o=await u.getNetworkExtra(n)),se(n)&&!o?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${n}"`);return{...o?.feePayer?{feePayer:o.feePayer}:{},decimals:o?.decimals??i.decimals,name:o?.name,version:o?.version,...p==="batch-settlement"&&o?.receiverAuthorizer?{receiverAuthorizer:o.receiverAuthorizer}:{},...p==="tab"?{voucherHeader:"x-tab-voucher",registrationEncoding:"base64(188-byte sessionRegisterMessage)"}:{}}}async function U(l,h){let{amountAtomic:A,timeoutSeconds:g=s}=h,v=await w(),b={scheme:p,network:n,amount:A,maxAmountRequired:A,asset:i.address,payTo:l,maxTimeoutSeconds:g,extra:v};return y(b),b}async function q(l){let h=await f({amountAtomic:l.amountAtomic,resourceUrl:l.resourceUrl});return U(h,l)}async function z(l){let{resourceUrl:h,description:A,mimeType:g="application/json"}=l,v={url:h,description:A,mimeType:g},b=await q(l);return{x402Version:2,resource:v,accepts:[b],error:"Payment required"}}function O(l){return ie(l)}function ae(l){return{status:402,headers:{"PAYMENT-REQUIRED":O(l)},body:{}}}async function W(l,h){if(!h){let A=await f({paymentHeader:l});h=m(A),h||(h=await U(A,{amountAtomic:De(l)??"0",resourceUrl:""}))}return u.verifyPayment(l,h)}async function F(l,h){if(!h){let A=await f({paymentHeader:l});h=m(A),h||(h=await U(A,{amountAtomic:De(l)??"0",resourceUrl:""}))}return u.settlePayment(l,h)}return{buildRequirements:z,encodeRequirements:O,create402Response:ae,verifyPayment:W,settlePayment:F,getPaymentAccept:q,network:n,assetDecimals:i.decimals,facilitator:u}}var dt={"solana:mainnet":R};function gt(e){let t=dt[e.network];if(!t)throw new Error(`tabChallengeMiddleware: unsupported network "${e.network}"`);let r=typeof e.sellerPubkey=="string"?e.sellerPubkey:e.sellerPubkey.toBase58();new pt(r);let n=H({payTo:r,network:t,scheme:"tab",facilitatorUrl:e.facilitatorUrl}),s=C(e.perUnit);return async(i,p,u)=>{if(i.headers[I])return u();try{let o=`${i.protocol}://${i.get("host")}${i.originalUrl}`,d=await n.buildRequirements({amountAtomic:s,resourceUrl:o,description:e.description}),c=n.create402Response(d);p.set(c.headers).status(c.status).json(c.body)}catch(o){let d=o?.message??String(o);p.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:d})}}}import{PublicKey as ht}from"@solana/web3.js";var yt={"solana:mainnet":R};function ft(e){let t=yt[e.network];if(!t)throw new Error(`tabOrExactMiddleware: unsupported network "${e.network}"`);let r=typeof e.sellerPubkey=="string"?e.sellerPubkey:e.sellerPubkey.toBase58();new ht(r);let n=H({payTo:r,network:t,scheme:"tab",facilitatorUrl:e.facilitatorUrl}),s=H({payTo:r,network:t,scheme:"exact",facilitatorUrl:e.facilitatorUrl}),i=C(e.perUnit),p=xe({connection:e.connection,sellerPubkey:r,network:e.network,perUnit:e.perUnit,settle:"on-close",facilitatorUrl:e.facilitatorUrl});return async(u,o,d)=>{if(u.headers[I])return p(u,o,d);let c=`${u.protocol}://${u.get("host")}${u.originalUrl}`,a=u.headers["payment-signature"];if(a){let y;try{y=await s.getPaymentAccept({amountAtomic:i,resourceUrl:c,description:e.description})}catch(m){let f=m?.message??String(m);o.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:f});return}try{let m=await s.verifyPayment(a,y);if(!m.isValid){o.status(402).json({error:"Payment verification failed",reason:m.invalidReason});return}let f=await s.settlePayment(a,y);if(!f.success){o.status(402).json({error:"Payment settlement failed",reason:f.errorReason});return}return u.x402={transaction:f.transaction,payer:m.payer??"",network:f.network||t},o.setHeader("PAYMENT-RESPONSE",ie({success:!0,transaction:f.transaction,network:f.network||t,payer:m.payer??""})),d()}catch{o.status(500).json({error:"Payment processing error"});return}}try{let y={amountAtomic:i,resourceUrl:c,description:e.description},[m,f]=await Promise.all([n.buildRequirements(y),s.buildRequirements(y)]),w={...m,accepts:[...m.accepts,...f.accepts]};o.set({"PAYMENT-REQUIRED":n.encodeRequirements(w)}).status(402).json({error:"Payment required",accepts:w.accepts,resource:w.resource})}catch(y){let m=y?.message??String(y);o.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:m})}}}export{ue as FileChannelLedger,Te as FileVoucherStore,$ as InMemoryChannelLedger,Pe as InMemoryVoucherStore,E as InvalidRegistrationError,S as InvalidVoucherError,T as InvalidVoucherSignatureError,_ as OnChainVerificationError,x as ScopeViolationError,I as TAB_VOUCHER_HEADER,Ae as enforceScope,rt as openSse,he as parseRegistration,tt as requireTab,gt as tabChallengeMiddleware,xe as tabMiddleware,ft as tabOrExactMiddleware,ye as verifyRegistrationOnChain,fe as verifyVoucherSignature};
|
|
6
|
+
`),e.end())}return{charge:c,send:a,end:y}}import{promises as B}from"fs";import{join as nt,dirname as it}from"path";function st(e){return{payload:e.payload,sessionPublicKey:Ee(e.sessionPublicKey),sessionRegistration:Ee(e.sessionRegistration),sessionSignature:Ee(e.sessionSignature)}}function ot(e){return{payload:e.payload,sessionPublicKey:Ce(e.sessionPublicKey),sessionRegistration:Ce(e.sessionRegistration),sessionSignature:Ce(e.sessionSignature)}}function Ee(e){let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}function Ce(e){if(e.length%2!==0)throw new Error(`hex length must be even, got ${e.length}`);let t=new Uint8Array(e.length/2);for(let r=0;r<t.length;r++)t[r]=parseInt(e.substr(r*2,2),16);return t}var Pe=class{map=new Map;async get(t){return this.map.get(t)??null}async set(t,r){this.map.set(t,r)}async delete(t){this.map.delete(t)}},Te=class{constructor(t){this.dir=t}pathFor(t){if(!/^[a-z0-9_-]+$/i.test(t))throw new Error(`unsafe channelId for filesystem: ${t}`);return nt(this.dir,`${t}.json`)}async get(t){try{let r=await B.readFile(this.pathFor(t),"utf8");return ot(JSON.parse(r))}catch(r){if(r?.code==="ENOENT")return null;throw r}}async set(t,r){let n=this.pathFor(t);await B.mkdir(it(n),{recursive:!0});let i=`${n}.tmp`;await B.writeFile(i,JSON.stringify(st(r))),await B.rename(i,n)}async delete(t){try{await B.unlink(this.pathFor(t))}catch(r){if(r?.code!=="ENOENT")throw r}}};import{PublicKey as pt}from"@solana/web3.js";var R="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",Ve="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",$e="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var K="eip155:8453",X="eip155:84532",J="eip155:42161",Y="eip155:137",G="eip155:10",Z="eip155:43114",Q="eip155:56",ee="eip155:1187947933",te="eip155:324705682",re="eip155:1";var ne="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var Be="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",at="0x55d398326f99059fF775485246999027B3197955",Ke="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Me={[Q]:Ke,[K]:Be,[X]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[J]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[Y]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[G]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[Z]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[ee]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[te]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[re]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Le={[at]:{symbol:"USDT",decimals:18},[Ke]:{symbol:"USDC",decimals:18}};var Rr={[Q]:56,[K]:8453,[X]:84532,[J]:42161,[Y]:137,[G]:10,[Z]:43114,[ee]:1187947933,[te]:324705682,[re]:1},_r={[R]:"https://api.dexter.cash/api/solana/rpc",[Ve]:"https://api.devnet.solana.com",[$e]:"https://api.testnet.solana.com"},Nr={[Q]:"https://api.dexter.cash/api/evm/bsc/rpc",[K]:"https://api.dexter.cash/api/base/rpc",[X]:"https://sepolia.base.org",[J]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[Y]:"https://api.dexter.cash/api/evm/polygon/rpc",[G]:"https://api.dexter.cash/api/evm/optimism/rpc",[Z]:"https://api.dexter.cash/api/evm/avalanche/rpc",[ee]:"https://skale-base.skalenodes.com/v1/base",[te]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[re]:"https://eth.llamarpc.com"},M="https://x402.dexter.cash";function ie(e){return e.startsWith("solana:")||e==="solana"}function ct(e){if(typeof Buffer<"u")return Buffer.from(e,"utf-8").toString("base64");let t=new TextEncoder().encode(e),r="";for(let n=0;n<t.length;n++)r+=String.fromCharCode(t[n]);return btoa(r)}function lt(e){if(typeof Buffer<"u")return Buffer.from(e,"base64").toString("utf-8");let t=atob(e),r=new Uint8Array(t.length);for(let n=0;n<t.length;n++)r[n]=t.charCodeAt(n);return new TextDecoder().decode(r)}function se(e){return ct(JSON.stringify(e))}function L(e){return JSON.parse(lt(e))}function ut(e){if(e instanceof TypeError)return!0;if(e&&typeof e=="object"&&"status"in e){let t=e.status;return t>=500&&t<600}return!1}var D=class extends Error{status;body;constructor(t,r){super(`HTTP ${t}`),this.status=t,this.body=r}},oe=class{facilitatorUrl;cachedSupported=null;cacheTime=0;CACHE_TTL_MS=6e4;timeoutMs;maxRetries;retryBaseMs;constructor(t=M,r){this.facilitatorUrl=t.replace(/\/$/,""),this.timeoutMs=r?.timeoutMs??1e4,this.maxRetries=r?.maxRetries??3,this.retryBaseMs=r?.retryBaseMs??500}async fetchWithTimeout(t,r){let n=new AbortController,i=setTimeout(()=>n.abort(),this.timeoutMs);try{return await fetch(t,{...r,signal:n.signal})}finally{clearTimeout(i)}}async fetchWithRetry(t,r){let n;for(let i=0;i<this.maxRetries;i++)try{let s=await this.fetchWithTimeout(t,r);if(!s.ok&&s.status>=500)throw new D(s.status,await s.text());return s}catch(s){if(n=s,i<this.maxRetries-1&&ut(s)){let p=this.retryBaseMs*Math.pow(2,i);await new Promise(u=>setTimeout(u,p));continue}throw s}throw n}async getSupported(){let t=Date.now();if(this.cachedSupported&&t-this.cacheTime<this.CACHE_TTL_MS)return this.cachedSupported;let r=await this.fetchWithTimeout(`${this.facilitatorUrl}/supported`);if(!r.ok)throw new Error(`Facilitator /supported returned ${r.status}`);return this.cachedSupported=await r.json(),this.cacheTime=t,this.cachedSupported}async getFeePayer(t){let n=(await this.getSupported()).kinds.find(i=>i.x402Version===2&&(i.scheme==="exact"||i.scheme==="exact-approval")&&i.network===t);if(!n)throw new Error(`Facilitator does not support network "${t}" with a recognized scheme`);return n.extra?.feePayer}async getNetworkExtra(t){return(await this.getSupported()).kinds.find(i=>i.x402Version===2&&(i.scheme==="exact"||i.scheme==="exact-approval"||i.scheme==="batch-settlement")&&i.network===t)?.extra}async verifyPayment(t,r){try{let n=L(t),i=await this.fetchWithRetry(`${this.facilitatorUrl}/verify`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:n,paymentRequirements:r})});return i.ok?await i.json():{isValid:!1,invalidReason:`facilitator_error_${i.status}`}}catch(n){return{isValid:!1,invalidReason:n instanceof D?`facilitator_error_${n.status}`:n instanceof Error&&n.name==="AbortError"?"facilitator_timeout":n instanceof Error?n.message:"unexpected_verify_error"}}}async settlePayment(t,r){try{let n=L(t),i=await this.fetchWithRetry(`${this.facilitatorUrl}/settle`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({x402Version:2,paymentPayload:n,paymentRequirements:r})});return i.ok?{...await i.json(),network:r.network}:{success:!1,network:r.network,errorReason:`facilitator_error_${i.status}`}}catch(n){let i=n instanceof D?`facilitator_error_${n.status}`:n instanceof Error&&n.name==="AbortError"?"facilitator_timeout":n instanceof Error?n.message:"unexpected_settle_error";return{success:!1,network:r.network,errorReason:i}}}};function mt(e){if(ie(e))return{address:ne,decimals:6};let t=Me[e];if(t){let r=Le[t]?.decimals??6;return{address:t,decimals:r}}return{address:ne,decimals:6}}function De(e){try{let t=L(e);return t?.accepted?.amount??t?.accepted?.maxAmountRequired}catch{return}}function H(e){let{payTo:t,facilitatorUrl:r=M,network:n=R,defaultTimeoutSeconds:i=60}=e,s=e.asset??mt(n),p=e.scheme??"exact";if(p==="tab"&&!ie(n))throw new Error(`scheme 'tab' is SVM-only; got network "${n}"`);let u=new oe(r),o=null,d=new Map,c=3e4,a=Date.now();function y(l){let h=(l.maxTimeoutSeconds||i)*1e3;if(d.set(l.payTo,{accept:l,expiresAt:Date.now()+h}),Date.now()-a>c){let A=Date.now();for(let[g,v]of d)v.expiresAt<A&&d.delete(g);a=A}}function m(l){let h=d.get(l);if(h){if(h.expiresAt<Date.now()){d.delete(l);return}return h.accept}}async function f(l){return typeof t=="string"?t:t(l||{})}async function w(){if(o||(o=await u.getNetworkExtra(n)),ie(n)&&!o?.feePayer)throw new Error(`Facilitator does not provide feePayer for network "${n}"`);return{...o?.feePayer?{feePayer:o.feePayer}:{},decimals:o?.decimals??s.decimals,name:o?.name,version:o?.version,...p==="batch-settlement"&&o?.receiverAuthorizer?{receiverAuthorizer:o.receiverAuthorizer}:{},...p==="tab"?{voucherHeader:"x-tab-voucher",registrationEncoding:"base64(188-byte sessionRegisterMessage)"}:{}}}async function U(l,h){let{amountAtomic:A,timeoutSeconds:g=i}=h,v=await w(),b={scheme:p,network:n,amount:A,maxAmountRequired:A,asset:s.address,payTo:l,maxTimeoutSeconds:g,extra:v};return y(b),b}async function q(l){let h=await f({amountAtomic:l.amountAtomic,resourceUrl:l.resourceUrl});return U(h,l)}async function z(l){let{resourceUrl:h,description:A,mimeType:g="application/json"}=l,v={url:h,description:A,mimeType:g},b=await q(l);return{x402Version:2,resource:v,accepts:[b],error:"Payment required"}}function k(l){return se(l)}function ae(l){return{status:402,headers:{"PAYMENT-REQUIRED":k(l)},body:{}}}async function W(l,h){if(!h){let A=await f({paymentHeader:l});h=m(A),h||(h=await U(A,{amountAtomic:De(l)??"0",resourceUrl:""}))}return u.verifyPayment(l,h)}async function F(l,h){if(!h){let A=await f({paymentHeader:l});h=m(A),h||(h=await U(A,{amountAtomic:De(l)??"0",resourceUrl:""}))}return u.settlePayment(l,h)}return{buildRequirements:z,encodeRequirements:k,create402Response:ae,verifyPayment:W,settlePayment:F,getPaymentAccept:q,network:n,assetDecimals:s.decimals,facilitator:u}}var dt={"solana:mainnet":R};function gt(e){let t=dt[e.network];if(!t)throw new Error(`tabChallengeMiddleware: unsupported network "${e.network}"`);let r=typeof e.sellerPubkey=="string"?e.sellerPubkey:e.sellerPubkey.toBase58();new pt(r);let n=H({payTo:r,network:t,scheme:"tab",facilitatorUrl:e.facilitatorUrl}),i=C(e.perUnit);return async(s,p,u)=>{if(s.headers[I])return u();try{let o=`${s.protocol}://${s.get("host")}${s.originalUrl}`,d=await n.buildRequirements({amountAtomic:i,resourceUrl:o,description:e.description}),c=n.create402Response(d);p.set(c.headers).status(c.status).json(c.body)}catch(o){let d=o?.message??String(o);p.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:d})}}}import{PublicKey as ht}from"@solana/web3.js";var yt={"solana:mainnet":R};function ft(e){let t=yt[e.network];if(!t)throw new Error(`tabOrExactMiddleware: unsupported network "${e.network}"`);let r=typeof e.sellerPubkey=="string"?e.sellerPubkey:e.sellerPubkey.toBase58();new ht(r);let n=H({payTo:r,network:t,scheme:"tab",facilitatorUrl:e.facilitatorUrl}),i=H({payTo:r,network:t,scheme:"exact",facilitatorUrl:e.facilitatorUrl}),s=C(e.perUnit),p=xe({connection:e.connection,sellerPubkey:r,network:e.network,perUnit:e.perUnit,settle:"on-close",facilitatorUrl:e.facilitatorUrl});return async(u,o,d)=>{if(u.headers[I])return p(u,o,d);let c=`${u.protocol}://${u.get("host")}${u.originalUrl}`,a=u.headers["payment-signature"];if(a){let y;try{y=await i.getPaymentAccept({amountAtomic:s,resourceUrl:c,description:e.description})}catch(m){let f=m?.message??String(m);o.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:f});return}try{let m=await i.verifyPayment(a,y);if(!m.isValid){o.status(402).json({error:"Payment verification failed",reason:m.invalidReason});return}let f=await i.settlePayment(a,y);if(!f.success){o.status(402).json({error:"Payment settlement failed",reason:f.errorReason});return}return u.x402={transaction:f.transaction,payer:m.payer??"",network:f.network||t},o.setHeader("PAYMENT-RESPONSE",se({success:!0,transaction:f.transaction,network:f.network||t,payer:m.payer??""})),d()}catch{o.status(500).json({error:"Payment processing error"});return}}try{let y={amountAtomic:s,resourceUrl:c,description:e.description},[m,f]=await Promise.all([n.buildRequirements(y),i.buildRequirements(y)]),w={...m,accepts:[...m.accepts,...f.accepts]};o.set({"PAYMENT-REQUIRED":n.encodeRequirements(w)}).status(402).json({error:"Payment required",accepts:w.accepts,resource:w.resource})}catch(y){let m=y?.message??String(y);o.status(503).set({"Retry-After":"5"}).json({error:"challenge_unavailable",detail:m})}}}export{ue as FileChannelLedger,Te as FileVoucherStore,$ as InMemoryChannelLedger,Pe as InMemoryVoucherStore,E as InvalidRegistrationError,S as InvalidVoucherError,T as InvalidVoucherSignatureError,_ as OnChainVerificationError,x as ScopeViolationError,I as TAB_VOUCHER_HEADER,Ae as enforceScope,rt as openSse,he as parseRegistration,tt as requireTab,gt as tabChallengeMiddleware,xe as tabMiddleware,ft as tabOrExactMiddleware,ye as verifyRegistrationOnChain,fe as verifyVoucherSignature};
|
|
@@ -52,7 +52,14 @@ interface VaultAdapter {
|
|
|
52
52
|
interface TabState {
|
|
53
53
|
/** Whether the tab is currently open (on chain) and accepting vouchers. */
|
|
54
54
|
isOpen: boolean;
|
|
55
|
-
/** Cumulative amount spent against this tab so far
|
|
55
|
+
/** Cumulative amount spent against this tab so far — the SESSION-LIFETIME
|
|
56
|
+
* odometer, matching the on-chain cumulative semantics. For a
|
|
57
|
+
* grant-resumed tab (`tabFromGrant`) this INCLUDES the on-chain frontier
|
|
58
|
+
* the tab resumed above, NOT just this process's spend — a receipt or
|
|
59
|
+
* meter that displays this field as "what this run spent" would overstate
|
|
60
|
+
* by the entire frontier. This-process spend = `spent` minus the frontier
|
|
61
|
+
* the tab was constructed at. (openTab tabs start at 0, where the two
|
|
62
|
+
* readings agree.) */
|
|
56
63
|
spent: HumanAmount;
|
|
57
64
|
/** Remaining headroom under the session's cap. */
|
|
58
65
|
remaining: HumanAmount;
|
|
@@ -111,10 +118,18 @@ interface Tab {
|
|
|
111
118
|
}
|
|
112
119
|
/** Result of `Tab.close()`. */
|
|
113
120
|
interface TabCloseResult {
|
|
114
|
-
/** Cumulative human amount settled on chain.
|
|
121
|
+
/** Cumulative human amount settled on chain. For a grant-resumed tab
|
|
122
|
+
* (`tabFromGrant`) this is the session's lifetime odometer — frontier +
|
|
123
|
+
* this process's spend — matching the on-chain cumulative semantics. */
|
|
115
124
|
settledAmount: HumanAmount;
|
|
116
125
|
/** Facilitator's on-chain settlement signature. */
|
|
117
126
|
settleTx: string;
|
|
127
|
+
/** Whether close() revoked the session on chain. `openTab` tabs revoke
|
|
128
|
+
* (passkey prompt); `tabFromGrant` tabs are settle-only — the grant
|
|
129
|
+
* holder has no passkey, so the session PDA stays live until the wallet
|
|
130
|
+
* owner revokes it or it expiry-sweeps. Absent on results predating this
|
|
131
|
+
* field. */
|
|
132
|
+
sessionRevoked?: boolean;
|
|
118
133
|
/** Atomic amount moved by the final settle, before any facilitator fee.
|
|
119
134
|
* Absent when the facilitator predates fee support. */
|
|
120
135
|
grossAmount?: string;
|
|
@@ -52,7 +52,14 @@ interface VaultAdapter {
|
|
|
52
52
|
interface TabState {
|
|
53
53
|
/** Whether the tab is currently open (on chain) and accepting vouchers. */
|
|
54
54
|
isOpen: boolean;
|
|
55
|
-
/** Cumulative amount spent against this tab so far
|
|
55
|
+
/** Cumulative amount spent against this tab so far — the SESSION-LIFETIME
|
|
56
|
+
* odometer, matching the on-chain cumulative semantics. For a
|
|
57
|
+
* grant-resumed tab (`tabFromGrant`) this INCLUDES the on-chain frontier
|
|
58
|
+
* the tab resumed above, NOT just this process's spend — a receipt or
|
|
59
|
+
* meter that displays this field as "what this run spent" would overstate
|
|
60
|
+
* by the entire frontier. This-process spend = `spent` minus the frontier
|
|
61
|
+
* the tab was constructed at. (openTab tabs start at 0, where the two
|
|
62
|
+
* readings agree.) */
|
|
56
63
|
spent: HumanAmount;
|
|
57
64
|
/** Remaining headroom under the session's cap. */
|
|
58
65
|
remaining: HumanAmount;
|
|
@@ -111,10 +118,18 @@ interface Tab {
|
|
|
111
118
|
}
|
|
112
119
|
/** Result of `Tab.close()`. */
|
|
113
120
|
interface TabCloseResult {
|
|
114
|
-
/** Cumulative human amount settled on chain.
|
|
121
|
+
/** Cumulative human amount settled on chain. For a grant-resumed tab
|
|
122
|
+
* (`tabFromGrant`) this is the session's lifetime odometer — frontier +
|
|
123
|
+
* this process's spend — matching the on-chain cumulative semantics. */
|
|
115
124
|
settledAmount: HumanAmount;
|
|
116
125
|
/** Facilitator's on-chain settlement signature. */
|
|
117
126
|
settleTx: string;
|
|
127
|
+
/** Whether close() revoked the session on chain. `openTab` tabs revoke
|
|
128
|
+
* (passkey prompt); `tabFromGrant` tabs are settle-only — the grant
|
|
129
|
+
* holder has no passkey, so the session PDA stays live until the wallet
|
|
130
|
+
* owner revokes it or it expiry-sweeps. Absent on results predating this
|
|
131
|
+
* field. */
|
|
132
|
+
sessionRevoked?: boolean;
|
|
118
133
|
/** Atomic amount moved by the final settle, before any facilitator fee.
|
|
119
134
|
* Absent when the facilitator predates fee support. */
|
|
120
135
|
grossAmount?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dexterai/x402",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "Full-stack x402 SDK - add paid API monetization to any endpoint. Express middleware, React hooks, Access Pass, dynamic pricing. Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, SKALE.",
|
|
5
5
|
"author": "Dexter",
|
|
6
6
|
"license": "MIT",
|