UNPKG

@cashu/cashu-ts

Version:

cashu library for communicating with a cashu mint

3 lines (2 loc) 45.8 kB
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const Y=require("buffer"),Xt=require("./crypto/client/NUT12.cjs.js"),V=require("./crypto/common.cjs.js"),D=require("@noble/curves/abstract/utils"),Yt=require("@noble/hashes/sha256"),St=require("./crypto/client/NUT11.cjs.js"),Zt=require("./crypto/client/NUT20.cjs.js"),et=require("./crypto/client.cjs.js"),C=require("@noble/hashes/utils"),Pt=require("./crypto/client/NUT09.cjs.js");function te(n){return Y.Buffer.from(n).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function vt(n){return Y.Buffer.from(n,"base64")}function Kt(n){const t=JSON.stringify(n);return ne(Y.Buffer.from(t).toString("base64"))}function ee(n){const t=Y.Buffer.from(se(n),"base64").toString();return JSON.parse(t)}function se(n){return n.replace(/-/g,"+").replace(/_/g,"/").split("=")[0]}function ne(n){return n.replace(/\+/g,"-").replace(/\//g,"_").split("=")[0]}function re(n){return typeof n=="number"||typeof n=="string"}function kt(n){const t=[];return bt(n,t),new Uint8Array(t)}function bt(n,t){if(n===null)t.push(246);else if(n===void 0)t.push(247);else if(typeof n=="boolean")t.push(n?245:244);else if(typeof n=="number")Rt(n,t);else if(typeof n=="string")Dt(n,t);else if(Array.isArray(n))ie(n,t);else if(n instanceof Uint8Array)oe(n,t);else if(typeof n=="object"&&n!==null&&!Array.isArray(n))ae(n,t);else throw new Error("Unsupported type")}function Rt(n,t){if(n<24)t.push(n);else if(n<256)t.push(24,n);else if(n<65536)t.push(25,n>>8,n&255);else if(n<4294967296)t.push(26,n>>24,n>>16&255,n>>8&255,n&255);else throw new Error("Unsupported integer size")}function oe(n,t){const e=n.length;if(e<24)t.push(64+e);else if(e<256)t.push(88,e);else if(e<65536)t.push(89,e>>8&255,e&255);else if(e<4294967296)t.push(90,e>>24&255,e>>16&255,e>>8&255,e&255);else throw new Error("Byte string too long to encode");for(let s=0;s<n.length;s++)t.push(n[s])}function Dt(n,t){const e=new TextEncoder().encode(n),s=e.length;if(s<24)t.push(96+s);else if(s<256)t.push(120,s);else if(s<65536)t.push(121,s>>8&255,s&255);else if(s<4294967296)t.push(122,s>>24&255,s>>16&255,s>>8&255,s&255);else throw new Error("String too long to encode");for(let r=0;r<e.length;r++)t.push(e[r])}function ie(n,t){const e=n.length;if(e<24)t.push(128|e);else if(e<256)t.push(152,e);else if(e<65536)t.push(153,e>>8,e&255);else throw new Error("Unsupported array length");for(const s of n)bt(s,t)}function ae(n,t){const e=Object.keys(n);Rt(e.length,t),t[t.length-1]|=160;for(const s of e)Dt(s,t),bt(n[s],t)}function _t(n){const t=new DataView(n.buffer,n.byteOffset,n.byteLength);return it(t,0).value}function it(n,t){if(t>=n.byteLength)throw new Error("Unexpected end of data");const e=n.getUint8(t++),s=e>>5,r=e&31;switch(s){case 0:return ce(n,t,r);case 1:return ue(n,t,r);case 2:return he(n,t,r);case 3:return le(n,t,r);case 4:return de(n,t,r);case 5:return fe(n,t,r);case 7:return ye(n,t,r);default:throw new Error(`Unsupported major type: ${s}`)}}function Z(n,t,e){if(e<24)return{value:e,offset:t};if(e===24)return{value:n.getUint8(t++),offset:t};if(e===25){const s=n.getUint16(t,!1);return t+=2,{value:s,offset:t}}if(e===26){const s=n.getUint32(t,!1);return t+=4,{value:s,offset:t}}if(e===27){const s=n.getUint32(t,!1),r=n.getUint32(t+4,!1);return t+=8,{value:s*2**32+r,offset:t}}throw new Error(`Unsupported length: ${e}`)}function ce(n,t,e){const{value:s,offset:r}=Z(n,t,e);return{value:s,offset:r}}function ue(n,t,e){const{value:s,offset:r}=Z(n,t,e);return{value:-1-s,offset:r}}function he(n,t,e){const{value:s,offset:r}=Z(n,t,e);if(r+s>n.byteLength)throw new Error("Byte string length exceeds data length");return{value:new Uint8Array(n.buffer,n.byteOffset+r,s),offset:r+s}}function le(n,t,e){const{value:s,offset:r}=Z(n,t,e);if(r+s>n.byteLength)throw new Error("String length exceeds data length");const o=new Uint8Array(n.buffer,n.byteOffset+r,s);return{value:new TextDecoder().decode(o),offset:r+s}}function de(n,t,e){const{value:s,offset:r}=Z(n,t,e),o=[];let a=r;for(let i=0;i<s;i++){const c=it(n,a);o.push(c.value),a=c.offset}return{value:o,offset:a}}function fe(n,t,e){const{value:s,offset:r}=Z(n,t,e),o={};let a=r;for(let i=0;i<s;i++){const c=it(n,a);if(!re(c.value))throw new Error("Invalid key type");const h=it(n,c.offset);o[c.value]=h.value,a=h.offset}return{value:o,offset:a}}function pe(n){const t=(n&31744)>>10,e=n&1023,s=n&32768?-1:1;return t===0?s*2**-14*(e/1024):t===31?e?NaN:s*(1/0):s*2**(t-15)*(1+e/1024)}function ye(n,t,e){if(e<24)switch(e){case 20:return{value:!1,offset:t};case 21:return{value:!0,offset:t};case 22:return{value:null,offset:t};case 23:return{value:void 0,offset:t};default:throw new Error(`Unknown simple value: ${e}`)}if(e===24)return{value:n.getUint8(t++),offset:t};if(e===25){const s=pe(n.getUint16(t,!1));return t+=2,{value:s,offset:t}}if(e===26){const s=n.getFloat32(t,!1);return t+=4,{value:s,offset:t}}if(e===27){const s=n.getFloat64(t,!1);return t+=8,{value:s,offset:t}}throw new Error(`Unknown simple or float value: ${e}`)}class ht{constructor(t,e,s,r,o,a,i=!1,c){this.transport=t,this.id=e,this.amount=s,this.unit=r,this.mints=o,this.description=a,this.singleUse=i,this.nut10=c}toRawRequest(){const t={};return this.transport&&(t.t=this.transport.map(e=>({t:e.type,a:e.target,g:e.tags}))),this.id&&(t.i=this.id),this.amount&&(t.a=this.amount),this.unit&&(t.u=this.unit),this.mints&&(t.m=this.mints),this.description&&(t.d=this.description),this.singleUse&&(t.s=this.singleUse),this.nut10&&(t.nut10={k:this.nut10.kind,d:this.nut10.data,t:this.nut10.tags}),t}toEncodedRequest(){const t=this.toRawRequest(),e=kt(t);return"creqA"+Y.Buffer.from(e).toString("base64")}getTransport(t){return this.transport?.find(e=>e.type===t)}static fromRawRequest(t){const e=t.t?t.t.map(r=>({type:r.t,target:r.a,tags:r.g})):void 0,s=t.nut10?{kind:t.nut10.k,data:t.nut10.d,tags:t.nut10.t}:void 0;return new ht(e,t.i,t.a,t.u,t.m,t.d,t.s,s)}static fromEncodedRequest(t){if(!t.startsWith("creq"))throw new Error("unsupported pr: invalid prefix");if(t[4]!=="A")throw new Error("unsupported pr version");const s=t.slice(5),r=vt(s),o=_t(r);return this.fromRawRequest(o)}}const ge="A",me="cashu";function R(n,t,e,s){if(e){const o=qt(e);if(o>n)throw new Error(`Split is greater than total amount: ${o} > ${n}`);if(e.some(a=>!Bt(a,t)))throw new Error("Provided amount preferences do not match the amounts of the mint keyset.");n=n-qt(e)}else e=[];return Ut(t,"desc").forEach(o=>{const a=Math.floor(n/o);for(let i=0;i<a;++i)e?.push(o);n%=o}),e.sort((o,a)=>o-a)}function It(n,t,e,s){const r=[],o=n.map(h=>h.amount);Ut(e,"asc").forEach(h=>{const u=o.filter(f=>f===h).length,l=Math.max(s-u,0);for(let f=0;f<l&&!(r.reduce((d,m)=>d+m,0)+h>t);++f)r.push(h)});const i=t-r.reduce((h,u)=>h+u,0);return i&&R(i,e).forEach(u=>{r.push(u)}),r.sort((h,u)=>h-u)}function Ut(n,t="desc"){return t=="desc"?Object.keys(n).map(e=>parseInt(e)).sort((e,s)=>s-e):Object.keys(n).map(e=>parseInt(e)).sort((e,s)=>e-s)}function Bt(n,t){return n in t}function we(n){return Ft(D.bytesToHex(n))}function Ft(n){return BigInt(`0x${n}`)}function ke(n){return n.toString(16).padStart(64,"0")}function Mt(n){return/^[a-f0-9]*$/i.test(n)}function Ot(n){return Array.isArray(n)?n.some(t=>!Mt(t.id)):Mt(n.id)}function be(n,t){t&&(n.proofs=at(n.proofs));const e={token:[{mint:n.mint,proofs:n.proofs}]};return n.unit&&(e.unit=n.unit),n.memo&&(e.memo=n.memo),me+ge+Kt(e)}function _e(n,t){if(Ot(n.proofs)||t?.version===3){if(t?.version===4)throw new Error("can not encode to v4 token if proofs contain non-hex keyset id");return be(n,t?.removeDleq)}return Nt(n,t?.removeDleq)}function Nt(n,t){if(t&&(n.proofs=at(n.proofs)),n.proofs.forEach(c=>{if(c.dleq&&c.dleq.r==null)throw new Error("Missing blinding factor in included DLEQ proof")}),Ot(n.proofs))throw new Error("can not encode to v4 token if proofs contain non-hex keyset id");const s=Lt(n),r=kt(s),o="cashu",a="B",i=te(r);return o+a+i}function Lt(n){const t={},e=n.mint;for(let r=0;r<n.proofs.length;r++){const o=n.proofs[r];t[o.id]?t[o.id].push(o):t[o.id]=[o]}const s={m:e,u:n.unit||"sat",t:Object.keys(t).map(r=>({i:D.hexToBytes(r),p:t[r].map(o=>({a:o.amount,s:o.secret,c:D.hexToBytes(o.C),...o.dleq&&{d:{e:D.hexToBytes(o.dleq.e),s:D.hexToBytes(o.dleq.s),r:D.hexToBytes(o.dleq.r??"00")}},...o.witness&&{w:JSON.stringify(o.witness)}}))}))};return n.memo&&(s.d=n.memo),s}function Ct(n){const t=[];n.t.forEach(s=>s.p.forEach(r=>{t.push({secret:r.s,C:D.bytesToHex(r.c),amount:r.a,id:D.bytesToHex(s.i),...r.d&&{dleq:{r:D.bytesToHex(r.d.r),s:D.bytesToHex(r.d.s),e:D.bytesToHex(r.d.e)}},...r.w&&{witness:r.w}})}));const e={mint:n.m,proofs:t,unit:n.u||"sat"};return n.d&&(e.memo=n.d),e}function Wt(n){return["web+cashu://","cashu://","cashu:","cashu"].forEach(e=>{n.startsWith(e)&&(n=n.slice(e.length))}),Ee(n)}function Ee(n){const t=n.slice(0,1),e=n.slice(1);if(t==="A"){const s=ee(e);if(s.token.length>1)throw new Error("Multi entry token are not supported");const r=s.token[0],o={mint:r.mint,proofs:r.proofs,unit:s.unit||"sat"};return s.memo&&(o.memo=s.memo),o}else if(t==="B"){const s=vt(e),r=_t(s);return Ct(r)}throw new Error("Token version is not supported")}function Tt(n){return Qt(n.keys)===n.id}function Qt(n){const t=Object.entries(n).sort((r,o)=>+r[0]-+o[0]).map(([,r])=>D.hexToBytes(r)).reduce((r,o)=>Ae(r,o),new Uint8Array),e=Yt.sha256(t);return"00"+Y.Buffer.from(e).toString("hex").slice(0,14)}function Ae(n,t){const e=new Uint8Array(n.length+t.length);return e.set(n),e.set(t,n.length),e}function O(n){return typeof n=="object"}function x(...n){return n.map(t=>t.replace(/(^\/+|\/+$)/g,"")).join("/")}function jt(n){return n.replace(/\/$/,"")}function j(n){return n.reduce((t,e)=>t+e.amount,0)}function Se(n){return ht.fromEncodedRequest(n)}class Pe{get value(){return this._value}set value(t){this._value=t}get next(){return this._next}set next(t){this._next=t}constructor(t){this._value=t,this._next=null}}class Ie{get first(){return this._first}set first(t){this._first=t}get last(){return this._last}set last(t){this._last=t}get size(){return this._size}set size(t){this._size=t}constructor(){this._first=null,this._last=null,this._size=0}enqueue(t){const e=new Pe(t);return this._size===0||!this._last?(this._first=e,this._last=e):(this._last.next=e,this._last=e),this._size++,!0}dequeue(){if(this._size===0||!this._first)return null;const t=this._first;return this._first=t.next,t.next=null,this._size--,t.value}}function at(n){return n.map(t=>{const e={...t};return delete e.dleq,e})}function Et(n,t){if(n.dleq==null)return!1;const e={e:D.hexToBytes(n.dleq.e),s:D.hexToBytes(n.dleq.s),r:Ft(n.dleq.r??"00")};if(!Bt(n.amount,t.keys))throw new Error(`undefined key for amount ${n.amount}`);const s=t.keys[n.amount];return!!Xt.verifyDLEQProof_reblind(new TextEncoder().encode(n.secret),e,V.pointFromHex(n.C),V.pointFromHex(s))}function Me(...n){const t=n.reduce((r,o)=>r+o.length,0),e=new Uint8Array(t);let s=0;for(let r=0;r<n.length;r++)e.set(n[r],s),s=s+n[r].length;return e}function Te(n){const t=new TextEncoder,e=Lt(n),s=kt(e),r=t.encode("craw"),o=t.encode("B");return Me(r,o,s)}function qe(n){const t=new TextDecoder,e=t.decode(n.slice(0,4)),s=t.decode(new Uint8Array([n[4]]));if(e!=="craw"||s!=="B")throw new Error("not a valid binary token");const r=n.slice(5),o=_t(r);return Ct(o)}function qt(n){return n.reduce((t,e)=>t+e,0)}let ct;typeof WebSocket<"u"&&(ct=WebSocket);function xe(n){ct=n}function ve(){if(ct===void 0)throw new Error("WebSocket implementation not initialized");return ct}const I={FATAL:"FATAL",ERROR:"ERROR",WARN:"WARN",INFO:"INFO",DEBUG:"DEBUG",TRACE:"TRACE"},N={fatal(){},error(){},warn(){},info(){},debug(){},trace(){},log(){}},st=class st{constructor(t=I.INFO){this.minLevel=t}logToConsole(t,e,s){if(st.SEVERITY[t]>st.SEVERITY[this.minLevel])return;const r=`[${t}] `;let o=e;const a=new Set;if(s){const i=Object.fromEntries(Object.entries(s).map(([u,l])=>[u,l instanceof Error?{message:l.message,stack:l.stack}:l]));o=e.replace(/\{(\w+)\}/g,(u,l)=>{if(l in i&&i[l]!==void 0){a.add(l);const f=i[l];return typeof f=="string"?f:typeof f=="number"||typeof f=="boolean"?f.toString():f==null?"":JSON.stringify(f)}return u});const c=Object.fromEntries(Object.entries(i).filter(([u])=>!a.has(u))),h=this.getConsoleMethod(t);Object.keys(c).length>0?h(r+o,c):h(r+o)}else this.getConsoleMethod(t)(r+o)}getConsoleMethod(t){switch(t){case I.FATAL:case I.ERROR:return console.error;case I.WARN:return console.warn;case I.INFO:return console.info;case I.DEBUG:return console.debug;case I.TRACE:return console.trace;default:return console.log}}fatal(t,e){this.logToConsole(I.FATAL,t,e)}error(t,e){this.logToConsole(I.ERROR,t,e)}warn(t,e){this.logToConsole(I.WARN,t,e)}info(t,e){this.logToConsole(I.INFO,t,e)}debug(t,e){this.logToConsole(I.DEBUG,t,e)}trace(t,e){this.logToConsole(I.TRACE,t,e)}log(t,e,s){this.logToConsole(t,e,s)}};st.SEVERITY={[I.FATAL]:0,[I.ERROR]:1,[I.WARN]:2,[I.INFO]:3,[I.DEBUG]:4,[I.TRACE]:5};let mt=st;function Ke(){const n=Date.now();return{elapsed:()=>Date.now()-n}}class z{constructor(){this.connectionMap=new Map}static getInstance(){return z.instance||(z.instance=new z),z.instance}getConnection(t,e){if(this.connectionMap.has(t))return this.connectionMap.get(t);const s=new Re(t,e);return this.connectionMap.set(t,s),s}}class Re{constructor(t,e){this.subListeners={},this.rpcListeners={},this.rpcId=0,this.onCloseCallbacks=[],this._WS=ve(),this.url=new URL(t),this.messageQueue=new Ie,this._logger=e??N}connect(){return this.connectionPromise||(this.connectionPromise=new Promise((t,e)=>{try{this.ws=new this._WS(this.url.toString()),this.onCloseCallbacks=[]}catch(s){e(s instanceof Error?s:new Error(String(s)));return}this.ws.onopen=()=>{t()},this.ws.onerror=()=>{e(new Error("Failed to open WebSocket"))},this.ws.onmessage=s=>{this.messageQueue.enqueue(s.data),this.handlingInterval||(this.handlingInterval=setInterval(this.handleNextMessage.bind(this),0))},this.ws.onclose=s=>{this.connectionPromise=void 0,this.onCloseCallbacks.forEach(r=>r(s))}})),this.connectionPromise}sendRequest(t,e){if(this.ws?.readyState!==1){if(t==="unsubscribe")return;throw this._logger.error("Attempted sendRequest, but socket was not open"),new Error("Socket not open")}const s=this.rpcId;this.rpcId++;const r=JSON.stringify({jsonrpc:"2.0",method:t,params:e,id:s});this.ws?.send(r)}closeSubscription(t){this.ws?.send(JSON.stringify(["CLOSE",t]))}addSubListener(t,e){(this.subListeners[t]=this.subListeners[t]||[]).push(e)}addRpcListener(t,e,s){this.rpcListeners[s]={callback:t,errorCallback:e}}removeRpcListener(t){delete this.rpcListeners[t]}removeListener(t,e){if(this.subListeners[t]){if(this.subListeners[t].length===1){delete this.subListeners[t];return}this.subListeners[t]=this.subListeners[t].filter(s=>s!==e)}}async ensureConnection(){this.ws?.readyState!==1&&await this.connect()}handleNextMessage(){if(this.messageQueue.size===0){clearInterval(this.handlingInterval),this.handlingInterval=void 0;return}const t=this.messageQueue.dequeue();let e;try{if(e=JSON.parse(t),"result"in e&&e.id!=null)this.rpcListeners[e.id]&&(this.rpcListeners[e.id].callback(),this.removeRpcListener(e.id));else if("error"in e&&e.id!=null)this.rpcListeners[e.id]&&(this.rpcListeners[e.id].errorCallback(new Error(e.error.message)),this.removeRpcListener(e.id));else if("method"in e&&!("id"in e)){const s=e.params?.subId;if(!s)return;if(this.subListeners[s]?.length>0){const r=e;this.subListeners[s].forEach(o=>o(r.params?.payload))}}}catch(s){this._logger.error("Error doing handleNextMessage",{e:s});return}}createSubscription(t,e,s){if(this.ws?.readyState!==1)throw this._logger.error("Attempted createSubscription, but socket was not open"),new Error("Socket is not open");const r=(Math.random()+1).toString(36).substring(7);return this.addRpcListener(()=>{this.addSubListener(r,e)},s,this.rpcId),this.sendRequest("subscribe",{...t,subId:r}),this.rpcId++,r}cancelSubscription(t,e,s){this.removeListener(t,e),this.addRpcListener(()=>{this._logger.info("Unsubscribed {subId}",{subId:t})},s||(r=>this._logger.error("Unsubscribe failed",{e:r})),this.rpcId),this.sendRequest("unsubscribe",{subId:t})}get activeSubscriptions(){return Object.keys(this.subListeners)}close(){this.ws&&this.ws?.close()}onClose(t){this.onCloseCallbacks.push(t)}}const De={UNSPENT:"UNSPENT",PENDING:"PENDING",SPENT:"SPENT"},J={UNPAID:"UNPAID",PENDING:"PENDING",PAID:"PAID"},ut={UNPAID:"UNPAID",PAID:"PAID",ISSUED:"ISSUED"};var Ht=(n=>(n.POST="post",n.NOSTR="nostr",n))(Ht||{});class X extends Error{constructor(t,e){super(t),this.status=e,this.name="HttpResponseError",Object.setPrototypeOf(this,X.prototype)}}class lt extends Error{constructor(t){super(t),this.name="NetworkError",Object.setPrototypeOf(this,lt.prototype)}}class dt extends X{constructor(t,e){super(e||"Unknown mint operation error",400),this.code=t,this.name="MintOperationError",Object.setPrototypeOf(this,dt.prototype)}}let $t={},zt=N;function Ue(n){$t=n}function Be(n){zt=n}async function Fe({endpoint:n,requestBody:t,headers:e,...s}){const r=t?JSON.stringify(t):void 0,o={Accept:"application/json, text/plain, */*",...r?{"Content-Type":"application/json"}:void 0,...e};let a;try{a=await fetch(n,{body:r,headers:o,...s})}catch(i){throw new lt(i instanceof Error?i.message:"Network request failed")}if(!a.ok){let i;try{i=await a.json()}catch{i={error:"bad response"}}if(a.status===400&&"code"in i&&typeof i.code=="number"&&"detail"in i&&typeof i.detail=="string")throw new dt(i.code,i.detail);let c="HTTP request failed";throw"error"in i&&typeof i.error=="string"?c=i.error:"detail"in i&&typeof i.detail=="string"&&(c=i.detail),new X(c,a.status)}try{return await a.json()}catch(i){throw zt.error("Failed to parse HTTP response",{err:i}),new X("bad response",a.status)}}async function K(n){return await Fe({...n,...$t})}function pt(n,t){return n.state||(t.warn("Field 'state' not found in MeltQuoteResponse. Update NUT-05 of mint: https://github.com/cashubtc/nuts/pull/136)"),typeof n.paid=="boolean"&&(n.state=n.paid?J.PAID:J.UNPAID)),n}function xt(n,t){return n.state||(t.warn("Field 'state' not found in MintQuoteResponse. Update NUT-04 of mint: https://github.com/cashubtc/nuts/pull/141)"),typeof n.paid=="boolean"&&(n.state=n.paid?ut.PAID:ut.UNPAID)),n}function Oe(n,t){return Array.isArray(n?.contact)&&n?.contact.length>0&&(n.contact=n.contact.map(e=>Array.isArray(e)&&e.length===2&&typeof e[0]=="string"&&typeof e[1]=="string"?(t.warn("Mint returned deprecated 'contact' field: Update NUT-06: https://github.com/cashubtc/nuts/pull/117"),{method:e[0],info:e[1]}):e)),n}class wt{constructor(t){this._mintInfo=t,t.nuts[22]&&(this._protectedEnpoints={cache:{},apiReturn:t.nuts[22].protected_endpoints.map(e=>({method:e.method,regex:new RegExp(e.path)}))})}isSupported(t){switch(t){case 4:case 5:return this.checkMintMelt(t);case 7:case 8:case 9:case 10:case 11:case 12:case 14:case 20:return this.checkGenericNut(t);case 17:return this.checkNut17();case 15:return this.checkNut15();default:throw new Error("nut is not supported by cashu-ts")}}requiresBlindAuthToken(t){if(!this._protectedEnpoints)return!1;if(typeof this._protectedEnpoints.cache[t]=="boolean")return this._protectedEnpoints.cache[t];const e=this._protectedEnpoints.apiReturn.some(s=>s.regex.test(t));return this._protectedEnpoints.cache[t]=e,e}checkGenericNut(t){return this._mintInfo.nuts[t]?.supported?{supported:!0}:{supported:!1}}checkMintMelt(t){const e=this._mintInfo.nuts[t];return e&&e.methods.length>0&&!e.disabled?{disabled:!1,params:e.methods}:{disabled:!0,params:e.methods}}checkNut17(){return this._mintInfo.nuts[17]&&this._mintInfo.nuts[17].supported.length>0?{supported:!0,params:this._mintInfo.nuts[17].supported}:{supported:!1}}checkNut15(){return this._mintInfo.nuts[15]&&this._mintInfo.nuts[15].methods.length>0?{supported:!0,params:this._mintInfo.nuts[15].methods}:{supported:!1}}get contact(){return this._mintInfo.contact}get description(){return this._mintInfo.description}get description_long(){return this._mintInfo.description_long}get name(){return this._mintInfo.name}get pubkey(){return this._mintInfo.pubkey}get nuts(){return this._mintInfo.nuts}get version(){return this._mintInfo.version}get motd(){return this._mintInfo.motd}}class v{constructor(t,e,s,r){this._mintUrl=t,this._customRequest=e,this._checkNut22=!1,this._mintUrl=jt(t),this._customRequest=e,s&&(this._checkNut22=!0,this._authTokenGetter=s),this._logger=r?.logger??N,Be(this._logger)}get mintUrl(){return this._mintUrl}static async getInfo(t,e,s){const r=s??N,a=await(e||K)({endpoint:x(t,"/v1/info")});return Oe(a,r)}async getInfo(){return v.getInfo(this._mintUrl,this._customRequest,this._logger)}async getLazyMintInfo(){if(this._mintInfo)return this._mintInfo;const t=await v.getInfo(this._mintUrl,this._customRequest);return this._mintInfo=new wt(t),this._mintInfo}static async swap(t,e,s,r){const o=s||K,a=r?{"Blind-auth":r}:{},i=await o({endpoint:x(t,"/v1/swap"),method:"POST",requestBody:e,headers:a});if(!O(i)||!Array.isArray(i?.signatures))throw new Error(i.detail??"bad response");return i}async swap(t){const e=await this.handleBlindAuth("/v1/swap");return v.swap(this._mintUrl,t,this._customRequest,e)}static async createMintQuote(t,e,s,r,o){const a=o??N,i=s||K,c=r?{"Blind-auth":r}:{},h=await i({endpoint:x(t,"/v1/mint/quote/bolt11"),method:"POST",requestBody:e,headers:c});return xt(h,a)}async createMintQuote(t){const e=await this.handleBlindAuth("/v1/mint/quote/bolt11");return v.createMintQuote(this._mintUrl,t,this._customRequest,e)}static async checkMintQuote(t,e,s,r,o){const a=o??N,i=s||K,c=r?{"Blind-auth":r}:{},h=await i({endpoint:x(t,"/v1/mint/quote/bolt11",e),method:"GET",headers:c});return xt(h,a)}async checkMintQuote(t){const e=await this.handleBlindAuth(`/v1/mint/quote/bolt11/${t}`);return v.checkMintQuote(this._mintUrl,t,this._customRequest,e)}static async mint(t,e,s,r){const o=s||K,a=r?{"Blind-auth":r}:{},i=await o({endpoint:x(t,"/v1/mint/bolt11"),method:"POST",requestBody:e,headers:a});if(!O(i)||!Array.isArray(i?.signatures))throw new Error("bad response");return i}async mint(t){const e=await this.handleBlindAuth("/v1/mint/bolt11");return v.mint(this._mintUrl,t,this._customRequest,e)}static async createMeltQuote(t,e,s,r,o){const a=o??N,i=s||K,c=r?{"Blind-auth":r}:{},h=await i({endpoint:x(t,"/v1/melt/quote/bolt11"),method:"POST",requestBody:e,headers:c}),u=pt(h,a);if(!O(u)||typeof u?.amount!="number"||typeof u?.fee_reserve!="number"||typeof u?.quote!="string")throw new Error("bad response");return u}async createMeltQuote(t){const e=await this.handleBlindAuth("/v1/melt/quote/bolt11");return v.createMeltQuote(this._mintUrl,t,this._customRequest,e)}static async checkMeltQuote(t,e,s,r,o){const a=o??N,i=s||K,c=r?{"Blind-auth":r}:{},h=await i({endpoint:x(t,"/v1/melt/quote/bolt11",e),method:"GET",headers:c}),u=pt(h,a);if(!O(u)||typeof u?.amount!="number"||typeof u?.fee_reserve!="number"||typeof u?.quote!="string"||typeof u?.state!="string"||!Object.values(J).includes(u.state))throw new Error("bad response");return u}async checkMeltQuote(t){const e=await this.handleBlindAuth(`/v1/melt/quote/bolt11/${t}`);return v.checkMeltQuote(this._mintUrl,t,this._customRequest,e)}static async melt(t,e,s,r,o){const a=o??N,i=s||K,c=r?{"Blind-auth":r}:{},h=await i({endpoint:x(t,"/v1/melt/bolt11"),method:"POST",requestBody:e,headers:c}),u=pt(h,a);if(!O(u)||typeof u?.state!="string"||!Object.values(J).includes(u.state))throw new Error("bad response");return u}async melt(t){const e=await this.handleBlindAuth("/v1/melt/bolt11");return v.melt(this._mintUrl,t,this._customRequest,e)}static async check(t,e,s){const o=await(s||K)({endpoint:x(t,"/v1/checkstate"),method:"POST",requestBody:e});if(!O(o)||!Array.isArray(o?.states))throw new Error("bad response");return o}static async getKeys(t,e,s){e&&(e=e.replace(/\//g,"_").replace(/\+/g,"-"));const o=await(s||K)({endpoint:e?x(t,"/v1/keys",e):x(t,"/v1/keys")});if(!O(o)||!Array.isArray(o.keysets))throw new Error("bad response");return o}async getKeys(t,e){return await v.getKeys(e||this._mintUrl,t,this._customRequest)}static async getKeySets(t,e){return(e||K)({endpoint:x(t,"/v1/keysets")})}async getKeySets(){return v.getKeySets(this._mintUrl,this._customRequest)}async check(t){return v.check(this._mintUrl,t,this._customRequest)}static async restore(t,e,s){const o=await(s||K)({endpoint:x(t,"/v1/restore"),method:"POST",requestBody:e});if(!O(o)||!Array.isArray(o?.outputs)||!Array.isArray(o?.signatures))throw new Error("bad response");return o}async restore(t){return v.restore(this._mintUrl,t,this._customRequest)}async connectWebSocket(){if(this.ws)await this.ws.ensureConnection();else{const t=new URL(this._mintUrl),e="v1/ws";t.pathname&&(t.pathname.endsWith("/")?t.pathname+=e:t.pathname+="/"+e),this.ws=z.getInstance().getConnection(`${t.protocol==="https:"?"wss":"ws"}://${t.host}${t.pathname}`);try{await this.ws.connect()}catch(s){throw this._logger.error("Failed to connect to WebSocket...",{e:s}),new Error("Failed to connect to WebSocket...")}}}disconnectWebSocket(){this.ws&&this.ws.close()}get webSocketConnection(){return this.ws}async handleBlindAuth(t){if(!this._checkNut22)return;if((await this.getLazyMintInfo()).requiresBlindAuthToken(t)){if(!this._authTokenGetter)throw new Error("Can not call a protected endpoint without authProofGetter");return this._authTokenGetter()}}}class yt{constructor(t,e,s){this.amount=t,this.B_=e,this.id=s}getSerializedBlindedMessage(){return{amount:this.amount,B_:this.B_.toHex(!0),id:this.id}}}function gt(n){return typeof n=="function"}class F{constructor(t,e,s){this.secret=s,this.blindingFactor=e,this.blindedMessage=t}toProof(t,e){let s;t.dleq&&(s={s:C.hexToBytes(t.dleq.s),e:C.hexToBytes(t.dleq.e),r:this.blindingFactor});const r={id:t.id,amount:t.amount,C_:V.pointFromHex(t.C_)},o=V.pointFromHex(e.keys[t.amount]),a=et.constructProofFromPromise(r,this.blindingFactor,this.secret,o);return{...et.serializeProof(a),...s&&{dleq:{s:C.bytesToHex(s.s),e:C.bytesToHex(s.e),r:ke(s.r??BigInt(0))}}}}static createP2PKData(t,e,s,r){return R(e,s.keys,r).map(a=>this.createSingleP2PKData(t,a,s.id))}static createSingleP2PKData(t,e,s){const r=Array.isArray(t.pubkey)?t.pubkey:[t.pubkey],o=Math.max(1,Math.min(t.requiredSignatures||1,r.length)),a=Math.max(1,Math.min(t.requiredRefundSignatures||1,t.refundKeys?t.refundKeys.length:1)),i=["P2PK",{nonce:C.bytesToHex(C.randomBytes(32)),data:r[0],tags:[]}];t.locktime&&i[1].tags.push(["locktime",String(t.locktime)]),r.length>1&&(i[1].tags.push(["pubkeys",...r.slice(1)]),o>1&&i[1].tags.push(["n_sigs",String(o)])),t.refundKeys&&(i[1].tags.push(["refund",...t.refundKeys]),a>1&&i[1].tags.push(["n_sigs_refund",String(a)]));const c=JSON.stringify(i),h=new TextEncoder().encode(c),{r:u,B_:l}=et.blindMessage(h);return new F(new yt(e,l,s).getSerializedBlindedMessage(),u,h)}static createRandomData(t,e,s){return R(t,e.keys,s).map(o=>this.createSingleRandomData(o,e.id))}static createSingleRandomData(t,e){const s=C.bytesToHex(C.randomBytes(32)),r=new TextEncoder().encode(s),{r:o,B_:a}=et.blindMessage(r);return new F(new yt(t,a,e).getSerializedBlindedMessage(),o,r)}static createDeterministicData(t,e,s,r,o){return R(t,r.keys,o).map((i,c)=>this.createSingleDeterministicData(i,e,s+c,r.id))}static createSingleDeterministicData(t,e,s,r){const o=Pt.deriveSecret(e,r,s),a=C.bytesToHex(o),i=new TextEncoder().encode(a),c=we(Pt.deriveBlindingFactor(e,r,s)),{r:h,B_:u}=et.blindMessage(i,c);return new F(new yt(t,u,r).getSerializedBlindedMessage(),h,i)}}const Ne=3,Le="sat";class Ce{constructor(t,e){this._keys=new Map,this._keysets=[],this._seed=void 0,this._unit=Le,this._mintInfo=void 0,this._denominationTarget=Ne,this.mint=t,this._logger=e?.logger??N;let s=[];if(e?.keys&&!Array.isArray(e.keys)?s=[e.keys]:e?.keys&&Array.isArray(e?.keys)&&(s=e?.keys),s&&s.forEach(r=>this._keys.set(r.id,r)),e?.unit&&(this._unit=e?.unit),e?.keysets&&(this._keysets=e.keysets),e?.mintInfo&&(this._mintInfo=new wt(e.mintInfo)),e?.denominationTarget&&(this._denominationTarget=e.denominationTarget),e?.bip39seed){if(e.bip39seed instanceof Uint8Array){this._seed=e.bip39seed;return}throw new Error("bip39seed must be a valid UInt8Array")}e?.keepFactory&&(this._keepFactory=e.keepFactory)}get unit(){return this._unit}get keys(){return this._keys}get keysetId(){if(!this._keysetId)throw new Error("No keysetId set");return this._keysetId}set keysetId(t){this._keysetId=t}get keysets(){return this._keysets}get mintInfo(){if(!this._mintInfo)throw new Error("Mint info not loaded");return this._mintInfo}async getMintInfo(){const t=await this.mint.getInfo();return this._mintInfo=new wt(t),this._mintInfo}async lazyGetMintInfo(){return this._mintInfo?this._mintInfo:await this.getMintInfo()}async loadMint(){await this.getMintInfo(),await this.getKeySets(),await this.getKeys()}getActiveKeyset(t){let e=t.filter(r=>r.active&&r.unit===this._unit);e=e.filter(r=>r.id.startsWith("00"));const s=e.sort((r,o)=>(r.input_fee_ppk??0)-(o.input_fee_ppk??0))[0];if(!s)throw new Error("No active keyset found");return s}async getKeySets(){const e=(await this.mint.getKeySets()).keysets.filter(s=>s.unit===this._unit);return this._keysets=e,this._keysets}async getAllKeys(){const t=await this.mint.getKeys();return t.keysets.forEach(e=>{if(!Tt(e))throw new Error(`Couldn't verify keyset ID ${e.id}`)}),this._keys=new Map(t.keysets.map(e=>[e.id,e])),this.keysetId=this.getActiveKeyset(this._keysets).id,t.keysets}async getKeys(t,e){if((!(this._keysets.length>0)||e)&&await this.getKeySets(),t||(t=this.getActiveKeyset(this._keysets).id),!this._keysets.find(s=>s.id===t)&&(await this.getKeySets(),!this._keysets.find(s=>s.id===t)))throw new Error(`could not initialize keys. No keyset with id '${t}' found`);if(!this._keys.get(t)){const s=await this.mint.getKeys(t);if(!Tt(s.keysets[0]))throw new Error(`Couldn't verify keyset ID ${s.keysets[0].id}`);this._keys.set(t,s.keysets[0])}return this.keysetId=t,this._keys.get(t)}async receive(t,e){const{requireDleq:s,keysetId:r,outputAmounts:o,counter:a,pubkey:i,privkey:c,outputData:h,p2pk:u}=e||{};typeof t=="string"&&(t=Wt(t));const l=await this.getKeys(r);if(s&&t.proofs.some(P=>!Et(P,l)))throw new Error("Token contains proofs with invalid DLEQ");const f=j(t.proofs)-this.getFeesForProofs(t.proofs);let d;h?d={send:h}:this._keepFactory&&(d={send:this._keepFactory});const m=this.createSwapPayload(f,t.proofs,l,o,a,i,c,d,u),{signatures:S}=await this.mint.swap(m.payload),b=m.outputData.map((P,k)=>P.toProof(S[k],l)),E=[];return m.sortedIndices.forEach((P,k)=>{E[P]=b[k]}),E}async send(t,e,s){const{offline:r,includeFees:o,includeDleq:a,keysetId:i,outputAmounts:c,pubkey:h,privkey:u,outputData:l}=s||{};if(a&&(e=e.filter(S=>S.dleq!=null)),j(e)<t)throw new Error("Not enough funds available to send");const{keep:f,send:d}=this.selectProofsToSend(e,t,s?.includeFees),m=o?this.getFeesForProofs(d):0;if(!r&&(j(d)!=t+m||c||h||u||i||l)){const S=await this.swap(t,e,s),{keep:b,send:E}=S,P=S.serialized;return{keep:b,send:E,serialized:P}}if(j(d)<t+m)throw new Error("Not enough funds available to send");return{keep:f,send:d}}selectProofsToSend(t,e,s=!1){const u=Ke();let l=null,f=1/0,d=0,m=0;const S=(y,p)=>y-(s?Math.ceil(p/1e3):0),b=y=>{const p=[...y];for(let w=p.length-1;w>0;w--){const g=Math.floor(Math.random()*(w+1));[p[w],p[g]]=[p[g],p[w]]}return p},E=(y,p,w)=>{let g=0,_=y.length-1,A=null;for(;g<=_;){const W=Math.floor((g+_)/2),H=y[W].exFee;(w?H<=p:H>=p)?(A=W,w?g=W+1:_=W-1):w?_=W-1:g=W+1}return w?A:g<y.length?g:null},P=(y,p)=>{const w=p.exFee;let g=0,_=y.length;for(;g<_;){const A=Math.floor((g+_)/2);y[A].exFee<w?g=A+1:_=A}y.splice(g,0,p)},k=(y,p)=>S(y,p)<e?1/0:y+p/1e3-e;let T=0,L=0;const nt=t.map(y=>{const p=this.getProofFeePPK(y),w=s?y.amount-p/1e3:y.amount,g={proof:y,exFee:w,ppkfee:p};return(!s||w>0)&&(T+=y.amount,L+=p),g});let M=s?nt.filter(y=>y.exFee>0):nt;if(M.sort((y,p)=>y.exFee-p.exFee),M.length>0){let y;{const p=E(M,e,!1);if(p!==null){const w=M[p].exFee,g=E(M,w,!0);if(g===null)throw new Error("Unexpected null rightIndex in binary search");y=g+1}else y=M.length}for(let p=y;p<M.length;p++)T-=M[p].proof.amount,L-=M[p].ppkfee;M=M.slice(0,y)}const rt=S(T,L);if(e<=0||e>rt)return{keep:t,send:[]};const tt=Math.min(Math.ceil(e*(1+0/100)),e+0,rt);for(let y=0;y<60;y++){const p=[];let w=0,g=0;for(const q of b(M)){const U=w+q.proof.amount,B=g+q.ppkfee,Q=S(U,B);if(p.push(q),w=U,g=B,Q>=e)break}const _=new Set(p),A=M.filter(q=>!_.has(q)),W=b(Array.from({length:p.length},(q,U)=>U)).slice(0,5e3);for(const q of W){const U=S(w,g);if(U===e||U>=e&&U<=tt)break;const B=p[q],Q=w-B.proof.amount,$=g-B.ppkfee,Jt=S(Q,$),At=e-Jt,ft=E(A,At,!1);if(ft!==null){const ot=A[ft];(At>=0||ot.exFee<=B.exFee)&&(p[q]=ot,w=Q+ot.proof.amount,g=$+ot.ppkfee,A.splice(ft,1),P(A,B))}}const H=k(w,g);if(H<f){this._logger.debug("selectProofsToSend: best solution found in trial #{trial} - amount: {amount}, delta: {delta}",{trial:y,amount:w,delta:H}),l=[...p].sort((U,B)=>B.exFee-U.exFee),f=H,d=w,m=g;const q=[...l];for(;q.length>1&&f>0;){const U=q.pop(),B=w-U.proof.amount,Q=g-U.ppkfee,$=k(B,Q);if($==1/0)break;$<f&&(l=[...q],f=$,d=B,m=Q,w=B,g=Q)}}if(l&&f<1/0){const q=S(d,m);if(q===e||q>=e&&q<=tt)break}if(u.elapsed()>1e3){this._logger.warn("Proof selection took too long. Returning best selection so far.");break}}if(l&&f<1/0){const y=l.map(g=>g.proof),p=new Set(y),w=t.filter(g=>!p.has(g));return this._logger.info("Proof selection took {time}ms",{time:u.elapsed()}),{keep:w,send:y}}return{keep:t,send:[]}}getFeesForProofs(t){const e=t.reduce((s,r)=>s+this.getProofFeePPK(r),0);return Math.ceil(e/1e3)}getProofFeePPK(t){const e=this._keysets.find(s=>s.id===t.id);if(!e)throw new Error(`Could not get fee. No keyset found for keyset id: ${t.id}`);return e?.input_fee_ppk||0}getFeesForKeyset(t,e){return Math.floor(Math.max((t*(this._keysets.find(r=>r.id===e)?.input_fee_ppk||0)+999)/1e3,0))}async swap(t,e,s){let{outputAmounts:r}=s||{};const{includeFees:o,keysetId:a,counter:i,pubkey:c,privkey:h,proofsWeHave:u,outputData:l,p2pk:f}=s||{},d=await this.getKeys(a);let m=t;const S=j(e);let b=r?.sendAmounts||R(m,d.keys);if(o){let _=this.getFeesForKeyset(b.length,d.id),A=R(_,d.keys);for(;this.getFeesForKeyset(b.concat(A).length,d.id)>_;)_++,A=R(_,d.keys);b=b.concat(A),m+=_}const{keep:E,send:P}=this.selectProofsToSend(e,m,!0),k=j(P)-this.getFeesForProofs(P)-m;if(k<0)throw new Error("Not enough balance to send");let T;if(!r?.keepAmounts&&!u)T=R(k,d.keys);else if(!r?.keepAmounts&&u)T=It(u,k,d.keys,this._denominationTarget);else if(r){if(r.keepAmounts?.reduce((_,A)=>_+A,0)!=k)throw new Error("Keep amounts do not match amount to keep");T=r.keepAmounts}if(m+this.getFeesForProofs(P)>S)throw this._logger.error(`Not enough funds available (${S}) for swap amountToSend: ${m} + fee: ${this.getFeesForProofs(P)} | length: ${P.length}`),new Error("Not enough funds available for swap");r={keepAmounts:T,sendAmounts:b};const L=l?.keep||this._keepFactory,nt=l?.send,M=this.createSwapPayload(m,P,d,r,i,c,h,{keep:L,send:nt},f),{signatures:rt}=await this.mint.swap(M.payload),tt=M.outputData.map((_,A)=>_.toProof(rt[A],d)),y=[],p=[],w=Array(M.keepVector.length),g=Array(tt.length);return M.sortedIndices.forEach((_,A)=>{w[_]=M.keepVector[A],g[_]=tt[A]}),g.forEach((_,A)=>{w[A]?y.push(_):p.push(_)}),{keep:[...y,...E],send:p}}async batchRestore(t=300,e=100,s=0,r){const o=Math.ceil(t/e),a=[];let i,c=0;for(;c<o;){const h=await this.restore(s,e,{keysetId:r});h.proofs.length>0?(c=0,a.push(...h.proofs),i=h.lastCounterWithSignature):c++,s+=e}return{proofs:a,lastCounterWithSignature:i}}async restore(t,e,s){const{keysetId:r}=s||{},o=await this.getKeys(r);if(!this._seed)throw new Error("CashuWallet must be initialized with a seed to use restore");const a=Array(e).fill(1),i=F.createDeterministicData(a.length,this._seed,t,o,a),{outputs:c,signatures:h}=await this.mint.restore({outputs:i.map(d=>d.blindedMessage)}),u={};c.forEach((d,m)=>u[d.B_]=h[m]);const l=[];let f;for(let d=0;d<i.length;d++){const m=u[i[d].blindedMessage.B_];m&&(f=t+d,i[d].blindedMessage.amount=m.amount,l.push(i[d].toProof(m,o)))}return{proofs:l,lastCounterWithSignature:f}}async createMintQuote(t,e){const s={unit:this._unit,amount:t,description:e},r=await this.mint.createMintQuote(s);return{...r,amount:r.amount||t,unit:r.unit||this.unit}}async createLockedMintQuote(t,e,s){const{supported:r}=(await this.getMintInfo()).isSupported(20);if(!r)throw new Error("Mint does not support NUT-20");const o={unit:this._unit,amount:t,description:s,pubkey:e},a=await this.mint.createMintQuote(o);if(typeof a.pubkey!="string")throw new Error("Mint returned unlocked mint quote");{const i=a.pubkey;return{...a,pubkey:i,amount:a.amount||t,unit:a.unit||this.unit}}}async checkMintQuote(t){const e=typeof t=="string"?t:t.quote,s=await this.mint.checkMintQuote(e);return typeof t=="string"?s:{...s,amount:s.amount||t.amount,unit:s.unit||t.unit}}async mintProofs(t,e,s){let{outputAmounts:r}=s||{};const{counter:o,pubkey:a,p2pk:i,keysetId:c,proofsWeHave:h,outputData:u,privateKey:l}=s||{},f=await this.getKeys(c);!r&&h&&(r={keepAmounts:It(h,t,f.keys,this._denominationTarget),sendAmounts:[]});let d=[];if(u)if(gt(u)){const b=R(t,f.keys,r?.keepAmounts);for(let E=0;E<b.length;E++)d.push(u(b[E],f))}else d=u;else if(this._keepFactory){const b=R(t,f.keys,r?.keepAmounts);for(let E=0;E<b.length;E++)d.push(this._keepFactory(b[E],f))}else d=this.createOutputData(t,f,o,a,r?.keepAmounts,i);let m;if(typeof e!="string"){if(!l)throw new Error("Can not sign locked quote without private key");const b=d.map(P=>P.blindedMessage),E=Zt.signMintQuote(l,e.quote,b);m={outputs:b,quote:e.quote,signature:E}}else m={outputs:d.map(b=>b.blindedMessage),quote:e};const{signatures:S}=await this.mint.mint(m);return d.map((b,E)=>b.toProof(S[E],f))}async createMeltQuote(t){const e={unit:this._unit,request:t},s=await this.mint.createMeltQuote(e);return{...s,unit:s.unit||this.unit,request:s.request||t}}async createMultiPathMeltQuote(t,e){const{supported:s,params:r}=(await this.lazyGetMintInfo()).isSupported(15);if(!s)throw new Error("Mint does not support NUT-15");if(!r?.some(h=>h.method==="bolt11"&&h.unit===this.unit))throw new Error(`Mint does not support MPP for bolt11 and ${this.unit}`);const a={mpp:{amount:e}},i={unit:this._unit,request:t,options:a};return{...await this.mint.createMeltQuote(i),request:t,unit:this._unit}}async checkMeltQuote(t){const e=typeof t=="string"?t:t.quote,s=await this.mint.checkMeltQuote(e);return typeof t=="string"?s:{...s,request:t.request,unit:t.unit}}async meltProofs(t,e,s){const{keysetId:r,counter:o,privkey:a}=s||{},i=await this.getKeys(r),c=this.createBlankOutputs(j(e)-t.amount,i,o,this._keepFactory);a!=null&&(e=St.signP2PKProofs(e,a)),e=at(e),e=e.map(l=>{const f=l.witness&&typeof l.witness!="string"?JSON.stringify(l.witness):l.witness;return{...l,witness:f}});const h={quote:t.quote,inputs:e,outputs:c.map(l=>l.blindedMessage)},u=await this.mint.melt(h);return{quote:{...u,unit:t.unit,request:t.request},change:u.change?.map((l,f)=>c[f].toProof(l,i))??[]}}createSwapPayload(t,e,s,r,o,a,i,c,h){const u=e.reduce((k,T)=>k+T.amount,0);r&&r.sendAmounts&&!r.keepAmounts&&(r.keepAmounts=R(u-t-this.getFeesForProofs(e),s.keys));const l=u-t-this.getFeesForProofs(e);let f=[],d=[];if(c?.keep)if(gt(c.keep)){const k=c.keep;R(l,s.keys).forEach(L=>{f.push(k(L,s))})}else f=c.keep;else f=this.createOutputData(l,s,o,void 0,r?.keepAmounts,void 0,this._keepFactory);if(c?.send)if(gt(c.send)){const k=c.send;R(t,s.keys).forEach(L=>{d.push(k(L,s))})}else d=c.send;else d=this.createOutputData(t,s,o?o+f.length:void 0,a,r?.sendAmounts,h);i&&(e=St.signP2PKProofs(e,i)),e=at(e),e=e.map(k=>{const T=k.witness&&typeof k.witness!="string"?JSON.stringify(k.witness):k.witness;return{...k,witness:T}});const m=[...f,...d],S=m.map((k,T)=>T).sort((k,T)=>m[k].blindedMessage.amount-m[T].blindedMessage.amount),b=[...Array.from({length:f.length},()=>!0),...Array.from({length:d.length},()=>!1)],E=S.map(k=>m[k]),P=S.map(k=>b[k]);return{payload:{inputs:e,outputs:E.map(k=>k.blindedMessage)},outputData:E,keepVector:P,sortedIndices:S}}async checkProofsStates(t){const e=new TextEncoder,s=t.map(a=>V.hashToCurve(e.encode(a.secret)).toHex(!0)),r=100,o=[];for(let a=0;a<s.length;a+=r){const i=s.slice(a,a+r),{states:c}=await this.mint.check({Ys:i}),h={};c.forEach(u=>{h[u.Y]=u});for(let u=0;u<i.length;u++){const l=h[i[u]];if(!l)throw new Error("Could not find state for proof with Y: "+i[u]);o.push(l)}}return o}async onMintQuoteUpdates(t,e,s){if(await this.mint.connectWebSocket(),!this.mint.webSocketConnection)throw new Error("failed to establish WebSocket connection.");const r=this.mint.webSocketConnection.createSubscription({kind:"bolt11_mint_quote",filters:t},e,s);return()=>{this.mint.webSocketConnection?.cancelSubscription(r,e)}}async onMeltQuotePaid(t,e,s){return this.onMeltQuoteUpdates([t],r=>{r.state===J.PAID&&e(r)},s)}async onMintQuotePaid(t,e,s){return this.onMintQuoteUpdates([t],r=>{r.state===ut.PAID&&e(r)},s)}async onMeltQuoteUpdates(t,e,s){if(await this.mint.connectWebSocket(),!this.mint.webSocketConnection)throw new Error("failed to establish WebSocket connection.");const r=this.mint.webSocketConnection.createSubscription({kind:"bolt11_melt_quote",filters:t},e,s);return()=>{this.mint.webSocketConnection?.cancelSubscription(r,e)}}async onProofStateUpdates(t,e,s){if(await this.mint.connectWebSocket(),!this.mint.webSocketConnection)throw new Error("failed to establish WebSocket connection.");const r=new TextEncoder,o={};for(let c=0;c<t.length;c++){const h=V.hashToCurve(r.encode(t[c].secret)).toHex(!0);o[h]=t[c]}const a=Object.keys(o),i=this.mint.webSocketConnection.createSubscription({kind:"proof_state",filters:a},c=>{e({...c,proof:o[c.Y]})},s);return()=>{this.mint.webSocketConnection?.cancelSubscription(i,e)}}createOutputData(t,e,s,r,o,a,i){let c;if(r)c=F.createP2PKData({pubkey:r},t,e,o);else if(s||s===0){if(!this._seed)throw new Error("cannot create deterministic messages without seed");c=F.createDeterministicData(t,this._seed,s,e,o)}else a?c=F.createP2PKData(a,t,e,o):i?c=R(t,e.keys).map(u=>i(u,e)):c=F.createRandomData(t,e,o);return c}createBlankOutputs(t,e,s,r){let o=Math.ceil(Math.log2(t))||1;o<0&&(o=0);const a=o?Array(o).fill(1):[];return this.createOutputData(a.length,e,s,void 0,a,void 0,r)}}class G{constructor(t,e){this._mintUrl=t,this._customRequest=e,this._mintUrl=jt(t),this._customRequest=e}get mintUrl(){return this._mintUrl}static async mint(t,e,s,r){const o=r||K,a={"Clear-auth":`${s}`},i=await o({endpoint:x(t,"/v1/auth/blind/mint"),method:"POST",requestBody:e,headers:a});if(!O(i)||!Array.isArray(i?.signatures))throw new Error("bad response");return i}async mint(t,e){return G.mint(this._mintUrl,t,e,this._customRequest)}static async getKeys(t,e,s){const o=await(s||K)({endpoint:e?x(t,"/v1/auth/blind/keys",e):x(t,"/v1/auth/blind/keys")});if(!O(o)||!Array.isArray(o.keysets))throw new Error("bad response");return o}async getKeys(t,e){return await G.getKeys(e||this._mintUrl,t,this._customRequest)}static async getKeySets(t,e){return(e||K)({endpoint:x(t,"/v1/auth/blind/keysets")})}async getKeySets(){return G.getKeySets(this._mintUrl,this._customRequest)}}class Gt{constructor(t,e){this._keys=new Map,this._keysets=[],this._unit="auth",this.mint=t;let s=[];e?.keys&&!Array.isArray(e.keys)?s=[e.keys]:e?.keys&&Array.isArray(e?.keys)&&(s=e?.keys),s&&s.forEach(r=>this._keys.set(r.id,r)),e?.keysets&&(this._keysets=e.keysets)}get keys(){return this._keys}get keysetId(){if(!this._keysetId)throw new Error("No keysetId set");return this._keysetId}set keysetId(t){this._keysetId=t}get keysets(){return this._keysets}async loadMint(){await this.getKeySets(),await this.getKeys()}getActiveKeyset(t){let e=t.filter(r=>r.active);e=e.filter(r=>r.id.startsWith("00"));const s=e.sort((r,o)=>(r.input_fee_ppk??0)-(o.input_fee_ppk??0))[0];if(!s)throw new Error("No active keyset found");return s}async getKeySets(){const e=(await this.mint.getKeySets()).keysets.filter(s=>s.unit===this._unit);return this._keysets=e,this._keysets}async getAllKeys(){const t=await this.mint.getKeys();return this._keys=new Map(t.keysets.map(e=>[e.id,e])),this.keysetId=this.getActiveKeyset(this._keysets).id,t.keysets}async getKeys(t,e){if((!(this._keysets.length>0)||e)&&await this.getKeySets(),t||(t=this.getActiveKeyset(this._keysets).id),!this._keysets.find(s=>s.id===t)&&(await this.getKeySets(),!this._keysets.find(s=>s.id===t)))throw new Error(`could not initialize keys. No keyset with id '${t}' found`);if(!this._keys.get(t)){const s=await this.mint.getKeys(t);this._keys.set(t,s.keysets[0])}return this.keysetId=t,this._keys.get(t)}async mintProofs(t,e,s){const r=await this.getKeys(s?.keysetId),o=F.createRandomData(t,r),a={outputs:o.map(h=>h.blindedMessage)},{signatures:i}=await this.mint.mint(a,e),c=o.map((h,u)=>h.toProof(i[u],r));if(c.some(h=>!Et(h,r)))throw new Error("Mint returned auth proofs with invalid DLEQ");return c}}function Vt(n){const t={id:n.id,secret:n.secret,C:n.C},e=Kt(t);return"auth"+"A"+e}async function We(n,t,e){const s=new G(t);return(await new Gt(s).mintProofs(n,e)).map(a=>Vt(a))}exports.CashuAuthMint=G;exports.CashuAuthWallet=Gt;exports.CashuMint=v;exports.CashuWallet=Ce;exports.CheckStateEnum=De;exports.ConsoleLogger=mt;exports.HttpResponseError=X;exports.LogLevel=I;exports.MeltQuoteState=J;exports.MintOperationError=dt;exports.MintQuoteState=ut;exports.NetworkError=lt;exports.OutputData=F;exports.PaymentRequest=ht;exports.PaymentRequestTransportType=Ht;exports.decodePaymentRequest=Se;exports.deriveKeysetId=Qt;exports.getBlindedAuthToken=We;exports.getDecodedToken=Wt;exports.getDecodedTokenBinary=qe;exports.getEncodedAuthToken=Vt;exports.getEncodedToken=_e;exports.getEncodedTokenBinary=Te;exports.getEncodedTokenV4=Nt;exports.hasValidDleq=Et;exports.injectWebSocketImpl=xe;exports.setGlobalRequestOptions=Ue; //# sourceMappingURL=cashu-ts.cjs.js.map