mppx 0.13.2 → 0.13.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/cli/cli.js +3 -3
- package/dist/cli/plugins/index.js +1 -1
- package/dist/cli/validate/helpers.d.ts +1 -0
- package/dist/cli/validate/helpers.js +2 -1
- package/dist/internal/version.d.ts +2 -2
- package/dist/internal/version.js +1 -1
- package/dist/server/Mppx.d.ts +1 -1
- package/dist/server/Mppx.js +6 -3
- package/dist/server/internal/challengeMeta.d.ts +5 -0
- package/dist/server/internal/challengeMeta.js +14 -0
- package/dist/tempo/server/Methods.d.ts +5 -0
- package/dist/tempo/server/Methods.js +5 -1
- package/dist/tempo/server/index.d.ts +1 -1
- package/dist/tempo/server/internal/html.gen.js +1 -1
- package/dist/tempo/session/client/Transports.js +39 -12
- package/dist/tempo/session/precompile/Chain.d.ts +4 -0
- package/dist/tempo/session/precompile/Chain.js +8 -2
- package/dist/tempo/session/server/ChannelStore.d.ts +8 -0
- package/dist/tempo/session/server/ChannelStore.js +17 -0
- package/dist/tempo/session/server/CredentialVerification.d.ts +3 -1
- package/dist/tempo/session/server/CredentialVerification.js +56 -11
- package/dist/tempo/session/server/Session.d.ts +4 -2
- package/dist/tempo/session/server/Session.js +23 -5
- package/dist/tempo/session/server/Settlement.d.ts +40 -1
- package/dist/tempo/session/server/Settlement.js +105 -34
- package/dist/tempo/session/server/index.d.ts +1 -1
- package/dist/x402/server/EvmCharge.js +10 -3
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import{createClient as e,createTransport as t,custom as n,encodeFunctionData as
|
|
|
4
4
|
`);switch(t){case`message`:return{type:`message`,data:r};case`payment-need-voucher`:{let e=ao(r);return eo(e)?{type:`payment-need-voucher`,data:e}:null}case`payment-receipt`:{let e=ao(r);return to(e)?{type:`payment-receipt`,data:e}:null}default:return{type:`message`,data:r}}}function ao(e){try{return JSON.parse(e)}catch{return null}}function oo(e){return JSON.stringify({mpp:`authorization`,authorization:e})}function so(){return JSON.stringify({mpp:`payment-close-request`})}function co(e){let t=lo(e);return t?t.mpp===`authorization`&&typeof t.authorization==`string`?{mpp:`authorization`,authorization:t.authorization}:t.mpp===`message`&&typeof t.data==`string`?{mpp:`message`,data:t.data}:t.mpp===`payment-close-request`?{mpp:`payment-close-request`}:t.mpp===`payment-close-ready`&&to(t.data)?{mpp:`payment-close-ready`,data:t.data}:t.mpp===`payment-error`&&typeof t.status==`number`&&typeof t.message==`string`?{mpp:`payment-error`,status:t.status,message:t.message}:t.mpp===`payment-need-voucher`&&eo(t.data)?{mpp:`payment-need-voucher`,data:t.data}:t.mpp===`payment-receipt`&&to(t.data)?{mpp:`payment-receipt`,data:t.data}:null:null}function lo(e){try{let t=JSON.parse(e);return typeof t!=`object`||!t?null:t}catch{return null}}const uo=`0x4d50500000000000000000000000000000000000`;function fo(e){return BigInt(e.authorizedSigner)===0n?e.payer:e.authorizedSigner}function po(e){let t=x.encode(x.from([`address payer`,`address payee`,`address operator`,`address token`,`bytes32 salt`,`address authorizedSigner`,`bytes32 expiringNonceHash`,`address escrow`,`uint256 chainId`]),[e.payer,e.payee,e.operator,e.token,e.salt,e.authorizedSigner,e.expiringNonceHash,e.escrow??`0x4d50500000000000000000000000000000000000`,BigInt(e.chainId)]);return w.keccak256(t)}function mo(e){return he.encodeForSigning(e)}function ho(e){let{feePayer:t,transaction:n}=e;return t?{...n,feePayerSignature:null}:n}function go(e,t){return w.keccak256(T.concat(mo(e),t.sender))}const _o=[{name:`payer`,type:`address`},{name:`payee`,type:`address`},{name:`operator`,type:`address`},{name:`token`,type:`address`},{name:`salt`,type:`bytes32`},{name:`authorizedSigner`,type:`address`},{name:`expiringNonceHash`,type:`bytes32`}],vo=[{name:`settled`,type:`uint96`},{name:`deposit`,type:`uint96`},{name:`closeRequestedAt`,type:`uint32`}],yo={name:`descriptor`,type:`tuple`,components:_o},bo=[{type:`function`,name:`CLOSE_GRACE_PERIOD`,stateMutability:`view`,inputs:[],outputs:[{type:`uint64`}]},{type:`function`,name:`VOUCHER_TYPEHASH`,stateMutability:`view`,inputs:[],outputs:[{type:`bytes32`}]},{type:`function`,name:`open`,stateMutability:`nonpayable`,inputs:[{name:`payee`,type:`address`},{name:`operator`,type:`address`},{name:`token`,type:`address`},{name:`deposit`,type:`uint96`},{name:`salt`,type:`bytes32`},{name:`authorizedSigner`,type:`address`}],outputs:[{name:`channelId`,type:`bytes32`}]},{type:`function`,name:`settle`,stateMutability:`nonpayable`,inputs:[yo,{name:`cumulativeAmount`,type:`uint96`},{name:`signature`,type:`bytes`}],outputs:[]},{type:`function`,name:`topUp`,stateMutability:`nonpayable`,inputs:[yo,{name:`additionalDeposit`,type:`uint96`}],outputs:[]},{type:`function`,name:`close`,stateMutability:`nonpayable`,inputs:[yo,{name:`cumulativeAmount`,type:`uint96`},{name:`captureAmount`,type:`uint96`},{name:`signature`,type:`bytes`}],outputs:[]},{type:`function`,name:`requestClose`,stateMutability:`nonpayable`,inputs:[yo],outputs:[]},{type:`function`,name:`withdraw`,stateMutability:`nonpayable`,inputs:[yo],outputs:[]},{type:`function`,name:`getChannel`,stateMutability:`view`,inputs:[yo],outputs:[{type:`tuple`,components:[{name:`descriptor`,type:`tuple`,components:_o},{name:`state`,type:`tuple`,components:vo}]}]},{type:`function`,name:`getChannelState`,stateMutability:`view`,inputs:[{name:`channelId`,type:`bytes32`}],outputs:[{type:`tuple`,components:vo}]},{type:`function`,name:`getChannelStatesBatch`,stateMutability:`view`,inputs:[{name:`channelIds`,type:`bytes32[]`}],outputs:[{type:`tuple[]`,components:vo}]},{type:`function`,name:`computeChannelId`,stateMutability:`view`,inputs:[{name:`payer`,type:`address`},{name:`payee`,type:`address`},{name:`operator`,type:`address`},{name:`token`,type:`address`},{name:`salt`,type:`bytes32`},{name:`authorizedSigner`,type:`address`},{name:`expiringNonceHash`,type:`bytes32`}],outputs:[{type:`bytes32`}]},{type:`function`,name:`getVoucherDigest`,stateMutability:`view`,inputs:[{name:`channelId`,type:`bytes32`},{name:`cumulativeAmount`,type:`uint96`}],outputs:[{type:`bytes32`}]},{type:`function`,name:`domainSeparator`,stateMutability:`view`,inputs:[],outputs:[{type:`bytes32`}]},{type:`event`,name:`ChannelOpened`,inputs:[{name:`channelId`,type:`bytes32`,indexed:!0},{name:`payer`,type:`address`,indexed:!0},{name:`payee`,type:`address`,indexed:!0},{name:`operator`,type:`address`},{name:`token`,type:`address`},{name:`authorizedSigner`,type:`address`},{name:`salt`,type:`bytes32`},{name:`expiringNonceHash`,type:`bytes32`},{name:`deposit`,type:`uint96`}]},{type:`event`,name:`Settled`,inputs:[{name:`channelId`,type:`bytes32`,indexed:!0},{name:`payer`,type:`address`,indexed:!0},{name:`payee`,type:`address`,indexed:!0},{name:`cumulativeAmount`,type:`uint96`},{name:`deltaPaid`,type:`uint96`},{name:`newSettled`,type:`uint96`}]},{type:`event`,name:`TopUp`,inputs:[{name:`channelId`,type:`bytes32`,indexed:!0},{name:`payer`,type:`address`,indexed:!0},{name:`payee`,type:`address`,indexed:!0},{name:`additionalDeposit`,type:`uint96`},{name:`newDeposit`,type:`uint96`}]},{type:`event`,name:`CloseRequested`,inputs:[{name:`channelId`,type:`bytes32`,indexed:!0},{name:`payer`,type:`address`,indexed:!0},{name:`payee`,type:`address`,indexed:!0},{name:`closeGraceEnd`,type:`uint256`}]},{type:`event`,name:`ChannelClosed`,inputs:[{name:`channelId`,type:`bytes32`,indexed:!0},{name:`payer`,type:`address`,indexed:!0},{name:`payee`,type:`address`,indexed:!0},{name:`settledToPayee`,type:`uint96`},{name:`refundedToPayer`,type:`uint96`}]},{type:`event`,name:`CloseRequestCancelled`,inputs:[{name:`channelId`,type:`bytes32`,indexed:!0},{name:`payer`,type:`address`,indexed:!0},{name:`payee`,type:`address`,indexed:!0}]}];function xo(e,t){return{name:`TIP20 Channel Reserve`,version:`1`,chainId:t,verifyingContract:e}}const So={Voucher:[{name:`channelId`,type:`bytes32`},{name:`cumulativeAmount`,type:`uint96`}]},Co={CloseAuthorization:[{name:`channelId`,type:`bytes32`},{name:`cumulativeAmount`,type:`uint96`}]};function wo(e,t){return pe.getVoucherSignPayload({chainId:e,channelId:t.channelId,cumulativeAmount:t.cumulativeAmount})}function To(e,t,n){return e.toLowerCase()===pe.address.toLowerCase()?wo(t,n):o({domain:xo(e,t),types:So,primaryType:`Voucher`,message:{channelId:n.channelId,cumulativeAmount:n.cumulativeAmount}})}function Eo(e){return e===`secp256k1`||e===`p256`||e===`webAuthn`}function Do(e,t){return ae.signVoucher(e,{chainId:t.chainId,channel:t.channelId,cumulativeAmount:t.cumulativeAmount})}async function Oo(e,t,n,r,i){let a=await(async()=>{if(r.toLowerCase()===pe.address.toLowerCase())try{return await Do(t,{chainId:i,channelId:n.channelId,cumulativeAmount:n.cumulativeAmount})}catch{}return v(e,{account:t,domain:xo(r,i),types:So,primaryType:`Voucher`,message:n})})(),o=I.from(a);if(!Eo(o.type))throw Error(`TIP-1034 vouchers require a TIP-1020 primitive signature; received "${o.type}".`);return I.serialize(o)}async function ko(e,t,n,r,i){let a=await v(e,{account:t,domain:xo(r,i),types:Co,primaryType:`CloseAuthorization`,message:n}),o=I.from(a);if(!Eo(o.type))throw Error(`TIP-1034 close authorizations require a TIP-1020 primitive signature; received "${o.type}".`);return I.serialize(o)}function Ao(e,t,n,r){try{let i=I.from(n.signature);if(!Eo(i.type)||I.serialize(i).toLowerCase()!==n.signature.toLowerCase())return!1;let a=To(e,t,n),o=I.extractAddress({payload:a,signature:i});return I.verify(i,{address:o,payload:a})&&aa(o,r)}catch{return!1}}function jo(e){return typeof e==`object`&&!!e}function Mo(e){return typeof e==`string`&&c(e,{strict:!1})?e:void 0}function No(e){return Mo(e.accessKeyAddress)}function Po(){let e=BigInt(Math.floor(Date.now()/1e3))-60n;return e<=0n?0:Number(BigInt(T.random(8))%e)}function Fo(e){return No(e)??e.address}async function Io(e,t){let{account:n,calls:r,feePayer:i,feeToken:a,validAfter:o}=t;return p(e,{account:n,calls:r,nonceKey:`expiring`,...i?{feePayer:!0}:{},feeToken:a,...o===void 0?{}:{validAfter:o}})}async function Lo(e,t){return await _(e,t)}function Ro(e,t,n=!1){let r=e.request.methodDetails,i=jo(r)?Mo(r.escrowContract)??Mo(r.escrow):void 0,a=t??`0x4d50500000000000000000000000000000000000`;if(i&&!Bo(i,a)&&(!n||t!==void 0))throw Error(`Tempo session escrow ${i} does not match client escrow ${a}.`);return i&&!Bo(i,a)?i:a}function zo(e,t,n,r){return Et({challenge:e,payload:t,source:`did:pkh:eip155:${n}:${r.address}`})}function Bo(e,t){return e.toLowerCase()===t.toLowerCase()}async function Vo(e,t,n,r,i,a=uo){let o=po({...n,chainId:i,escrow:a}),s=Ka(r),c=await Oo(e,t,{channelId:o,cumulativeAmount:s},a,i);return{action:`voucher`,channelId:o,descriptor:n,cumulativeAmount:s.toString(),signature:c}}async function Ho(e,t,n,r,i,a=uo){let o=await Vo(e,t,n,r,i,a),s=await ko(e,t,{channelId:o.channelId,cumulativeAmount:Ka(BigInt(o.cumulativeAmount))},a,i);return{action:`close`,channelId:o.channelId,descriptor:n,cumulativeAmount:o.cumulativeAmount,signature:o.signature,closeSignature:s}}async function Uo(e,t,n){let i=Fo(t),a=n.escrow??`0x4d50500000000000000000000000000000000000`,o=n.operator??`0x0000000000000000000000000000000000000000`,s=T.random(32),c=Ka(n.deposit),l=Ka(n.initialAmount),u=r({abi:bo,functionName:`open`,args:[n.payee,o,n.token,c,s,i]}),d=await Lo(e,await Io(e,{account:t,calls:[...n.prefixCalls??[],{to:a,data:u}],feePayer:n.feePayer,feeToken:n.feeToken??n.token})),f=ce.deserialize(d),p={authorizedSigner:i,expiringNonceHash:go(ho({...n.feePayer?{feePayer:!0}:{},transaction:f}),{sender:t.address}),operator:o,payee:n.payee,payer:t.address,salt:s,token:n.token},m=po({...p,chainId:n.chainId,escrow:a});return{action:`open`,type:`transaction`,channelId:m,transaction:d,signature:await Oo(e,t,{channelId:m,cumulativeAmount:l},a,n.chainId),descriptor:p,cumulativeAmount:l.toString(),authorizedSigner:p.authorizedSigner}}async function Wo(e,t,n,i,a,o,s=uo,c=[],l=n.token){let u=po({...n,chainId:a,escrow:s}),d=Ka(i);return{action:`topUp`,type:`transaction`,channelId:u,transaction:await Lo(e,await Io(e,{account:t,calls:[...c,{to:s,data:r({abi:bo,functionName:`topUp`,args:[n,d]})}],feePayer:o,feeToken:l,validAfter:Po()})),descriptor:n,additionalDeposit:d.toString()}}function Go(e){let{payee:t,token:n,escrow:r,chainId:i}=e;return`${t.toLowerCase()}:${n.toLowerCase()}:${r.toLowerCase()}:${i}`}function Ko(e){return Go({payee:e.descriptor.payee,token:e.descriptor.token,escrow:e.escrow,chainId:e.chainId})}function qo(){let e=new Map;return{get:t=>e.get(t),set(t){e.set(Ko(t),t)},delete(t){e.delete(t)}}}const Jo=2n**96n-1n;function Yo(e){if(e<0n||e>Jo)throw new K({reason:`amount exceeds uint96 range`})}async function Xo(e,t,n=uo,r){return Zo(await m(e,{address:n,abi:bo,functionName:`getChannelState`,args:[t],...r===void 0?{}:{blockNumber:r}}))}function Zo(e){return Yo(e.settled),Yo(e.deposit),{settled:e.settled,deposit:e.deposit,closeRequestedAt:e.closeRequestedAt}}const Qo=B.custom(e=>typeof e==`string`&&c(e,{strict:!1})),$o=B.custom(e=>typeof e==`string`&&/^0x[0-9a-fA-F]{64}$/.test(e)),es=B.custom(e=>typeof e==`string`&&/^0x[0-9a-fA-F]+$/.test(e)),ts=B.object({authorizedSigner:Qo,expiringNonceHash:$o,operator:Qo,payee:Qo,payer:Qo,salt:$o,token:Qo}),ns=Nt(B.object({acceptedCumulative:B.string(),chainId:B.number(),channelId:$o,closeRequestedAt:B.optional(B.string()),deposit:B.string(),descriptor:ts,escrow:Qo,highestVoucher:B.optional(B.object({channelId:$o,cumulativeAmount:B.string(),signature:es})),requiredCumulative:B.string(),settled:B.string(),spent:B.string(),units:B.optional(B.number())}));function rs(e){return ns.encode(e)}function is(e){return ns.decode(e)}const as={status:`idle`};function os(e){return{status:`active`,...e}}function ss(e,t){switch(t.type){case`challengeReceived`:return e.status===`closing`||e.status===`closed`?$(e,t):{state:{status:`challenged`,challengeId:t.challengeId},effects:[]};case`challenge`:return e.status!==`idle`&&e.status!==`active`?$(e,t):t.snapshot?{state:{status:`hydrating`,challengeId:t.challengeId,snapshot:t.snapshot},effects:[{type:`hydrate`,snapshot:t.snapshot}]}:{state:{status:`opening`,challengeId:t.challengeId},effects:[{type:`open`}]};case`hydrated`:return e.status===`hydrating`?{state:us(e.challengeId,t.snapshot),effects:[]}:$(e,t);case`activated`:return e.status===`closing`||e.status===`closed`?$(e,t):{state:Cs({challengeId:t.challengeId,entry:t.entry,spent:t.spent,units:t.units??0}),effects:[]};case`opened`:return e.status===`opening`?{state:ds(e.challengeId,t.receipt,t.descriptor,t.deposit),effects:[]}:$(e,t);case`receiptAccepted`:return e.status===`closing`||e.status===`closed`?$(e,t):{state:Es(t.receipt,t.entry),effects:[]};case`needVoucher`:return e.status===`active`?ls({challengeId:e.challengeId,descriptor:t.descriptor,event:t.event}):$(e,t);case`topUpStarted`:return e.status===`voucherNeeded`?{state:{status:`toppingUp`,challengeId:e.challengeId,channelId:e.channelId,descriptor:e.descriptor,deposit:e.deposit},effects:[]}:$(e,t);case`voucherAccepted`:return e.status!==`voucherNeeded`&&e.status!==`toppingUp`?$(e,t):{state:ds(e.challengeId,t.receipt,e.descriptor,t.deposit??e.deposit),effects:[]};case`settleStarted`:return e.status===`active`?{state:{status:`settling`,channelId:e.channelId,descriptor:e.descriptor,deposit:e.deposit},effects:[{type:`settle`,channelId:e.channelId}]}:$(e,t);case`settled`:return e.status===`settling`?{state:ds(t.receipt.challengeId,t.receipt,e.descriptor,t.deposit??e.deposit),effects:[]}:$(e,t);case`closeRequested`:return e.status===`active`?{state:{status:`closeRequested`,channelId:e.channelId,descriptor:e.descriptor},effects:[{type:`requestClose`,channelId:e.channelId}]}:$(e,t);case`withdrawable`:return e.status===`closeRequested`?{state:{status:`withdrawable`,channelId:e.channelId,descriptor:e.descriptor},effects:[{type:`withdraw`,channelId:e.channelId}]}:$(e,t);case`closeStarted`:return e.status!==`active`&&e.status!==`withdrawable`&&e.status!==`closeRequested`?$(e,t):{state:{status:`closing`,channelId:e.channelId,descriptor:e.descriptor},effects:[{type:`close`,channelId:e.channelId}]};case`closed`:return e.status!==`closing`&&e.status!==`withdrawable`?$(e,t):{state:{status:`closed`,channelId:e.channelId,descriptor:e.descriptor},effects:[]}}}function cs(e,t){let n=ss(e.state,t);return e.state=n.state,n}function ls(e){let{challengeId:t,descriptor:n,event:r}=e,i=BigInt(r.requiredCumulative),a=BigInt(r.deposit);return i>a?{state:{status:`toppingUp`,challengeId:t,channelId:r.channelId,descriptor:n,deposit:r.deposit},effects:[{type:`topUp`,channelId:r.channelId,amount:(i-a).toString()}]}:{state:{status:`voucherNeeded`,challengeId:t,channelId:r.channelId,descriptor:n,requiredCumulative:r.requiredCumulative,deposit:r.deposit},effects:[{type:`voucher`}]}}function us(e,t){return os({challengeId:e,channelId:t.channelId,descriptor:t.descriptor,acceptedCumulative:t.acceptedCumulative,deposit:t.deposit,spent:t.spent,units:t.units??0})}function ds(e,t,n,r){return os({challengeId:e,channelId:t.channelId,descriptor:n,acceptedCumulative:t.acceptedCumulative,deposit:r,spent:t.spent,units:t.units??0})}function $(e,t){throw Error(`Invalid session transition: ${e.status} + ${t.type}`)}function fs(e){let{cumulativeAmount:t,maxVoucherCumulative:n}=e;if(n!==null&&!(t<=n))throw Error(`requested voucher amount ${t} exceeds local maxDeposit ${n}`)}function ps(e){let{channel:t,maxVoucherCumulative:n,receipt:r}=e;if(!t||r.channelId!==t.channelId)return;let i=BigInt(r.acceptedCumulative),a=BigInt(r.spent);if(a>i)throw Error(`receipt spent exceeds accepted cumulative voucher amount`);if(i>t.cumulativeAmount)throw Error(`receipt accepted cumulative exceeds local voucher state`);if(a>t.cumulativeAmount)throw Error(`receipt spent exceeds local voucher state`);fs({cumulativeAmount:i,maxVoucherCumulative:n}),fs({cumulativeAmount:a,maxVoucherCumulative:n})}function ms(e){let{channel:t,maxVoucherCumulative:n,receipt:r,spent:i}=e;if(!r||r.channelId!==t?.channelId)return i;ps({channel:t,maxVoucherCumulative:n,receipt:r});let a=BigInt(r.spent);return i>a?i:a}function hs(e,t){return typeof e==`bigint`?e:d(e,t)}function gs(e){let{contextDepositRaw:t,maxDeposit:n,requestAmount:r,suggestedDepositRaw:i}=e;if(vs(r,n),t!==void 0){let e=BigInt(t);if(e<r)throw Error(`opening deposit ${e} below request amount ${r}`);return e}let a=i===void 0?void 0:BigInt(i),o=a!==void 0&&a>r?a:r;return n===void 0||o<n?o:n}function _s(e){let{deposit:t,maxDeposit:n,requiredCumulative:r,suggestedDeposit:i,topUpAmount:a}=e;if(r<=t)return 0n;fs({cumulativeAmount:r,maxVoucherCumulative:n??null});let o=r-t,s=a??i??o,c=s>o?s:o;if(n==null)return c;let l=n-t;return c<l?c:l}function vs(e,t){fs({cumulativeAmount:e,maxVoucherCumulative:t??null})}function ys(e){let{channel:t,currentSocket:n,lastChallenge:r}=e;if(!t?.opened)return;let i=n?.challenge??r,a=n?.channelId??t.channelId;if(!i)throw Error(`Cannot close session: no challenge available. This usually means close() was called on a SessionManager instance that was recreated after the session was opened. Use the same SessionManager instance that opened the session, or make a request first to receive a fresh 402 challenge.`);if(!a)throw Error(`Cannot close session: no channel ID available. The session may not have been fully opened.`);return{challenge:i,channel:t,channelId:a}}function bs(e){let{cumulativeAmount:t,spent:n}=e;return t>n?t:n}function xs(e){let{cumulativeAmount:t,readySpent:n,spent:r}=e;if(!Wa(n))throw Error(`close-ready spent is not a uint96 amount`);if(n<r)throw Error(`close-ready spent is below locally confirmed spend`);if(n>bs({cumulativeAmount:t,spent:r}))throw Error(`close-ready spent exceeds local voucher state`)}function Ss(e){let{challengeId:t,channelId:n,expectedCloseAmount:r,minimumSpent:i=0n,receipt:a}=e,o=Ga(r),s=Ga(a.spent);return o===void 0||s===void 0||!Wa(i)?!1:!!a.txHash&&a.challengeId===t&&a.channelId===n&&a.acceptedCumulative===r&&s>=i&&s<=o}function Cs(e){return os({challengeId:e.challengeId,channelId:e.entry.channelId,descriptor:e.entry.descriptor,acceptedCumulative:e.entry.cumulativeAmount.toString(),deposit:e.entry.deposit.toString(),spent:e.spent,units:e.units})}function ws(){return{channel:null,lastChallenge:null,lastUrl:null,spent:0n,socketSession:null,state:as}}function Ts(e){let{maxVoucherCumulative:t,receipt:n,runtime:r}=e;r.spent=ms({channel:r.channel,maxVoucherCumulative:t,receipt:n,spent:r.spent}),n&&r.channel?.channelId===n.channelId&&cs(r,{type:`receiptAccepted`,receipt:n,entry:r.channel})}function Es(e,t){return os({challengeId:e.challengeId,channelId:e.channelId,descriptor:t.descriptor,acceptedCumulative:e.acceptedCumulative,deposit:t.deposit.toString(),spent:e.spent,units:e.units??0})}function Ds(e){let{challengeId:t,channelId:n,closeReadyReceipt:r,cumulativeAmount:i,deliveredChunks:a=0n,socketChallengeId:o,socketChannelId:s,spent:c,tickCost:l=0n}=e;if(c>i)throw Error(`locally confirmed spend exceeds local voucher state`);if(r&&r.challengeId===t&&r.channelId===n){let e=Ga(r.spent);if(e===void 0)throw Error(`close-ready spent is not a uint96 amount`);return e>c?e:c}if(o===t&&s===n&&l>0n){let e=a*l,t=c>e?c:e;return t>i?i:t}return i}function Os(e){let{channel:t,channelId:n,challengeId:r,cumulativeAmount:i,spent:a,state:o}=e;if(!(!t||t.channelId!==n)&&(t.cumulativeAmount=i,r))return ss(o,{type:`activated`,challengeId:r,entry:t,spent:a.toString(),units:o.status===`active`?o.units:0}).state}function ks(e){return{channel:e.channel===null?null:{entry:e.channel,cumulativeAmount:e.channel.cumulativeAmount,deposit:e.channel.deposit,opened:e.channel.opened},spent:e.spent,state:e.state}}function As(e,t){return e.channel?(e.channel.entry.cumulativeAmount=e.channel.cumulativeAmount,e.channel.entry.deposit=e.channel.deposit,e.channel.entry.opened=e.channel.opened,{channel:e.channel.entry,spent:e.spent,state:e.state}):(t&&(t.opened=!1),{channel:null,spent:e.spent,state:e.state})}async function js(e){let{activeSocket:t,currentSocket:n,target:r}=e,i=n.closeReadyReceipt??await(async()=>(t.send(so()),e.waitForCloseReady()))(),a=BigInt(i.spent);xs({cumulativeAmount:r.channel.cumulativeAmount,readySpent:a,spent:e.spent});let o=await e.createSessionCredential(r.challenge,{action:`close`,channelId:r.channelId,descriptor:r.channel.descriptor,cumulativeAmountRaw:a.toString()}),s=a.toString();n.expectedCloseAmount=s;try{let i=e.waitForReceipt(e=>Ss({challengeId:r.challenge.id,channelId:r.channelId,expectedCloseAmount:s,minimumSpent:a,receipt:e}));t.send(oo(o));let c=await i;return t.close(),n.closeReadyReceipt=null,c}finally{n.expectedCloseAmount=null}}function Ms(e){return`cumulativeAmount`in e}function Ns(e){if(Ms(e))return BigInt(e.cumulativeAmount)}async function Ps(e,t){t.opened?await e.store.set(t):await e.store.delete(Ko(t)),e.notifyUpdate(t)}async function Fs(e,t,n){let r=Ns(n);if(r===void 0)return;let i=await e.store.get(t);i&&i.channelId.toLowerCase()===n.channelId.toLowerCase()&&(i.cumulativeAmount=i.cumulativeAmount>r?i.cumulativeAmount:r,n.action===`close`&&(i.opened=!1),await Ps(e,i))}const Is=B.custom(e=>typeof e==`string`&&/^0x[0-9a-fA-F]*$/.test(e)),Ls=B.custom(e=>typeof e==`string`&&/^0x[0-9a-fA-F]{64}$/.test(e)),Rs=B.object({account:B.optional(B.custom()),autoSwap:B.optional(B.custom()),action:B.optional(B.enum([`open`,`topUp`,`voucher`,`close`])),channelId:B.optional(Ls),cumulativeAmount:B.optional(V()),cumulativeAmountRaw:B.optional(B.string()),transaction:B.optional(Is),descriptor:B.optional(B.custom()),additionalDeposit:B.optional(V()),additionalDepositRaw:B.optional(B.string()),depositRaw:B.optional(B.string())});function zs(e){return e?.action!==void 0}function Bs(e){return zs(e)&&e.descriptor!==void 0}function Vs(e,t,n){let r=n===`additionalDeposit`?e.additionalDepositRaw:e.cumulativeAmountRaw,i=n===`additionalDeposit`?e.additionalDeposit:e.cumulativeAmount;if(r)return BigInt(r);if(i)return d(i,t)}function Hs(e,t,n,r){let i=Vs(e,t,n);if(i===void 0)throw Error(`${n} required for ${r} action`);return i}function Us(e){return typeof e==`object`&&!!e}function Ws(e){return typeof e==`string`&&c(e,{strict:!1})?e:void 0}function Gs(e){let t=e.request.methodDetails;return Us(t)?{chainId:typeof t.chainId==`number`?t.chainId:void 0,escrowContract:Ws(t.escrowContract),escrow:Ws(t.escrow),feePayer:typeof t.feePayer==`boolean`?t.feePayer:void 0,feeToken:Ws(t.feeToken),operator:Ws(t.operator),sessionSnapshot:Je(t,Ke.sessionSnapshot)}:{}}function Ks(e,t){if(typeof e==`string`&&c(e,{strict:!1}))return e;throw Error(`tempo session challenge missing ${t}`)}function qs(e){if(typeof e==`string`)return BigInt(e);throw Error(`tempo session challenge missing amount`)}function Js(e){return typeof e==`string`?e:void 0}async function Ys(e){let{allowCustomEscrow:t,challenge:n,escrowOverride:r,allowedChainIds:i,getClient:a}=e,o=Gs(n);(o.chainId!==void 0||i?.length===0)&&ea(i,o.chainId);let s=o.chainId??(i?.length===1?i[0]:void 0),c=await a({chainId:s});$i(c,s);let l=s??c.chain?.id;if(ea(i,l),!l)throw Error(`No chainId configured for TIP-1034 session challenge.`);let u=Ro(n,r,t),d=Ks(n.request.recipient,`recipient`),f=Ks(n.request.currency,`currency`);return{amount:qs(n.request.amount),challenge:n,chainId:l,client:c,escrow:u,feePayer:o.feePayer,feeToken:o.feeToken,key:Go({payee:d,token:f,escrow:u,chainId:l}),operator:o.operator,payee:d,snapshot:o.sessionSnapshot,suggestedDepositRaw:Js(n.request.suggestedDeposit),token:f}}async function Xs(e){let{channelId:t,client:n,descriptor:r,expected:i,readChannelState:a=Xo}=e,o=po({...r,chainId:i.chainId,escrow:i.escrow});Zs({channelId:t,descriptor:r,expectedChannelId:o,payee:i.payee,payer:i.payer,authorizedSigner:i.authorizedSigner,token:i.token});let s=await a(n,o,i.escrow);if(s.deposit===0n)throw Error(`Channel ${o} cannot be reused (closed or not found on-chain).`);if(s.closeRequestedAt!==0)throw Error(`Channel ${o} cannot be reused (pending close request).`);return{channelId:o,state:s}}function Zs(e){let{authorizedSigner:t,channelId:n,descriptor:r,expectedChannelId:i,payee:a,payer:o,token:s}=e;if(n&&n.toLowerCase()!==i.toLowerCase())throw Error(`context channelId does not match descriptor`);if(!Bo(r.payee,a))throw Error(`context descriptor payee does not match challenge`);if(!Bo(r.token,s))throw Error(`context descriptor token does not match challenge`);if(!Bo(r.payer,o))throw Error(`context descriptor payer does not match account`);if(!Bo(fo(r),t))throw Error(`context descriptor authorizedSigner does not match account`)}function Qs(e){let{context:t,snapshot:n}=e,r=t?.descriptor??n?.descriptor;if(r)return{...t,channelId:t?.channelId??n?.channelId,descriptor:r}}function $s(e){let{context:t,decimals:n,requestAmount:r,snapshot:i,settled:a}=e;if(i)return[BigInt(i.acceptedCumulative),BigInt(i.requiredCumulative),BigInt(i.spent)+r,a].reduce((e,t)=>t>e?t:e,0n);let o=Vs(t,n,`cumulativeAmount`);return o===void 0?a+r:o+r}async function ec(e){let{account:t,client:n,readChannelState:r,snapshot:i}=e,a=i.highestVoucher;if(!a)throw Error(`session snapshot is missing its highest signed voucher`);if(a.channelId.toLowerCase()!==i.channelId.toLowerCase())throw Error(`session snapshot voucher channelId does not match snapshot channelId`);let o=BigInt(i.acceptedCumulative),s=BigInt(a.cumulativeAmount),c=BigInt(i.requiredCumulative),l=BigInt(i.deposit),u=BigInt(i.settled),d=BigInt(i.spent);if(s!==o)throw Error(`session snapshot voucher amount does not match acceptedCumulative`);if(d>o)throw Error(`session snapshot spent exceeds acceptedCumulative`);if(u>l)throw Error(`session snapshot settled amount exceeds deposit`);if(!Ao(i.escrow,i.chainId,{channelId:a.channelId,cumulativeAmount:s,signature:a.signature},fo(i.descriptor)))throw Error(`session snapshot highest voucher signature is invalid`);let f=await Xs({channelId:i.channelId,client:n,descriptor:i.descriptor,expected:{chainId:i.chainId,escrow:i.escrow,payee:i.descriptor.payee,payer:t.address,authorizedSigner:Fo(t),token:i.descriptor.token},readChannelState:r}),p=[o,c,f.state.settled].reduce((e,t)=>t>e?t:e,0n);if(p>f.state.deposit)throw Error(`recovered session cumulative amount exceeds on-chain channel deposit`);return{entry:{channelId:f.channelId,cumulativeAmount:p,deposit:f.state.deposit,descriptor:i.descriptor,escrow:i.escrow,chainId:i.chainId,opened:!0},spent:d}}function tc(e,t){return Bo(e.address,t.payer)?Bo(Fo(e),fo(t)):!1}function nc(e){let{account:t,entry:n,context:r,decimals:i,maxDeposit:a,resolved:o}=e;if(zs(r)){if(!Bs(r))throw Error(`descriptor required for TIP-1034 session action`);return{type:`manual`,account:t,context:r,decimals:i,resolved:o}}if(!n&&r?.channelId&&!r.descriptor)throw Error(`descriptor required to reuse TIP-1034 channel`);let s=Qs({context:r,snapshot:o.snapshot});return!n&&s&&tc(t,s.descriptor)?{type:`recover`,account:t,context:s,decimals:i,maxDeposit:a,resolved:o}:n?.opened&&tc(t,n.descriptor)?{type:`voucher`,account:t,entry:n,maxDeposit:a,resolved:o}:{type:`open`,account:t,context:r,maxDeposit:a,resolved:o}}async function rc(e,t,n=!1){switch(e.type){case`open`:return ac(e,t,n);case`recover`:return oc(e,t);case`voucher`:return sc(e,t);case`manual`:return cc(e,t,n)}}async function ic(e,t){if(e)return await sa(t.client,{account:t.account,amountOut:t.amountOut,tokenOut:t.tokenOut,tokenIn:e.tokenIn,slippage:e.slippage})}async function ac(e,t,n){let{account:r,resolved:i}=e,a=gs({contextDepositRaw:e.context?.depositRaw,maxDeposit:e.maxDeposit,requestAmount:i.amount,suggestedDepositRaw:i.suggestedDepositRaw}),o=await Uo(i.client,r,{chainId:i.chainId,deposit:a,escrow:i.escrow,feePayer:i.feePayer,feeToken:i.feeToken,initialAmount:i.amount,operator:i.operator,payee:i.payee,prefixCalls:await ic(n,{account:r.address,amountOut:a,client:i.client,tokenOut:i.token}),token:i.token});return await Ps(t,{channelId:o.channelId,cumulativeAmount:i.amount,deposit:a,descriptor:o.descriptor,escrow:i.escrow,chainId:i.chainId,opened:!0}),o}async function oc(e,t){let{account:n,context:r,decimals:i,maxDeposit:a,resolved:o}=e,{descriptor:s}=r,c=await Xs({channelId:r.channelId,client:o.client,descriptor:s,expected:{chainId:o.chainId,escrow:o.escrow,payee:o.payee,payer:n.address,authorizedSigner:Fo(n),token:o.token}}),l=$s({context:r,decimals:i,requestAmount:o.amount,settled:c.state.settled,snapshot:o.snapshot});if(l>c.state.deposit)throw Error(`recovered voucher amount exceeds on-chain channel deposit`);vs(l,a);let u=await Vo(o.client,n,s,l,o.chainId,o.escrow);return await Ps(t,{channelId:c.channelId,cumulativeAmount:l,deposit:c.state.deposit,descriptor:s,escrow:o.escrow,chainId:o.chainId,opened:!0}),u}async function sc(e,t){let{account:n,entry:r,resolved:i}=e,a=r.cumulativeAmount+i.amount;vs(a,e.maxDeposit);let o=await Vo(i.client,n,r.descriptor,a,i.chainId,i.escrow);return r.cumulativeAmount=a,await Ps(t,r),o}async function cc(e,t,n){let{account:r,context:i,decimals:a,resolved:o}=e,{descriptor:s}=i,c=po({...s,chainId:o.chainId,escrow:o.escrow});Zs({channelId:i.channelId,descriptor:s,expectedChannelId:c,payee:o.payee,payer:r.address,authorizedSigner:Fo(r),token:o.token});let l=await lc({account:r,channelId:c,context:i,decimals:a,descriptor:s,resolved:o},n);return await Fs(t,o.key,l),l}async function lc(e,t){switch(e.context.action){case`open`:return uc(e);case`topUp`:return dc(e,t);case`voucher`:return fc(e);case`close`:return pc(e)}}async function uc(e){let{account:t,channelId:n,context:r,decimals:i,descriptor:a,resolved:o}=e;if(!r.transaction)throw Error(`transaction required for open action`);let s=Hs(r,i,`cumulativeAmount`,`open`),c=await Vo(o.client,t,a,s,o.chainId,o.escrow);return{action:`open`,type:`transaction`,channelId:n,transaction:r.transaction,signature:c.signature,descriptor:a,cumulativeAmount:s.toString(),authorizedSigner:a.authorizedSigner}}async function dc(e,t){let{account:n,channelId:r,context:i,decimals:a,descriptor:o,resolved:s}=e,c=Hs(i,a,`additionalDeposit`,`topUp`);return i.transaction?{action:`topUp`,type:`transaction`,channelId:r,transaction:i.transaction,descriptor:o,additionalDeposit:c.toString()}:Wo(s.client,n,o,c,s.chainId,s.feePayer,s.escrow,await ic(t,{account:n.address,amountOut:c,client:s.client,tokenOut:s.token}),s.feeToken)}function fc(e){let{account:t,context:n,decimals:r,descriptor:i,resolved:a}=e;return Vo(a.client,t,i,Hs(n,r,`cumulativeAmount`,`voucher`),a.chainId,a.escrow)}function pc(e){let{account:t,context:n,decimals:r,descriptor:i,resolved:a}=e;return Ho(a.client,t,i,Hs(n,r,`cumulativeAmount`,`close`),a.chainId,a.escrow)}const mc={CONNECTING:0,OPEN:1,CLOSING:2,CLOSED:3};function hc(e){let t=new Map,n=!1,r=[],i=e.readyState,a=(e,n,i)=>{let a=t.get(e);if(a||(a=new Set,t.set(e,a)),a.add({once:typeof i==`object`&&i.once===!0,value:n}),e===`message`&&r){let e=r;r=null;for(let t of e)s(`message`,t)}},o=(e,n)=>{let r=t.get(e);if(r)for(let e of r)e.value===n&&r.delete(e)};function s(e,a){if(a.type===`close`){if(n)return;n=!0,i=mc.CLOSED,r=null}if(a.type===`open`&&(i=mc.OPEN),a.type===`message`&&r){r.push(a);return}switch(a.type){case`close`:l.onclose?.(a);break;case`error`:l.onerror?.(a);break;case`message`:l.onmessage?.(a);break;case`open`:l.onopen?.(a)}let o=t.get(e);if(o)for(let e of Array.from(o))typeof e.value==`function`?e.value(a):e.value.handleEvent(a),e.once&&o.delete(e)}let c=null,l={addEventListener:a,close(t,n){e.close(t,n)},get bufferedAmount(){return e.bufferedAmount},get extensions(){return e.extensions},on(e,t){a(e,t)},onclose:null,onerror:null,get onmessage(){return c},set onmessage(e){if(c=e,e&&r){let e=r;r=null;for(let t of e)s(`message`,t)}},onopen:null,off(e,t){o(e,t)},get protocol(){return e.protocol},get readyState(){return i},removeEventListener:o,send(t){e.send(t)},get url(){return e.url}};return{emit:s,socket:l}}function gc(e){return{acceptedCumulative:BigInt(e.acceptedCumulative),deposit:BigInt(e.deposit),requiredCumulative:BigInt(e.requiredCumulative)}}function _c(e){let{amount:t,assertVoucherWithinLocalLimit:n,channel:r,decimals:i,lastChallenge:a,lastUrl:o}=e;if(!r?.opened)throw Error(`Cannot top up session: no open channel.`);if(!a)throw Error(`Cannot top up session: no challenge available. Make a request first.`);if(!o)throw Error(`Cannot top up session: no URL available. Call fetch(), sse(), or ws() first.`);let s=hs(t,i);if(s<=0n)throw Error(`Top-up amount must be greater than zero.`);return n(r.cumulativeAmount+s),{additionalDeposit:s,challenge:a,channelId:r.channelId,input:o}}function vc(e){let{additionalDeposit:t,channel:n,channelId:r,challengeId:i,currentState:a,knownDeposit:o,receipt:s,spent:c}=e;if(n?.channelId!==r)return;let l=o!==void 0&&o>n.deposit?o:n.deposit,u={...n,deposit:l+t};return s?{channel:u,state:Es(s,u)}:i?{channel:u,state:Cs({challengeId:i,entry:u,spent:c.toString(),units:a.status===`active`?a.units:0})}:{channel:u}}async function yc(e){if(e.event.channelId!==e.expectedChannelId)return{status:`ignored`,reason:`channel-mismatch`};let t=gc(e.event);e.assertVoucherWithinLocalLimit(t.requiredCumulative),await e.topUpIfNeeded({challenge:e.challenge,input:e.input,channelId:e.expectedChannelId,deposit:t.deposit,requiredCumulative:t.requiredCumulative,...e.signal?{signal:e.signal}:{}});let n=e.getChannel();if(!n||n.channelId!==e.expectedChannelId)return{status:`ignored`,reason:`missing-channel`};let r=n.cumulativeAmount>t.requiredCumulative?n.cumulativeAmount:Ka(t.requiredCumulative);return{status:`ready`,context:{action:`voucher`,channelId:e.expectedChannelId,descriptor:n.descriptor,cumulativeAmountRaw:r.toString()}}}function bc(e){return e.method===We.tempo&&e.intent===Ge.session}function xc(e){return bc(e)&&Je(e.request.methodDetails,Ke.sessionProtocol)===qe.v2}function Sc(e){return Je(e.request.methodDetails,Ke.sessionSnapshot)}function Cc(e,t,n){let r=e instanceof Request?e.headers:void 0;return{...t,headers:{...Q(r),...Q(t?.headers),[R.authorization]:n}}}function wc(e){try{let t=typeof location>`u`?void 0:location.href,n=e instanceof Request?new URL(e.url):e instanceof URL?new URL(e):new URL(String(e),t);return n.hash=``,n}catch{return e}}function Tc(e){let t=new URL(e.toString());return t.protocol===`ws:`&&(t.protocol=`http:`),t.protocol===`wss:`&&(t.protocol=`https:`),t}async function Ec(e){let t=await e.text().catch(()=>``);if(!t)return``;if(!e.headers.get(`Content-Type`)?.includes(`application/problem+json`))return t;try{return JSON.parse(t).detail??t}catch{return t}}async function Dc(e){let{channel:t,channelId:n}=e;if(!t?.descriptor||t.channelId!==n)throw Error(`Cannot top up session: no local channel descriptor available.`);let r=await Oc({challenge:e.challenge,context:{action:`topUp`,channelId:n,descriptor:t.descriptor,additionalDepositRaw:e.additionalDeposit.toString()},createSessionCredential:e.createSessionCredential,fetch:e.fetch,input:e.input,signal:e.signal});if(!r.ok)throw Error(`Top-up POST failed with status ${r.status}`);let i=r.headers.get(R.paymentReceipt);return i?no(i):void 0}async function Oc(e){let t=async t=>e.fetch(wc(e.input),{method:`POST`,...e.signal?{signal:e.signal}:{},headers:{[R.authorization]:await e.createSessionCredential(t,e.context)}}),n=await t(e.challenge);if(n.status!==402)return n;let r=pt(n).find(xc);return r?t(r):n}async function kc(e){let t=Ac({channel:e.getChannel(),response:e.response});if(!t)return;let{channel:n,challenge:r,snapshot:i}=t;e.setChallenge(r);let a=BigInt(i.requiredCumulative),o=n.cumulativeAmount;await e.topUpIfNeeded({challenge:r,input:e.input,channelId:i.channelId,deposit:BigInt(i.deposit),requiredCumulative:a,signal:e.init?.signal??(e.input instanceof Request?e.input.signal:void 0)});let s=e.getChannel();if(!s?.descriptor||s.channelId!==i.channelId)return;let c=s.cumulativeAmount>a?s.cumulativeAmount:a,l=()=>e.restoreCumulative(i.channelId,o),u;try{let t=await e.createSessionCredential(r,{action:`voucher`,channelId:i.channelId,descriptor:s.descriptor,cumulativeAmountRaw:c.toString()});u=await e.fetch(e.input,Cc(e.input,e.init,t))}catch(e){throw await l(),e}return!u.ok&&!u.headers.get(R.paymentReceipt)&&await l(),u}function Ac(e){let t=pt(e.response).find(xc);if(!t)return;let n=Sc(t);if(!n)return;let{channel:r}=e;if(!(!r?.descriptor||r.channelId!==n.channelId))return{channel:r,challenge:t,snapshot:n}}async function jc(e){if(!e.lastUrl)throw Error(`Cannot close session: no URL available. This usually means close() was called on a SessionManager instance that was recreated after the session was opened. Use the same SessionManager instance that opened the session, or call fetch()/sse() before close().`);let t=e.target.challenge,n=e.signedCloseAmount,r=async(r,i=!1)=>{t=r,n=(i?e.resolveSignedCloseAmount?.(r):void 0)??e.signedCloseAmount;let a=await e.createSessionCredential(r,{action:`close`,channelId:e.target.channelId,descriptor:e.target.channel.descriptor,cumulativeAmountRaw:n});return e.fetch(e.lastUrl,{method:`POST`,headers:{[R.authorization]:a}})},i=await r(e.target.challenge);if(i.status===402){let t=pt(i).find(xc);t&&(e.setChallenge?.(t),i=await r(t,!0))}if(!i.ok){let e=await Ec(i),t=i.headers.get(R.wwwAuthenticate)??``;throw Error(`Close request failed with status ${i.status}${e?`: ${e}`:``}${t?` [${R.wwwAuthenticate}: ${t}]`:``}`)}let a=i.headers.get(R.paymentReceipt);if(!a)return;let o=no(a);if(!o.txHash||!T.validate(o.txHash,{strict:!0})||T.size(o.txHash)!==32||!Ss({challengeId:t.id,channelId:e.target.channelId,expectedCloseAmount:n,minimumSpent:e.getMinimumSpent?.()??0n,receipt:o}))throw Error(`Session close response included a mismatched payment receipt.`);return o}async function Mc(e,t,n){let{onReceipt:r,signal:i,...a}=t??{},o=i??(e instanceof Request?e.signal:void 0),s={...a,headers:{...Q(a.headers),Accept:`text/event-stream`},...o?{signal:o}:{}},c=await n.doFetch(e,s);return!ro(c)&&n.getChannel()?.opened&&(c=await n.doFetch(e,s)),Nc(e,c,{onReceipt:r,signal:o},n)}function Nc(e,t,n,r){if(!ro(t))throw Error(`SSE response is not an event stream.`);if(!t.body)throw Error(`Response has no body.`);let i=r.getChallenge();return Pc({onNeedVoucher:t=>zc({challenge:i,driver:r,input:e,signal:n?.signal},t),onReceipt(e){r.acceptReceipt(e),n?.onReceipt?.(e)},response:t,signal:n?.signal})}async function*Pc(e){for await(let t of Fc(e))t.data!==void 0&&(yield t.data)}async function*Fc(e){if(!e.response.body)throw Error(`Response has no body.`);let t=e.response.body.getReader(),n=new TextDecoder,r=``,i=!1,a=()=>{t.cancel(e.signal?.reason).catch(()=>void 0)};e.signal?.addEventListener(`abort`,a,{once:!0}),e.signal?.aborted&&a();try{for(;!e.signal?.aborted;){let{done:a,value:o}=await t.read();for(a?(i=!0,r+=n.decode()):r+=n.decode(o,{stream:!0});;){let t=Ic(r,a);if(!t)break;let n=t.index+t.length,i=r.slice(0,t.index),o=r.slice(0,n);if(r=r.slice(n),!i.trim())continue;let s=io(i.replace(/\r\n|\r/g,`
|
|
5
5
|
`));if(!s){yield{raw:o};continue}switch(s.type){case`message`:yield{data:s.data,raw:o};break;case`payment-need-voucher`:await e.onNeedVoucher(s.data,e.signal);break;case`payment-receipt`:e.onReceipt(s.data)}}if(a)break}}finally{e.signal?.removeEventListener(`abort`,a),i||await t.cancel().catch(()=>void 0),t.releaseLock()}}function Ic(e,t){for(let n=0;n<e.length;n++){let r=Lc(e,n,t);if(!r)continue;let i=Lc(e,n+r,t);if(i)return{index:n,length:r+i};n+=r-1}}function Lc(e,t,n){return e[t]===`
|
|
6
6
|
`?1:e[t]===`\r`?e[t+1]===`
|
|
7
|
-
`?2:t+1===e.length&&!n?0:1:0}function Rc(e){let t=new AbortController,n=()=>t.abort(e.signal?.reason);e.signal?.addEventListener(`abort`,n,{once:!0}),e.signal?.aborted&&n();let r=Fc({...e,signal:t.signal}),i=new TextEncoder,a=new Headers(e.response.headers);a.delete(`content-length`);let o=()=>e.signal?.removeEventListener(`abort`,n),s=new Response(new ReadableStream({async pull(e){try{let t=await r.next();if(t.done)return o(),e.close();e.enqueue(i.encode(t.value.raw))}catch(e){throw o(),e}},async cancel(){o(),t.abort(),await r.return(void 0)}}),{headers:a,status:e.response.status,statusText:e.response.statusText});for(let t of[`redirected`,`type`,`url`])Object.defineProperty(s,t,{configurable:!0,get:()=>e.response[t]});return s}async function zc(e,t){let n=e.driver.getChannel();if(!n||!e.challenge)return;let r=await yc({assertVoucherWithinLocalLimit:e.driver.assertVoucherWithinLocalLimit,challenge:e.challenge,event:t,expectedChannelId:n.channelId,getChannel:e.driver.getChannel,input:e.input,signal:e.signal,topUpIfNeeded:e.driver.topUpIfNeeded});if(r.status!==`ready`)return;let i=await Oc({challenge:e.challenge,context:r.context,createSessionCredential:e.driver.createSessionCredential,fetch:e.driver.fetch,input:e.input,signal:e.signal});if(!i.ok)throw Error(`Voucher POST failed with status ${i.status}`)}async function Bc(e){let t=new URL(e.input.toString()),n=Tc(t);e.onProbeUrl?.(n);let r=await e.fetch(n,{...e.probeInit,...e.signal?{signal:e.signal}:{}});if(r.status!==402)throw Error(`Expected a 402 payment challenge from ${n}, received ${r.status} instead.`);let i=pt(r).find(xc);if(!i)throw Error(`No payment challenge received from HTTP endpoint for this WebSocket URL. The server may not require payment or did not advertise a challenge.`);return{challenge:i,httpUrl:n,wsUrl:t}}async function Vc(e){let t=await Bc(e);return{...t,credential:await e.createSessionCredential(t.challenge,{})}}function Hc(e){let{challenge:t,credential:n,socket:r}=e;return{challenge:t,channelId:St(n).payload.channelId,closeReadyReceipt:null,deliveredChunks:0n,expectedCloseAmount:null,socket:r,tickCost:$a(t)}}function Uc(e){let{challengeId:t,channelId:n,receipt:r}=e;return r.challengeId===t&&r.channelId===n}function Wc(e){if(!Uc(e))return`received mismatched payment-close-ready frame`;let t=Ga(e.receipt.spent);if(t===void 0)return`received invalid payment-close-ready spend`;if(t>e.cumulativeAmount)return`received payment-close-ready beyond local voucher state`}function Gc(e){let{challengeId:t,channelId:n,expectedCloseAmount:r,receipt:i}=e;if(!Uc(e))return`received mismatched payment-receipt frame`;if(r!==null&&i.txHash&&!Ss({challengeId:t,channelId:n,expectedCloseAmount:r,minimumSpent:BigInt(r),receipt:i}))return`received mismatched payment-close receipt frame`}async function Kc(e){let{challenge:t,credential:n,options:r,WebSocket:i,wsUrl:a}=e,o=new i(a,r?.protocols),s=Hc({challenge:t,credential:n,socket:o});e.setSocketSession(s);let c=hc(o),l=t=>{e.rejectReceipt(Error(t)),e.rejectCloseReady(Error(t)),(o.readyState===mc.CONNECTING||o.readyState===mc.OPEN)&&o.close(3008,t)};return o.addEventListener(`close`,t=>{s.socket=null,s.expectedCloseAmount=null,e.rejectReceipt(Error(`WebSocket closed before the payment flow completed.`)),e.rejectCloseReady(Error(`WebSocket closed before the payment flow completed.`)),c.emit(`close`,{code:t.code??1e3,reason:t.reason??``,type:`close`,wasClean:!0})}),o.addEventListener(`error`,()=>{c.emit(`error`,{type:`error`})}),o.addEventListener(`message`,async t=>{let n=typeof t.data==`string`?t.data:void 0;n&&await Jc({driver:e,failSocketFlow:l,managedEmit:c.emit,message:n,rawSocket:o,socketState:s})}),r?.signal?.addEventListener(`abort`,()=>{e.rejectReceipt(Error(`WebSocket payment flow aborted.`)),e.rejectCloseReady(Error(`WebSocket payment flow aborted.`)),o.close()},{once:!0}),await qc(o,c.emit,a),o.send(oo(n)),await e.waitForReceipt(),c.socket}function qc(e,t,n){return new Promise((r,i)=>{let a=()=>{e.removeEventListener(`error`,o),t(`open`,{type:`open`}),r()},o=()=>{e.removeEventListener(`open`,a),i(Error(`WebSocket connection to ${n} failed to open.`))};e.addEventListener(`open`,a,{once:!0}),e.addEventListener(`error`,o,{once:!0})})}async function Jc(e){let t=co(e.message);if(!t){e.managedEmit(`message`,{data:e.message,type:`message`});return}switch(t.mpp){case`authorization`:return;case`message`:e.socketState.deliveredChunks+=1n,e.managedEmit(`message`,{data:t.data,type:`message`});return;case`payment-close-ready`:Yc(e,t.data);return;case`payment-error`:e.driver.rejectReceipt(Error(t.message)),e.driver.rejectCloseReady(Error(t.message));return;case`payment-need-voucher`:await Xc(e,t.data);return;case`payment-receipt`:Zc(e,t.data);return}}function Yc(e,t){let n=e.driver.getChannel()?.cumulativeAmount??0n,r=Wc({challengeId:e.driver.challenge.id,channelId:e.socketState.channelId,cumulativeAmount:n,receipt:t});if(r){e.failSocketFlow(r);return}e.driver.acceptReceipt(t),e.driver.options?.onReceipt?.(t),e.driver.settleCloseReady(t),e.managedEmit(`close`,{code:1e3,reason:`stream complete`,type:`close`,wasClean:!0})}async function Xc(e,t){try{let n=e.driver.challenge;n.expires&&new Date(n.expires).getTime()<=Date.now()+5e3&&(n=await e.driver.refreshChallenge(),e.driver.challenge=n,e.socketState.challenge=n);let r=await yc({assertVoucherWithinLocalLimit:e.driver.assertVoucherWithinLocalLimit,challenge:n,event:t,expectedChannelId:e.socketState.channelId,getChannel:e.driver.getChannel,input:e.driver.httpUrl,signal:e.driver.options?.signal,topUpIfNeeded:e.driver.topUpIfNeeded});if(r.status===`ignored`){e.failSocketFlow(r.reason===`channel-mismatch`?`received mismatched payment-need-voucher frame`:`cannot create voucher: no active channel`);return}let i=await e.driver.createSessionCredential(n,r.context);e.rawSocket.send(oo(i))}catch(t){e.failSocketFlow(t instanceof Error?t.message:`failed to create websocket voucher`)}}function Zc(e,t){let n=Gc({challengeId:e.driver.challenge.id,channelId:e.socketState.channelId,expectedCloseAmount:e.socketState.expectedCloseAmount,receipt:t});if(n){e.failSocketFlow(n);return}e.driver.acceptReceipt(t),e.driver.options?.onReceipt?.(t),e.driver.settleReceipt(t)}const Qc=new WeakMap;async function $c(e,t){let n=Qc.get(e)??new Map;Qc.set(e,n);let r=n.get(t),i,a=new Promise(e=>{i=e});return n.set(t,a),await r,()=>{i(),n.get(t)===a&&n.delete(t)}}function el(e,t){try{return t?.channelId.toLowerCase()===e.channelId.toLowerCase()&&BigInt(t.acceptedCumulative)===e.cumulativeAmount}catch{return!1}}function tl(e,t,n){try{let r=e.response?.headers.get(R.paymentReceipt);if(r){let e=no(r);if(e.challengeId===t.id&&el(n,e))return!0}}catch{}return e.challenges?.some(e=>xc(e)?el(n,Sc(e)):!1)??!1}function nl(e={}){let{account:t,allowCustomEscrow:n=!1,autoSwap:r,channelStore:i,decimals:a=6,escrow:o,allowedChainIds:s,getClient:c,maxDeposit:l,topUpAmount:u,onChannelUpdate:f,resolveAccount:p}=e,m=Qi({chain:b,getClient:c,rpcUrl:Hn}),h=Ji({account:t}),g=l===void 0?void 0:d(l,a),_=u===void 0?void 0:d(u,a),v=i??qo(),y={store:v,notifyUpdate:e=>f?.(e)},x=async(e,t,n)=>{let r=h(e.client,t),i=t?.action?t.descriptor:n?.descriptor??Qs({context:t,snapshot:e.snapshot})?.descriptor;return await p?.({account:r,chainId:e.chainId,operation:{kind:`authorizePaymentChannel`,...i?{authority:fo(i)}:{}}})??r},S=async(e,t,n)=>nc({account:await x(e,t,n),entry:n,context:t,decimals:a,maxDeposit:g,resolved:e}),C=Mt(za,{canHandleChallenge:({challenge:e})=>xc(e),context:Rs,async createCredential(e){let{challenge:t,context:i}=e,a=await Ys({allowCustomEscrow:n,challenge:t,escrowOverride:o,allowedChainIds:s,getClient:m}),c=li(e),l=()=>{};try{let e=!zs(i)&&i?.descriptor===void 0;e&&(l=await $c(v,a.key),c&&(await v.get(a.key))?.opened&&await c.prepare());let n=await v.get(a.key),o=await S(a,i,n);if(!e&&c&&o.type===`open`){l=await $c(v,a.key);let e=await v.get(a.key);e?.channelId!==n?.channelId&&(n=e,n?.opened&&(await c.prepare(),n=await v.get(a.key)),o=await S(a,i,n))}let s,u=c&&o.type===`open`?{store:{get:e=>v.get(e),async set(e){s=e},delete:e=>v.delete(e)},notifyUpdate(){}}:y,d=await zo(t,await rc(o,u,ca(i?.autoSwap??r,oa)),a.chainId,o.account);if(c&&s){let e=s;c.settle=async n=>{let r=n.status===`accepted`||tl(n,t,e);if(!r&&n.status===`pending`)return!1;try{if(r){let t=await v.get(a.key);(!t?.opened||t.channelId.toLowerCase()!==e.channelId.toLowerCase())&&(await v.set(e),y.notifyUpdate(e))}return!0}finally{l()}}}else l();return d}catch(e){throw l(),e}}}),w=async({challenge:e,channel:t,deposit:n,fetch:r,input:i,requiredCumulative:a,signal:o})=>{let s=t.deposit>n?t.deposit:n,c=_s({deposit:s,maxDeposit:g,requiredCumulative:a,suggestedDeposit:e.request.suggestedDeposit===void 0?void 0:BigInt(e.request.suggestedDeposit),topUpAmount:_});c>0n&&await Dc({additionalDeposit:c,challenge:e,channel:t,channelId:t.channelId,createSessionCredential:(e,t)=>C.createCredential({challenge:e,context:t}),fetch:r,input:i,signal:o});let l=s+c;if(l===t.deposit)return;let u=await v.get(Ko(t)),d=u?.channelId.toLowerCase()===t.channelId.toLowerCase()?u:t,f={...d,deposit:d.deposit>l?d.deposit:l};await v.set(f),y.notifyUpdate(f)};return ti(C,async({challenge:e,context:t,fetch:r,input:i,signal:a})=>{if(!xc(e))return;let c=t===void 0?void 0:Rs.parse(t);if(zs(c))return;let l=await Ys({allowCustomEscrow:n,challenge:e,escrowOverride:o,allowedChainIds:s,getClient:m}),u=await v.get(l.key);if(!u?.opened)return;let d=l.snapshot?.channelId.toLowerCase()===u.channelId.toLowerCase()?l.snapshot:void 0,f=u.cumulativeAmount+$a(e),p=d?BigInt(d.requiredCumulative):f,h=p>f?p:f,g=d?BigInt(d.deposit):u.deposit,_=g>u.deposit?g:u.deposit;h<=_&&_===u.deposit||!tc(await x(l,c,u),u.descriptor)||await w({challenge:e,channel:u,deposit:_,fetch:r,input:i,requiredCumulative:h,signal:a})}),oi(C,async({challenge:e,credential:t,fetch:r,headers:i,input:a,refetch:c,response:l,signal:u})=>{if(!xc(e))return l;if(!ro(l))return Qa(St(t).payload).action===`open`&&i.get(`accept`)?.toLowerCase().includes(`text/event-stream`)?await c?.()??l:l;let d=(await Ys({allowCustomEscrow:n,challenge:e,escrowOverride:o,allowedChainIds:s,getClient:m})).key,f=await v.get(d),p={assertVoucherWithinLocalLimit:e=>vs(e,g),createSessionCredential:(e,t)=>C.createCredential({challenge:e,context:t}),fetch:r,getChannel:()=>f??null,async topUpIfNeeded({deposit:t,requiredCumulative:n,signal:i}){f&&await w({challenge:e,channel:f,deposit:f.deposit>t?f.deposit:t,fetch:r,input:a,requiredCumulative:n,signal:i})}};return Rc({onNeedVoucher:(t,n)=>zc({challenge:e,driver:p,input:a,signal:n},t),onReceipt(){},response:l,signal:u})})}const rl=new WeakMap;function il(e,t){rl.set(e,t)}function al(e){let t=null;return{wait(n=()=>!0){if(t)throw Error(`${e} wait already in progress`);return new Promise((e,r)=>{t={predicate:n,resolve:e,reject:r}})},settle(e){if(!t||!t.predicate(e))return;let n=t;t=null,n.resolve(e)},reject(e){if(!t)return;let n=t;t=null,n.reject(e)}}}function ol(e){let t=al(`close-ready`),n=al(`receipt`);return{waitForReceipt(e){return n.wait(e)},waitForCloseReady(){let n=e.getSocketSession()?.closeReadyReceipt;return n?Promise.resolve(n):t.wait()},settleReceipt(e){n.settle(e)},settleCloseReady(n){let r=e.getSocketSession();r&&r.challenge.id===n.challengeId&&r.channelId===n.channelId&&(r.closeReadyReceipt=n),t.settle(n)},rejectReceipt(e){n.reject(e)},rejectCloseReady(e){t.reject(e)}}}function sl(e){return e.method===We.tempo&&e.intent===Ge.charge}function cl(e){if(!sl(e)||typeof e.request.amount!=`string`)return!1;try{return BigInt(e.request.amount)===0n}catch{return!1}}function ll(e,t,n){if(!n)return t;let r={...Q(e instanceof Request?e.headers:void 0),...Q(t?.headers)};return Object.keys(r).some(e=>e.toLowerCase()===R.paymentSession.toLowerCase())?t:{...t,headers:{...r,[R.paymentSession]:n}}}function ul(e,t){return e===void 0?t:{...Rs.parse(e),...t}}function dl(e){let t=e.decimals??6,n=e.webSocket??globalThis.WebSocket;return{decimals:t,fetch:e.fetch??globalThis.fetch.bind(globalThis),maxVoucherCumulative:e.maxDeposit===void 0?null:d(e.maxDeposit,t),topUpAmount:e.topUpAmount===void 0?null:d(e.topUpAmount,t),WebSocket:n}}function fl(e){let t=e.client?.chain?.id;(t!==void 0||e.allowedChainIds?.length===0)&&ea(e.allowedChainIds,t);let n=e.allowCustomEscrow??!1,r=dl(e),i=Qi({chain:b,getClient:e.client?()=>e.client:e.getClient,rpcUrl:Hn}),a=Ji({account:e.account}),o=ws(),s=e.credentialContext===void 0?void 0:ul(e.credentialContext,{}),c=ol({getSocketSession:()=>o.socketSession}),l=e.channelStore??qo(),u=new Set,d;async function f(e){let t=await l.get(e);if(t?.opened&&!u.has(t.channelId))return t}let p={async get(e){let t=await f(e);return t&&d&&(d.seenExisting.add(e),!d.committed&&!d.created.has(e)&&(d.resumed??=t)),t},async set(e){let t=Ko(e);e.opened&&u.delete(e.channelId),d?.trackCreates&&!d.seenExisting.has(t)&&d.created.set(t,e),await l.set(e)},delete:e=>l.delete(e)};async function m(e){let t=Ko(e);u.add(e.channelId),d?.seenExisting.delete(t),d?.resumed===e&&(d.resumed=void 0),await Promise.resolve(l.delete(t)).catch(()=>void 0)}async function h(){let e=d;if(e?.created.size){for(let[t,n]of e.created)u.add(n.channelId),await Promise.resolve(l.delete(t)).catch(()=>void 0);e.created.clear(),await re(e.committed??e.previous)}}function g(e){let t=Je(e.request.methodDetails,Ke.sessionSnapshot);if(typeof t?.channelId!=`string`)return!1;let n=d;if(!n?.created.size||!o.channel)return!1;for(let[e,r]of n.created)if(r.channelId.toLowerCase()===t.channelId.toLowerCase()&&o.channel.channelId.toLowerCase()===t.channelId.toLowerCase())return n.created.delete(e),n.committed=ks({channel:o.channel,spent:o.spent,state:o.state}),!0;return!1}function _(e){return cs(o,e)}function v(){let e=o.state.status===`active`?o.state:d?.committed?.state??d?.previous.state;return e?.status===`active`?e.units:0}function y(e){let t=d,n=t?.committed?.channel?.entry??t?.resumed;!t||n?.channelId.toLowerCase()!==e.channelId.toLowerCase()||e.deposit<=n.deposit||(t.resumed=void 0,t.committed=ks({channel:o.channel,spent:o.spent,state:o.state}))}let x=nl({account:e.account,allowCustomEscrow:n,autoSwap:e.autoSwap,getClient:e.client?()=>e.client:e.getClient,resolveAccount:e.resolveAccount,escrow:e.escrow,allowedChainIds:e.allowedChainIds,decimals:r.decimals,maxDeposit:e.maxDeposit,topUpAmount:e.topUpAmount,channelStore:p,onChannelUpdate(e){e.channelId!==o.channel?.channelId&&(o.spent=0n),o.channel=e,o.lastChallenge&&_({type:`activated`,challengeId:o.lastChallenge.id,entry:e,spent:o.spent.toString(),units:v()}),y(e)}});si(x);let S=Ha({allowedChainIds:e.allowedChainIds,account:e.account,getClient:e.client?()=>e.client:e.getClient,resolveAccount:e.resolveAccount}),C=mi({fetch:r.fetch,methods:[x],onChallenge:async(e,t)=>{if(!bc(e))return;let n=d,r=n&&n.challengesReceived>0&&e.id===o.lastChallenge?.id,i=r&&at(e)===at(o.lastChallenge);n&&n.challengesReceived++,!i&&(g(e)||(n?.created.size?await h():r&&await re(n.committed??n.previous)),o.lastChallenge=e,_({type:`challengeReceived`,challengeId:e.id}))}});function w(e,t){return x.createCredential({challenge:e,context:ul(s,t)})}function T(e){Ts({maxVoucherCumulative:r.maxVoucherCumulative,receipt:e,runtime:o})}function E(e=o.state.status===`active`?o.state.units:0){!o.channel||!o.lastChallenge||o.state.status!==`active`&&o.state.status!==`withdrawable`&&o.state.status!==`closeRequested`&&_({type:`activated`,challengeId:o.lastChallenge.id,entry:o.channel,spent:o.spent.toString(),units:e})}async function D(t){let n=t.headers.get(R.paymentSessionSnapshot);if(!n)return;let r=is(n);ea(e.allowedChainIds,r.chainId);let s=await i({chainId:r.chainId});$i(s,r.chainId);let c=a(s),{entry:l,spent:u}=await ec({account:await e.resolveAccount?.({account:c,chainId:r.chainId,operation:{authority:fo(r.descriptor),kind:`authorizePaymentChannel`}})??c,client:s,snapshot:r});return N(l.cumulativeAmount),await Promise.resolve(p.set(l)).catch(()=>void 0),o.channel=l,o.spent=u,l}async function O(t,n){if(!e.bootstrap||o.channel?.opened)return;let i=t instanceof Request?t.headers:void 0,{body:a,method:s,...c}=n??{},l=t instanceof Request?t.url:t,u={...c,method:`HEAD`,headers:{...Q(i),...Q(n?.headers),[R.acceptPayment]:`${We.tempo}/${Ge.charge}`}};try{let e=await r.fetch(l,u);if(e.status!==402)return await D(e);let t=pt(e).find(sl);if(!t||!cl(t))return;let n=await S.createCredential({challenge:t,context:{}}),i=await r.fetch(l,{...u,headers:{...Q(u.headers),[R.authorization]:n}});return i.ok?await D(i):void 0}catch{return}}function k(e,t){let n=o.socketSession;return Ds({challengeId:e.id,channelId:t,closeReadyReceipt:n?.closeReadyReceipt,cumulativeAmount:o.channel?.channelId===t?o.channel.cumulativeAmount:0n,deliveredChunks:n?.deliveredChunks,socketChallengeId:n?.challenge.id,socketChannelId:n?.channelId,spent:o.spent,tickCost:n?.tickCost})}function A(e,t){let n=Sc(t);if(!n)return;if(po({...n.descriptor,chainId:n.chainId,escrow:n.escrow}).toLowerCase()!==n.channelId.toLowerCase())throw Error(`close snapshot descriptor does not match its channel ID`);if(n.channelId.toLowerCase()!==e.channelId.toLowerCase())throw Error(`close snapshot channel ID does not match local session`);if(n.chainId!==e.chainId||n.escrow.toLowerCase()!==e.escrow.toLowerCase())throw Error(`close snapshot payment scope does not match local session`);let r=BigInt(n.acceptedCumulative),i=BigInt(n.spent);if(r<0n||i<0n)throw Error(`close snapshot amounts must not be negative`);if(i>r)throw Error(`close snapshot spent exceeds accepted cumulative amount`);if(r>e.cumulativeAmount)throw Error(`close snapshot accepted cumulative exceeds local voucher state`);return{acceptedCumulative:r,spent:i}}function j(e,t){let n=A(e.channel,t);if(!n)return;let{acceptedCumulative:r,spent:i}=n;if(o.spent>r)throw Error(`close snapshot accepted cumulative is below locally confirmed spend`);return i>o.spent&&(o.spent=i),n}function M(e,t=e.challenge,n=!1){let r=(n?j(e,t):A(e.channel,t))?.acceptedCumulative??k(t,e.channelId);if(r>e.channel.cumulativeAmount)throw Error(`fallback close amount exceeds local voucher state`);return N(r),r.toString()}function N(e){fs({cumulativeAmount:e,maxVoucherCumulative:r.maxVoucherCumulative})}async function ee(e){let{knownDeposit:t,...n}=e,i=await Dc({...n,channel:o.channel,createSessionCredential:w,fetch:r.fetch});T(i);let a=vc({additionalDeposit:e.additionalDeposit,channel:o.channel,channelId:e.channelId,challengeId:o.lastChallenge?.id,currentState:o.state,knownDeposit:t,receipt:i,spent:o.spent});return a?.channel&&o.lastChallenge&&(await p.set(a.channel),_({type:`activated`,challengeId:o.lastChallenge.id,entry:a.channel,spent:o.spent.toString(),units:v()}),y(a.channel)),i}async function te(e){let t=o.channel?.channelId===e.channelId?o.channel.deposit:0n,n=t>e.deposit?t:e.deposit,i=_s({deposit:n,maxDeposit:r.maxVoucherCumulative,requiredCumulative:e.requiredCumulative,suggestedDeposit:e.challenge.request.suggestedDeposit===void 0?void 0:BigInt(e.challenge.request.suggestedDeposit),topUpAmount:r.topUpAmount});i!==0n&&await ee({challenge:e.challenge,input:e.input,channelId:e.channelId,additionalDeposit:i,knownDeposit:n,signal:e.signal})}async function ne(e,t){let n=Os({channel:o.channel,channelId:e,challengeId:o.lastChallenge?.id,cumulativeAmount:t,spent:o.spent,state:o.state});n&&o.channel&&(_({type:`activated`,challengeId:n.challengeId,entry:o.channel,spent:n.spent,units:n.units}),await l.set(o.channel))}async function re(e){let t=As(e,o.channel);o.channel=t.channel,o.spent=t.spent,o.state=t.state,o.channel?.opened&&await l.set(o.channel)}function ie(e){let t=e.headers.get(R.paymentReceipt),n=t?no(t):null;return T(n),Object.assign(e,{receipt:n,challenge:o.lastChallenge,channelId:o.channel?.channelId??null,cumulative:o.channel?.cumulativeAmount??0n})}async function ae(e,t){if(d)throw Error(`SessionManager: a request is already in flight; concurrent requests on one manager are not supported`);o.lastUrl=e;let n=ks({channel:o.channel,spent:o.spent,state:o.state}),i={challengesReceived:0,committed:void 0,created:new Map,previous:n,seenExisting:new Set,resumed:void 0,trackCreates:!1};d=i;try{await O(e,t),i.trackCreates=!0;let a=ll(e,t,o.channel?.opened?o.channel.channelId:void 0);s&&(a={...a,context:s});let c=!n.channel?.opened;async function l(){let n=i.resumed;return!c||!n?!1:(c=!1,await m(n),a=ll(e,t,void 0),!0)}for(;;){let t;try{t=await C(e,a)}catch(e){if(i.created.size?await h():await re(i.committed??n),await l())continue;throw e}let s=ie(t),c=!1;if(s.status===402){let t=await kc({input:e,init:a,response:s,createSessionCredential:w,fetch:r.fetch,getChannel:()=>o.channel,restoreCumulative:ne,setChallenge(e){o.lastChallenge=e},topUpIfNeeded:te});t&&(c=!0,s=ie(t))}if(!c&&!s.ok&&!s.receipt){if(i.created.size?await h():await re(i.committed??n),await l())continue;return s}return s}}finally{d=void 0}}async function P(e){let t=await jc({createSessionCredential:w,fetch:r.fetch,getMinimumSpent:()=>o.spent,lastUrl:o.lastUrl,resolveSignedCloseAmount:t=>M(e,t,!0),signedCloseAmount:M(e),setChallenge(e){o.lastChallenge=e},target:e});return t&&(E(),_({type:`closeStarted`}),_({type:`closed`,receipt:t})),t}let oe={createSessionCredential:w,doFetch:ae,fetch:r.fetch,getChannel:()=>o.channel,getChallenge:()=>o.lastChallenge,assertVoucherWithinLocalLimit:N,acceptReceipt(e){T(e)},topUpIfNeeded:te},se={get channelId(){return o.channel?.channelId},get cumulative(){return o.channel?.cumulativeAmount??0n},get opened(){return o.channel?.opened??!1},get state(){return o.state},fetch:ae,async topUp(e){let t=_c({amount:e,assertVoucherWithinLocalLimit:N,channel:o.channel,decimals:r.decimals,lastChallenge:o.lastChallenge,lastUrl:o.lastUrl});return ee({additionalDeposit:t.additionalDeposit,challenge:t.challenge,channelId:t.channelId,input:t.input})},async sse(e,t){return Mc(e,t,oe)},async ws(e,t){if(!r.WebSocket)throw Error("No WebSocket implementation available. Pass `webSocket` to sessionManager() in this runtime.");let n=Tc(e),i=t?.signal?{signal:t.signal}:void 0;await O(n,i);let a=o.channel?.opened?o.channel.channelId:void 0,{challenge:s,credential:l,httpUrl:u,wsUrl:d}=await Vc({async createSessionCredential(e,i){return o.lastChallenge=e,await ri(x,{challenge:e,context:i,fetch:r.fetch,input:n,signal:t?.signal}),w(e,i)},fetch:r.fetch,input:e,onProbeUrl(e){o.lastUrl=e.toString()},probeInit:ll(n,i,a),signal:t?.signal});return o.lastChallenge=s,Kc({challenge:s,credential:l,httpUrl:u,WebSocket:r.WebSocket,wsUrl:d,options:t,createSessionCredential:w,getChannel:()=>o.channel,setSocketSession(e){o.socketSession=e},async refreshChallenge(){let e=await Bc({fetch:r.fetch,input:u,probeInit:ll(u,i,o.channel?.opened?o.channel.channelId:void 0),signal:t?.signal});return o.lastChallenge=e.challenge,e.challenge},assertVoucherWithinLocalLimit:N,acceptReceipt:T,rejectCloseReady:c.rejectCloseReady,rejectReceipt:c.rejectReceipt,settleCloseReady:c.settleCloseReady,settleReceipt:c.settleReceipt,topUpIfNeeded:te,waitForReceipt:c.waitForReceipt})},async close(){let e=o.socketSession,t=ys({channel:o.channel,currentSocket:e,lastChallenge:o.lastChallenge});if(!t)return;let n=e?.socket;if(e&&n?.readyState===mc.OPEN){let r=await js({activeSocket:n,createSessionCredential:w,currentSocket:e,spent:o.spent,target:t,waitForCloseReady:c.waitForCloseReady,waitForReceipt:c.waitForReceipt});return E(),_({type:`closeStarted`}),_({type:`closed`,receipt:r}),r}return P(t)}};return il(se,{consumeSseResponse(e,t,n){return Nc(e,t,n,oe)},rehydrate({channel:e,challenge:t,input:n,spent:r}){if(!e.opened)throw Error(`Cannot restore a closed session channel.`);if(!bc(t))throw Error(`Cannot restore session: challenge is not tempo/session.`);if(r<0n)throw Error(`Cannot restore session: spent must not be negative.`);if(r>e.cumulativeAmount)throw Error(`Cannot restore session: spent exceeds local voucher state.`);N(e.cumulativeAmount);let i=A(e,t),a=i&&i.spent>r?i.spent:r;o.lastUrl=n,o.lastChallenge=t,o.channel=e,o.spent=a,_({type:`challengeReceived`,challengeId:t.id}),_({type:`activated`,challengeId:t.id,entry:e,spent:a.toString(),units:0})}}),se}(function(e){e.serializeSnapshot=rs,e.deserializeSnapshot=is})(fl||={});const pl=(1n<<64n)-1n,ml={dev_second:1n,day:86400n,week:604800n};function hl(e){return e instanceof Date?e:new Date(e)}function gl(e){let t=e.getTime();if(!Number.isFinite(t))throw new K({reason:`subscriptionExpires is invalid`});if(t%1e3!=0)throw new K({reason:`subscriptionExpires must be representable as whole seconds`});let n=t/1e3;if(n<=0||!Number.isSafeInteger(n))throw new K({reason:`subscriptionExpires cannot be represented in a Tempo key authorization`});return n}function _l(e){if(!/^[1-9]\d*$/.test(e.periodCount))throw new K({reason:`periodCount is invalid`});let t=ml[e.periodUnit];if(t===void 0)throw new K({reason:`periodUnit is invalid`});let n=BigInt(e.periodCount)*t;if(n>pl)throw new K({reason:`subscription period cannot be represented as an unsigned 64-bit integer`});if(n>BigInt(2**53-1))throw new K({reason:`subscription period cannot be represented exactly by this Tempo client`});return Number(n)}function vl(e){let{challengeExpires:t,request:n}=e;_l(n);let r=gl(hl(n.subscriptionExpires));if(t){let e=Math.floor(new Date(t).getTime()/1e3);if(!Number.isFinite(e)||r<=e)throw new K({reason:`subscriptionExpires must be strictly later than challenge expires`})}}function yl(e){return[{address:Ml(e.currency,`currency`),selector:`0x95777d59`,recipients:[Ml(e.recipient,`recipient`)]}]}function bl(e){try{let t=T.fromBytes(S.toBytes(e));if(T.size(t)!==32)throw Error(`invalid challenge id size`);return t}catch{throw new K({reason:`challenge id must encode 32 bytes`})}}async function xl(e){let{accessKey:t,account:n,challengeId:r,chainId:i,request:a}=e;if(typeof n.sign!=`function`)return;let o=Cl({accessKey:t,challengeId:r,chainId:i,request:a}),s=await n.sign({hash:F.getSignPayload(o)}),c=I.from(s);if(c.type===`keychain`||c.type===`multisig`)throw new K({reason:`keyAuthorization must use a primitive signature`});return F.from(o,{signature:s})}function Sl(e){let{accessKey:t,challengeId:n,chainId:r,payload:i,request:a}=e;if(i.type!==`keyAuthorization`)throw new K({reason:`invalid keyAuthorization payload`});let o=wl(i.signature),s=Tl(o);if(El({accessKey:t,authorization:o,chainId:r}),o.witness?.toLowerCase()!==bl(n))throw new K({reason:`keyAuthorization challenge mismatch`});return Dl(o,a),kl(Ol(o),a),Al(o.scopes,a),{authorization:o,source:{address:jl(o,s),chainId:r}}}function Cl(e){let{accessKey:t,challengeId:n,chainId:r,request:i}=e;return F.from({address:Ml(t.accessKeyAddress,`accessKeyAddress`),chainId:BigInt(r),expiry:gl(hl(i.subscriptionExpires)),limits:[{token:Ml(i.currency,`currency`),limit:BigInt(i.amount),period:_l(i)}],scopes:yl(i),type:t.keyType,witness:bl(n)})}function wl(e){try{return F.deserialize(e)}catch(e){throw e instanceof F.InvalidSignatureTypeError?new K({reason:`keyAuthorization must use a primitive signature`}):new K({reason:`invalid keyAuthorization payload`})}}function Tl(e){let t=e.signature;if(!t)throw new K({reason:`keyAuthorization must use a primitive signature`});return t}function El(e){let{accessKey:t,authorization:n,chainId:r}=e;if(n.chainId!==BigInt(r))throw new K({reason:`keyAuthorization chainId mismatch`});if(t){if(!l(n.address,Ml(t.accessKeyAddress,`accessKeyAddress`)))throw new K({reason:`keyAuthorization access key mismatch`});if(n.type!==t.keyType)throw new K({reason:`keyAuthorization key type mismatch`})}}function Dl(e,t){if(vl({request:t}),e.expiry!==gl(hl(t.subscriptionExpires)))throw new K({reason:`keyAuthorization expiry mismatch`})}function Ol(e){let[t]=e.limits??[];if(!t||e.limits?.length!==1)throw new K({reason:`keyAuthorization must contain exactly one token limit`});return t}function kl(e,t){if(!l(e.token,Ml(t.currency,`currency`)))throw new K({reason:`keyAuthorization currency mismatch`});if(e.limit!==BigInt(t.amount))throw new K({reason:`keyAuthorization amount mismatch`});if(e.period!==_l(t))throw new K({reason:`keyAuthorization period mismatch`})}function Al(e,t){if(!e||e.length!==1)throw new K({reason:`keyAuthorization must contain a recipient-scoped transferWithMemo call`});let n=Ml(t.currency,`currency`),r=Ml(t.recipient,`recipient`),i=new Set;for(let t of e){if(!l(t.address,n))throw new K({reason:`keyAuthorization call target mismatch`});let e=Nl(t.selector);if(e!==`0xa9059cbb`&&e!==`0x95777d59`)throw new K({reason:`keyAuthorization selector not allowed`});if(i.has(e))throw new K({reason:`keyAuthorization duplicate selector`});if(i.add(e),t.recipients?.length!==1||!l(t.recipients[0],r))throw new K({reason:`keyAuthorization recipient mismatch`})}if(!i.has(`0x95777d59`))throw new K({reason:`keyAuthorization must allow transferWithMemo`})}function jl(e,t){let n=F.getSignPayload(e);try{let e=I.extractAddress({payload:n,signature:t});if(!I.verify(t,{address:e,payload:n}))throw new K({reason:`keyAuthorization signature is invalid`});return e}catch(e){throw e instanceof K?e:new K({reason:`keyAuthorization signature is invalid`})}}function Ml(e,t){if(!c(e))throw new K({reason:`${t} must be an address`});return e.toLowerCase()}function Nl(e){return typeof e==`string`?e.toLowerCase():``}const Pl=B.object({accessKey:B.optional(B.custom()),account:B.optional(B.custom())});function Fl(e={}){let t=Qi({chain:N,getClient:e.getClient,rpcUrl:Hn}),n=Ji({account:e.account});return Mt(Ba,{context:Pl,async createCredential({challenge:r,context:i}){let a=r.request.methodDetails?.chainId??Y.testnet,o=await t({chainId:a}),s=n(o,i),c=i?.accessKey??e.accessKey??r.request.methodDetails?.accessKey;if(!c)throw Error("No `accessKey` provided. The subscription challenge must include `accessKey`, or the client must pass one to parameters/context.");Ll(r.request),await e.validateRequest?.(r.request);let u=await Il(o,{accessKey:c,account:s,challengeId:r.id,chainId:a,request:r.request}),d=Sl({accessKey:c,challengeId:r.id,chainId:a,payload:{signature:F.serialize(u),type:`keyAuthorization`},request:r.request});if(!l(d.source.address,s.address))throw Error(`keyAuthorization signer does not match the selected account`);return Et({challenge:r,payload:{signature:F.serialize(u),type:`keyAuthorization`},source:`did:pkh:eip155:${a}:${s.address.toLowerCase()}`})}})}async function Il(e,t){let{accessKey:n,account:r,challengeId:i,chainId:a,request:o}=t,s=await xl({accessKey:n,account:r,challengeId:i,chainId:a,request:o});if(s)return s;let c=await e.request({method:`wallet_authorizeAccessKey`,params:[{address:n.accessKeyAddress,expiry:gl(hl(o.subscriptionExpires)),keyType:n.keyType,limits:[{token:o.currency,limit:T.fromNumber(BigInt(o.amount)),period:_l(o)}],scopes:yl(o),witness:bl(i)}]});return F.fromRpc(c.keyAuthorization)}function Ll(e){_l(e),gl(hl(e.subscriptionExpires))}const Rl=Object.assign(nl,{manager:fl});function zl(e={}){let t=e.expectedChainId!==void 0&&(e.allowedChainIds===void 0||e.allowedChainIds.includes(e.expectedChainId)),n=e.expectedChainId===void 0?e:{...e,allowedChainIds:t?[e.expectedChainId]:[]};return[Ha(e),Rl(n)]}(function(e){e.charge=Ha,e.common=zl,e.session=Rl,e.subscription=Fl})(zl||={});const Bl=M.union([M.boolean(),M.literal(`true`).transform(()=>!0),M.literal(`false`).transform(()=>!1)]);async function Vl(e){process.stdout.write(Buffer.from(await e.arrayBuffer()))}const Hl=M.object({allowCustomEscrow:M.optional(Bl),autoSwap:M.optional(Bl),channel:M.optional(M.coerce.string()),deposit:M.optional(M.union([M.string(),M.number()])),payWith:M.optional(M.string()),slippage:M.optional(M.coerce.number()),tokenIn:M.optional(M.string())}),Ul=[`allowCustomEscrow`,`autoSwap`,`channel`,`deposit`,`payWith`,`slippage`,`tokenIn`];function Wl(){let t;return sr({method:`tempo`,supports(e){return e.method===`tempo`&&[`charge`,`session`].includes(e.intent)},async setup({challenge:n,options:r,methodOpts:i}){let a=rr(r.account),o=n.request,c=o.currency,l=Xl(i),u=eu({autoSwap:l.autoSwap??r.autoSwap,payWith:l.payWith??r.payWith,slippage:l.slippage??r.slippage,tokenIn:l.tokenIn}),d=c??``,f=o.decimals??6,p,m,h,g=!1,_=process.env.MPPX_PRIVATE_KEY?.trim()||(Wn(a)?void 0:await ir(a).get());if(!_&&Wn(a)&&lu()){g=!0;let t=su(a);if(t){let i=qn(r.rpcUrl,{network:r.network});h=e({chain:await Jn({network:r.network,rpcUrl:i}),transport:s(i)}),Ql({challenge:n,clientChainId:h.chain?.id}),p=h.chain?.blockExplorers?.default?.url;let a=c?await Zn(h,c,t.wallet_address).catch(()=>void 0):void 0;d=a?.symbol??c??``,f=a?.decimals??o.decimals??6}}else if(_)m=de(_);else{let e=du();if(e){let t=await ir(e).get();t&&(m=de(t))}if(!m)throw r.account?new J({code:`ACCOUNT_NOT_FOUND`,message:`Account "${a}" not found.`,exitCode:69}):new J({code:`ACCOUNT_NOT_FOUND`,message:`No account found.`,exitCode:69})}if(!g&&m){let t=qn(r.rpcUrl,{network:r.network});h=e({chain:await Jn({network:r.network,rpcUrl:t}),transport:s(t)}),Ql({challenge:n,clientChainId:h.chain?.id}),p=h.chain?.blockExplorers?.default?.url;let i=c?await Zn(h,c,m.address).catch(()=>void 0):void 0;d=i?.symbol??c??``,f=i?.decimals??o.decimals??6}if(g)return{tokenSymbol:d,tokenDecimals:f,explorerUrl:p,methods:[],async createCredential(e){let t=e.headers.get(`www-authenticate`);if(!t)throw Error(`No WWW-Authenticate header in 402 response.`);return uu(t)}};if(!m||!h)throw new J({code:`ACCOUNT_NOT_FOUND`,message:`Tempo requires a configured account.`,exitCode:69});let v=zl({account:m,...l.allowCustomEscrow===void 0?{}:{allowCustomEscrow:l.allowCustomEscrow},getClient:()=>h,...u===void 0?{}:{autoSwap:u},maxDeposit:(()=>{if(n.intent!==`session`)return;let e=n.request.suggestedDeposit,t=(l.deposit===void 0?void 0:String(l.deposit))??e??(Xn(h.chain)?`10`:void 0);if(!t)throw new J({code:`MISSING_DEPOSIT`,message:`Session payment requires a deposit. Use -M deposit=<amount> or connect to testnet.`,exitCode:2});return t})()}),y=(()=>{if(!l.channel)return;let e=l.channel,t=nu(e);return{channelId:e,...t!==void 0&&{cumulativeAmountRaw:t.toString()}}})();return t={descriptor:void 0,async signVoucher({channelId:e,cumulativeAmount:r,escrowContract:i,chainId:a,action:o=`voucher`}){let s=t?.descriptor;if(!s)throw Error(`session descriptor not available`);let c={channelId:e,cumulativeAmount:r},l=await Oo(h,m,c,i,a);return Et({challenge:n,payload:{action:o,channelId:e,...o===`close`?{closeSignature:await ko(h,m,c,i,a)}:{},descriptor:s,cumulativeAmount:r.toString(),signature:l},source:`did:pkh:eip155:${a}:${m.address}`})},source:`did:pkh:eip155:${h.chain.id}:${m.address}`},{tokenSymbol:d,tokenDecimals:f,explorerUrl:p,methods:[...v],credentialContext:y}},prepareCredentialRequest({challenge:e,headers:t}){e.intent===`session`&&(t.Accept=`text/event-stream`)},async handleResponse(e){if(e.challenge.intent!==`session`||!t)return!1;let{challenge:n,credential:r,response:i,fetchUrl:a,fetchInit:o,verbose:s}=e,{silent:c,confirmEnabled:l,tokenSymbol:u,tokenDecimals:d,explorerUrl:f,shownKeys:p}=e,m=c?e=>{}:e=>process.stderr.write(e),h=St(r),g=n.request,_=g.methodDetails,v=h.payload.channelId,y=_?.escrowContract??_?.escrow??`0x4d50500000000000000000000000000000000000`,b=_?.chainId??0,x=BigInt(g.amount),C=`cumulativeAmount`in h.payload&&h.payload.cumulativeAmount?BigInt(h.payload.cumulativeAmount):0n;if(`descriptor`in h.payload&&(t.descriptor=h.payload.descriptor),s>=1){if(h.payload.action===`open`){let e=g.suggestedDeposit,t=e?` ${X.dim(`(deposit ${e} ${u})`)}`:``;m(`${l?``:`
|
|
7
|
+
`?2:t+1===e.length&&!n?0:1:0}function Rc(e){let t=new AbortController,n=()=>t.abort(e.signal?.reason);e.signal?.addEventListener(`abort`,n,{once:!0}),e.signal?.aborted&&n();let r=Fc({...e,signal:t.signal}),i=new TextEncoder,a=new Headers(e.response.headers);a.delete(`content-length`);let o=()=>e.signal?.removeEventListener(`abort`,n),s=new Response(new ReadableStream({async pull(e){try{let t=await r.next();if(t.done)return o(),e.close();e.enqueue(i.encode(t.value.raw))}catch(e){throw o(),e}},async cancel(){o(),t.abort(),await r.return(void 0)}}),{headers:a,status:e.response.status,statusText:e.response.statusText});for(let t of[`redirected`,`type`,`url`])Object.defineProperty(s,t,{configurable:!0,get:()=>e.response[t]});return s}async function zc(e,t){let n=e.driver.getChannel();if(!n||!e.challenge)return;let r=await yc({assertVoucherWithinLocalLimit:e.driver.assertVoucherWithinLocalLimit,challenge:e.challenge,event:t,expectedChannelId:n.channelId,getChannel:e.driver.getChannel,input:e.input,signal:e.signal,topUpIfNeeded:e.driver.topUpIfNeeded});if(r.status!==`ready`)return;let i=await Oc({challenge:e.challenge,context:r.context,createSessionCredential:e.driver.createSessionCredential,fetch:e.driver.fetch,input:e.input,signal:e.signal});if(!i.ok)throw Error(`Voucher POST failed with status ${i.status}`)}async function Bc(e){let t=new URL(e.input.toString()),n=Tc(t);e.onProbeUrl?.(n);let r=await e.fetch(n,{...e.probeInit,...e.signal?{signal:e.signal}:{}});if(r.status!==402)throw Error(`Expected a 402 payment challenge from ${n}, received ${r.status} instead.`);let i=pt(r).find(xc);if(!i)throw Error(`No payment challenge received from HTTP endpoint for this WebSocket URL. The server may not require payment or did not advertise a challenge.`);return{challenge:i,httpUrl:n,wsUrl:t}}async function Vc(e){e.signal?.throwIfAborted();let t=await Bc(e);e.signal?.throwIfAborted();let n=await e.createSessionCredential(t.challenge,{});return e.signal?.throwIfAborted(),{...t,credential:n}}function Hc(e){let{challenge:t,credential:n,socket:r}=e;return{challenge:t,channelId:St(n).payload.channelId,closeReadyReceipt:null,deliveredChunks:0n,expectedCloseAmount:null,socket:r,tickCost:$a(t)}}function Uc(e){let{challengeId:t,channelId:n,receipt:r}=e;return r.challengeId===t&&r.channelId===n}function Wc(e){if(!Uc(e))return`received mismatched payment-close-ready frame`;let t=Ga(e.receipt.spent);if(t===void 0)return`received invalid payment-close-ready spend`;if(t>e.cumulativeAmount)return`received payment-close-ready beyond local voucher state`}function Gc(e){let{challengeId:t,channelId:n,expectedCloseAmount:r,receipt:i}=e;if(!Uc(e))return`received mismatched payment-receipt frame`;if(r!==null&&i.txHash&&!Ss({challengeId:t,channelId:n,expectedCloseAmount:r,minimumSpent:BigInt(r),receipt:i}))return`received mismatched payment-close receipt frame`}async function Kc(e){let{challenge:t,credential:n,options:r,WebSocket:i,wsUrl:a}=e,o=r?.signal;o?.throwIfAborted();let s=new i(a,r?.protocols),c=Hc({challenge:t,credential:n,socket:s});e.setSocketSession(c);let l=hc(s),u=t=>{e.rejectReceipt(Error(t)),e.rejectCloseReady(Error(t)),(s.readyState===mc.CONNECTING||s.readyState===mc.OPEN)&&s.close(3008,t)},d=()=>{e.rejectReceipt(Error(`WebSocket payment flow aborted.`)),e.rejectCloseReady(Error(`WebSocket payment flow aborted.`)),s.close()};s.addEventListener(`close`,t=>{o?.removeEventListener(`abort`,d),c.socket=null,c.expectedCloseAmount=null,e.rejectReceipt(Error(`WebSocket closed before the payment flow completed.`)),e.rejectCloseReady(Error(`WebSocket closed before the payment flow completed.`)),l.emit(`close`,{code:t.code??1e3,reason:t.reason??``,type:`close`,wasClean:!0})}),s.addEventListener(`error`,()=>{l.emit(`error`,{type:`error`})}),s.addEventListener(`message`,async t=>{let n=typeof t.data==`string`?t.data:void 0;n&&await Jc({driver:e,failSocketFlow:u,managedEmit:l.emit,message:n,rawSocket:s,socketState:c})}),o?.addEventListener(`abort`,d,{once:!0});try{await qc(s,l.emit,a,o),o?.throwIfAborted()}catch(e){throw o?.removeEventListener(`abort`,d),s.close(),e}return s.send(oo(n)),await e.waitForReceipt(),l.socket}function qc(e,t,n,r){return new Promise((i,a)=>{let o=()=>{e.removeEventListener(`open`,s),e.removeEventListener(`error`,c),e.removeEventListener(`close`,c),r?.removeEventListener(`abort`,l)},s=()=>{o(),t(`open`,{type:`open`}),i()},c=()=>{o(),a(Error(`WebSocket connection to ${n} failed to open.`))},l=()=>{o(),a(r?.reason)};e.addEventListener(`open`,s,{once:!0}),e.addEventListener(`error`,c,{once:!0}),e.addEventListener(`close`,c,{once:!0}),r?.addEventListener(`abort`,l,{once:!0}),r?.aborted&&l()})}async function Jc(e){let t=co(e.message);if(!t){e.managedEmit(`message`,{data:e.message,type:`message`});return}switch(t.mpp){case`authorization`:return;case`message`:e.socketState.deliveredChunks+=1n,e.managedEmit(`message`,{data:t.data,type:`message`});return;case`payment-close-ready`:Yc(e,t.data);return;case`payment-error`:e.driver.rejectReceipt(Error(t.message)),e.driver.rejectCloseReady(Error(t.message));return;case`payment-need-voucher`:await Xc(e,t.data);return;case`payment-receipt`:Zc(e,t.data);return}}function Yc(e,t){let n=e.driver.getChannel()?.cumulativeAmount??0n,r=Wc({challengeId:e.driver.challenge.id,channelId:e.socketState.channelId,cumulativeAmount:n,receipt:t});if(r){e.failSocketFlow(r);return}e.driver.acceptReceipt(t),e.driver.options?.onReceipt?.(t),e.driver.settleCloseReady(t),e.managedEmit(`close`,{code:1e3,reason:`stream complete`,type:`close`,wasClean:!0})}async function Xc(e,t){try{let n=e.driver.challenge;n.expires&&new Date(n.expires).getTime()<=Date.now()+5e3&&(n=await e.driver.refreshChallenge(),e.driver.challenge=n,e.socketState.challenge=n);let r=await yc({assertVoucherWithinLocalLimit:e.driver.assertVoucherWithinLocalLimit,challenge:n,event:t,expectedChannelId:e.socketState.channelId,getChannel:e.driver.getChannel,input:e.driver.httpUrl,signal:e.driver.options?.signal,topUpIfNeeded:e.driver.topUpIfNeeded});if(r.status===`ignored`){e.failSocketFlow(r.reason===`channel-mismatch`?`received mismatched payment-need-voucher frame`:`cannot create voucher: no active channel`);return}let i=await e.driver.createSessionCredential(n,r.context);e.rawSocket.send(oo(i))}catch(t){e.failSocketFlow(t instanceof Error?t.message:`failed to create websocket voucher`)}}function Zc(e,t){let n=Gc({challengeId:e.driver.challenge.id,channelId:e.socketState.channelId,expectedCloseAmount:e.socketState.expectedCloseAmount,receipt:t});if(n){e.failSocketFlow(n);return}e.driver.acceptReceipt(t),e.driver.options?.onReceipt?.(t),e.driver.settleReceipt(t)}const Qc=new WeakMap;async function $c(e,t){let n=Qc.get(e)??new Map;Qc.set(e,n);let r=n.get(t),i,a=new Promise(e=>{i=e});return n.set(t,a),await r,()=>{i(),n.get(t)===a&&n.delete(t)}}function el(e,t){try{return t?.channelId.toLowerCase()===e.channelId.toLowerCase()&&BigInt(t.acceptedCumulative)===e.cumulativeAmount}catch{return!1}}function tl(e,t,n){try{let r=e.response?.headers.get(R.paymentReceipt);if(r){let e=no(r);if(e.challengeId===t.id&&el(n,e))return!0}}catch{}return e.challenges?.some(e=>xc(e)?el(n,Sc(e)):!1)??!1}function nl(e={}){let{account:t,allowCustomEscrow:n=!1,autoSwap:r,channelStore:i,decimals:a=6,escrow:o,allowedChainIds:s,getClient:c,maxDeposit:l,topUpAmount:u,onChannelUpdate:f,resolveAccount:p}=e,m=Qi({chain:b,getClient:c,rpcUrl:Hn}),h=Ji({account:t}),g=l===void 0?void 0:d(l,a),_=u===void 0?void 0:d(u,a),v=i??qo(),y={store:v,notifyUpdate:e=>f?.(e)},x=async(e,t,n)=>{let r=h(e.client,t),i=t?.action?t.descriptor:n?.descriptor??Qs({context:t,snapshot:e.snapshot})?.descriptor;return await p?.({account:r,chainId:e.chainId,operation:{kind:`authorizePaymentChannel`,...i?{authority:fo(i)}:{}}})??r},S=async(e,t,n)=>nc({account:await x(e,t,n),entry:n,context:t,decimals:a,maxDeposit:g,resolved:e}),C=Mt(za,{canHandleChallenge:({challenge:e})=>xc(e),context:Rs,async createCredential(e){let{challenge:t,context:i}=e,a=await Ys({allowCustomEscrow:n,challenge:t,escrowOverride:o,allowedChainIds:s,getClient:m}),c=li(e),l=()=>{};try{let e=!zs(i)&&i?.descriptor===void 0;e&&(l=await $c(v,a.key),c&&(await v.get(a.key))?.opened&&await c.prepare());let n=await v.get(a.key),o=await S(a,i,n);if(!e&&c&&o.type===`open`){l=await $c(v,a.key);let e=await v.get(a.key);e?.channelId!==n?.channelId&&(n=e,n?.opened&&(await c.prepare(),n=await v.get(a.key)),o=await S(a,i,n))}let s,u=c&&o.type===`open`?{store:{get:e=>v.get(e),async set(e){s=e},delete:e=>v.delete(e)},notifyUpdate(){}}:y,d=await zo(t,await rc(o,u,ca(i?.autoSwap??r,oa)),a.chainId,o.account);if(c&&s){let e=s;c.settle=async n=>{let r=n.status===`accepted`||tl(n,t,e);if(!r&&n.status===`pending`)return!1;try{if(r){let t=await v.get(a.key);(!t?.opened||t.channelId.toLowerCase()!==e.channelId.toLowerCase())&&(await v.set(e),y.notifyUpdate(e))}return!0}finally{l()}}}else l();return d}catch(e){throw l(),e}}}),w=async({challenge:e,channel:t,deposit:n,fetch:r,input:i,requiredCumulative:a,signal:o})=>{let s=t.deposit>n?t.deposit:n,c=_s({deposit:s,maxDeposit:g,requiredCumulative:a,suggestedDeposit:e.request.suggestedDeposit===void 0?void 0:BigInt(e.request.suggestedDeposit),topUpAmount:_});c>0n&&await Dc({additionalDeposit:c,challenge:e,channel:t,channelId:t.channelId,createSessionCredential:(e,t)=>C.createCredential({challenge:e,context:t}),fetch:r,input:i,signal:o});let l=s+c;if(l===t.deposit)return;let u=await v.get(Ko(t)),d=u?.channelId.toLowerCase()===t.channelId.toLowerCase()?u:t,f={...d,deposit:d.deposit>l?d.deposit:l};await v.set(f),y.notifyUpdate(f)};return ti(C,async({challenge:e,context:t,fetch:r,input:i,signal:a})=>{if(!xc(e))return;let c=t===void 0?void 0:Rs.parse(t);if(zs(c))return;let l=await Ys({allowCustomEscrow:n,challenge:e,escrowOverride:o,allowedChainIds:s,getClient:m}),u=await v.get(l.key);if(!u?.opened)return;let d=l.snapshot?.channelId.toLowerCase()===u.channelId.toLowerCase()?l.snapshot:void 0,f=u.cumulativeAmount+$a(e),p=d?BigInt(d.requiredCumulative):f,h=p>f?p:f,g=d?BigInt(d.deposit):u.deposit,_=g>u.deposit?g:u.deposit;h<=_&&_===u.deposit||!tc(await x(l,c,u),u.descriptor)||await w({challenge:e,channel:u,deposit:_,fetch:r,input:i,requiredCumulative:h,signal:a})}),oi(C,async({challenge:e,credential:t,fetch:r,headers:i,input:a,refetch:c,response:l,signal:u})=>{if(!xc(e))return l;if(!ro(l))return Qa(St(t).payload).action===`open`&&i.get(`accept`)?.toLowerCase().includes(`text/event-stream`)?await c?.()??l:l;let d=(await Ys({allowCustomEscrow:n,challenge:e,escrowOverride:o,allowedChainIds:s,getClient:m})).key,f=await v.get(d),p={assertVoucherWithinLocalLimit:e=>vs(e,g),createSessionCredential:(e,t)=>C.createCredential({challenge:e,context:t}),fetch:r,getChannel:()=>f??null,async topUpIfNeeded({deposit:t,requiredCumulative:n,signal:i}){f&&await w({challenge:e,channel:f,deposit:f.deposit>t?f.deposit:t,fetch:r,input:a,requiredCumulative:n,signal:i})}};return Rc({onNeedVoucher:(t,n)=>zc({challenge:e,driver:p,input:a,signal:n},t),onReceipt(){},response:l,signal:u})})}const rl=new WeakMap;function il(e,t){rl.set(e,t)}function al(e){let t=null;return{wait(n=()=>!0){if(t)throw Error(`${e} wait already in progress`);return new Promise((e,r)=>{t={predicate:n,resolve:e,reject:r}})},settle(e){if(!t||!t.predicate(e))return;let n=t;t=null,n.resolve(e)},reject(e){if(!t)return;let n=t;t=null,n.reject(e)}}}function ol(e){let t=al(`close-ready`),n=al(`receipt`);return{waitForReceipt(e){return n.wait(e)},waitForCloseReady(){let n=e.getSocketSession()?.closeReadyReceipt;return n?Promise.resolve(n):t.wait()},settleReceipt(e){n.settle(e)},settleCloseReady(n){let r=e.getSocketSession();r&&r.challenge.id===n.challengeId&&r.channelId===n.channelId&&(r.closeReadyReceipt=n),t.settle(n)},rejectReceipt(e){n.reject(e)},rejectCloseReady(e){t.reject(e)}}}function sl(e){return e.method===We.tempo&&e.intent===Ge.charge}function cl(e){if(!sl(e)||typeof e.request.amount!=`string`)return!1;try{return BigInt(e.request.amount)===0n}catch{return!1}}function ll(e,t,n){if(!n)return t;let r={...Q(e instanceof Request?e.headers:void 0),...Q(t?.headers)};return Object.keys(r).some(e=>e.toLowerCase()===R.paymentSession.toLowerCase())?t:{...t,headers:{...r,[R.paymentSession]:n}}}function ul(e,t){return e===void 0?t:{...Rs.parse(e),...t}}function dl(e){let t=e.decimals??6,n=e.webSocket??globalThis.WebSocket;return{decimals:t,fetch:e.fetch??globalThis.fetch.bind(globalThis),maxVoucherCumulative:e.maxDeposit===void 0?null:d(e.maxDeposit,t),topUpAmount:e.topUpAmount===void 0?null:d(e.topUpAmount,t),WebSocket:n}}function fl(e){let t=e.client?.chain?.id;(t!==void 0||e.allowedChainIds?.length===0)&&ea(e.allowedChainIds,t);let n=e.allowCustomEscrow??!1,r=dl(e),i=Qi({chain:b,getClient:e.client?()=>e.client:e.getClient,rpcUrl:Hn}),a=Ji({account:e.account}),o=ws(),s=e.credentialContext===void 0?void 0:ul(e.credentialContext,{}),c=ol({getSocketSession:()=>o.socketSession}),l=e.channelStore??qo(),u=new Set,d;async function f(e){let t=await l.get(e);if(t?.opened&&!u.has(t.channelId))return t}let p={async get(e){let t=await f(e);return t&&d&&(d.seenExisting.add(e),!d.committed&&!d.created.has(e)&&(d.resumed??=t)),t},async set(e){let t=Ko(e);e.opened&&u.delete(e.channelId),d?.trackCreates&&!d.seenExisting.has(t)&&d.created.set(t,e),await l.set(e)},delete:e=>l.delete(e)};async function m(e){let t=Ko(e);u.add(e.channelId),d?.seenExisting.delete(t),d?.resumed===e&&(d.resumed=void 0),await Promise.resolve(l.delete(t)).catch(()=>void 0)}async function h(){let e=d;if(e?.created.size){for(let[t,n]of e.created)u.add(n.channelId),await Promise.resolve(l.delete(t)).catch(()=>void 0);e.created.clear(),await re(e.committed??e.previous)}}function g(e){let t=Je(e.request.methodDetails,Ke.sessionSnapshot);if(typeof t?.channelId!=`string`)return!1;let n=d;if(!n?.created.size||!o.channel)return!1;for(let[e,r]of n.created)if(r.channelId.toLowerCase()===t.channelId.toLowerCase()&&o.channel.channelId.toLowerCase()===t.channelId.toLowerCase())return n.created.delete(e),n.committed=ks({channel:o.channel,spent:o.spent,state:o.state}),!0;return!1}function _(e){return cs(o,e)}function v(){let e=o.state.status===`active`?o.state:d?.committed?.state??d?.previous.state;return e?.status===`active`?e.units:0}function y(e){let t=d,n=t?.committed?.channel?.entry??t?.resumed;!t||n?.channelId.toLowerCase()!==e.channelId.toLowerCase()||e.deposit<=n.deposit||(t.resumed=void 0,t.committed=ks({channel:o.channel,spent:o.spent,state:o.state}))}let x=nl({account:e.account,allowCustomEscrow:n,autoSwap:e.autoSwap,getClient:e.client?()=>e.client:e.getClient,resolveAccount:e.resolveAccount,escrow:e.escrow,allowedChainIds:e.allowedChainIds,decimals:r.decimals,maxDeposit:e.maxDeposit,topUpAmount:e.topUpAmount,channelStore:p,onChannelUpdate(e){e.channelId!==o.channel?.channelId&&(o.spent=0n),o.channel=e,o.lastChallenge&&_({type:`activated`,challengeId:o.lastChallenge.id,entry:e,spent:o.spent.toString(),units:v()}),y(e)}});si(x);let S=Ha({allowedChainIds:e.allowedChainIds,account:e.account,getClient:e.client?()=>e.client:e.getClient,resolveAccount:e.resolveAccount}),C=mi({fetch:r.fetch,methods:[x],onChallenge:async(e,t)=>{if(!bc(e))return;let n=d,r=n&&n.challengesReceived>0&&e.id===o.lastChallenge?.id,i=r&&at(e)===at(o.lastChallenge);n&&n.challengesReceived++,!i&&(g(e)||(n?.created.size?await h():r&&await re(n.committed??n.previous)),o.lastChallenge=e,_({type:`challengeReceived`,challengeId:e.id}))}});function w(e,t){return x.createCredential({challenge:e,context:ul(s,t)})}function T(e){Ts({maxVoucherCumulative:r.maxVoucherCumulative,receipt:e,runtime:o})}function E(e=o.state.status===`active`?o.state.units:0){!o.channel||!o.lastChallenge||o.state.status!==`active`&&o.state.status!==`withdrawable`&&o.state.status!==`closeRequested`&&_({type:`activated`,challengeId:o.lastChallenge.id,entry:o.channel,spent:o.spent.toString(),units:e})}async function D(t){let n=t.headers.get(R.paymentSessionSnapshot);if(!n)return;let r=is(n);ea(e.allowedChainIds,r.chainId);let s=await i({chainId:r.chainId});$i(s,r.chainId);let c=a(s),{entry:l,spent:u}=await ec({account:await e.resolveAccount?.({account:c,chainId:r.chainId,operation:{authority:fo(r.descriptor),kind:`authorizePaymentChannel`}})??c,client:s,snapshot:r});return N(l.cumulativeAmount),await Promise.resolve(p.set(l)).catch(()=>void 0),o.channel=l,o.spent=u,l}async function O(t,n){if(!e.bootstrap||o.channel?.opened)return;let i=t instanceof Request?t.headers:void 0,{body:a,method:s,...c}=n??{},l=t instanceof Request?t.url:t,u={...c,method:`HEAD`,headers:{...Q(i),...Q(n?.headers),[R.acceptPayment]:`${We.tempo}/${Ge.charge}`}};try{let e=await r.fetch(l,u);if(e.status!==402)return await D(e);let t=pt(e).find(sl);if(!t||!cl(t))return;let n=await S.createCredential({challenge:t,context:{}}),i=await r.fetch(l,{...u,headers:{...Q(u.headers),[R.authorization]:n}});return i.ok?await D(i):void 0}catch{return}}function k(e,t){let n=o.socketSession;return Ds({challengeId:e.id,channelId:t,closeReadyReceipt:n?.closeReadyReceipt,cumulativeAmount:o.channel?.channelId===t?o.channel.cumulativeAmount:0n,deliveredChunks:n?.deliveredChunks,socketChallengeId:n?.challenge.id,socketChannelId:n?.channelId,spent:o.spent,tickCost:n?.tickCost})}function A(e,t){let n=Sc(t);if(!n)return;if(po({...n.descriptor,chainId:n.chainId,escrow:n.escrow}).toLowerCase()!==n.channelId.toLowerCase())throw Error(`close snapshot descriptor does not match its channel ID`);if(n.channelId.toLowerCase()!==e.channelId.toLowerCase())throw Error(`close snapshot channel ID does not match local session`);if(n.chainId!==e.chainId||n.escrow.toLowerCase()!==e.escrow.toLowerCase())throw Error(`close snapshot payment scope does not match local session`);let r=BigInt(n.acceptedCumulative),i=BigInt(n.spent);if(r<0n||i<0n)throw Error(`close snapshot amounts must not be negative`);if(i>r)throw Error(`close snapshot spent exceeds accepted cumulative amount`);if(r>e.cumulativeAmount)throw Error(`close snapshot accepted cumulative exceeds local voucher state`);return{acceptedCumulative:r,spent:i}}function j(e,t){let n=A(e.channel,t);if(!n)return;let{acceptedCumulative:r,spent:i}=n;if(o.spent>r)throw Error(`close snapshot accepted cumulative is below locally confirmed spend`);return i>o.spent&&(o.spent=i),n}function M(e,t=e.challenge,n=!1){let r=(n?j(e,t):A(e.channel,t))?.acceptedCumulative??k(t,e.channelId);if(r>e.channel.cumulativeAmount)throw Error(`fallback close amount exceeds local voucher state`);return N(r),r.toString()}function N(e){fs({cumulativeAmount:e,maxVoucherCumulative:r.maxVoucherCumulative})}async function ee(e){let{knownDeposit:t,...n}=e,i=await Dc({...n,channel:o.channel,createSessionCredential:w,fetch:r.fetch});T(i);let a=vc({additionalDeposit:e.additionalDeposit,channel:o.channel,channelId:e.channelId,challengeId:o.lastChallenge?.id,currentState:o.state,knownDeposit:t,receipt:i,spent:o.spent});return a?.channel&&o.lastChallenge&&(await p.set(a.channel),_({type:`activated`,challengeId:o.lastChallenge.id,entry:a.channel,spent:o.spent.toString(),units:v()}),y(a.channel)),i}async function te(e){let t=o.channel?.channelId===e.channelId?o.channel.deposit:0n,n=t>e.deposit?t:e.deposit,i=_s({deposit:n,maxDeposit:r.maxVoucherCumulative,requiredCumulative:e.requiredCumulative,suggestedDeposit:e.challenge.request.suggestedDeposit===void 0?void 0:BigInt(e.challenge.request.suggestedDeposit),topUpAmount:r.topUpAmount});i!==0n&&await ee({challenge:e.challenge,input:e.input,channelId:e.channelId,additionalDeposit:i,knownDeposit:n,signal:e.signal})}async function ne(e,t){let n=Os({channel:o.channel,channelId:e,challengeId:o.lastChallenge?.id,cumulativeAmount:t,spent:o.spent,state:o.state});n&&o.channel&&(_({type:`activated`,challengeId:n.challengeId,entry:o.channel,spent:n.spent,units:n.units}),await l.set(o.channel))}async function re(e){let t=As(e,o.channel);o.channel=t.channel,o.spent=t.spent,o.state=t.state,o.channel?.opened&&await l.set(o.channel)}function ie(e){let t=e.headers.get(R.paymentReceipt),n=t?no(t):null;return T(n),Object.assign(e,{receipt:n,challenge:o.lastChallenge,channelId:o.channel?.channelId??null,cumulative:o.channel?.cumulativeAmount??0n})}async function ae(e,t){if(d)throw Error(`SessionManager: a request is already in flight; concurrent requests on one manager are not supported`);o.lastUrl=e;let n=ks({channel:o.channel,spent:o.spent,state:o.state}),i={challengesReceived:0,committed:void 0,created:new Map,previous:n,seenExisting:new Set,resumed:void 0,trackCreates:!1};d=i;try{await O(e,t),i.trackCreates=!0;let a=ll(e,t,o.channel?.opened?o.channel.channelId:void 0);s&&(a={...a,context:s});let c=!n.channel?.opened;async function l(){let n=i.resumed;return!c||!n?!1:(c=!1,await m(n),a=ll(e,t,void 0),!0)}for(;;){let t;try{t=await C(e,a)}catch(e){if(i.created.size?await h():await re(i.committed??n),await l())continue;throw e}let s=ie(t),c=!1;if(s.status===402){let t=await kc({input:e,init:a,response:s,createSessionCredential:w,fetch:r.fetch,getChannel:()=>o.channel,restoreCumulative:ne,setChallenge(e){o.lastChallenge=e},topUpIfNeeded:te});t&&(c=!0,s=ie(t))}if(!c&&!s.ok&&!s.receipt){if(i.created.size?await h():await re(i.committed??n),await l())continue;return s}return s}}finally{d=void 0}}async function P(e){let t=await jc({createSessionCredential:w,fetch:r.fetch,getMinimumSpent:()=>o.spent,lastUrl:o.lastUrl,resolveSignedCloseAmount:t=>M(e,t,!0),signedCloseAmount:M(e),setChallenge(e){o.lastChallenge=e},target:e});return t&&(E(),_({type:`closeStarted`}),_({type:`closed`,receipt:t})),t}let oe={createSessionCredential:w,doFetch:ae,fetch:r.fetch,getChannel:()=>o.channel,getChallenge:()=>o.lastChallenge,assertVoucherWithinLocalLimit:N,acceptReceipt(e){T(e)},topUpIfNeeded:te},se={get channelId(){return o.channel?.channelId},get cumulative(){return o.channel?.cumulativeAmount??0n},get opened(){return o.channel?.opened??!1},get state(){return o.state},fetch:ae,async topUp(e){let t=_c({amount:e,assertVoucherWithinLocalLimit:N,channel:o.channel,decimals:r.decimals,lastChallenge:o.lastChallenge,lastUrl:o.lastUrl});return ee({additionalDeposit:t.additionalDeposit,challenge:t.challenge,channelId:t.channelId,input:t.input})},async sse(e,t){return Mc(e,t,oe)},async ws(e,t){if(!r.WebSocket)throw Error("No WebSocket implementation available. Pass `webSocket` to sessionManager() in this runtime.");let n=Tc(e),i=t?.signal?{signal:t.signal}:void 0;await O(n,i);let a=o.channel?.opened?o.channel.channelId:void 0,{challenge:s,credential:l,httpUrl:u,wsUrl:d}=await Vc({async createSessionCredential(e,i){return o.lastChallenge=e,await ri(x,{challenge:e,context:i,fetch:r.fetch,input:n,signal:t?.signal}),w(e,i)},fetch:r.fetch,input:e,onProbeUrl(e){o.lastUrl=e.toString()},probeInit:ll(n,i,a),signal:t?.signal});return o.lastChallenge=s,Kc({challenge:s,credential:l,httpUrl:u,WebSocket:r.WebSocket,wsUrl:d,options:t,createSessionCredential:w,getChannel:()=>o.channel,setSocketSession(e){o.socketSession=e},async refreshChallenge(){let e=await Bc({fetch:r.fetch,input:u,probeInit:ll(u,i,o.channel?.opened?o.channel.channelId:void 0),signal:t?.signal});return o.lastChallenge=e.challenge,e.challenge},assertVoucherWithinLocalLimit:N,acceptReceipt:T,rejectCloseReady:c.rejectCloseReady,rejectReceipt:c.rejectReceipt,settleCloseReady:c.settleCloseReady,settleReceipt:c.settleReceipt,topUpIfNeeded:te,waitForReceipt:c.waitForReceipt})},async close(){let e=o.socketSession,t=ys({channel:o.channel,currentSocket:e,lastChallenge:o.lastChallenge});if(!t)return;let n=e?.socket;if(e&&n?.readyState===mc.OPEN){let r=await js({activeSocket:n,createSessionCredential:w,currentSocket:e,spent:o.spent,target:t,waitForCloseReady:c.waitForCloseReady,waitForReceipt:c.waitForReceipt});return E(),_({type:`closeStarted`}),_({type:`closed`,receipt:r}),r}return P(t)}};return il(se,{consumeSseResponse(e,t,n){return Nc(e,t,n,oe)},rehydrate({channel:e,challenge:t,input:n,spent:r}){if(!e.opened)throw Error(`Cannot restore a closed session channel.`);if(!bc(t))throw Error(`Cannot restore session: challenge is not tempo/session.`);if(r<0n)throw Error(`Cannot restore session: spent must not be negative.`);if(r>e.cumulativeAmount)throw Error(`Cannot restore session: spent exceeds local voucher state.`);N(e.cumulativeAmount);let i=A(e,t),a=i&&i.spent>r?i.spent:r;o.lastUrl=n,o.lastChallenge=t,o.channel=e,o.spent=a,_({type:`challengeReceived`,challengeId:t.id}),_({type:`activated`,challengeId:t.id,entry:e,spent:a.toString(),units:0})}}),se}(function(e){e.serializeSnapshot=rs,e.deserializeSnapshot=is})(fl||={});const pl=(1n<<64n)-1n,ml={dev_second:1n,day:86400n,week:604800n};function hl(e){return e instanceof Date?e:new Date(e)}function gl(e){let t=e.getTime();if(!Number.isFinite(t))throw new K({reason:`subscriptionExpires is invalid`});if(t%1e3!=0)throw new K({reason:`subscriptionExpires must be representable as whole seconds`});let n=t/1e3;if(n<=0||!Number.isSafeInteger(n))throw new K({reason:`subscriptionExpires cannot be represented in a Tempo key authorization`});return n}function _l(e){if(!/^[1-9]\d*$/.test(e.periodCount))throw new K({reason:`periodCount is invalid`});let t=ml[e.periodUnit];if(t===void 0)throw new K({reason:`periodUnit is invalid`});let n=BigInt(e.periodCount)*t;if(n>pl)throw new K({reason:`subscription period cannot be represented as an unsigned 64-bit integer`});if(n>BigInt(2**53-1))throw new K({reason:`subscription period cannot be represented exactly by this Tempo client`});return Number(n)}function vl(e){let{challengeExpires:t,request:n}=e;_l(n);let r=gl(hl(n.subscriptionExpires));if(t){let e=Math.floor(new Date(t).getTime()/1e3);if(!Number.isFinite(e)||r<=e)throw new K({reason:`subscriptionExpires must be strictly later than challenge expires`})}}function yl(e){return[{address:Ml(e.currency,`currency`),selector:`0x95777d59`,recipients:[Ml(e.recipient,`recipient`)]}]}function bl(e){try{let t=T.fromBytes(S.toBytes(e));if(T.size(t)!==32)throw Error(`invalid challenge id size`);return t}catch{throw new K({reason:`challenge id must encode 32 bytes`})}}async function xl(e){let{accessKey:t,account:n,challengeId:r,chainId:i,request:a}=e;if(typeof n.sign!=`function`)return;let o=Cl({accessKey:t,challengeId:r,chainId:i,request:a}),s=await n.sign({hash:F.getSignPayload(o)}),c=I.from(s);if(c.type===`keychain`||c.type===`multisig`)throw new K({reason:`keyAuthorization must use a primitive signature`});return F.from(o,{signature:s})}function Sl(e){let{accessKey:t,challengeId:n,chainId:r,payload:i,request:a}=e;if(i.type!==`keyAuthorization`)throw new K({reason:`invalid keyAuthorization payload`});let o=wl(i.signature),s=Tl(o);if(El({accessKey:t,authorization:o,chainId:r}),o.witness?.toLowerCase()!==bl(n))throw new K({reason:`keyAuthorization challenge mismatch`});return Dl(o,a),kl(Ol(o),a),Al(o.scopes,a),{authorization:o,source:{address:jl(o,s),chainId:r}}}function Cl(e){let{accessKey:t,challengeId:n,chainId:r,request:i}=e;return F.from({address:Ml(t.accessKeyAddress,`accessKeyAddress`),chainId:BigInt(r),expiry:gl(hl(i.subscriptionExpires)),limits:[{token:Ml(i.currency,`currency`),limit:BigInt(i.amount),period:_l(i)}],scopes:yl(i),type:t.keyType,witness:bl(n)})}function wl(e){try{return F.deserialize(e)}catch(e){throw e instanceof F.InvalidSignatureTypeError?new K({reason:`keyAuthorization must use a primitive signature`}):new K({reason:`invalid keyAuthorization payload`})}}function Tl(e){let t=e.signature;if(!t)throw new K({reason:`keyAuthorization must use a primitive signature`});return t}function El(e){let{accessKey:t,authorization:n,chainId:r}=e;if(n.chainId!==BigInt(r))throw new K({reason:`keyAuthorization chainId mismatch`});if(t){if(!l(n.address,Ml(t.accessKeyAddress,`accessKeyAddress`)))throw new K({reason:`keyAuthorization access key mismatch`});if(n.type!==t.keyType)throw new K({reason:`keyAuthorization key type mismatch`})}}function Dl(e,t){if(vl({request:t}),e.expiry!==gl(hl(t.subscriptionExpires)))throw new K({reason:`keyAuthorization expiry mismatch`})}function Ol(e){let[t]=e.limits??[];if(!t||e.limits?.length!==1)throw new K({reason:`keyAuthorization must contain exactly one token limit`});return t}function kl(e,t){if(!l(e.token,Ml(t.currency,`currency`)))throw new K({reason:`keyAuthorization currency mismatch`});if(e.limit!==BigInt(t.amount))throw new K({reason:`keyAuthorization amount mismatch`});if(e.period!==_l(t))throw new K({reason:`keyAuthorization period mismatch`})}function Al(e,t){if(!e||e.length!==1)throw new K({reason:`keyAuthorization must contain a recipient-scoped transferWithMemo call`});let n=Ml(t.currency,`currency`),r=Ml(t.recipient,`recipient`),i=new Set;for(let t of e){if(!l(t.address,n))throw new K({reason:`keyAuthorization call target mismatch`});let e=Nl(t.selector);if(e!==`0xa9059cbb`&&e!==`0x95777d59`)throw new K({reason:`keyAuthorization selector not allowed`});if(i.has(e))throw new K({reason:`keyAuthorization duplicate selector`});if(i.add(e),t.recipients?.length!==1||!l(t.recipients[0],r))throw new K({reason:`keyAuthorization recipient mismatch`})}if(!i.has(`0x95777d59`))throw new K({reason:`keyAuthorization must allow transferWithMemo`})}function jl(e,t){let n=F.getSignPayload(e);try{let e=I.extractAddress({payload:n,signature:t});if(!I.verify(t,{address:e,payload:n}))throw new K({reason:`keyAuthorization signature is invalid`});return e}catch(e){throw e instanceof K?e:new K({reason:`keyAuthorization signature is invalid`})}}function Ml(e,t){if(!c(e))throw new K({reason:`${t} must be an address`});return e.toLowerCase()}function Nl(e){return typeof e==`string`?e.toLowerCase():``}const Pl=B.object({accessKey:B.optional(B.custom()),account:B.optional(B.custom())});function Fl(e={}){let t=Qi({chain:N,getClient:e.getClient,rpcUrl:Hn}),n=Ji({account:e.account});return Mt(Ba,{context:Pl,async createCredential({challenge:r,context:i}){let a=r.request.methodDetails?.chainId??Y.testnet,o=await t({chainId:a}),s=n(o,i),c=i?.accessKey??e.accessKey??r.request.methodDetails?.accessKey;if(!c)throw Error("No `accessKey` provided. The subscription challenge must include `accessKey`, or the client must pass one to parameters/context.");Ll(r.request),await e.validateRequest?.(r.request);let u=await Il(o,{accessKey:c,account:s,challengeId:r.id,chainId:a,request:r.request}),d=Sl({accessKey:c,challengeId:r.id,chainId:a,payload:{signature:F.serialize(u),type:`keyAuthorization`},request:r.request});if(!l(d.source.address,s.address))throw Error(`keyAuthorization signer does not match the selected account`);return Et({challenge:r,payload:{signature:F.serialize(u),type:`keyAuthorization`},source:`did:pkh:eip155:${a}:${s.address.toLowerCase()}`})}})}async function Il(e,t){let{accessKey:n,account:r,challengeId:i,chainId:a,request:o}=t,s=await xl({accessKey:n,account:r,challengeId:i,chainId:a,request:o});if(s)return s;let c=await e.request({method:`wallet_authorizeAccessKey`,params:[{address:n.accessKeyAddress,expiry:gl(hl(o.subscriptionExpires)),keyType:n.keyType,limits:[{token:o.currency,limit:T.fromNumber(BigInt(o.amount)),period:_l(o)}],scopes:yl(o),witness:bl(i)}]});return F.fromRpc(c.keyAuthorization)}function Ll(e){_l(e),gl(hl(e.subscriptionExpires))}const Rl=Object.assign(nl,{manager:fl});function zl(e={}){let t=e.expectedChainId!==void 0&&(e.allowedChainIds===void 0||e.allowedChainIds.includes(e.expectedChainId)),n=e.expectedChainId===void 0?e:{...e,allowedChainIds:t?[e.expectedChainId]:[]};return[Ha(e),Rl(n)]}(function(e){e.charge=Ha,e.common=zl,e.session=Rl,e.subscription=Fl})(zl||={});const Bl=M.union([M.boolean(),M.literal(`true`).transform(()=>!0),M.literal(`false`).transform(()=>!1)]);async function Vl(e){process.stdout.write(Buffer.from(await e.arrayBuffer()))}const Hl=M.object({allowCustomEscrow:M.optional(Bl),autoSwap:M.optional(Bl),channel:M.optional(M.coerce.string()),deposit:M.optional(M.union([M.string(),M.number()])),payWith:M.optional(M.string()),slippage:M.optional(M.coerce.number()),tokenIn:M.optional(M.string())}),Ul=[`allowCustomEscrow`,`autoSwap`,`channel`,`deposit`,`payWith`,`slippage`,`tokenIn`];function Wl(){let t;return sr({method:`tempo`,supports(e){return e.method===`tempo`&&[`charge`,`session`].includes(e.intent)},async setup({challenge:n,options:r,methodOpts:i}){let a=rr(r.account),o=n.request,c=o.currency,l=Xl(i),u=eu({autoSwap:l.autoSwap??r.autoSwap,payWith:l.payWith??r.payWith,slippage:l.slippage??r.slippage,tokenIn:l.tokenIn}),d=c??``,f=o.decimals??6,p,m,h,g=!1,_=process.env.MPPX_PRIVATE_KEY?.trim()||(Wn(a)?void 0:await ir(a).get());if(!_&&Wn(a)&&lu()){g=!0;let t=su(a);if(t){let i=qn(r.rpcUrl,{network:r.network});h=e({chain:await Jn({network:r.network,rpcUrl:i}),transport:s(i)}),Ql({challenge:n,clientChainId:h.chain?.id}),p=h.chain?.blockExplorers?.default?.url;let a=c?await Zn(h,c,t.wallet_address).catch(()=>void 0):void 0;d=a?.symbol??c??``,f=a?.decimals??o.decimals??6}}else if(_)m=de(_);else{let e=du();if(e){let t=await ir(e).get();t&&(m=de(t))}if(!m)throw r.account?new J({code:`ACCOUNT_NOT_FOUND`,message:`Account "${a}" not found.`,exitCode:69}):new J({code:`ACCOUNT_NOT_FOUND`,message:`No account found.`,exitCode:69})}if(!g&&m){let t=qn(r.rpcUrl,{network:r.network});h=e({chain:await Jn({network:r.network,rpcUrl:t}),transport:s(t)}),Ql({challenge:n,clientChainId:h.chain?.id}),p=h.chain?.blockExplorers?.default?.url;let i=c?await Zn(h,c,m.address).catch(()=>void 0):void 0;d=i?.symbol??c??``,f=i?.decimals??o.decimals??6}if(g)return{tokenSymbol:d,tokenDecimals:f,explorerUrl:p,methods:[],async createCredential(e){let t=e.headers.get(`www-authenticate`);if(!t)throw Error(`No WWW-Authenticate header in 402 response.`);return uu(t)}};if(!m||!h)throw new J({code:`ACCOUNT_NOT_FOUND`,message:`Tempo requires a configured account.`,exitCode:69});let v=zl({account:m,...l.allowCustomEscrow===void 0?{}:{allowCustomEscrow:l.allowCustomEscrow},getClient:()=>h,...u===void 0?{}:{autoSwap:u},maxDeposit:(()=>{if(n.intent!==`session`)return;let e=n.request.suggestedDeposit,t=(l.deposit===void 0?void 0:String(l.deposit))??e??(Xn(h.chain)?`10`:void 0);if(!t)throw new J({code:`MISSING_DEPOSIT`,message:`Session payment requires a deposit. Use -M deposit=<amount> or connect to testnet.`,exitCode:2});return t})()}),y=(()=>{if(!l.channel)return;let e=l.channel,t=nu(e);return{channelId:e,...t!==void 0&&{cumulativeAmountRaw:t.toString()}}})();return t={descriptor:void 0,async signVoucher({channelId:e,cumulativeAmount:r,escrowContract:i,chainId:a,action:o=`voucher`}){let s=t?.descriptor;if(!s)throw Error(`session descriptor not available`);let c={channelId:e,cumulativeAmount:r},l=await Oo(h,m,c,i,a);return Et({challenge:n,payload:{action:o,channelId:e,...o===`close`?{closeSignature:await ko(h,m,c,i,a)}:{},descriptor:s,cumulativeAmount:r.toString(),signature:l},source:`did:pkh:eip155:${a}:${m.address}`})},source:`did:pkh:eip155:${h.chain.id}:${m.address}`},{tokenSymbol:d,tokenDecimals:f,explorerUrl:p,methods:[...v],credentialContext:y}},prepareCredentialRequest({challenge:e,headers:t}){e.intent===`session`&&(t.Accept=`text/event-stream`)},async handleResponse(e){if(e.challenge.intent!==`session`||!t)return!1;let{challenge:n,credential:r,response:i,fetchUrl:a,fetchInit:o,verbose:s}=e,{silent:c,confirmEnabled:l,tokenSymbol:u,tokenDecimals:d,explorerUrl:f,shownKeys:p}=e,m=c?e=>{}:e=>process.stderr.write(e),h=St(r),g=n.request,_=g.methodDetails,v=h.payload.channelId,y=_?.escrowContract??_?.escrow??`0x4d50500000000000000000000000000000000000`,b=_?.chainId??0,x=BigInt(g.amount),C=`cumulativeAmount`in h.payload&&h.payload.cumulativeAmount?BigInt(h.payload.cumulativeAmount):0n;if(`descriptor`in h.payload&&(t.descriptor=h.payload.descriptor),s>=1){if(h.payload.action===`open`){let e=g.suggestedDeposit,t=e?` ${X.dim(`(deposit ${e} ${u})`)}`:``;m(`${l?``:`
|
|
8
8
|
`}${X.dim(`Channel opened ${h.payload.channelId}`)}${t}\n`)}else m(`${l?``:`
|
|
9
9
|
`}${X.dim(`Channel reused ${h.payload.channelId}`)}\n`)}let w=i;w.ok&&!w.headers.get(`Content-Type`)?.includes(`text/event-stream`)&&h.payload.action===`open`&&`cumulativeAmount`in h.payload&&(C=BigInt(h.payload.cumulativeAmount));let T=w.headers.get(R.paymentReceipt);if(T)try{let e=JSON.parse(S.toString(T));Kl(e,C),typeof e.acceptedCumulative==`string`&&e.acceptedCumulative&&ru(v,C),s>=1&&Gl(e,{info:m,shownKeys:p,tokenSymbol:u,tokenDecimals:d,explorerUrl:f,handler:this,prefix:`
|
|
10
10
|
`})}catch{}return(w.headers.get(`Content-Type`)??``).includes(`text/event-stream`)?await ql(w,{challenge:n,channelId:v,escrowContract:y,chainId:b,cumulativeAmount:C,tickCost:x,fetchUrl:a,fetchInit:o,session:t,info:m,verbose:s,shownKeys:p,tokenSymbol:u,tokenDecimals:d,explorerUrl:f,handler:this}):(await Vl(w),v&&y&&b&&(l&&m(`
|
|
@@ -37,6 +37,7 @@ export type Counts = {
|
|
|
37
37
|
skipped: number;
|
|
38
38
|
};
|
|
39
39
|
export declare function printResults(results: CheckResult[], counts: Counts): void;
|
|
40
|
+
/** Fetches the validation target without allowing it to redirect probes elsewhere. */
|
|
40
41
|
export declare function fetchWithTimeout(url: RequestInfo | URL, init: RequestInit, timeoutMs?: number): Promise<Response>;
|
|
41
42
|
export declare function formatBytes(bytes: number): string;
|
|
42
43
|
export declare const HTTP_METHODS: Set<string>;
|
|
@@ -57,11 +57,12 @@ export function printResults(results, counts) {
|
|
|
57
57
|
counts.skipped++;
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
+
/** Fetches the validation target without allowing it to redirect probes elsewhere. */
|
|
60
61
|
export async function fetchWithTimeout(url, init, timeoutMs = 15_000) {
|
|
61
62
|
const controller = new AbortController();
|
|
62
63
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
63
64
|
try {
|
|
64
|
-
return await fetch(url, { ...init, signal: controller.signal });
|
|
65
|
+
return await fetch(url, { ...init, redirect: 'error', signal: controller.signal });
|
|
65
66
|
}
|
|
66
67
|
finally {
|
|
67
68
|
clearTimeout(timeout);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Current mppx package version. */
|
|
2
|
-
export declare const version = "0.13.
|
|
2
|
+
export declare const version = "0.13.4";
|
|
3
3
|
/** Canonical SDK identifier for this mppx release. */
|
|
4
|
-
export declare const sdkIdentifier = "mppx/0.13.
|
|
4
|
+
export declare const sdkIdentifier = "mppx/0.13.4";
|
|
5
5
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/internal/version.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Generated by scripts/sync-version.ts.
|
|
2
2
|
/** Current mppx package version. */
|
|
3
|
-
export const version = '0.13.
|
|
3
|
+
export const version = '0.13.4';
|
|
4
4
|
/** Canonical SDK identifier for this mppx release. */
|
|
5
5
|
export const sdkIdentifier = `mppx/${version}`;
|
|
6
6
|
//# sourceMappingURL=version.js.map
|
package/dist/server/Mppx.d.ts
CHANGED
|
@@ -359,7 +359,7 @@ declare namespace MethodFn {
|
|
|
359
359
|
description?: string | undefined;
|
|
360
360
|
/** Optional challenge expiration timestamp (ISO 8601) or Date. */
|
|
361
361
|
expires?: z.DatetimeInput | undefined;
|
|
362
|
-
/** Optional server-defined correlation data
|
|
362
|
+
/** Optional server-defined correlation data serialized as `opaque`. `_mppx_nonce` is reserved for a fresh server-generated issuance nonce; clients MUST echo opaque unchanged. */
|
|
363
363
|
meta?: Record<string, string> | undefined;
|
|
364
364
|
/** Optional route/resource scope bound via reserved challenge metadata. */
|
|
365
365
|
scope?: string | undefined;
|
package/dist/server/Mppx.js
CHANGED
|
@@ -12,6 +12,7 @@ import * as PaymentRequest from '../PaymentRequest.js';
|
|
|
12
12
|
import * as x402_Header from '../x402/Header.js';
|
|
13
13
|
import * as x402_Types from '../x402/Types.js';
|
|
14
14
|
import * as z from '../zod.js';
|
|
15
|
+
import * as ChallengeMeta from './internal/challengeMeta.js';
|
|
15
16
|
import * as Html from './internal/html/config.js';
|
|
16
17
|
import { serviceWorker } from './internal/html/serviceWorker.gen.js';
|
|
17
18
|
import * as Scope from './internal/scope.js';
|
|
@@ -1300,7 +1301,7 @@ async function resolveRouteChallenge(parameters) {
|
|
|
1300
1301
|
description: parameters.description,
|
|
1301
1302
|
expires: parameters.expires,
|
|
1302
1303
|
header: parameters.header,
|
|
1303
|
-
meta: parameters.meta,
|
|
1304
|
+
meta: ChallengeMeta.withNonce(parameters.meta),
|
|
1304
1305
|
realm: effectiveRealm,
|
|
1305
1306
|
request: request,
|
|
1306
1307
|
secretKey: parameters.secretKey,
|
|
@@ -1316,7 +1317,7 @@ function createFallbackChallenge(parameters) {
|
|
|
1316
1317
|
description: parameters.description,
|
|
1317
1318
|
expires: parameters.expires,
|
|
1318
1319
|
header: parameters.header,
|
|
1319
|
-
meta: parameters.meta,
|
|
1320
|
+
meta: ChallengeMeta.withNonce(parameters.meta),
|
|
1320
1321
|
realm: parameters.realm ??
|
|
1321
1322
|
(parameters.capturedRequest
|
|
1322
1323
|
? resolveRealmFromCapturedRequest(parameters.capturedRequest)
|
|
@@ -1478,7 +1479,9 @@ function normalizeComparable(value) {
|
|
|
1478
1479
|
return typeof value === 'string' ? normalizeHex(value) : value;
|
|
1479
1480
|
}
|
|
1480
1481
|
function opaqueValuesMatch(expected, actual) {
|
|
1481
|
-
|
|
1482
|
+
// The echoed nonce is authenticated by the challenge HMAC, but is not a
|
|
1483
|
+
// stable route requirement. Every other metadata field remains pinned.
|
|
1484
|
+
return isDeepStrictEqual(ChallengeMeta.routeMeta(expected), ChallengeMeta.routeMeta(actual));
|
|
1482
1485
|
}
|
|
1483
1486
|
function hydrateCredentialMeta(credential) {
|
|
1484
1487
|
const { challenge } = credential;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Adds fresh issuance randomness while preserving application and route metadata. */
|
|
2
|
+
export declare function withNonce(meta: Record<string, string> | undefined): Record<string, string>;
|
|
3
|
+
/** Removes issuance-only metadata when comparing stable route requirements. */
|
|
4
|
+
export declare function routeMeta(meta: Record<string, string> | undefined): Record<string, string> | undefined;
|
|
5
|
+
//# sourceMappingURL=challengeMeta.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Secp256k1 } from 'ox';
|
|
2
|
+
/** Reserved metadata key for HMAC-bound, per-issuance challenge randomness. */
|
|
3
|
+
const nonceKey = '_mppx_nonce';
|
|
4
|
+
/** Adds fresh issuance randomness while preserving application and route metadata. */
|
|
5
|
+
export function withNonce(meta) {
|
|
6
|
+
// Ox uses runtime-specific secure randomness, including Node without global Web Crypto.
|
|
7
|
+
return { ...meta, [nonceKey]: Secp256k1.randomPrivateKey() };
|
|
8
|
+
}
|
|
9
|
+
/** Removes issuance-only metadata when comparing stable route requirements. */
|
|
10
|
+
export function routeMeta(meta) {
|
|
11
|
+
const { [nonceKey]: _, ...rest } = meta ?? {};
|
|
12
|
+
return Object.keys(rest).length ? rest : undefined;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=challengeMeta.js.map
|
|
@@ -2,6 +2,7 @@ import type { NoExtraKeys } from '../../internal/types.js';
|
|
|
2
2
|
import * as Store from '../../Store.js';
|
|
3
3
|
import * as Currencies from '../internal/currencies.js';
|
|
4
4
|
import { charge as sessionCharge_, session as session_, settle as settle_, settleBatch as settleBatch_ } from '../session/server/Session.js';
|
|
5
|
+
import * as Settlement from '../session/server/Settlement.js';
|
|
5
6
|
import type { SessionController as SessionController_ } from '../session/server/Sse.js';
|
|
6
7
|
import * as Ws_ from '../session/server/Ws.js';
|
|
7
8
|
import { charge as charge_ } from './Charge.js';
|
|
@@ -2425,6 +2426,10 @@ export declare namespace tempo {
|
|
|
2425
2426
|
const settle: typeof settle_;
|
|
2426
2427
|
/** Batch-settle precompile-backed session channels. */
|
|
2427
2428
|
const settleBatch: typeof settleBatch_;
|
|
2429
|
+
/** Raised by `settle` when its transaction confirmed but the channel store could not record it. */
|
|
2430
|
+
const SettlementCheckpointError: typeof Settlement.SettlementCheckpointError;
|
|
2431
|
+
/** Raised by `settle` when its transaction confirmed but the channel store could not record it. */
|
|
2432
|
+
type SettlementCheckpointError = Settlement.SettlementCheckpointError;
|
|
2428
2433
|
/** Types for Tempo session streams. */
|
|
2429
2434
|
namespace Sse {
|
|
2430
2435
|
/** Controller passed to manual-charge SSE generators. */
|
|
@@ -2,6 +2,7 @@ import * as Store from '../../Store.js';
|
|
|
2
2
|
import * as Currencies from '../internal/currencies.js';
|
|
3
3
|
import * as ChannelStore from '../session/server/ChannelStore.js';
|
|
4
4
|
import { charge as sessionCharge_, session as session_, settle as settle_, settleBatch as settleBatch_, } from '../session/server/Session.js';
|
|
5
|
+
import * as Settlement from '../session/server/Settlement.js';
|
|
5
6
|
import * as Ws_ from '../session/server/Ws.js';
|
|
6
7
|
import { charge as charge_ } from './Charge.js';
|
|
7
8
|
import { renew as renewSubscription_, subscription as subscription_ } from './Subscription.js';
|
|
@@ -86,6 +87,8 @@ export function tempo(parameters) {
|
|
|
86
87
|
tempo.settle = settle_;
|
|
87
88
|
/** Batch-settle precompile-backed session channels. */
|
|
88
89
|
tempo.settleBatch = settleBatch_;
|
|
90
|
+
/** Raised by `settle` when its transaction confirmed but the channel store could not record it. */
|
|
91
|
+
tempo.SettlementCheckpointError = Settlement.SettlementCheckpointError;
|
|
89
92
|
/** Experimental websocket helpers for Tempo sessions. */
|
|
90
93
|
tempo.Ws = Ws_;
|
|
91
94
|
})(tempo || (tempo = {}));
|
|
@@ -126,7 +129,8 @@ function sessionOffers(parameters) {
|
|
|
126
129
|
serveWebSocket: (options) => Ws_.serve({
|
|
127
130
|
...options,
|
|
128
131
|
store: ChannelStore.fromStore(store),
|
|
129
|
-
|
|
132
|
+
// Failed settlements are reported by the session handler; the charged request stays served.
|
|
133
|
+
onChargeCommitted: (channel) => settleScheduled(channel).catch(Settlement.ignoreRetryableSettlementFailure),
|
|
130
134
|
}),
|
|
131
135
|
};
|
|
132
136
|
function create(currency) {
|
|
@@ -4,6 +4,6 @@ export * as Ws from '../session/server/Ws.js';
|
|
|
4
4
|
export { charge } from './Charge.js';
|
|
5
5
|
export { tempo } from './Methods.js';
|
|
6
6
|
export { session, settle, settleBatch } from '../session/server/Session.js';
|
|
7
|
-
export type { OnSessionSettlement, SessionSettlementContext, SettlementSchedule, } from '../session/server/Session.js';
|
|
7
|
+
export type { OnSessionSettlement, OnSessionSettlementFailure, SessionSettlementContext, SessionSettlementFailureContext, SettlementSchedule, } from '../session/server/Session.js';
|
|
8
8
|
export { renew as renewSubscription, subscription } from './Subscription.js';
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|