PageSourceSearch

https://2140.wtf/assets/cashuBackup-Nbaxj3cm.js

js 2140.wtf collected 2026-10-04 05:19:20 UTC 150,223 bytes, 1 lines download raw bytes

1import{a as e}from"./rolldown-runtime-Cyuzqnbw.js";import{ha as t}from"./lucide-icons-COCRnNA-.js";import{t as n}from"./dist-CESQMHVB.js";import{a as r,c as i,f as a,l as o,n as s,r as c,t as l}from"./esm-BGwiZfkP.js";import{et as u,t as d}from"./useCurrentUser-DKkxnPFy.js";import{t as f}from"./useAppContext-CBwW6cIB.js";import{n as p}from"./hmac-Clq8vIsc.js";import{l as m,n as h,o as g,s as _}from"./secp256k1-C1vwLGz_.js";import{t as v}from"./hkdf-BZqP4k4D.js";import{t as y}from"./usePublishPreferences-EuP1OEvC.js";import{t as b}from"./secureStorage-B-xXkFEK.js";import{a as x,i as ee,n as S,r as te,t as ne}from"./english-kzPtcOoV.js";import{a as re,i as ie,n as ae,o as oe,r as se,s as ce,t as le}from"./cashu-ts.es-BoxuTLVu.js";import{t as ue}from"./baoRelayMarkets-BP_HNNfq.js";import{t as de}from"./zaps-BteuLnhf.js";var C=e(t(),1),fe=e=>`2140_cashu_seed_${e}`,pe=15e3;function me(e,t,n){return new Promise((r,i)=>{let a=setTimeout(()=>{i(Error(`${n} timed out after ${t}ms`))},t);e.then(e=>{clearTimeout(a),r(e)},e=>{clearTimeout(a),i(e)})})}function he(){let{user:e}=d(),[t,n]=(0,C.useState)(void 0),[r,i]=(0,C.useState)(!1),[a,o]=(0,C.useState)(null),[s,c]=(0,C.useState)(0),l=(0,C.useRef)(s);l.current=s;let u=(0,C.useCallback)(()=>c(e=>e+1),[]),f=(0,C.useCallback)(async()=>{let t=e?.pubkey;if(t)try{await b.removeItem(fe(t))}catch{}c(e=>e+1)},[e?.pubkey]);return(0,C.useEffect)(()=>{let t=e?.pubkey,r=e?.signer?.nip44;if(!t||!r){n(void 0),i(!1),o(null);return}let a=!1,s=l.current;return i(!0),o(null),(async()=>{try{let e=fe(t),i=await me(b.getItem(e),pe,`Load Cashu seed`);if(i){let e=await me(r.decrypt(t,i),pe,`Decrypt Cashu seed`);!a&&s===l.current&&n(e)}else{let i=te(ne,128),o=await me(r.encrypt(t,i),pe,`Encrypt Cashu seed`);await me(b.setItem(e,o),pe,`Save Cashu seed`),!a&&s===l.current&&n(i)}}catch(e){if(!a&&s===l.current){let t=e instanceof Error?e.message:``;o(/denied/i.test(t)?`Your signer rejected the encryption request (${t}). Enable NIP-44 encrypt/decrypt permission for this app in your signer's connection settings, then retry.`:/invalid mac/i.test(t)?`This wallet was encrypted with a different key or signer profile. Reconnect the signer you used when the wallet was created, or restore from a backup. (Regenerating would discard your existing wallet.)`:t||`Failed to load or create Cashu seed`),n(void 0)}}finally{!a&&s===l.current&&i(!1)}})(),()=>{a=!0}},[e?.pubkey,e?.signer?.nip44,s]),{seedPhrase:t,loading:r,error:a,available:!!t,retry:u,regenerate:f}}var ge=!1,_e=ge?globalThis.console:null,w={log:(...e)=>{ge&&_e?.log(...e)},warn:(...e)=>{ge&&_e?.warn(...e)},error:(...e)=>{ge&&_e?.error(...e)}},ve=`ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/`,ye=(()=>{let e={};for(let t=0;t<64;t++)e[ve[t]]=t;return e})();function be(e){let t=e.length,n=``;for(let r=0;r<t;r+=3){let i=e[r],a=r+1<t?e[r+1]:0,o=r+2<t?e[r+2]:0,s=i<<16|a<<8|o;n+=ve[s>>18&63],n+=ve[s>>12&63],n+=r+1<t?ve[s>>6&63]:`=`,n+=r+2<t?ve[s&63]:`=`}return n}function xe(e){let t=e.replace(/[^A-Za-z0-9+/=]/g,``),n=t.length;if(n%4!=0)throw Error(`Invalid base64 string`);let r=0;t.endsWith(`==`)?r=2:t.endsWith(`=`)&&(r=1);let i=n*3/4-r,a=new Uint8Array(new ArrayBuffer(i)),o=0;for(let e=0;e<n;e+=4){let n=ye[t[e]]??0,r=ye[t[e+1]]??0,s=ye[t[e+2]]??0,c=ye[t[e+3]]??0,l=n<<18|r<<12|s<<6|c;o<i&&(a[o++]=l>>16&255),o<i&&(a[o++]=l>>8&255),o<i&&(a[o++]=l&255)}return a}function Se(e){return be(new TextEncoder().encode(encodeURIComponent(e)))}var Ce=[{name:`Kashu`,url:`https://kashu.me`},{name:`Minibits`,url:`https://mint.minibits.cash/Bitcoin`}],we=5e4,Te=`freedomid:cashu:proof-encryption:v1`,Ee=`ditto:cashu:nutzap:v1`,De=`ditto:cashu:walletkey:v1`,Oe=`ditto:cashu:bao:walletkey:v1`,T=`2140:cashu:bao:seed:v1`,E=`v1:`,D=`freedomid:proofs:`,ke=`freedomid:transactions`;function Ae(e){e&&typeof e.fill==`function`&&e.fill(0)}function je(e,t,n=we){return!Number.isSafeInteger(e)||e<0||!Number.isSafeInteger(t)||t<0||n<0?!1:e<=Number(BigInt(t)*BigInt(n)/1000000n)}function Me(e){return!!e&&typeof e.toHex==`function`}function Ne(e){try{if(typeof e==`string`&&e.length>0)return{point:h.Point.fromHex(e),valid:!0};if(Me(e))return{point:h.Point.fromHex(e.toHex(!0)),valid:!0}}catch{}return{point:void 0,valid:!1}}function Pe(e){if(typeof e==`string`)try{let t=m(e);if(t.length===32)return t}catch{}return e instanceof Uint8Array&&e.length===32?e:null}function Fe(e){if(typeof e==`bigint`)return e;if(typeof e==`number`&&Number.isInteger(e)&&e>=0)return BigInt(e);if(typeof e==`string`)try{let t=m(e);if(t.length>0)return _(t)}catch{}return e instanceof Uint8Array&&e.length>0?_(e):null}function Ie(e,t){if(!Array.isArray(e))return{valid:!1,reason:`proofs must be an array`};let{activeKeysetIds:n,localSecrets:r,getKeyset:i,requireDleq:a}=t;for(let t of e){if(!t||typeof t!=`object`)return{valid:!1,reason:`proof is not an object`};let e=t,o=String(e.id),s=String(e.secret),c=Number(e.amount);
1if(!n.has(o))return{valid:!1,reason:`received proof has invalid keyset id: ${o}`};if(!Number.isInteger(c)||c<=0||c>2**53-1)return{valid:!1,reason:`received proof has invalid amount: ${c}`};if(s.length===0||s.length>4096)return{valid:!1,reason:`received proof has invalid secret`};if(r?.has(s))return{valid:!1,reason:`received proof reuses a secret already in local store`};let l=Ne(e.C);if(!l.valid)return{valid:!1,reason:`received proof C is not a valid curve point: ${String(e.C).slice(0,24)}`};if(a){let t=e.dleq;if(!t||typeof t!=`object`)return{valid:!1,reason:`received proof is missing a DLEQ proof`};let n=t,r=Pe(n.s),a=Pe(n.e),u=Fe(n.r);if(!r||!a||u===null)return{valid:!1,reason:`received proof has malformed DLEQ proof`};let d=i?.(o);if(!d)return{valid:!1,reason:`cannot verify DLEQ: keyset ${o} keys unavailable`};let f=d.keys[c];if(!f||typeof f!=`string`)return{valid:!1,reason:`no public key for amount ${c} in keyset ${o}`};let p;try{p=h.Point.fromHex(f)}catch{return{valid:!1,reason:`invalid public key for keyset ${o}`}}try{if(!re(new TextEncoder().encode(s),{s:r,e:a,r:u},ce(l.point.toHex(!0)),ce(p.toHex(!0))))return{valid:!1,reason:`received proof has invalid DLEQ proof`}}catch(e){return{valid:!1,reason:`DLEQ verification failed: ${e instanceof Error?e.message:String(e)}`}}}}return{valid:!0}}async function Le(e){if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);return crypto.subtle.importKey(`raw`,e,{name:`AES-GCM`},!1,[`encrypt`,`decrypt`])}function Re(e){let t=e.trim();if(t.length===0)throw Error(`Invalid seed phrase`);if(t.length>2e3)throw Error(`Seed phrase too long`);return x(t)}async function ze(e){if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);let t=Re(e);try{return await Le(v(p,t,new Uint8Array,new TextEncoder().encode(Te),32))}finally{Ae(t)}}function Be(e){let t=Re(e);try{let e=v(p,t,new Uint8Array,new TextEncoder().encode(Ee),32);return{privkey:e,pubkey:g(h.getPublicKey(e,!0))}}finally{Ae(t)}}function Ve(e){let t=Re(e);try{let e=v(p,t,new Uint8Array,new TextEncoder().encode(De),32);return{privkey:e,pubkey:r(e)}}finally{Ae(t)}}function O(e){let t=Re(e);try{let e=v(p,t,new Uint8Array,new TextEncoder().encode(Oe),32);return{privkey:e,pubkey:r(e)}}finally{Ae(t)}}function He(e){let t=e.trim();if(t.length===0)throw Error(`Invalid seed phrase`);let n=ee(t,ne),r=v(p,n,new Uint8Array,new TextEncoder().encode(T),16);try{return S(r,ne)}finally{Ae(r),Ae(n)}}async function Ue(e){if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);let t=Re(e);try{return await Le(await crypto.subtle.digest(`SHA-256`,t))}finally{Ae(t)}}function k(e){if(e)return new TextEncoder().encode(e)}function We(e,t){return t===void 0?{name:`AES-GCM`,iv:e}:{name:`AES-GCM`,iv:e,additionalData:t}}async function Ge(e,t,n){if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);let r=crypto.getRandomValues(new Uint8Array(12)),i=new TextEncoder().encode(JSON.stringify(e)),a=k(n),o=await crypto.subtle.encrypt(We(r,a),t,i),s=new Uint8Array(r.length+o.byteLength);return s.set(r),s.set(new Uint8Array(o),r.length),E+be(s)}function Ke(e){if(e.startsWith(E))try{return{combined:xe(e.slice(3))}}catch{return null}try{return{combined:xe(e)}}catch{return null}}async function qe(e,t,n){if(e.length<12)throw Error(`Ciphertext too short`);let r=e.slice(0,12),i=e.slice(12),a=k(n);return crypto.subtle.decrypt(We(r,a),t,i)}async function A(e,t,n,r){if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);let i=Ke(e);if(!i)throw Error(`Invalid base64 encoding`);let{combined:a}=i,o=e.startsWith(E)?r:void 0,s;try{s=await qe(a,t,o)}catch{if(n)try{s=await qe(a,n,o)}catch{throw Error(`Decryption failed — wrong key or corrupted data`)}else throw Error(`Decryption failed — wrong key or corrupted data`)}try{return JSON.parse(new TextDecoder().decode(s))}
1catch{throw Error(`Decrypted data is not valid JSON`)}}async function j(e,t,n){if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);let r=crypto.getRandomValues(new Uint8Array(12)),i=new TextEncoder().encode(e),a=k(n),o=await crypto.subtle.encrypt(We(r,a),t,i),s=new Uint8Array(r.length+o.byteLength);return s.set(r),s.set(new Uint8Array(o),r.length),E+be(s)}async function M(e,t,n,r){if(!e)return null;if(typeof crypto>`u`||!crypto.subtle)throw Error(`Web Crypto API not available. HTTPS or secure context required.`);let i=Ke(e);if(!i)throw Error(`Invalid base64 encoding`);let{combined:a}=i,o=e.startsWith(E)?r:void 0,s;try{s=await qe(a,t,o)}catch{if(n)try{s=await qe(a,n,o)}catch{throw Error(`Decryption failed — wrong key or corrupted data`)}else throw Error(`Decryption failed — wrong key or corrupted data`)}return new TextDecoder().decode(s)}function Je(e){let t=e.split(`.`);return t.length!==4||!t.every(e=>/^\d{1,3}$/.test(e)&&Number(e)<=255)?NaN:t.reduce((e,t)=>(e<<8)+Number(t),0)>>>0}function Ye(e){let t=Je(e);return Number.isNaN(t)?!1:t>>>24==127||t>>>24==10||t>>>20==2753||t>>>16==49320||t>>>16==43518||t===0}function N(e){let t=e.toLowerCase();return!!(t===`::1`||t===`0:0:0:0:0:0:0:1`||t.startsWith(`fc`)||t.startsWith(`fd`)||t.startsWith(`fe8`)||t.startsWith(`fe9`)||t.startsWith(`fea`)||t.startsWith(`feb`))}function Xe(e){let t=e.toLowerCase().match(/^::ffff:(?:(\d{1,3}(?:\.\d{1,3}){3})|([0-9a-f]{1,4}):([0-9a-f]{1,4}))$/);if(!t)return null;if(t[1])return t[1];let n=parseInt(t[2],16),r=parseInt(t[3],16);return`${n>>8&255}.${n&255}.${r>>8&255}.${r&255}`}function P(e,t){try{let n=new URL(e);if(n.protocol!==`https:`)return!1;let r=n.hostname.replace(/^\[|\]$/g,``).toLowerCase();if(r===`localhost`)return!1;if(r.includes(`:`)){let e=Xe(r);if(e?Ye(e):N(r))return!1}else if(Ye(r))return!1;if(t&&t.length>0){let r=n.href.replace(/\/+$/,``);if(!t.map(e=>{try{return new URL(e).href.replace(/\/+$/,``)}catch{return``}}).filter(Boolean).includes(r))return w.warn(`Mint URL not in allow-list:`,e),!1}return!0}catch{return!1}}function F(e){let t=e.trim();try{let e=new URL(t);return e.protocol!==`http:`&&e.protocol!==`https:`?null:(e.protocol===`https:`&&e.port===`443`&&(e.port=``),e.protocol===`http:`&&e.port===`80`&&(e.port=``),e.pathname=e.pathname.replace(/\/+$/,``),e.host=e.host.toLowerCase(),e.toString().replace(/\/$/,``))}catch{let e=t.replace(/\/+$/,``).match(/^([a-zA-Z][a-zA-Z0-9+.-]*:\/\/[^/]+)(.*)$/);if(e){let t=e[1].split(`://`)[0].toLowerCase();if(t!==`http`&&t!==`https`)return null;let n=e[1].toLowerCase();return n=n.replace(/:443(?=\/|$)/,``).replace(/:80(?=\/|$)/,``),n+e[2]}return null}}function I(e){return F(e)??e.trim()}function Ze(e){let t=e.witness;if(typeof t!=`string`)return e;try{let n=JSON.parse(t);if(n&&typeof n==`object`&&!Array.isArray(n))return{...e,witness:n}}catch{}return e}function L(e){let t=0;for(let n of e)if(t+=n.amount,!Number.isSafeInteger(t))return null;return t}function R(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.id!=`string`||t.id.length===0||t.id.length>4096||typeof t.C!=`string`||t.C.length===0||t.C.length>4096||typeof t.secret!=`string`||t.secret.length===0||t.secret.length>
14096||t.witness!==void 0&&(typeof t.witness!=`string`||t.witness.length>4096)||typeof t.amount!=`number`)return!1;let n=t.amount;return Number.isInteger(n)&&n>0&&n<=2**53-1}function Qe(e){let t=[...e].map(e=>({mintUrl:F(e.mintUrl)??e.mintUrl,proofs:[...e.proofs].map(e=>{let t=e;return{id:String(t.id),amount:Number(t.amount),secret:String(t.secret),C:String(t.C)}}).sort((e,t)=>e.secret.localeCompare(t.secret))})).sort((e,t)=>e.mintUrl.localeCompare(t.mintUrl));return be(p(new TextEncoder().encode(JSON.stringify(t))))}function $e(e){if(typeof e!=`string`||e.length>1e5)return null;let t=e.trim();if(t.toLowerCase().startsWith(`cashu://`)?t=t.slice(8):t.toLowerCase().startsWith(`cashu:`)?t=t.slice(6):t.toLowerCase().startsWith(`cashu`)&&(t=t.slice(5)),!t)return null;let n;try{n=le(t)}catch{return null}let r=[];if(`token`in n&&Array.isArray(n.token))for(let e of n.token){let t=e?.mint,n=e?.proofs;if(typeof t!=`string`||t.length===0||!P(t)||!Array.isArray(n)||n.length===0)continue;let i=n.filter(R);if(i.length===0)continue;let a=L(i);a!==null&&r.push({mintUrl:t,proofs:i,amount:a})}else if(`mint`in n&&`proofs`in n){let e=n.mint,t=n.proofs;if(typeof e!=`string`||e.length===0||!P(e)||!Array.isArray(t)||t.length===0)return null;let i=t.filter(R);if(i.length===0)return null;let a=L(i);if(a===null)return null;r.push({mintUrl:e,proofs:i,amount:a})}return r.length>0?r:null}var et=17375,tt=7375,nt=7376,rt=7374,it=10019,at=9321,ot=`sat`,z=`2140_nip60_token_event_`,st=`2140_nip60_token_hash_`,ct=`2140_nip60_config_hash`,lt=`2140_nip60_nutzap_info_hash`;function ut(e,t){return t?`${t}${e}`:e}function dt(e){return{pubkey:e.pubkey,nip44Encrypt:async(t,n)=>{try{return await e.signer.nip44.encrypt(t,n)}catch(e){return w.error(`Identity NIP-44 encrypt failed:`,e),null}},nip44Decrypt:async(t,n)=>{try{return await e.signer.nip44.decrypt(t,n)}catch(e){return w.error(`Identity NIP-44 decrypt failed:`,e),null}},signEvent:async t=>{try{return await e.signer.signEvent(t)}catch(e){return w.error(`Identity sign failed:`,e),null}}}}function ft(e){return{pubkey:r(e),nip44Encrypt:async(t,n)=>{try{let r=o.v2.utils.getConversationKey(e,t);return o.v2.encrypt(n,r)}catch(e){return w.error(`NIP-60 encrypt failed:`,e),null}},nip44Decrypt:async(t,n)=>{try{let r=o.v2.utils.getConversationKey(e,t);return o.v2.decrypt(n,r)}catch(e){return w.error(`NIP-60 decrypt failed:`,e),null}},signEvent:async t=>{try{return s(t,e)}catch(e){return w.error(`NIP-60 sign failed:`,e),null}}}}function pt(e,t){let n=[...new Set(t.map(e=>F(e)).filter(Boolean))];return{id:`default`,privkey:g(e),mints:n}}function mt(e){return g(p(new TextEncoder().encode(JSON.stringify(e))))}async function ht(e,t,n){try{let r=await j(e,t);localStorage.setItem(ut(ct,n),r)}catch(e){w.warn(`Failed to save NIP-60 wallet config hash:`,e)}}async function gt(e,t){let n=null;try{n=localStorage.getItem(ut(lt,t))}catch{return null}if(!n)return null;try{return await M(n,e)}catch{return null}}async function _t(e,t,n){try{let r=await j(e,t);localStorage.setItem(ut(lt,n),r)}catch(e){w.warn(`Failed to save NIP-60 Nutzap info hash:`,e)}}function vt(e,t,n){let r=F(t);return r?(n||``)+e+g(new TextEncoder().encode(r)):null}async function yt(e,t,n){let r=vt(z,e,n);if(!r)return null;let i=null;try{i=localStorage.getItem(r)}catch{return null}if(!i)return null;try{return await M(i,t)}catch{return null}}async function bt(e,t,n,r){let i=vt(z,e,r);if(i)try{let e=await j(t,n);localStorage.setItem(i,e)}catch(e){w.warn(`Failed to save NIP-60 token event id:`,e)}}async function xt(e,t,n,r){let i=vt(st,e,r);if(i)try{let e=await j(t,n);localStorage.setItem(i,e)}catch(e){w.warn(`Failed to save NIP-60 token hash:`,e)}}function St(e,t){return!t||t.length===0?e:[...e,...t]}function Ct(e,t){return!t||e.some(([e])=>e===`published_at`)?e:[...e,[`published_at`,String(t)]]}async function wt(e,t,n){let r=Array.isArray(e)?e:[e],i=[];for(let e of r){let t=e.id??`default`;t==="default"?i.push([`privkey`,e.privkey]):i.push([`privkey`,t,e.privkey]);for(let t of e.mints){let e=F(t);e&&i.push([`mint`,e])}}let a=JSON.stringify(i),o=await t.nip44Encrypt(t.pubkey,a);if(!o)return null;let s=n?.extraTags?[...n.extraTags]:[];return s=Ct(s,n?.publishedAt),t.signEvent({kind:et,content:o,tags:s,created_at:n?.createdAt??Math.floor(Date.now()/1e3)})}async function Tt(e,t){if(e.kind!==17375||!a(e))return[];let n=await t.nip44Decrypt(e.pubkey,e.content);if(!n)return[];try{let e=JSON.parse(n);if(!Array.isArray(e))return[];let t=e,r=[],i=null;for(let e of t){if(!Array.isArray(e)||e.length<2)continue;let[t,...n]=e;if(t===`privkey`)i&&i.privkey.length===64&&r.push(i),i=null,n.length===1&&typeof n[0]==`string`?i={id:`default`,privkey:n[0],mints:[]}:n.length===2&&typeof n[0]==`string`&&typeof n[1]==`string`&&(i={id:n[0],privkey:n[1],mints:[]});else if(t===`mint`&&i&&typeof n[0]==`string`){let e=F(n[0]);e&&i.mints.push(e)}}return i&&i.privkey.length===64&&r.push(i),r.filter(e=>e.mints.length>0)}catch{return[]}}async function Et(e,t,n,r,i,a){let o=F(e);if(!o)return null;let s={mint:o,unit:ot,proofs:t.slice()};r&&r.length>0&&(s.del=[...new Set(r)]);let c=await n.nip44Encrypt(n.pubkey,JSON.stringify(s));return c?n.signEvent({kind:tt,content:c,tags:i?[...i]:[],created_at:a??Math.floor(Date.now()/1e3)}):null}async function Dt(e,t){if(e.kind!==7375||!a(e))return null;let n=await t.nip44Decrypt(e.pubkey,e.content);if(!n)return null;try{let e=JSON.parse(n);if(!e||typeof e!=`object`)return null;let t=e;if(typeof t.mint!=`string`||t.unit!==ot||!Array.isArray(t.proofs))return null;let r=F(t.mint);if(!r)return null;let i={mint:r,unit:ot,proofs:t.proofs};return Array.isArray(t.del)&&(i.del=t.del.filter(e=>typeof e==`string`)),i}catch{return null}}async function Ot(e,t,n=`spent`,r,i){let a=[...new Set(e)].filter(e=>typeof e==`string`&&e.length===64);return a.length===0?null:t.signEvent({kind:5,content:n,tags:St(a.map(e=>[`e`,e]),r),created_at:i??Math.floor(Date.now()/1e3)})}async function kt(e,t,n,r,i,a,o){let s=F(n);if(!s)return null;
1let c=[[`direction`,e],[`amount`,String(t)],[`unit`,ot],[`mint`,s]];if(i)for(let e of i)c.push([`e`,e.id,``,e.marker]);let l=await r.nip44Encrypt(r.pubkey,JSON.stringify(c));return l?r.signEvent({kind:nt,content:l,tags:a?[...a]:[],created_at:o??Math.floor(Date.now()/1e3)}):null}async function At(e,t){if(e.kind!==7376||!a(e))return null;let n=await t.nip44Decrypt(e.pubkey,e.content);if(!n)return null;try{let e=JSON.parse(n);if(!Array.isArray(e))return null;let t=e,r=e=>t.find(([t])=>t===e)?.[1],i=r(`direction`),a=Number(r(`amount`)),o=r(`mint`);if(i!==`in`&&i!==`out`||!Number.isFinite(a)||typeof o!=`string`)return null;let s=[];for(let e of t)if(e[0]===`e`&&typeof e[1]==`string`){let t=e[3]===`created`||e[3]===`destroyed`?e[3]:`created`;s.push({id:e[1],marker:t})}return{direction:i,amount:a,unit:ot,mint:o,events:s}}catch{return null}}async function jt(e,t,n,r){let i=F(t);if(!i||!e||e.length>1e3)return null;let a=r?.quotePrivateKey;if(a!==void 0&&!/^[0-9a-f]{64}$/.test(a))return null;let o=a?JSON.stringify({quote_id:e,p2pk_priv:a}):e,s=await n.nip44Encrypt(n.pubkey,o);if(!s)return null;let c=r?.createdAt??Math.floor(Date.now()/1e3),l=r?.expiration??c+336*60*60;return n.signEvent({kind:rt,content:s,tags:St([[`expiration`,String(l)],[`mint`,i]],r?.extraTags),created_at:c})}async function Mt(e,t){if(e.kind!==7374||e.pubkey!==t.pubkey||!a(e))return null;let n=e.tags.find(e=>e[0]===`mint`)?.[1];if(typeof n!=`string`)return null;let r=F(n);if(!r)return null;let i=await t.nip44Decrypt(e.pubkey,e.content);if(!i)return null;let o=i,s;try{let e=JSON.parse(i);if(!e||typeof e!=`object`)return null;let t=e,n=t.quote_id??t.quoteId??t.quote;if(typeof n!=`string`)return null;o=n;let r=t.p2pk_priv??t.quotePrivateKey??t.signingPrivkey;if(r!==void 0){if(typeof r!=`string`||!/^[0-9a-f]{64}$/.test(r))return null;s=r}}catch{}if(!o||o.length>1e3)return null;let c=e.tags.find(e=>e[0]===`expiration`)?.[1],l=c===void 0?void 0:Number(c);return{eventId:e.id,quoteId:o,mint:r,quotePrivateKey:s,createdAt:e.created_at,expiresAt:Number.isSafeInteger(l)&&(l??0)>0?l*1e3:void 0}}async function Nt(e,t,n=Date.now()){let[r,i]=await Promise.all([t({kinds:[rt],authors:[e.pubkey],limit:200}),t({kinds:[5],authors:[e.pubkey],limit:500})]),o=new Set;for(let t of i)if(!(t.kind!==5||t.pubkey!==e.pubkey||!a(t)))for(let e of t.tags)e[0]===`e`&&typeof e[1]==`string`&&o.add(e[1]);let s=await Promise.all(r.filter(e=>!o.has(e.id)).map(t=>Mt(t,e))),c=new Map;for(let e of s){if(!e||e.expiresAt!==void 0&&e.expiresAt<=n)continue;let t=c.get(e.quoteId);(!t||e.createdAt>t.createdAt)&&c.set(e.quoteId,e)}return[...c.values()].sort((e,t)=>t.createdAt-e.createdAt)}async function Pt(e,t,n,r,i){let a=[];for(let e of[...new Set(t)]){let t=e.trim();t&&a.push([`relay`,t])}for(let t of[...new Set(e.map(e=>F(e)).filter(e=>!!e))])a.push([`mint`,t,ot]);if(!n||n.length!==64)return null;a.push([`pubkey`,n]);let o=Ct(St(a,i?.extraTags),i?.publishedAt);return r.signEvent({kind:it,content:``,tags:o,created_at:i?.createdAt??Math.floor(Date.now()/1e3)})}function Ft(e,t){if(e.kind!==10019||!a(e)||t&&e.pubkey.toLowerCase()!==t.toLowerCase())return null;let n=[],r=[],i=null;for(let t of e.tags){if(!Array.isArray(t)||t.length<2)continue;let[e,a]=t;if(e===`relay`&&typeof a==`string`&&a.trim())n.push(a.trim());else if(e===`mint`&&typeof a==`string`){let e=F(a);e&&r.push(e)}else if(e===`pubkey`&&typeof a==`string`){let e=a.trim().toLowerCase();(/^[0-9a-f]{64}$/.test(e)||/^0[23][0-9a-f]{64}$/.test(e))&&(i=e)}}return!i||r.length===0?null:{pubkey:i,mints:[...new Set(r)],relays:[...new Set(n)]}}async function It(e,t,n,r,i){let a=F(t);if(!a||!e||e.length!==64||!Array.isArray(n)||n.length===0)return null;let o=[[`p`,e],[`u`,a],[`unit`,ot]];i?.zappedEvent&&(o.push([`e`,i.zappedEvent.id,i.zappedEvent.relay??``]),o.push([`k`,String(i.zappedEvent.kind)]));for(let e of n)o.push([`proof`,JSON.stringify(e)]);return r.signEvent({kind:at,content:i?.memo??``,tags:i?.extraTags?[...o,...i.extraTags]:o,created_at:i?.createdAt??Math.floor(Date.now()/1e3)})}function Lt(e,t){if(e.kind!==9321||!a(e)||t&&e.pubkey.toLowerCase()!==t.toLowerCase())return null;let n=``,r=``,i=[];for(let t of e.tags)if(!(!Array.isArray(t)||t.length<2)&&(t[0]===`u`&&typeof t[1]==`string`&&(n=t[1]),t[0]===`p`&&typeof t[1]==`string`&&(r=t[1]),t[0]===`proof`&&typeof t[1]==`string`))try{i.push(JSON.parse(t[1])
1)}catch{}if(!n||!r||i.length===0)return null;let o=i.reduce((e,t)=>{if(t&&typeof t==`object`&&`amount`in t){let n=Number(t.amount);if(Number.isInteger(n)&&n>0)return e+n}return e},0);return{mint:n,proofs:i,recipient:r,sender:e.pubkey,amount:o}}async function Rt(e,t,n,r,i,a,o,s){let c=F(t);if(!c||!i||i.length!==64)return null;let l=[[`direction`,`in`],[`amount`,String(e)],[`unit`,ot],[`mint`,c],[`e`,i,``,`created`]],u=await a.nip44Encrypt(a.pubkey,JSON.stringify(l));if(!u)return null;let d=[[`e`,n,``,`redeemed`],[`p`,r]];return a.signEvent({kind:nt,content:u,tags:o?[...d,...o]:d,created_at:s??Math.floor(Date.now()/1e3)})}function zt(e,t){let n=[...e].sort((e,t)=>t.created_at-e.created_at||t.id.localeCompare(e.id)),r=new Set(t),i={};for(let e of n){if(r.has(e.id)){if(e.content.del)for(let t of e.content.del)r.add(t);continue}let t=i[e.content.mint];if(t?t.push(...e.content.proofs):i[e.content.mint]=e.content.proofs.slice(),e.content.del)for(let t of e.content.del)r.add(t)}return i}async function Bt(e,t,n){let r={config:null,configs:[],proofsByMint:{},history:[]};try{let[i,o,s,c]=await Promise.all([n({kinds:[et],authors:[t.pubkey],limit:5}),n({kinds:[tt],authors:[e.pubkey],limit:500}),n({kinds:[5],authors:[e.pubkey],limit:500}),n({kinds:[nt],authors:[e.pubkey],limit:200})]),l=i.filter(e=>a(e)).sort((e,t)=>t.created_at-e.created_at)[0];l&&(r.configs=await Tt(l,t),r.config=r.configs.find(e=>(e.id??`default`)==="default")??r.configs[0]??null);let u=new Set;for(let e of s)if(a(e))for(let t of e.tags)t[0]===`e`&&typeof t[1]==`string`&&u.add(t[1]);let d=[];for(let t of o){let n=await Dt(t,e);n&&d.push({id:t.id,content:n,created_at:t.created_at})}r.proofsByMint=zt(d,u);for(let t of c){let n=await At(t,e);n&&r.history.push(n)}r.history.sort((e,t)=>t.amount-e.amount)}catch(e){w.error(`NIP-60 restore failed:`,e)}return r}var Vt={"https://relay.bao.network/bao-api/v1/proxy/cashu":`https://relay.bao.network/cashu`};function Ht(e){return Vt[e]??e}async function Ut(e,t){let n={result:{config:null,configs:[],proofsByMint:{},history:[]},walletPrivkey:null,walletPubkey:null};try{let r=(await t({kinds:[et],authors:[e.pubkey],limit:5})).filter(e=>a(e)).sort((e,t)=>t.created_at-e.created_at)[0];if(!r)return n;let i=await Tt(r,e),o=i.find(e=>(e.id??`default`)==="default")??i[0]??null;if(!o||!/^[0-9a-f]{64}$/i.test(o.privkey))return n;let s=m(o.privkey),c=ft(s);return{result:await Bt(c,e,t),walletPrivkey:s,walletPubkey:c.pubkey}}catch(e){return w.error(`Cross-app NIP-60 restore failed:`,e),n}}var Wt=8e3,Gt=8e3;function B(){let{nostr:e}=n(),{user:t}=d(),{config:r}=f();return(0,C.useMemo)(()=>{if(!t)return;if(!t.signer.nip44){w.warn(`Current signer does not support NIP-44; NIP-60 sync disabled.`);return}let n=dt(t),i=ue.replace(/\/+$/,``).toLowerCase(),a=(r.relayMetadata?.relays??[]).filter(e=>typeof e.url==`string`&&e.url.length>0).filter(e=>e.url.replace(/\/+$/,``).toLowerCase()!==i),o=a.filter(e=>e.read!==!1).map(e=>e.url),s=a.filter(e=>e.write!==!1).map(e=>e.url);return{signer:n,publish:async t=>{if(s.length===0)return null;try{return await e.group(s).event(t,{signal:AbortSignal.timeout(Wt)}),t.id}catch(e){return w.error(`NIP-60 publish failed:`,e),null}},query:async t=>{if(o.length===0)return[];try{return await e.group(o).query([t],{signal:AbortSignal.timeout(Gt)})}catch(e){return w.error(`NIP-60 query failed:`,e),[]}},queryRelays:async(t,n)=>{try{return await e.group(t).query([n],{signal:AbortSignal.timeout(Gt)})}catch(e){return w.error(`NIP-60 targeted relay query failed:`,e),[]}},publishToRelays:async(t,n)=>{try{return await e.group(t).event(n,{signal:AbortSignal.timeout(Wt)}),n.id}catch(e){return w.error(`NIP-60 targeted relay publish failed:`,e),null}},relays:[...new Set([...o,...s])]}},[t,e,r.relayMetadata?.relays])}var Kt=9321;function qt(e){let t=new Set,n=[];for(let r of e){if(!r?.url)continue;let e=r.url.trim();!e||t.has(e)||(t.add(e),n.push(e))}return n.sort()}function V(e,t,r,i={}){let{user:a}=d(),{nostr:o}=n(),s=(0,C.useRef)(null),c=(0,C.useRef)(r);c.current=r,(0,C.useEffect)(()=>{if(!e){s.current=null;return}try{s.current=Be(e)}catch(e){w.error(`Failed to derive nutzap key:`,e),s.current=null}},[e]);let l=(0,C.useMemo)(()=>qt(t),[t]),u=(0,C.useMemo)(()=>[...new Set((i.relayUrls??[]).map(e=>
1e.trim()).filter(Boolean))].sort(),[i.relayUrls]);(0,C.useEffect)(()=>{if(!a||!r||l.length===0)return;let e=[...new Set(l.flatMap(e=>{let t=e.trim(),n=F(t);return n&&n!==t?[t,n]:[t]}).filter(Boolean))];if(e.length===0)return;let t=[{kinds:[Kt],"#p":[a.pubkey],"#u":e}],n=new AbortController,i=!0;return(async()=>{for(;i&&!n.signal.aborted;){try{let e=u.length>0?o.group(u):o;for await(let r of e.req(t,{signal:n.signal})){if(!i||n.signal.aborted)break;r[0]===`EVENT`&&c.current?.(r[2])}}catch(e){w.warn(`Nutzap subscription error:`,e)}if(!i||n.signal.aborted)break;await new Promise(e=>setTimeout(e,5e3))}})(),()=>{i=!1,n.abort()}},[a,l,o,u])}var H=(e,t=`freedomid_`)=>`${t}proof_recovery_${Se(e)}`,Jt=(e,t=`freedomid_`)=>`${t}send_recovery_${Se(e)}`,Yt=(e,t=`freedomid_`)=>`${t}melt_change_recovery_${Se(e)}`,Xt=(e,t=`freedomid_`)=>`${t}melt_input_recovery_${Se(e)}`,U=(e,t=`freedomid_`)=>`${t}proof_store_ts_${Se(e)}`,Zt=(e=`freedomid_`)=>`${e}minted_quotes`;function Qt(e,t){try{localStorage.setItem(U(e,t),String(Date.now()))}catch{}}async function W(e,t,n,r){try{let i=await j(JSON.stringify({version:1,timestamp:Date.now(),proofs:t}),n);localStorage.setItem(H(e,r),i)}catch(e){w.warn(`Failed to write proof recovery:`,e)}}function $t(e,t){try{localStorage.removeItem(H(e,t))}catch{}}async function en(e,t,n,r){let i=null;try{i=localStorage.getItem(H(e,r))}catch{return null}if(!i)return null;try{let e=await M(i,t,n);if(!e)return null;let r=JSON.parse(e);return r&&typeof r==`object`&&Array.isArray(r.proofs)?{version:Number(r.version)||0,timestamp:Number(r.timestamp)||0,proofs:r.proofs}:Array.isArray(r)?{version:0,timestamp:0,proofs:r}:null}catch{return null}}async function G(e,t,n,r){try{let i=await j(JSON.stringify({version:1,timestamp:Date.now(),proofs:t}),n);localStorage.setItem(Jt(e,r),i)}catch(e){w.warn(`Failed to write send recovery:`,e)}}function tn(e,t){try{localStorage.removeItem(Jt(e,t))}catch{}}async function K(e,t,n,r){let i=null;try{i=localStorage.getItem(Jt(e,r))}catch{return null}if(!i)return null;try{let e=await M(i,t,n);if(!e)return null;let r=JSON.parse(e);return r&&typeof r==`object`&&Array.isArray(r.proofs)?{version:Number(r.version)||0,timestamp:Number(r.timestamp)||0,proofs:r.proofs}:Array.isArray(r)?{version:0,timestamp:0,proofs:r}:null}catch{return null}}async function q(e,t,n,r){try{let i=await j(JSON.stringify({version:1,timestamp:Date.now(),proofs:t}),n);localStorage.setItem(Yt(e,r),i)}catch(e){w.warn(`Failed to write melt change recovery:`,e)}}function nn(e,t){try{localStorage.removeItem(Yt(e,t))}catch{}}async function rn(e,t,n,r){let i=null;try{i=localStorage.getItem(Yt(e,r))}catch{return null}if(!i)return null;try{let e=await M(i,t,n);if(!e)return null;let r=JSON.parse(e);return r&&typeof r==`object`&&Array.isArray(r.proofs)?{version:Number(r.version)||0,timestamp:Number(r.timestamp)||0,proofs:r.proofs}:null}catch{return null}}async function an(e,t,n,r){try{let i=await j(JSON.stringify({version:1,timestamp:Date.now(),proofs:t}),n);localStorage.setItem(Xt(e,r),i)}catch(e){w.warn(`Failed to write melt input recovery:`,e)}}function on(e,t){try{localStorage.removeItem(Xt(e,t))}catch{}}async function J(e,t,n,r){let i=null;try{i=localStorage.getItem(Xt(e,r))}catch{return null}if(!i)return null;try{let e=await M(i,t,n);if(!e)return null;let r=JSON.parse(e);return r&&typeof r==`object`&&Array.isArray(r.proofs)?{version:Number(r.version)||0,timestamp:Number(r.timestamp)||0,proofs:r.proofs}:null}catch{return null}}async function Y(e,t,n){let r=null;try{r=localStorage.getItem(Zt(n))}catch{return[]}if(!r)return[];try{let n=await M(r,e,t);if(!n)return[];let i=JSON.parse(n);return Array.isArray(i)?i.filter(e=>typeof e==`string`):[]}catch{return[]}}async function sn(e,t,n=2,r){return Rn(async()=>{let i;for(let a=0;a<n;a++)try{let n=await Y(t,void 0,r);if(n.includes(e))return;n.push(e);let i=await j(JSON.stringify(n),t);localStorage.setItem(Zt(r),i);return}catch(e){i=e}throw Error(`Failed to persist minted quote after ${n} attempts: ${i instanceof Error?i.message:String(i)}`)},r)}async function X(e,t,n=2,r){return Rn(async()=>{let i;for(let a=0;a<n;a++)try{let n=await Y(t,void 0,r),i=[...new Set([...n,...e])],a=await j(JSON.stringify(i),t);localStorage.setItem(Zt(r),a);return}catch(e){i=e}throw Error(`Failed to persist minted quotes after ${n} attempts: ${i instanceof Error?i.message:String(i)}`)},r)}var cn=`freedomid:receive-pending`,ln=(e,t)=>`${t??`freedomid_`}receive_pending_${Se(e)}`;async function un(e,t,n,r){let i=null;try{i=localStorage.getItem(ln(e,r))}catch{return null}if(!i)return null;try{let e=await M(i,t,n,cn);if(!e)return null;let r=JSON.parse(e);return r&&typeof r==`object`&&typeof r.tokenStr==`string`?r:null}catch{return null}}async function dn(e,t){try{await Rn(async()=>{try{localStorage.removeItem(ln(e,t))}catch{}},t)}catch{}}async function Z(e,t,n,r,i,a,o,s){return Rn(async()=>{let c=await un(t,i,void 0,s),l={tokenStr:e,tokenHash:t,mintUrls:n,amount:r,status:`pending`,timestamp:Date.now(),attempts:o??c?.attempts??0,succeededMintUrls:a??c?.succeededMintUrls??[]},u=await j(JSON.stringify(l),i,cn);localStorage.setItem(ln(t,s),u)},s)}var fn=`freedomid_`;function Q(e){return e&&e.length>0?e:fn}var pn=null;function mn(e){if(pn!==null)return pn;try{let t=Q(e)+`__quota_test__`;return localStorage.setItem(t,`1`),localStorage.removeItem(t),pn=!0,!0}catch{return pn=!1,!1}}function hn(e){pn=null}function gn(e){return e instanceof DOMException&&(e.name===`QuotaExceededError`||e.name===`NS_ERROR_DOM_QUOTA_REACHED`)}function _n(e){let t=e instanceof Error?e.message:String(e);return gn(e)||t.toLowerCase().includes(`storage`)||t.toLowerCase().includes(`quota`)||t.toLowerCase().includes(`full`)}function vn(e,t){try{localStorage.setItem(e,t)}catch{}}var $=3e4,yn=`FreedomIDLocks`,bn=1,xn=`locks`;function Sn(e){try{let t=localStorage.getItem(e);if(!t)return null;let n=JSON.parse(t);if(n&&typeof n==`object`&&`owner`in n&&`expires`in n&&typeof n.owner==`string`&&typeof n.expires==`number`)return n}catch{}return null}function Cn(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(e){throw _n(e)&&hn(),Error(`Failed to write wallet lock — storage may be full: ${e instanceof Error?e.message:String(e)}`)}}function wn(){return typeof indexedDB<`u`}var Tn=null;function En(){return Tn||(Tn=new Promise((e,t)=>
1{let n=indexedDB.open(yn,bn),r=()=>{Tn=null};n.onerror=()=>{r(),t(n.error)},n.onblocked=()=>{r(),t(Error(`IndexedDB lock database blocked`))},n.onsuccess=()=>e(n.result),n.onupgradeneeded=()=>{let e=n.result;e.objectStoreNames.contains(xn)||e.createObjectStore(xn,{keyPath:`name`})}}),Tn)}var Dn=class extends Error{};async function On(e,t,n){try{let r=await En();return await new Promise((i,a)=>{let o=!1,s=r.transaction(xn,`readwrite`),c=s.objectStore(xn),l=c.get(e);l.onerror=()=>a(l.error),l.onsuccess=()=>{let r=l.result;(!r||r.expires<Date.now())&&(c.put({name:e,token:t,expires:Date.now()+n}),o=!0)},s.oncomplete=()=>i(o),s.onerror=()=>a(s.error),s.onabort=()=>a(s.error??Error(`IndexedDB lock transaction aborted`))})}catch(e){if(e instanceof Error&&(e.name===`QuotaExceededError`||e.name===`InvalidStateError`||e.name===`UnknownError`))throw new Dn(e.message);return!1}}async function kn(e,t,n){try{let r=await En();return await new Promise((i,a)=>{let o=!1,s=r.transaction(xn,`readwrite`),c=s.objectStore(xn),l=c.get(e);l.onerror=()=>a(l.error),l.onsuccess=()=>{let e=l.result;e?.token===t&&(c.put({...e,expires:Date.now()+n}),o=!0)},s.oncomplete=()=>i(o),s.onerror=()=>a(s.error),s.onabort=()=>a(s.error??Error(`IndexedDB lease transaction aborted`))})}catch{return!0}}async function An(e,t){try{let n=await En();await new Promise((r,i)=>{let a=n.transaction(xn,`readwrite`),o=a.objectStore(xn),s=o.get(e);s.onerror=()=>i(s.error),s.onsuccess=()=>{s.result?.token===t&&o.delete(e)},a.oncomplete=()=>r(),a.onerror=()=>i(a.error),a.onabort=()=>i(a.error??Error(`IndexedDB release transaction aborted`))})}catch{}}function jn(){let e=new Uint8Array(16);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}var Mn=class{key;owner=null;depth=0;useIdb=!1;extendTimer=null;storageAbortController=null;constructor(e){this.key=e}invalidate(){this.extendTimer&&=(clearInterval(this.extendTimer),null),this.owner=null,this.depth=0,this.useIdb=!1}async assertOwnership(){if(this.depth<=0||!this.owner)throw Error(`Wallet lock is not held by this tab`);if(!await this.refreshOwnLease())throw this.invalidate(),Error(`Wallet lock was lost while held — another tab may have taken it`)}async acquire(){if(this.depth>0&&this.owner){if(!await this.refreshOwnLease())throw this.invalidate(),Error(`Wallet lock was lost while held — another tab may have taken it`);this.depth++;return}let e=jn(),t=Date.now();if(wn()){let n=!1;for(;Date.now()-t<=1e4&&!n;){try{if(await On(this.key,e,3e4)){this.owner=e,this.depth=1,this.useIdb=!0,this.extendTimer=setInterval(()=>{let e=this.owner;e&&kn(this.key,e,$).then(t=>{!t&&this.owner===e&&this.invalidate()})},$/2);return}}catch(e){e instanceof Dn&&(n=!0)}await new Promise(e=>setTimeout(e,50+Math.random()*20))}if(!n)throw Error(`Could not acquire wallet lock — another tab may be busy`)}this.storageAbortController=new AbortController;let n=this.storageAbortController.signal;typeof window<`u`&&window.addEventListener(`storage`,t=>{if(t.key!==this.key||n.aborted)return;let r=Sn(this.key);r&&r.owner!==e&&r.expires>Date.now()&&this.storageAbortController?.abort()},{signal:n});try{for(;;){if(n.aborted)throw Error(`Could not acquire wallet lock — another tab may be busy`);let r=Date.now(),i=Sn(this.key);if(!i||i.expires<r){try{Cn(this.key,{owner:e,expires:r+$})}catch(e){throw gn(e)&&hn(),e}if(Sn(this.key)?.owner===e){this.owner=e,this.depth=1,this.useIdb=!1,this.extendTimer=setInterval(()=>{let e=this.owner;if(e)if(Sn(this.key)?.owner===e)try{Cn(this.key,{owner:e,expires:Date.now()+$})}catch(e){gn(e)&&hn()}else this.invalidate()},$/2);return}}if(r-t>1e4)throw Error(`Could not acquire wallet lock — another tab may be busy`);await new Promise(e=>setTimeout(e,50+Math.floor(Math.random()*50)))}}finally{this.storageAbortController?.abort(),this.storageAbortController=null}}async refreshOwnLease(){if(!this.owner)return!1;if(this.useIdb)try{let e=await En();return await new Promise((t,n)=>{let r=!1,i=e.transaction(xn,`readwrite`),a=i.objectStore(xn),o=a.get(this.key);o.onerror=()=>n(o.error),o.onsuccess=()=>{let e=o.result;e?.token===this.owner&&(a.put({...e,expires:Date.now()+$}),r=!0)},i.oncomplete=()=>t(r),i.onerror=()=>n(i.error),i.onabort=()=>n(i.error??Error(`IndexedDB refresh transaction aborted`))})}catch{return!0}if(Sn(this.key)?.owner!==this.owner)return!1;try{Cn(this.key,{owner:this.owner,expires:Date.now()+$})}catch{}return!0}release(){if(!(this.depth<=0||!this.owner)&&(this.depth--,!(this.depth>0))){if(this.extendTimer&&=(clearInterval(this.extendTimer),null),this.useIdb)An(this.key,this.owner).catch(()=>{});else if(Sn(this.key)?.owner===this.owner)try{localStorage.removeItem(this.key)}catch{}this.owner=null,this.useIdb=!1}}},Nn=new Map,Pn=new Map;function Fn(e){let t=Q(e)+`proof_lock`,n=Nn.get(t);return n||(n=new Mn(t),Nn.set(t,n)),n}function In(e){let t=Q(e)+`tx_lock`,n=Pn.get(t);return n||(n=new Mn(t),Pn.set(t,n)),n}async function Ln(e,t){if(!mn(t))throw Error(`Storage quota exceeded — cannot perform wallet operation. Free up space and try again.`);let n=Fn(t);await n.acquire();try{return await e()}finally{n.release()}}async function Rn(e,t){let n=In(t);await n.acquire();try{return await e()}finally{n.release()}}async function zn(e){await Fn(e).assertOwnership()}var Bn=(e,t)=>`${Q(t)}mint_counter_${Se(e)}`;function Vn(e,t){try{let n=localStorage.getItem(Bn(e,t)),r=n?Number(n):NaN;return Number.isInteger(r)&&r>=0?r:0}catch{return 0}}function Hn(e,t,n){if(!(!Number.isInteger(t)||t<0))try{localStorage.setItem(Bn(e,n),String(t))}catch{}}var Un=`freedomid:pending-mint`,Wn=(e,t)=>`${Q(t)}pending_mint_${Se(e)}`;async function Gn(e,t,n,r){try{let i=await j(JSON.stringify(t),n,Un);localStorage.setItem(Wn(e,r),i)}catch(e){w.warn(`Failed to write pending mint journal:`,e)}}async function Kn(e,t,n,r){let i=null;try{i=localStorage.getItem(Wn(e,r))}catch{return null}if(!i)return null;try{let e=await M(i,t,n,Un);if(!e)return null;let r=JSON.parse(e);return r&&typeof r==`object`&&typeof r.quoteId==`string`&&typeof r.counterStart==`number`&&typeof r.amount==`number`&&(r.method===void 0||r.method===`bolt11`||r.method===`bolt12`)?r:null}catch{return null}}function qn(e,t){try{localStorage.removeItem(Wn(e,t))}catch{}}var Jn=new Set([`__proto__`,`constructor`,`prototype`]);function Yn(e,t){if(t&&typeof t==`object`&&!Array.isArray(t)){let e=Object.create(null);for(let n of Object.keys(t))Jn.has(n)||(e[n]=t[n]);return e}return t}function Xn(e){if(!e||typeof e!=`object`)return!1;if(Array.isArray(e))return e.some(Xn);for(let t of Object.keys(e))if(Jn.has(t)||Xn(e[t]))return!0;return!1}function Zn(e,t,n){try{let r=localStorage.getItem(Q(n)+e);if(r===null)return t;let i=JSON.parse(r,Yn);return i===void 0?t:i}catch{return t}}function Qn(e,t,n){if(Xn(t))throw Error(`Refusing to save ${e}: value contains prototype-polluting keys`);try{localStorage.setItem(Q(n)+e,JSON.stringify(t))}catch(t){throw _n(t)&&hn(),Error(`Failed to save ${e} to localStorage: ${t instanceof Error?t.message:String(t)}`)}}var $n=`custom_mints`,er=`selected_mint_url`,tr=`mint_metadata_migration_done`;function nr(e){return!!e&&typeof e==`object`&&typeof e.url==`string`&&typeof e.name==`string`}async function rr(e,t,n){if(!(typeof localStorage>`u`)&&localStorage.getItem(Q(n)+tr)!==`1`)try{let t=Zn($n,[],n),r
1=localStorage.getItem(Q(n)+er)||``,i=await j(JSON.stringify(t),e,`freedomid:custom-mints`),a=r?await j(r,e,`freedomid:selected-mint`):``;Qn($n,i,n),a&&vn(Q(n)+er,a),vn(Q(n)+tr,`1`)}catch(e){w.warn(`Mint metadata migration failed:`,e)}}async function ir(e,t,n){let r=null;try{r=localStorage.getItem(Q(n)+$n)}catch{return[]}if(!r)return[];if(e)try{let n=await M(r,e,t,`freedomid:custom-mints`);if(n===null)return[];let i=JSON.parse(n);return Array.isArray(i)?i.filter(nr):[]}catch{return w.warn(`Failed to decrypt custom mints`),[]}let i=Zn($n,[],n);return Array.isArray(i)?i.filter(nr):[]}async function ar(e,t,n){try{if(t){let r=await j(JSON.stringify(e),t,`freedomid:custom-mints`);localStorage.setItem(Q(n)+$n,r)}else Qn($n,e,n)}catch(e){_n(e)&&hn(),w.warn(`Storage full: failed to save custom mints`)}}async function or(e,t,n){let r=null;try{r=localStorage.getItem(Q(n)+er)}catch{return``}if(!r)return``;if(e)try{return await M(r,e,t,`freedomid:selected-mint`)??``}catch{return w.warn(`Failed to decrypt selected mint URL`),``}return r}async function sr(e,t,n){try{if(t&&e){let r=await j(e,t,`freedomid:selected-mint`);vn(Q(n)+er,r)}else t?vn(Q(n)+er,``):vn(Q(n)+er,e)}catch(e){_n(e)&&hn(),w.warn(`Storage full: failed to save selected mint URL`)}}function cr(e,t){return Q(t)+`proofs_`+Se(e)}async function lr(e,t,n,r){try{let i=localStorage.getItem(cr(e,r));if(!i)return[];let a=await A(i,t,n,`${D}${e}`);return Array.isArray(a)?a:[]}catch{return[]}}function ur(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&t.id.length<=4096&&typeof t.amount==`number`&&Number.isInteger(t.amount)&&t.amount>0&&t.amount<=2**53-1&&typeof t.secret==`string`&&t.secret.length>0&&t.secret.length<=4096&&typeof t.C==`string`&&t.C.length>0&&t.C.length<=4096&&(t.witness===void 0||typeof t.witness==`string`&&t.witness.length<=4096)}async function dr(e,t,n,r){let i=Array.isArray(t)?t.filter(ur):[],a;try{a=await Ge(i,n,`${D}${e}`)}catch(t){throw w.error(`Encryption failed: failed to save proofs for mint`,e),Error(`Failed to encrypt proofs: ${t instanceof Error?t.message:String(t)}`)}try{localStorage.setItem(cr(e,r),a)}catch(t){throw _n(t)&&hn(),w.error(`Storage full: failed to save proofs for mint`,e),Error(`Failed to save proofs — storage may be full: ${t instanceof Error?t.message:String(t)}`)}}var fr=`transactions`;function pr(e,t){if(!e||typeof e!=`object`)return!1;let n=e;return!(typeof n.id!=`string`||n.id.length===0||n.id.length>1e3||typeof n.type!=`string`||![`send`,`receive`,`mint`,`melt`].includes(n.type)||typeof n.amount!=`number`||!Number.isInteger(n.amount)||n.amount<0||n.amount>2**53-1||typeof n.memo!=`string`||n.memo.length>1e4||typeof n.mintUrl!=`string`||n.mintUrl.length===0||n.mintUrl.length>2e3||typeof n.status!=`string`||![`pending`,`completed`,`failed`,`expired`].includes(n.status)||n.quoteId!==void 0&&(typeof n.quoteId!=`string`||n.quoteId.length>1e3)||n.paymentRequest!==void 0&&(typeof n.paymentRequest!=`string`||n.paymentRequest.length>1e4)||n.quotePrivateKey!==void 0&&(typeof n.quotePrivateKey!=`string`||!/^[0-9a-f]{64}$/.test(n.quotePrivateKey))||n.quoteEventId!==void 0&&(typeof n.quoteEventId!=`string`||!/^[0-9a-f]{64}$/.test(n.quoteEventId))||typeof n.createdAt!=`number`||!Number.isFinite(n.createdAt)||!Number.isInteger(n.createdAt)||n.createdAt<0)}var mr=`tx_migration_done`;async function hr(e,t,n={},r){let i=null;try{i=localStorage.getItem(Q(r)+fr)}catch{return[]}if(!i)return[];let a;if(e)try{let n=await M(i,e,t,ke);if(n===null)return[];a=n}catch{return w.warn(`Failed to decrypt transactions — treating as corrupted`),[]}else if(n.allowPlaintextFallback)a=i;else return[];try{let e=JSON.parse(a);return Array.isArray(e)?e.filter(e=>pr(e)):[]}catch{return[]}}function gr(e={},t){let n=null;try{n=localStorage.getItem(Q(t)+fr)}catch{return[]}if(!n||!n.trim().startsWith(`[`)&&!n.trim().startsWith(`{`)||!e.allowPlaintextFallback)return[];try{let e=JSON.parse(n,(e,t)=>{if(!Jn.has(e))return t});return Array.isArray(e)?e.filter(e=>pr(e)):[]}catch{return[]}}async function _r(e,t,n){let r=[...e].sort((e,t)=>(t.createdAt??0)-(e.createdAt??0)),i=r.length>500?r.slice(0,500):r,a=JSON.stringify(i);if(t){let e=await j(a,t,ke);try{localStorage.setItem(Q(n)+fr,e)}catch(e){throw _n(e)&&hn(),w.warn(`Storage full: failed to save transactions`),Error(`Failed to save transactions — storage may be full`)}}else try{Qn(fr,i,n)}catch(e){throw _n(e)&&hn(),w.warn(`Storage full: failed to save transactions`),Error(`Failed to save transactions — storage may be full`)}}async function vr(e,t,n){if(!(typeof localStorage>`u`)&&localStorage.getItem(Q(n)+mr)!==`1`)try{let t=localStorage.getItem(Q(n)+fr);if(!t){vn(Q(n)+mr,`1`);return}if(!t.trim().startsWith(`[`)&&!t.trim().startsWith(`{`)){vn(Q(n)+mr,`1`);return}let r=gr({allowPlaintextFallback:!0},n);r.length>0&&await _r(r,e,n),vn(Q(n)+mr,`1`)}catch(e){w.warn(`Plaintext transaction migration failed:`,e)}}async function yr(e,t,n,r,i){return Rn(async()=>{let a=await hr(t,n,r,i),o;try{o=crypto.randomUUID?crypto.randomUUID():Array.from(crypto.getRandomValues(new Uint8Array(16)),e=>e.toString(16).padStart(2,`0`)).join(``)}catch{console.warn(`addTransaction: crypto API unavailable; falling back to Math.random() for transaction id`),o=`${Date.now().toString(36)}_${Array.from({length:4},()=>Math.floor(Math.random()*256).toString(16).padStart(2,`0`)).join(``)}`}let s={...e,id:o,createdAt:Date.now()};if(!pr(s))throw Error(`Invalid transaction data`);return a.some(e=>e.id===o)&&(o=`${o}_${Date.now()}`,s.id=o),a.unshift(s),a.length>500&&a.pop(),await _r(a,t,i),o},i)}var br=[`pending`,`completed`,`failed`,`expired`];async function xr(e,t,n,r,i,a){if(!br.includes(t))throw Error(`Invalid transaction status: ${t}`);return Rn(async()=>{let o=await hr(n,r,i,a),s=o.findIndex(t=>t.id===e);if(s<0)throw Error(`Transaction not found: ${e}`);o[s].status=t,await _r(o,n,a)},a)}var Sr=`freedomid:processed-tokens`,Cr=`processed_tokens`,wr=1e3,Tr=10080*60*1e3;async function Er(e,t,n){let r=null;try{r=localStorage.getItem(Q(n)+Cr)}catch{return[]}if(!r)return[];if(e)try{let n=await M(r,e,t,Sr);if(n===null)return[];let i=JSON.parse(n);if(!Array.isArray(i))return[];let a=Date.now();return i.filter(e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.hash==`string`&&t.hash.length>0&&typeof t.expiresAt==`number`&&Number.isFinite(t.expiresAt)&&t.expiresAt>a})}catch{return[]}return[]}
1async function Dr(e,t,n,r){return e?(await Er(t,n,r)).some(t=>t.hash===e):!1}async function Or(e,t,n){if(t)return Rn(async()=>{let r=Date.now(),i=e.filter(e=>e&&typeof e==`object`&&typeof e.hash==`string`&&e.hash.length>0&&typeof e.expiresAt==`number`&&e.expiresAt>r).sort((e,t)=>t.expiresAt-e.expiresAt).slice(0,wr),a=await j(JSON.stringify(i),t,Sr);try{localStorage.setItem(Q(n)+Cr,a)}catch(e){throw _n(e)&&hn(),Error(`Failed to save processed token hashes: ${e instanceof Error?e.message:String(e)}`)}},n)}async function kr(e,t,n,r){if(!(!e||!t))return Rn(async()=>{let i=await Er(t,n,r),a=Date.now(),o=i.filter(t=>t.hash!==e);o.push({hash:e,expiresAt:a+Tr}),o.sort((e,t)=>t.expiresAt-e.expiresAt);let s=o.slice(0,wr),c=await j(JSON.stringify(s),t,Sr);try{localStorage.setItem(Q(r)+Cr,c)}catch(e){throw _n(e)&&hn(),Error(`Failed to save processed token hash: ${e instanceof Error?e.message:String(e)}`)}},r)}var Ar=`freedomid:processed-nutzaps`,jr=`processed_nutzaps`,Mr=1e3,Nr=10080*60*1e3;async function Pr(e,t,n){let r=null;try{r=localStorage.getItem(Q(n)+jr)}catch{return[]}if(!r||!e)return[];try{let n=await M(r,e,t,Ar);if(n===null)return[];let i=JSON.parse(n);if(!Array.isArray(i))return[];let a=Date.now();return i.filter(e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.expiresAt==`number`&&Number.isFinite(t.expiresAt)&&t.expiresAt>a})}catch{return[]}}async function Fr(e,t,n,r){return e?(await Pr(t,n,r)).some(t=>t.id===e):!1}async function Ir(e,t,n,r){if(!(!e||!t))return Rn(async()=>{let i=await Pr(t,n,r),a=Date.now(),o=i.filter(t=>t.id!==e);o.push({id:e,expiresAt:a+Nr}),o.sort((e,t)=>t.expiresAt-e.expiresAt);let s=o.slice(0,Mr),c=await j(JSON.stringify(s),t,Ar);try{localStorage.setItem(Q(r)+jr,c)}catch(e){throw _n(e)&&hn(),Error(`Failed to save processed Nutzap id: ${e instanceof Error?e.message:String(e)}`)}},r)}var Lr=`freedomid:pending-nutzaps`,Rr=`pending_nutzaps`,zr=100,Br=6e4;async function Vr(e,t,n){let r=null;try{r=localStorage.getItem(Q(n)+Rr)}catch{return[]}if(!r||!e)return[];try{let n=await M(r,e,t,Lr);if(n===null)return[];let i=JSON.parse(n);return Array.isArray(i)?i.filter(e=>{if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.recipientPubkey==`string`&&typeof t.mintUrl==`string`&&typeof t.amount==`number`&&Number.isInteger(t.amount)&&t.amount>0&&typeof t.timestamp==`number`&&Number.isFinite(t.timestamp)&&typeof t.attempts==`number`&&Number.isInteger(t.attempts)&&t.attempts>=0&&Array.isArray(t.sendProofs)}):[]}catch{return[]}}async function Hr(e,t,n,r){if(!(!t||!e?.id))return Rn(async()=>{let i=(await Vr(t,n,r)).filter(t=>t.id!==e.id);i.push(e),i.sort((e,t)=>t.timestamp-e.timestamp);let a=i.slice(0,zr),o=await j(JSON.stringify(a),t,Lr);try{localStorage.setItem(Q(r)+Rr,o)}catch(e){throw _n(e)&&hn(),Error(`Failed to save pending Nutzap: ${e instanceof Error?e.message:String(e)}`)}},r)}async function Ur(e,t,n,r){if(!(!t||!e))return Rn(async()=>{let i=await Vr(t,n,r),a=i.filter(t=>t.id!==e);if(a.length===i.length)return;let o=await j(JSON.stringify(a),t,Lr);try{localStorage.setItem(Q(r)+Rr,o)}catch(e){throw _n(e)&&hn(),Error(`Failed to remove pending Nutzap: ${e instanceof Error?e.message:String(e)}`)}},r)}function Wr(e,t=Date.now()){if(!e.lastAttemptAt)return 0;let n=e.lastAttemptAt+Br-t;return n>0?n:0}async function Gr(e){let t={deleted:!0,blocked:!1},n=[`freedomid_`,`freedomid-`,`freedom-id:`,`pets:cashu:`,`2140_`,`bao_faucet_claimed_`],r=new Set([`pwa-ios-prompt-dismissed`]);try{if(typeof localStorage<`u`){let e=[];for(let t=0;t<localStorage.length;t++){let i=localStorage.key(t);i&&(n.some(e=>i.startsWith(e))||r.has(i))&&e.push(i)}e.forEach(e=>{try{localStorage.removeItem(e)}catch{}})}}catch{}try{if(typeof indexedDB<`u`){let e=!1;await new Promise((t,n)=>{let r=indexedDB.deleteDatabase(`FreedomID`);r.onsuccess=()=>t(),r.onerror=()=>n(r.error),r.onblocked=()=>{e=!0,t()}}),e&&(t.deleted=!1,t.blocked=!0,w.warn(`IndexedDB deleteDatabase was blocked; data may still be present in other tabs`))}}catch{t.deleted=!1}return t}function Kr(e){return{canWriteLocalStorage:()=>mn(e),resetCanWriteLocalStorageCache:()=>hn(),withProofLock:t=>Ln(t,e),withTxLock:t=>Rn(t,e),assertProofLockOwnership:()=>zn(e),loadMintCounter:t=>Vn(t,e),saveMintCounter:(t,n)=>Hn(t,n,e),writePendingMint:(t,n,r)=>Gn(t,n,r,e),loadPendingMint:(t,n,r)=>Kn(t,n,r,e),clearPendingMint:t=>qn(t,e),loadItem:(t,n)=>
1Zn(t,n,e),setItem:(t,n)=>Qn(t,n,e),migrateMintMetadata:(t,n)=>rr(t,n,e),loadCustomMints:(t,n)=>ir(t,n,e),saveCustomMints:(t,n)=>ar(t,n,e),loadSelectedMintUrl:(t,n)=>or(t,n,e),saveSelectedMintUrl:(t,n)=>sr(t,n,e),mintStorageKey:t=>cr(t,e),getProofsForMint:(t,n,r)=>lr(t,n,r,e),saveProofsForMint:(t,n,r)=>dr(t,n,r,e),isValidTransaction:e=>pr(e),loadTransactions:(t,n,r)=>hr(t,n,r,e),loadTransactionsSync:t=>gr(t,e),saveTransactions:(t,n)=>_r(t,n,e),migratePlaintextTransactions:(t,n)=>vr(t,n,e),addTransaction:(t,n,r,i)=>yr(t,n,r,i,e),updateTransactionStatus:(t,n,r,i,a)=>xr(t,n,r,i,a,e),loadProcessedTokenHashes:(t,n)=>Er(t,n,e),isProcessedTokenHash:(t,n,r)=>Dr(t,n,r,e),addProcessedTokenHash:(t,n,r)=>kr(t,n,r,e),saveProcessedTokenHashes:(t,n)=>Or(t,n,e),loadProcessedNutzapIds:(t,n)=>Pr(t,n,e),isProcessedNutzapId:(t,n,r)=>Fr(t,n,r,e),addProcessedNutzapId:(t,n,r)=>Ir(t,n,r,e),loadPendingNutzaps:(t,n)=>Vr(t,n,e),savePendingNutzap:(t,n,r)=>Hr(t,n,r,e),removePendingNutzap:(t,n,r)=>Ur(t,n,r,e),pendingNutzapCooldownRemaining:(e,t)=>Wr(e,t),writeProofStoreTimestamp:t=>Qt(t,e),writeProofRecovery:(t,n,r)=>W(t,n,r,e),clearProofRecovery:t=>$t(t,e),loadProofRecovery:(t,n,r)=>en(t,n,r,e),writeSendRecovery:(t,n,r)=>G(t,n,r,e),clearSendRecovery:t=>tn(t,e),loadSendRecovery:(t,n,r)=>K(t,n,r,e),writeMeltChangeRecovery:(t,n,r)=>q(t,n,r,e),clearMeltChangeRecovery:t=>nn(t,e),loadMeltChangeRecovery:(t,n,r)=>rn(t,n,r,e),writeMeltInputRecovery:(t,n,r)=>an(t,n,r,e),clearMeltInputRecovery:t=>on(t,e),loadMeltInputRecovery:(t,n,r)=>J(t,n,r,e),loadMintedQuotes:(t,n)=>Y(t,n,e),writeMintedQuote:(t,n,r)=>sn(t,n,r,e),saveMintedQuotes:(t,n,r)=>X(t,n,r,e),loadPendingReceive:(t,n,r)=>un(t,n,r,e),clearPendingReceive:t=>dn(t,e),writePendingReceive:(t,n,r,i,a,o,s)=>Z(t,n,r,i,a,o,s,e),wipeAllAppData:()=>Gr()}}var qr=1440*60,Jr=3600;function Yr(e){if(typeof e!=`string`)return null;let t=e.toLowerCase();return/^[0-9a-f]{64}$/.test(t)?t:/^0[23][0-9a-f]{64}$/.test(t)?t.slice(2):null}function Xr(e){return`02`+e}function Zr(e){let t=Yr(e.partyAPubkey),n=Yr(e.partyBPubkey),r=Yr(e.operatorPubkey),i=Yr(e.refundPubkey);if(!t||!n||!r||!i)throw Error(`Invalid escrow pubkey`);if(new Set([t,n,r]).size!==3)throw Error(`Escrow parties and operator must be three distinct keys`);if(i!==t&&i!==n)throw Error(`Refund key must be one of the two escrow parties`);
1if(!Number.isSafeInteger(e.locktime)||e.locktime<=0)throw Error(`Invalid escrow refund locktime`);return{pubkey:[t,n,r].sort().map(Xr),requiredSignatures:2,locktime:e.locktime,refundKeys:[Xr(i)]}}function Qr(e){if(typeof e!=`string`)return null;try{let t=JSON.parse(e);if(!Array.isArray(t)||t.length<2||t[0]!==`P2PK`)return null;let n=t[1],r=null,i=[];if(typeof n==`string`)r=n,i=t.slice(2);else if(n&&typeof n==`object`&&!Array.isArray(n)){let e=n;if(typeof e.data!=`string`||(r=e.data,e.tags!==void 0&&!Array.isArray(e.tags)))return null;i=e.tags??[]}else return null;let a=Yr(r);if(!a)return null;let o=[],s=[],c,l=1,u=1;for(let e of i){if(!Array.isArray(e)||e.length===0||typeof e[0]!=`string`)return null;let[,...t]=e;switch(e[0]){case`pubkeys`:if(o=t.map(e=>Yr(typeof e==`string`?e:null)??``),o.some(e=>!e))return null;break;case`refund`:if(s=t.map(e=>Yr(typeof e==`string`?e:null)??``),s.some(e=>!e))return null;break;case`locktime`:{let e=Number(t[0]);if(!Number.isSafeInteger(e)||e<=0)return null;c=e;break}case`n_sigs`:{let e=Number(t[0]);if(!Number.isSafeInteger(e)||e<1)return null;l=e;break}case`n_sigs_refund`:{let e=Number(t[0]);if(!Number.isSafeInteger(e)||e<1)return null;u=e;break}default:break}}return{lockKeys:[a,...o].sort(),requiredSignatures:l,locktime:c,refundKeys:s,requiredRefundSignatures:u}}catch{return null}}function $r(e){let t=$e(e);return t&&t.length>0?t:null}function ei(e){return F(e)??e.trim().replace(/\/+$/,``)}function ti(e,t){let n=(e,t=0)=>({valid:!1,reason:e,amount:t}),r=$r(e);if(!r)return n(`Token is empty or invalid`);let i=r.reduce((e,t)=>e+t.amount,0);if(i<=0)return n(`Token is empty or invalid`);if(i!==t.expectedAmount)return n(`Token amount ${i} does not match expected ${t.expectedAmount}`,i);let a=Yr(t.partyAPubkey),o=Yr(t.partyBPubkey),s=Yr(t.operatorPubkey),c=Yr(t.depositorPubkey);if(!a||!o||!s||!c)return n(`Escrow pubkeys are not configured`,i);let l=[a,o,s].sort().join(`,`);if(t.allowedMints&&t.allowedMints.length>0){let e=new Set(t.allowedMints.map(ei));for(let t of r)if(!e.has(ei(t.mintUrl)))return n(`Token mint ${t.mintUrl} is not the agreed escrow mint`,i)}for(let e of r)for(let r of e.proofs){let e=Qr(r.secret);if(!e)return n(`Deposit proof is not a multisig P2PK lock`,i);if(e.lockKeys.length!==3||e.lockKeys.join(`,`)!==l)return n(`Deposit is not locked to the two players and the escrow operator`,i);if(e.requiredSignatures!==2)return n(`Deposit does not require two-of-three signatures`,i);if(e.refundKeys.length!==1||e.refundKeys[0]!==c)return n(`Deposit refund key is not the depositor — the stake could be reclaimed by someone else`,i);
1if(e.locktime===void 0||e.locktime<t.minLocktime)return n(`Deposit refund locktime is missing or too soon`,i)}return{valid:!0,amount:i}}function ni(e){let t=$r(e);if(!t)return null;let n=null;for(let e of t)for(let t of e.proofs){let e=Qr(t.secret);if(!e||e.locktime===void 0)return null;n=n===null?e.locktime:Math.min(n,e.locktime)}return n}var ri=12e4;function ii(e){if(!e||typeof e!=`object`)return null;let t=e.nuts;if(!t||typeof t!=`object`)return null;let n=t[19];if(!n||typeof n!=`object`)return null;let{ttl:r,cached_endpoints:i}=n;if(!Number.isSafeInteger(r)||r<=0||!Array.isArray(i))return null;let a=new Set;for(let e of i){if(!e||typeof e!=`object`)continue;let t=e.method,n=e.path;typeof t==`string`&&typeof n==`string`&&n.startsWith(`/`)&&a.add(`${t.toUpperCase()} ${n}`)}return a.size>0?{ttl:r,endpoints:a}:null}function ai(e,t){if(!P(e))return!1;if(t.length===0)return!0;try{let n=new URL(e);return t.some(e=>{try{let t=new URL(e),r=t.pathname.replace(/\/+$/,``),i=n.pathname.toLowerCase(),a=r.toLowerCase(),o=i===a||i.startsWith(a+`/`);return n.protocol===t.protocol&&n.host.toLowerCase()===t.host.toLowerCase()&&o}catch{return!1}})}catch{return!1}}function oi(e){let t=null;return async function(n){let{endpoint:r,requestBody:i,headers:a,...o}=n;if(!ai(r,e))throw Error(`Mint URL is not allowed: ${r}`);let s=i?JSON.stringify(i):void 0,c=(o.method??`GET`).toUpperCase(),l=new URL(r).pathname,u=()=>t!==null&&[...t.endpoints].some(e=>{let t=e.indexOf(` `),n=e.slice(0,t),r=e.slice(t+1);return n===c&&(l===r||l.endsWith(r))}),d={Accept:`application/json, text/plain, */*`,...s?{"Content-Type":`application/json`}:void 0,...a},f=async()=>fetch(r,{...o,method:c,headers:d,body:s,signal:o.signal??AbortSignal.timeout(ri),redirect:`manual`}),p=!1,m;for(;;)try{m=await f();break}catch(e){if(!p&&!o.signal&&u()){p=!0;continue}throw e&&typeof e==`object`&&e.name===`AbortError`?Error(`Mint request was aborted`):(w.warn(`Mint network request failed:`,r,e),Error(e instanceof Error?e.message:`Network request failed`))}if(m.status>=300&&m.status<400)throw Error(`Mint redirect blocked (${m.status})`);if(!m.ok){let e;try{let t=await m.json();e=t&&typeof t.detail==`string`&&t.detail||t&&typeof t.error==`string`&&t.error||`HTTP ${m.status}`}catch{e=`HTTP ${m.status}`}throw Error(e)}for(;;)try{let e=await m.json(),n=ii(e);return n&&(t=n),e}catch(e){if(!p&&!o.signal&&u()){p=!0;try{m=await f()}catch(e){throw w.warn(`Mint NUT-19 replay failed:`,r,e),Error(e instanceof Error?e.message:`Network request failed`)}if(!m.ok)throw Error(`HTTP ${m.status}`);continue}throw w.warn(`Mint returned non-JSON response:`,r,e),Error(`Mint returned an invalid response`)}}}var si=30078,ci=`mint-list`,li=new TextEncoder().encode(`cashu-mint-backup`),ui=100;function di(e){let t=x(e),n=new Uint8Array(t.length+li.length);return n.set(t),n.set(li,t.length),p(n)}function fi(e){return[...new Set(e.map(I).filter(e=>e&&P(e)))].slice(0,ui)}async function pi(e,t,n=`2140.wtf`){let r=ft(di(e)),i=await r.nip44Encrypt(r.pubkey,JSON.stringify({mints:fi(t),timestamp:Math.floor(Date.now()/1e3)}));if(!i)throw Error(`Could not encrypt NUT-27 mint backup`);let a=await r.signEvent({kind:si,created_at:Math.floor(Date.now()/1e3),tags:[[`d`,ci],[`client`,n]],content:i});if(!a)throw Error(`Could not sign NUT-27 mint backup`);return a}async function mi(e,t){let n=di(e),i=ft(n),a={kinds:[si],authors:[r(n)],"#d":[ci],limit:5},o=(await t.query(a)).filter(e=>e.kind===30078&&e.pubkey===i.pubkey&&e.tags.some(([e,t])=>e===`d`&&t===`mint-list`)).sort((e,t)=>t.created_at-e.created_at);for(let e of o){let t=await i.nip44Decrypt(i.pubkey,e.content);if(t)try{let e=JSON.parse(t);if(Array.isArray(e.mints)&&e.mints.every(e=>typeof e==`string`))return fi(e.mints)}catch{}}return[]}function hi(e,t,n=5e4){if(!Number.isSafeInteger(e)||e<=0||e%1e3!=0)throw Error(`NUT-15 requires a positive whole-sat BOLT11 amount`);if(!Number.isSafeInteger(n)||n<0||n>1e6)throw Error(`Invalid NUT-15 fee reserve`);let r=t.filter(e=>Number.isSafeInteger(e.balanceSats)&&e.balanceSats>1).map(e=>({...e,capacity:Math.floor(e.balanceSats*1e6/(1e6+n))})).filter(e=>e.capacity>0).sort((e,t)=>
1t.capacity-e.capacity||e.mintUrl.localeCompare(t.mintUrl)).slice(0,4),i=e/1e3;if(r.length<2)throw Error(`NUT-15 requires balances at two supported mints`);let a=2;for(;a<r.length&&r.slice(0,a).reduce((e,t)=>e+t.capacity,0)<i;)a++;let o=r.slice(0,a);if(o.reduce((e,t)=>e+t.capacity,0)<i)throw Error(`Combined NUT-15 mint balances are insufficient after fee reserves`);let s=i;return o.map((e,t)=>{let n=o.length-t-1,r=t===o.length-1?s:Math.min(e.capacity,s-n);if(!Number.isSafeInteger(r)||r<=0)throw Error(`Unable to allocate a positive amount to every NUT-15 leg`);return s-=r,{mintUrl:e.mintUrl,amountSats:r,amountMsats:r*1e3,balanceSats:e.balanceSats}})}var gi=`wss://relay.bao.network`,_i=new Set([`UNSPENT`,`PENDING`,`SPENT`]),vi=12e4,yi=10080*60*1e3,bi=5,xi=(e,t)=>{try{let n=localStorage.getItem(`${t}proof_store_ts_${Se(e)}`),r=n?Number(n):NaN;return Number.isFinite(r)&&r>0?r:0}catch{return 0}};async function Si(e){for(;e.current;)await e.current;let t=()=>{},n=new Promise(r=>{t=()=>{e.current===n&&(e.current=null),r()}});return e.current=n,t}function Ci(e){return e.trim().toLowerCase().replace(/\/+$/,``)}async function wi(e,t){return(await Promise.allSettled(t.map(async t=>{let n=new u(t);try{return await n.event(e,{signal:AbortSignal.timeout(8e3)}),t}finally{try{await n.close()}catch{}}}))).flatMap(e=>e.status===`fulfilled`?[e.value]:[])}var Ti=`cleared`;function Ei(e,t){let{config:n}=f(),{isEnabled:r}=y(),o=r(`nutzaps`),s=(0,C.useRef)(o),l=t?.defaultMints,u=(0,C.useMemo)(()=>l??Ce,[JSON.stringify(l)]),d=(0,C.useMemo)(()=>t?.deriveWalletKey??Ve,[t?.deriveWalletKey]);t?.walletLabel;let p=t?.enabled!==!1,m=t?.nip60SyncEnabled!==!1,[_,v]=(0,C.useState)(null),[b,x]=(0,C.useState)(u[0]?.url||``),[ee,S]=(0,C.useState)([]),te=`${t?.storageNamespace??`freedomid_`}removed_default_mints_${t?.preferenceScope??`anonymous`}`,[ne,re]=(0,C.useState)(()=>{try{let e=JSON.parse(localStorage.getItem(te)??`[]`);return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}catch{return[]}}),[ce,le]=(0,C.useState)(null),[fe,pe]=(0,C.useState)({}),[me,he]=(0,C.useState)(0),[ge,_e]=(0,C.useState)([]),[ve,ye]=(0,C.useState)([]),[be,xe]=(0,C.useState)(`idle`),[Se,Te]=(0,C.useState)(`idle`),[Ee,De]=(0,C.useState)(null),Oe=(0,C.useRef)(``),T=(0,C.useRef)(null),E=(0,C.useRef)(null),D=(0,C.useRef)(null),ke=()=>{let e=E.current;if(!e)throw Error(`Wallet not initialized`);return e},Ae=()=>{let e=T.current;if(!e)throw Error(`Wallet seed not available`);return e},[Me,Ne]=(0,C.useState)(!1),[Pe,Fe]=(0,C.useState)(!1),[Le,O]=(0,C.useState)(!1),[He,k]=(0,C.useState)(``),[We,Ge]=(0,C.useState)(``),Ke=(0,C.useRef)(0),qe=(0,C.useRef)(null),A=(0,C.useRef)(!0),j=(0,C.useRef)(null),M=(0,C.useRef)(new Map),Je=(0,C.useRef)(t?.backupCashuState),Ye=(0,C.useRef)(t?.restoreCashuState),N=(0,C.useRef)(t?.nip60Sync),Xe=(0,C.useRef)(t?.baoWalletConfig);(0,C.useEffect)(()=>{Je.current=t?.backupCashuState},[t?.backupCashuState]),(0,C.useEffect)(()=>{Ye.current=t?.restoreCashuState},[t?.restoreCashuState]),(0,C.useEffect)(()=>{N.current=t?.nip60Sync},[t?.nip60Sync]),(0,C.useEffect)(()=>{Xe.current=t?.baoWalletConfig},[t?.baoWalletConfig]);let L=(0,C.useRef)(t?.storageNamespace??`freedomid_`);(0,C.useEffect)(()=>{L.current=t?.storageNamespace??`freedomid_`},[t?.storageNamespace]);let R=(0,C.useRef)(Kr(t?.storageNamespace??`freedomid_`)),nt=(0,C.useRef)(null),at=(0,C.useRef)(!1),ot=(0,C.useRef)(null),z=(0,C.useRef)(L.current.startsWith(`freedomid_bao_`)),st=(0,C.useRef)(new Set),ct=(0,C.useRef)(!1),lt=(0,C.useRef)(``),ut=(0,C.useRef)(0),dt=(0,C.useRef)(null),vt=(0,C.useRef)(new Set),St=(0,C.useRef)(!1),Ct=(0,C.useRef)(null),At=(0,C.useRef)(async()=>{}),Mt=(0,C.useRef)(b),zt=(0,C.useRef)(ee),Vt=(0,C.useRef)(null),Wt=(0,C.useRef)(async()=>0),Gt=(0,C.useRef)(t?.sendTimeoutMs??6e4);(0,C.useEffect)(()=>{Gt.current=t?.sendTimeoutMs??6e4},[t?.sendTimeoutMs]),(0,C.useEffect)(()=>{Mt.current=b},[b]),(0,C.useEffect)(()=>{zt.current=ee},[ee]),(0,C.useEffect)(()=>{Vt.current=_},[_]),(0,C.useEffect)(()=>{let e=E.current;e&&R.current.saveCustomMints(ee,e).catch(e=>w.error(`Failed to persist custom mints:`,e))},[ee]),(0,C.useEffect)(()=>{try{localStorage.setItem(te,JSON.stringify(ne))}catch{}},[ne,te]);let B=e=>e.reduce((e,t)=>
1e+(Number.isInteger(t?.amount)&&t.amount>0?t.amount:0),0),Kt=e=>{if(typeof e!=`string`||!e.startsWith(`[`)&&!e.startsWith(`{`))return null;try{let t=JSON.parse(e),n=Array.isArray(t)&&t[0]===`P2PK`?typeof t[1]==`string`?t[1]:t[1]&&typeof t[1]==`object`&&typeof t[1].data==`string`?t[1].data:null:t&&typeof t==`object`&&!Array.isArray(t)&&typeof t.pubkey==`string`?t.pubkey:null;if(typeof n!=`string`)return null;let r=n.toLowerCase();return/^([0-9a-f]{64}|0[23][0-9a-f]{64})$/.test(r)?r:null}catch{return null}},qt=(0,C.useCallback)(e=>{let t=Kt(e?.secret);if(!t)return!0;let n=t.length===66?t.slice(2):t;return[nt.current?.pubkey,Ct.current?.pubkey].filter(e=>typeof e==`string`).map(e=>e.length===66?e.slice(2):e).includes(n)},[]),V=e=>{let t=new Set;return e.filter(e=>{if(!e||!e.C)return!1;let n=String(e.C);return t.has(n)?!1:(t.add(n),!0)})},H=e=>Array.isArray(e)?e.filter(e=>{if(!e||typeof e!=`object`||typeof e.amount!=`number`)return!1;let t=e.amount;return Number.isInteger(t)&&t>0&&t<=2**53-1&&typeof e.C==`string`&&e.C.length>0&&e.C.length<=4096&&typeof e.secret==`string`&&e.secret.length>0&&e.secret.length<=4096&&typeof e.id==`string`&&e.id.length>0&&e.id.length<=4096&&(e.witness===void 0||typeof e.witness==`string`&&e.witness.length<=4096)}):[],Jt=(0,C.useCallback)(async()=>{let e=E.current,t=Vt.current;if(!e||!t)return;let n=[];try{for(let e=0;e<localStorage.length;e++){let t=localStorage.key(e);t&&t.startsWith(`${L.current}receive_pending_`)&&n.push(t)}}catch{return}for(let t of n){let n=``;try{let e=t.slice((L.current+`receive_pending_`).length);n=atob(e)}catch{continue}let r=await R.current.loadPendingReceive(n,e,D.current??void 0);if(!r||r.status!==`pending`){R.current.clearPendingReceive(n);continue}if(Date.now()-r.timestamp>yi){w.warn(`Pending receive entry expired, clearing:`,n),R.current.clearPendingReceive(n);continue}if(r.attempts>=bi){w.warn(`Pending receive exceeded max attempts, clearing:`,n),R.current.clearPendingReceive(n);continue}r.attempts+=1;try{await R.current.writePendingReceive(r.tokenStr,n,r.mintUrls,r.amount,e,r.succeededMintUrls,r.attempts)}catch{continue}w.log(`Re-attempting pending receive:`,n,`attempt`,r.attempts);try{await Wt.current(r.tokenStr)}catch(e){w.warn(`Pending receive re-attempt failed:`,n,e)}}},[]),Yt=(0,C.useRef)(async()=>{});Yt.current=async e=>{let t=E.current,n=T.current;if(!t)return;let r=I(e),i=await R.current.loadMeltInputRecovery(r,t,D.current??void 0),a=!1;if((!i||i.proofs.length===0)&&(i=await R.current.loadProofRecovery(r,t,D.current??void 0),a=!0),!i||i.proofs.length===0)return;let o=n,s=i.proofs;if(o)try{s=await on(r,s,o)}catch(e){w.warn(`Could not verify melt input proofs during async recovery:`,r,e);return}let c=new Set(s.map(e=>String(e?.secret))),l=o?i.proofs.filter(e=>!c.has(String(e?.secret))):[],u=await Si(dt);try{await R.current.withProofLock(async()=>{let e=V([...H(await R.current.getProofsForMint(r,t,D.current??void 0)),...s]);await R.current.saveProofsForMint(r,e,t),R.current.writeProofStoreTimestamp(r),a&&R.current.clearProofRecovery(r),l.length>0?await R.current.writeMeltInputRecovery(r,l,t):R.current.clearMeltInputRecovery(r),R.current.clearMeltChangeRecovery(r)})}finally{u()}await Z()};let Xt=(e,t)=>{let n=new Set;return e.filter(e=>{let r=t(e);return n.has(r)?!1:(n.add(r),!0)})},U=(e,t,n,r)=>{let i;return Promise.race([e.finally(()=>clearTimeout(i)),new Promise((a,o)=>{i=setTimeout(()=>{if(w.warn(`${n} timed out after ${t}ms`),r){let n=!1,i=()=>{if(!n){n=!0;try{r()}catch(e){w.error(`Timeout recovery callback failed:`,e)}}};e.then(i,i),setTimeout(i,Math.max(1,vi-t)+5e3)}o(Error(`${n} timed out — please try again`))},t)})])},Zt=async()=>Si(dt),Qt=(0,C.useMemo)(()=>Xt([...u.filter(e=>!ne.includes(I(e.url))),...ee],e=>I(e.url)),[ee,u,ne]),W=(0,C.useRef)(Qt);(0,C.useEffect)(()=>{W.current=Qt},[Qt]);let $t=(0,C.useRef)(!1),en=(0,C.useCallback)(async()=>{if($t.current||!Je.current||!E.current||!T.current)return;let e=ke(),t=Ae(),n=W.current,r=Mt.current,i=zt.current;if(!(!e||!t)){$t.current=!0;try{xe(`syncing`);let t=[],a=[];await R.current.withProofLock(async()=>{await R.current.withTxLock(async()=>{for(let r of n)try{let n=H(await R.current.getProofsForMint(I(r.url),e,D.current??void 0));n.length>0&&t.push({mintUrl:r.url,proofs:n}
1)}catch(e){w.warn(`Failed to read proofs for backup:`,r.url,e)}a=await R.current.loadTransactions(e,D.current??void 0)})});let o=[],s=[];try{o=await R.current.loadMintedQuotes(e,D.current??void 0)}catch(e){w.warn(`Failed to read minted quotes for backup:`,e)}try{s=await R.current.loadProcessedTokenHashes(e,D.current??void 0)}catch(e){w.warn(`Failed to read processed token hashes for backup:`,e)}let c={version:2,timestamp:Date.now(),epoch:0,mints:n.map(e=>e.url),proofs:t,transactions:a,selectedMintUrl:r,customMints:i.map(e=>({name:e.name,url:e.url})),nutzapPubkey:Ct.current?.pubkey,mintedQuoteIds:o,processedTokenHashes:s},l=await Je.current(c);A.current&&(l?(xe(`synced`),De(Date.now())):xe(`failed`))}catch(e){w.error(`Auto-backup failed:`,e),A.current&&xe(`failed`)}finally{$t.current=!1}}},[]),G=(0,C.useCallback)(async()=>{let e=E.current,n=T.current;if(!t?.backupCashuState||!e||!n){j.current&&clearTimeout(j.current),j.current=null;return}j.current&&clearTimeout(j.current),j.current=setTimeout(()=>{A.current&&en()},3e3)},[t?.backupCashuState,en]),tn=(0,C.useCallback)(async()=>{j.current&&=(clearTimeout(j.current),null),await en()},[en]);(0,C.useEffect)(()=>{A.current=!0,$t.current=!1;let e=M.current,t=()=>{tn()};return typeof window<`u`&&window.addEventListener(`beforeunload`,t),()=>{A.current=!1,tn(),qe.current&&clearTimeout(qe.current),j.current&&clearTimeout(j.current),e.clear(),typeof window<`u`&&window.removeEventListener(`beforeunload`,t)}},[tn]);let K=(e,t=3e3)=>{A.current&&(Ge(e),qe.current&&clearTimeout(qe.current),qe.current=setTimeout(()=>{A.current&&Ge(``)},t))};(0,C.useEffect)(()=>{b&&E.current&&R.current.saveSelectedMintUrl(b,E.current).catch(e=>w.error(`Failed to persist selected mint:`,e))},[b]),(0,C.useEffect)(()=>{let e=E.current;if(!e)return;let t=!1;return(async()=>{try{await R.current.migrateMintMetadata(e,D.current??void 0);let[n,r]=await Promise.all([R.current.loadSelectedMintUrl(e,D.current??void 0),R.current.loadCustomMints(e,D.current??void 0)]);if(t)return;n&&x(n),r.length>0&&S(r),await R.current.migratePlaintextTransactions(e,D.current??void 0);let i=await R.current.loadTransactions(e,D.current??void 0);if(t)return;_e(i)}catch(e){w.error(`Failed to load encrypted wallet metadata:`,e)}})(),()=>{t=!0}},[]),(0,C.useEffect)(()=>{if(!p)return;let t=!1;return(async()=>{if(e){let n=e.trim();lt.current!==n&&(M.current.clear(),lt.current=n),Oe.current=n;let r,i;try{r=Re(n),i=await ze(n),D.current=await Ue(n)}catch(e){w.error(`Invalid wallet seed:`,e),A.current&&(k(`Invalid recovery phrase`),v(null),T.current&&T.current.fill(0),T.current=null,E.current=null,pe({}),he(0),le(null));return}if(t)return;T.current=r,E.current=i;try{Ct.current=Be(n)}catch(e){w.warn(`Failed to derive nutzap key:`,e),Ct.current=null}try{nt.current=d(n)}catch(e){w.warn(`Failed to derive NIP-60 wallet key:`,e),nt.current=null}try{let e=await R.current.loadProcessedTokenHashes(i,D.current??void 0);for(let t of e)vt.current.add(t.hash)}catch{}try{let e=await R.current.loadProcessedNutzapIds(i,D.current??void 0);for(let t of e)st.current.add(t.id)}catch{}if(await pn(r,i),t)return;try{let e=await R.current.loadTransactions(i,D.current??void 0);if(t)return;A.current&&_e(e)}catch(e){w.error(`Transaction load failed:`,e)}if(!t&&N.current&&nt.current&&!z.current){A.current&&Te(`verifying`);try{let e=await R.current.loadCustomMints(i,D.current??void 0),t=W.current;if(W.current=Xt([...u,...e],e=>I(e.url)),!at.current){await fn();let e=await mi(Oe.current,N.current);if(e.length>0){let t=await R.current.loadCustomMints(i,D.current??void 0),n=e.map(e=>({name:new URL(e).hostname,url:e,custom:!0})),r=Xt([...t,...n],e=>I(e.url));await R.current.saveCustomMints(r,i),S(r),W.current=Xt([...u,...r],e=>I(e.url))}at.current=!0}let n=await ln(),r=await cn();s.current?await un():await dn(),W.current=t,A.current&&Te(n&&r?`verified`:`failed`)}catch(e){w.error(`NIP-60 init sync failed:`,e),A.current&&Te(`failed`)}}if(!t&&z.current&&m&&N.current)try{await Q(),await ln(),await cn(),s.current&&await un()}catch(e){w.error(`bao.markets NIP-60 init restore failed:`,e)}let a=Ye.current;if(a&&i)try{let e=await R.current.loadCustomMints(i,D.current??void 0),n=[...u,...e],r=await(async()=>{for(let e of n){let n=H(await R.current.getProofsForMint(I(e.url),i,D.current??void 0));if(t)return!1;if(n.length>0)return!0}return!1})();if(t)return;let o=await R.current.loadTransactions(i,D.current??void 0);if(t)return;if(localStorage.getItem(L.current+`restore_attempted`)!==`true`||!r&&o.length===0){w.log(`Attempting relay restore`);let e=await a();try{localStorage.setItem(L.current+`restore_attempted`,`true`)}catch{}if(t)return;if(e&&A.current){if(Array.isArray(e.proofs)&&(await R.current.withProofLock(async()=>{let n=T.current;
1for(let r of e.proofs){if(t)return;if(r&&typeof r.mintUrl==`string`&&r.mintUrl.length>0&&P(r.mintUrl,W.current.map(e=>e.url))&&Array.isArray(r.proofs)&&r.proofs.length>0){let e=I(r.mintUrl),t=H(await R.current.getProofsForMint(e,i,D.current??void 0)),a=H(r.proofs);if(n)try{a=H(V(await an(e,a,n)))}catch(t){w.warn(`Could not verify backed-up proofs, skipping restore for mint:`,e,t);continue}let o=V([...t,...a]);await R.current.saveProofsForMint(e,o,i)}}}),t)||Array.isArray(e.transactions)&&e.transactions.length>0&&(await R.current.withTxLock(async()=>{let n=2**53-1,r=Date.now(),a=e.transactions.filter(e=>R.current.isValidTransaction(e));a=a.filter(e=>e.amount<=n);let o=a.filter(e=>r-e.createdAt>15552e6);o.length>0&&w.warn(`Restore contains ${o.length} transactions older than 180 days`),a=a.slice(0,500);let s=await R.current.loadTransactions(i,D.current??void 0),c=new Set(s.map(e=>e.id)),l=a.filter(e=>!c.has(e.id));if(l.length>0){if(await R.current.saveTransactions([...s,...l],i),t)return;let e=await R.current.loadTransactions(i,D.current??void 0);if(t)return;_e(e)}}),t))return;if(Array.isArray(e.customMints)){let t=e.customMints.filter(e=>e&&typeof e==`object`&&typeof e.url==`string`&&e.url.length>0&&typeof e.name==`string`&&e.name.length>0&&P(e.url));if(t.length>0){let e=Xt([...await R.current.loadCustomMints(i,D.current??void 0),...t],e=>I(e.url));S(e),await R.current.saveCustomMints(e,i)}}if(e.selectedMintUrl){let t=F(e.selectedMintUrl);t&&P(t)?x(t):w.warn(`Restored selected mint URL is not allowed, skipping:`,t)}if(e.version===2&&Array.isArray(e.mintedQuoteIds)&&e.mintedQuoteIds.length>0)try{await R.current.saveMintedQuotes(e.mintedQuoteIds,i)}catch(e){w.warn(`Failed to restore minted quote IDs:`,e)}if(e.version===2&&Array.isArray(e.processedTokenHashes)&&e.processedTokenHashes.length>0)try{let t=await R.current.loadProcessedTokenHashes(i,D.current??void 0),n=new Set(t.map(e=>e.hash)),r=[...t,...e.processedTokenHashes.filter(e=>!!e&&typeof e==`object`&&typeof e.hash==`string`&&typeof e.expiresAt==`number`&&!n.has(e.hash))];await R.current.saveProcessedTokenHashes(r,i)}catch(e){w.warn(`Failed to restore processed token hashes:`,e)}if(t)return;await Z(void 0,i),w.log(`Wallet restored from Nostr relays`),K(`Wallet restored from backup`)}}}catch(e){w.error(`Auto-restore failed:`,e)}}else{if(await tn(),t)return;try{localStorage.removeItem(L.current+`restore_attempted`)}catch{}Oe.current=``,T.current&&T.current.fill(0),T.current=null,Ct.current&&Ct.current.privkey.fill(0),Ct.current=null,E.current=null,v(null),_e([]),pe({}),he(0),le(null),O(!1)}})(),()=>{t=!0}},[e,p,u]),(0,C.useEffect)(()=>{!m||!E.current||!N.current||!Y()||!Oe.current||(async()=>{await ln(),await cn(),s.current?await un():await dn()})()},[Qt,t?.nip60Sync,m]),(0,C.useEffect)(()=>{s.current=o,!(!E.current||!N.current||!Y()||!Oe.current)&&(o?un().catch(e=>w.error(`Nutzap info publish failed:`,e)):dn().catch(e=>w.error(`Nutzap info clear failed:`,e)))},[o]),(0,C.useEffect)(()=>{b&&T.current&&pn(T.current).catch(e=>w.error(`Wallet init effect error:`,e))},[b]),(0,C.useEffect)(()=>{T.current&&E.current&&Z().catch(e=>w.error(`Balance calc effect error:`,e))},[Qt]),(0,C.useEffect)(()=>{let e=E.current;if(!e)return;let t=!1;return(async()=>{try{let n=await R.current.loadTransactions(e,D.current??void 0);if(t)return;let r=Date.now(),i=!1,a=n.map(e=>e.status===`pending`&&e.type===`melt`&&(typeof e.expiresAt==`number`&&e.expiresAt>0?r>e.expiresAt:r-e.createdAt>864e5)?(i=!0,{...e,status:`expired`}):e);i&&!t&&await R.current.withTxLock(async()=>{if(t)return;let n=await R.current.loadTransactions(e,D.current??void 0),r=new Set(n.map(e=>e.id)),i=a.filter(e=>r.has(e.id));i.length>0&&await R.current.saveTransactions(i,e)}),t||await $()}catch(e){w.error(`Pending transaction cleanup failed:`,e)}})(),()=>{t=!0}},[]),(0,C.useEffect)(()=>{if(!E.current||!_)return;let e=!1;return(async()=>{e||await Jt()})(),()=>{e=!0}},[_,Qt,Jt]);let q=(0,C.useCallback)(async(e,t,n=!1)=>{let r=n?[...W.current.map(e=>e.url),e]:W.current.map(e=>e.url);if(!P(e,r))throw Error(`Mint URL is not allowed`);let i=I(e),a=M.current.get(i);if(a)try{return await U(a.loadMint(),15e3,`Mint load`),a}catch{M.current.delete(i)}return a=new se(new ie(e,oi(r)),{bip39seed:t,unit:`sat`}),await U(a.loadMint(),15e3,`Mint load`),M.current.set(i,a),a},[]),nn=(0,C.useCallback)(async(e,t,n,r=!1)=>{let i=await U((await q(e,n,r)).checkProofsStates(t),15e3,`Check proof states`);if(!Array.isArray(i))throw Error(`Invalid proof states response: expected array`);if(i.length!==t.length)throw Error(`Proof state length mismatch: expected ${t.length}, got ${i.length}`);let a=new Map;for(let e of i){if(!e||typeof e!=`object`||typeof e.Y!=`string`||!_i.has(e.state))throw Error(`Invalid proof state entry: ${JSON.stringify(e)}`);a.set(e.Y,e.state)}return a},[q]),rn=(e,t,n)=>{let r=new TextEncoder;return e.filter(e=>{if(!e||typeof e!=`object`||typeof e.secret!=`string`)return!1;let i=oe(r.encode(String(e.secret))).toHex(!0),a=t.get(i);if(!a)throw Error(`Missing state for proof with secret ${String(e.secret).slice(0,20)}`);return n(a)})},an=(0,C.useCallback)(async(e,t,n,r=!1)=>t.length?rn(t,await nn(e,t,n,r),e=>e!==`SPENT`):[],[nn]),on=(0,C.useCallback)(async(e,t,n,r=!1)=>t.length?rn(t,await nn(e,t,n,r),e=>e===`UNSPENT`):[],[nn]),J=(0,C.useCallback)(()=>[`client`,n.clientName??n.appName??`2140`],[n.clientName,n.appName]),Y=(0,C.useCallback)(()=>z.current?ot.current??nt.current:nt.current,[]),sn=(0,C.useCallback)(()=>{let e=Y();return e?ft(e.privkey):null},[Y]),X=(0,C.useCallback)(async(e,t,n,r)=>{if(!m)return;let i=N.current,a=E.current,o=sn();if(!i||!a||!o)return;let s=F(e);if(!s)return;let c=z.current&&i.queryRelays?e=>i.queryRelays([ue],e):i.query,l=z.current&&i.publishToRelays?e=>i.publishToRelays([ue],e):i.publish;try{let e=H(await R.current.getProofsForMint(s,a,D.current??void 0)),i=L.current,u=await yt(s,a,i),d=new Set;u&&d.add(u);let f,p=!1,m=!1,h=mt({mint:s,unit:`sat`,proofs:e});try{let e=await c({kinds:[tt],authors:[o.pubkey],limit:500});for(let t of e){let e=await Dt(t,o);e&&e.mint===s&&(t.id!==u&&d.add(t.id),e.proofs.length>0&&(p=!0),mt({mint:s,unit:`sat`,proofs:e.proofs})===h&&(f=t))}}catch(e){w.warn(`Failed to query remote token events for sync:`,s,e),m=!0}if(e.length===0){(p||m)&&w.warn(`Skipping NIP-60 token publish: local store empty but remote backup state has proofs or is unknown for mint:`,s);return}if(f)return await bt(s,f.id,a,i),await xt(s,h,a,i),f;let g=[...d].filter(e=>e.length===64),_=mt({mint:s,unit:`sat`,proofs:e,del:g.length>
10?g:void 0}),v=await Et(s,e,o,g.length>0?g:void 0,[J()]);if(!v){w.warn(`Failed to build NIP-60 token event for mint:`,s);return}if(!await l(v)){w.warn(`NIP-60 token event publish failed for mint:`,s);return}if(g.length>0){let e=await Ot(g,o,`spent`,[J()]);e&&await l(e).catch(()=>{})}let y=[...r??[],{id:v.id,marker:`created`}];u&&y.push({id:u,marker:`destroyed`});let b=await kt(t,n,s,o,y,[J()]);return b&&await l(b).catch(()=>{}),await bt(s,v.id,a,i),await xt(s,_,a,i),v}catch(e){w.error(`NIP-60 token sync failed for mint:`,s,e);return}},[J,sn,m]),cn=(0,C.useCallback)(async()=>{if(!m)return!1;let e=N.current,t=E.current;if(!e||!t||!sn())return!1;let n=!0;for(let e of W.current){let r=I(e.url),i=H(await R.current.getProofsForMint(r,t,D.current??void 0)),a=await X(r,`in`,0);i.length>0&&!a&&(n=!1)}return n},[sn,m,X]),ln=(0,C.useCallback)(async()=>{if(!m||t?.publishWalletConfig===!1)return!1;let e=N.current,r=E.current,i=Y();if(!e||!r||!i)return!1;try{let t=W.current.map(e=>e.url);if(Oe.current&&!z.current)try{let r=await pi(Oe.current,t,n.clientName??`2140.wtf`);await e.publish(r)}catch(e){w.warn(`NUT-27 mint-list backup failed; NIP-60 sync will continue:`,e)}let a=pt(i.privkey,t),o=Xe.current,s=!z.current&&o?[a,o]:a,c=mt(s),l=L.current,u=z.current&&e.queryRelays?t=>e.queryRelays([ue],t):e.query;try{let t=await u({kinds:[et],authors:[e.signer.pubkey],limit:50});for(let n of t){let t=await Tt(n,e.signer);if((Array.isArray(s)?s:[s]).every(e=>t.some(t=>{let n=e.mints.map(I).sort(),r=t.mints.map(I).sort();return t.privkey===e.privkey&&(t.id??`default`)===(e.id??`default`)&&mt(r)===mt(n)})))return await ht(c,r,l),!0}}catch(e){w.warn(`Could not verify NIP-60 wallet config on relays; republishing:`,e)}let d=await wt(s,e.signer,{extraTags:[J()]});return!d||!(z.current&&e.publishToRelays?await e.publishToRelays([`wss://relay.bao.network`],d):await e.publish(d))?!1:(await ht(c,r,l),!0)}catch(e){return w.error(`NIP-60 wallet config sync failed:`,e),!1}},[n.clientName,J,Y,m,t?.publishWalletConfig]),un=(0,C.useCallback)(async()=>{if(!s.current)return;let e=N.current,t=E.current,n=Y();if(!(!e||!t||!n))try{let r=W.current.map(e=>e.url),i=z.current?[ue]:e.relays,a=mt({pubkey:n.pubkey,mints:r,relays:i}),o=L.current;if(a===await gt(t,o))return;let s=await Pt(r,i,n.pubkey,e.signer,{extraTags:[J()]});if(!s)return;(z.current&&e.publishToRelays?await e.publishToRelays([`wss://relay.bao.network`],s):await e.publish(s))&&await _t(a,t,o)}catch(e){w.error(`NIP-60 Nutzap info publish failed:`,e)}},[J,Y]),dn=(0,C.useCallback)(async()=>{let e=N.current,t=E.current,n=Y();if(!(!e||!t||!n))try{let n=L.current,r=await gt(t,n);if(!r||r===Ti)return;let i=await e.signer.signEvent({kind:it,content:``,tags:[...e.relays.map(e=>[`relay`,e]),J()],created_at:Math.floor(Date.now()/1e3)});if(!i)return;z.current&&e.publishToRelays?await e.publishToRelays([ue],i):await e.publish(i);let a=await e.signer.signEvent({kind:5,content:`nutzap info hidden`,tags:[[`a`,`${it}:${i.pubkey}`],J()],created_at:Math.floor(Date.now()/1e3)});if(!a)return;z.current&&e.publishToRelays?await e.publishToRelays([ue],a):await e.publish(a),await _t(Ti,t,n)}catch(e){w.error(`NIP-60 Nutzap info clear failed:`,e)}},[J,Y]),Z=(0,C.useCallback)(async(e,t)=>{let n=E.current,r=t??n;if(!r)return;let i=++ut.current,a={},o=0;for(let e of Qt)try{let t=I(e.url),n=H(await R.current.getProofsForMint(t,r,D.current??void 0)).reduce((e,t)=>{let n=Number(t.amount);return e+(Number.isInteger(n)&&n>0?n:0)},0);a[t]=n,o+=n}catch{a[I(e.url)]=0}i===ut.current&&A.current&&(pe(a),he(o))},[Qt]),fn=(0,C.useCallback)(async()=>{let e=N.current,t=E.current,n=sn();if(!e||!t||!n)return!1;try{let r=await Bt(n,e.signer,e.query),i=!1,a=await Nt(e.signer,e.query);if(a.length>0){let e=await R.current.loadTransactions(t,D.current??void 0),n=new Set(e.map(e=>e.quoteId).filter(Boolean)),r=T.current;if(r){let e=a.filter(e=>!n.has(e.quoteId)).slice(0,8),o=await Promise.all(e.map(async e=>{try{return{remoteQuote:e,quote:await U((await q(e.mint,r,!0)).checkMintQuote(e.quoteId),15e3,`Restore mint quote`)}}catch(t){return w.warn(`Failed to restore pending NIP-60 mint quote:`,e.mint,t),null}}));for(let e of o){if(!e)continue;let{remoteQuote:r,quote:a}=e,o=Number(a.amount);if(!Number.isSafeInteger(o)||o<=0||typeof a.request!=`string`||!a.request)continue;
1let s=typeof a.expiry==`number`&&a.expiry>0?a.expiry*1e3:r.expiresAt;if(!(s!==void 0&&s<=Date.now()&&a.state===`UNPAID`))try{await R.current.addTransaction({type:`mint`,amount:o,memo:`Lightning deposit`,mintUrl:r.mint,status:`pending`,quoteId:r.quoteId,paymentRequest:a.request,quotePrivateKey:r.quotePrivateKey,quoteEventId:r.eventId,expiresAt:s},t,D.current??void 0),n.add(r.quoteId),i=!0}catch(e){w.warn(`Failed to persist restored NIP-60 mint quote:`,r.mint,e)}}i&&A.current&&_e(await R.current.loadTransactions(t,D.current??void 0))}}if(!r.config)return i;let o=T.current;if(o&&(await R.current.withProofLock(async()=>{for(let[e,n]of Object.entries(r.proofsByMint)){let r=F(e);if(!(!r||n.length===0))try{let e=H(V(await an(r,n,o)));if(e.length===0)continue;let i=V([...H(await R.current.getProofsForMint(r,t,D.current??void 0)),...e]);await R.current.saveProofsForMint(r,i,t)}catch(e){w.warn(`Failed to merge remote NIP-60 proofs for mint:`,r,e)}}}),await Z()),r.config.mints.length>0&&!L.current.startsWith(`freedomid_bao_`)){let e=new Set(W.current.map(e=>I(e.url))),n=r.config.mints.filter(t=>!e.has(t));if(n.length>0){let e=n.filter(e=>P(e));if(e.length>0){let n=Xt([...await R.current.loadCustomMints(t,D.current??void 0),...e.map(e=>({name:e,url:e}))],e=>I(e.url));S(n),await R.current.saveCustomMints(n,t)}}}return!0}catch(e){return w.error(`NIP-60 restore failed:`,e),!1}},[sn,Z,an,q]),Q=(0,C.useCallback)(async()=>{let e=N.current,t=E.current;if(!e?.queryRelays||!t)return!1;try{let{result:n,walletPrivkey:r,walletPubkey:i}=await Ut(e.signer,t=>e.queryRelays([ue],t));if(!n.config||!r||!i)return!1;ot.current={privkey:r,pubkey:i};let a=T.current,o=Object.entries(n.proofsByMint);return o.length>0&&a&&(await R.current.withProofLock(async()=>{for(let[e,n]of o){let r=F(Ht(e));if(!(!r||n.length===0))try{let e=H(V(await an(r,n,a)));if(e.length===0)continue;let i=H(await R.current.getProofsForMint(r,t,D.current??void 0)),o=V([...i,...e]);o.length!==i.length&&await R.current.saveProofsForMint(r,o,t)}catch(e){w.warn(`Failed to merge bao.markets NIP-60 proofs for mint:`,r,e)}}}),await Z()),!0}catch(e){return w.error(`bao.markets NIP-60 restore failed:`,e),!1}},[Z,an]),pn=(0,C.useCallback)(async(e,t)=>{let n=++Ke.current;try{A.current&&O(!0),A.current&&k(``);try{let r=await q(b,e);try{let e=await U(new ie(b,oi(W.current.map(e=>e.url))).getInfo(),15e3,`Mint info`);A.current&&n===Ke.current&&le(e)}catch(e){w.warn(`Mint info failed:`,e),A.current&&n===Ke.current&&le({name:`Unknown Mint`,nuts:{}})}A.current&&n===Ke.current&&(v(r),await Z(void 0,t))}catch(t){w.warn(`Failed to initialize wallet for mint:`,b,t);let r=W.current.find(e=>I(e.url)!==I(b));if(r)try{let t=await q(r.url,e);await U(t.loadMint(),15e3,`Mint load`),A.current&&n===Ke.current&&(v(t),x(I(r.url)),w.log(`Fell back to mint:`,r.url));return}catch(e){w.error(`Fallback mint also failed:`,r.url,e)}A.current&&n===Ke.current&&(v(null),k(`Failed to connect to mint. Please try a different mint.`))}}catch(e){w.error(`Wallet init error:`,e),A.current&&n===Ke.current&&(k(`Failed to connect to mint: ${e.message}`),v(null))}finally{A.current&&n===Ke.current&&O(!1)}},[b,q,Z]),mn=(0,C.useCallback)(async()=>{let e=E.current;if(!e||!_)return;let t=await Si(dt);try{let t=new Set,n=!1;try{let n=await R.current.loadTransactions(e,D.current??void 0);for(let e of n)e.type===`melt`&&e.status===`pending`&&typeof e.quoteId==`string`&&e.quoteId.length>0&&t.add(I(e.mintUrl))}catch(e){n=!0,w.warn(`Could not load transactions for reconcile; skipping proof-recovery journals:`,e)}for(let r of Qt){let i=I(r.url),a=async(t,n,r,a=!1,o=!1)=>{let s=await t();if(!(!s||s.proofs.length===0)){w.warn(`Recovered ${r} for mint`,i);try{let t=T.current,c=H(await R.current.getProofsForMint(i,e,D.current??void 0)),l=xi(i,L.current);if(c.length>0&&s.timestamp<=l){w.warn(`${r} is older than store, clearing stale recovery:`,i),n(i);return}let u=a?s.proofs.filter(qt):s.proofs;if(u.length===0){w.warn(`${r} contains only foreign-locked proofs, leaving journal untouched:`,i);return}let d=[],f=u;if(o&&t){let e=await on(i,u,t),n=new Set(e.map(e=>String(e?.secret)));if(d=u.filter(e=>!n.has(String(e?.secret))),f=e,f.length===0){w.warn(`${r} contains only mint-locked (PENDING) proofs, leaving journal untouched:`,i);return}}await R.current.withProofLock(async()=>{let a=f;if(t)try{a=H(o?await on(i,f,t):await an(i,f,t))}catch(e){w.warn(`${r}: spent-state re-check inside the lock failed; keeping journal for retry:`,e);return}let s=Xt([...H(await R.current.getProofsForMint(i,e,D.current??void 0)),...a],e=>String(e?.secret));await R.current.saveProofsForMint(i,s,e),R.current.writeProofStoreTimestamp(i),d.length>0?await R.current.writeMeltInputRecovery(i,d,e):n(i)})}catch(e){w.error(`Failed to reconcile ${r}:`,e)}}};await a(()=>R.current.loadProofRecovery(i,e,D.current??void 0),R.current.clearProofRecovery,`proof recovery`),await a(()=>R.current.loadSendRecovery(i,e,D.current??void 0),R.current.clearSendRecovery,`send recovery`,!0),await a(()=>R.current.loadMeltChangeRecovery(i,e,D.current??void 0),R.current.clearMeltChangeRecovery,`melt 
1change recovery`),!n&&!t.has(i)&&await a(()=>R.current.loadMeltInputRecovery(i,e,D.current??void 0),R.current.clearMeltInputRecovery,`melt input recovery`,!1,!0)}await Z()}catch(e){w.error(`Proof recovery reconciliation failed:`,e)}finally{t()}},[_,Qt,Z,an,on,qt]);(0,C.useEffect)(()=>{At.current=mn}),(0,C.useEffect)(()=>{if(!E.current||!_)return;let e=!1;return(async()=>{e||await mn()})(),()=>{e=!0}},[_,Qt,mn]);let hn=(0,C.useCallback)(async()=>{if(!Oe.current||!Oe.current.trim())return;let e=Oe.current.trim(),t,n;try{t=Re(e),n=await ze(e),D.current=await Ue(e)}catch(e){w.error(`Invalid seed phrase:`,e),k(`Invalid recovery phrase`);return}M.current.clear(),lt.current=e,A.current&&(T.current=t,E.current=n,Fe(!1),Ne(!1));try{await pn(t,n)}catch(e){A.current&&k(e.message||`Wallet init failed after backup`)}G()},[G,pn]),gn=(0,C.useCallback)(e=>{if(typeof e!=`string`)return;let t=F(e);if(t){if(!P(t,W.current.map(e=>e.url))){w.warn(`Attempted to select a mint that is not allowed:`,t);return}x(t),G()}},[G]),_n=(0,C.useCallback)((e,t)=>{if(typeof e!=`string`||typeof t!=`string`){k(`Invalid mint data`);return}let n=F(t);if(!(!n||!e.trim())){try{if(new URL(n).protocol!==`https:`){k(`Mint URL must use HTTPS`);return}if(!P(n)){k(`Mint host is not allowed (localhost/private networks are blocked)`);return}}catch{k(`Invalid mint URL`);return}if(n.length>2e3){k(`Mint URL too long`);return}if(e.trim().length>100){k(`Mint name too long (max 100 chars)`);return}if(u.some(e=>I(e.url)===n)){re(e=>e.filter(e=>e!==n));return}S(t=>[...u,...t].some(e=>I(e.url)===n)?t:[...t,{name:e.trim(),url:n}]),G()}},[G,u]),vn=(0,C.useCallback)(async(e,t)=>{if(typeof e!=`string`)return k(`Invalid mint URL`),{status:`rejected`};let n=F(e);if(!n)return k(`Invalid mint URL`),{status:`rejected`};let r=u.some(e=>I(e.url)===n),i=E.current;if(!i)return k(`Wallet not initialized`),{status:`rejected`};let a=await Si(dt);try{let e=B(H(await R.current.getProofsForMint(n,i,D.current??void 0)));if(e>0&&t!==e)return{status:`confirmation-required`,balance:e};try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n&&n.startsWith(`${L.current}receive_pending_`)&&e.push(n)}for(let t of e)try{let e=atob(t.slice((L.current+`receive_pending_`).length)),r=await R.current.loadPendingReceive(e,i,D.current??void 0);r&&r.mintUrls.some(e=>I(e)===n)&&await R.current.clearPendingReceive(e)}catch{}}catch{}r?re(e=>e.includes(n)?e:[...e,n]):S(e=>e.filter(e=>I(e.url)!==n)),G(),M.current.delete(n);try{await R.current.withProofLock(async()=>{let e=R.current.mintStorageKey(n);localStorage.removeItem(e),R.current.clearProofRecovery(n),R.current.clearSendRecovery(n),R.current.clearMeltInputRecovery(n),R.current.clearMeltChangeRecovery(n)})}catch(e){w.error(`Failed to clean up mint storage:`,e)}if(pe(e=>{let t={...e};return Object.keys(t).forEach(e=>{I(e)===n&&delete t[e]}),t}),I(b)===n){let e=Qt.find(e=>I(e.url)!==n);e?x(I(e.url)):(x(``),v(null))}return{status:`removed`}}catch(e){return w.error(`Failed to remove custom mint:`,e),k(`Failed to remove mint`),{status:`rejected`}}finally{a()}},[b,Qt,G,u]),$=(0,C.useCallback)(async()=>{let e=E.current,t=await R.current.loadTransactions(e??void 0,D.current??void 0);A.current&&_e(t)},[]),yn=(0,C.useCallback)(async(e,t)=>{let n=E.current,r=T.current;if(typeof e!=`string`||e.trim().length===0)return k(`Invalid Cashu token`),0;if(!_||!r||!n)return k(`Wallet not initialized`),0;let i=await Zt();try{O(!0),k(``);let i=$e(e);if(!i||i.length===0)throw Error(`Invalid Cashu token`);let a=Qe(i);if(vt.current.has(a)||await R.current.isProcessedTokenHash(a,n,D.current??void 0))return w.warn(`Token already processed, skipping:`,a),R.current.clearPendingReceive(a),A.current&&K(`Token already received`),0;let o=[],s=new Map;for(let e of i){if(!e.mintUrl){o.push(`Token entry missing mint URL`),w.error(`Token entry missing mint URL:`,e);continue}let t=I(Ht(e.mintUrl)),n=s.get(t);n?n.proofs.push(...e.proofs):s.set(t,{mintUrl:t,proofs:[...e.proofs]})}let c=await R.current.loadPendingReceive(a,n,D.current??void 0),l=new Set((c?.succeededMintUrls??[]).map(e=>I(Ht(e)))),u=Array.from(s.values()),d=u.map(e=>
1I(e.mintUrl)).filter(Boolean),f=u.reduce((e,t)=>e+B(t.proofs),0);await R.current.writePendingReceive(e,a,d,f,n,[...l]);let p=0;for(let[i,c]of s){if(l.has(i))continue;let s;try{s=ae({mint:i,proofs:c.proofs.map(Ze),unit:`sat`})}catch(e){o.push(`Invalid token entry`),w.error(`Failed to encode token entry:`,e);continue}try{let o=F(b),u=i===o?_:await U(q(i,r,!0),15e3,`Foreign mint load`),m=await R.current.withProofLock(async()=>{let p=H(await R.current.getProofsForMint(i,n,D.current??void 0)),m=B(c.proofs),h=await U(u.receive(s,{proofsWeHave:p,requireDleq:!0,privkey:t}),6e4,`Receive`,()=>setTimeout(()=>At.current(),0)),g=H(h??[]);g.length>0&&await R.current.writeProofRecovery(i,g,n);let _=0;try{_=u.getFeesForProofs(c.proofs)}catch{_=Math.max(1,Math.floor(m*.001))}if(!je(_,m,5e4))throw Error(`Mint fee exceeds maximum allowed`);let v=m-B(g);if(v<0||v>_)throw Error(`Mint returned received proofs with incorrect total amount`);let y=new Set(u.keysets.filter(e=>e.active).map(e=>e.id)),b=Ie(g,{activeKeysetIds:y,localSecrets:new Set(p.map(e=>String(e?.secret))),getKeyset:e=>u.keys.get(e),requireDleq:!0});if(!b.valid)throw Error(b.reason);let ee=await U(an(i,g,r,!0),15e3,`Check received proof states`);if(ee.length!==g.length)throw Error(`Mint returned spent proofs`);g=H(ee);let te=V([...p,...g]);if(await R.current.writeProofRecovery(i,te,n),await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(i,te,n),R.current.writeProofStoreTimestamp(i),R.current.clearProofRecovery(i),i!==o&&P(i)){if(!W.current.map(e=>I(e.url)).includes(i)){let e=(()=>{try{return new URL(i).hostname}catch{return i}})(),t=await R.current.loadCustomMints(n,D.current??void 0);if(!t.some(e=>I(e.url)===i)){let r=[...t,{name:e,url:i,custom:!0}];S(r),await R.current.saveCustomMints(r,n)}}let e=I(Mt.current);e&&e!==i&&B(H(await R.current.getProofsForMint(e,n,D.current??void 0)))===0&&x(i)}await Z();let ne=Array.isArray(h)?h.reduce((e,t)=>e+(Number.isInteger(t?.amount)?t.amount:0),0):0;return await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`receive`,amount:ne,memo:`Cashu token`,mintUrl:i,status:`completed`},n,D.current??void 0)}),await $(),X(i,`in`,ne).catch(e=>{w.warn(`NIP-60 receive sync deferred/failed:`,e)}),l.add(i),await R.current.writePendingReceive(e,a,d,f,n,[...l]),h}),h=Array.isArray(m)?m.reduce((e,t)=>e+(Number.isInteger(t?.amount)?t.amount:0),0):0;p+=h,i!==o&&(W.current.map(e=>I(e.url)).includes(i)||w.warn(`Received token references a mint not in the allowed list:`,i))}catch(e){if(o.push(e?.message||`Failed to receive from mint`),w.error(`Failed to receive token entry:`,c.mintUrl,e),!W.current.map(e=>I(e.url)).includes(i)&&P(i)){w.warn(`Adopting foreign mint after post-swap receive failure so its recovery journal is reconciled:`,i);try{let e=(()=>{try{return new URL(i).hostname}catch{return i}})(),t=await R.current.loadCustomMints(n,D.current??void 0);if(!t.some(e=>I(e.url)===i)){let r=[...t,{name:e,url:i,custom:!0}];S(r),await R.current.saveCustomMints(r,n)}let r=I(Mt.current);r&&r!==i&&B(H(await R.current.getProofsForMint(r,n,D.current??void 0)))===0&&x(i)}catch(e){w.warn(`Failed to adopt foreign mint for recovery:`,e)}}}}if(s.size>0&&l.size===s.size){vt.current.add(a);try{await R.current.addProcessedTokenHash(a,n,D.current??void 0)}catch(e){w.warn(`Failed to persist processed token hash:`,e)}R.current.clearPendingReceive(a)}return A.current&&(o.length>0&&p===0?k(`Failed to receive: ${o[0]}`):o.length>0?K(`Received ${p} sats (some mints failed)`):K(`Received ${p} sats`)),p}catch(e){return w.error(`Receive error:`,e),A.current&&k(`Failed to receive: ${e.message}`),0}finally{i(),A.current&&O(!1),await G()}},[_,b,G,Z,$,q,an,X]);(0,C.useEffect)(()=>{Wt.current=yn},[yn]);let bn=e=>!Number.isInteger(e)||e<=0||e>2**53-1?`Amount must be a positive integer`:null,xn=(0,C.useCallback)(async(e,t=``,n,r,i,a)=>{St.current=!1;let o=E.current,s=T.current,c=bn(e);if(c)return k(c),null;if(typeof t!=`string`)return k(`Memo must be a string`),null;if(t.length>500)return k(`Memo too long (max 500 chars)`),null;if(i&&n)return k(`Cannot combine a single-recipient lock with a multisig escrow lock`),null;if(!s||!o)return k(`Wallet not initialized`),null;
1let l=I(r??b),u=_;if(r)try{u=await q(l,s,!0)}catch(e){return k(`Failed to load mint wallet: ${e.message}`),null}if(!u)return k(`Wallet not initialized`),null;let d=await Si(dt),f=!1;try{O(!0),k(``);let r=await R.current.withProofLock(async()=>{let r=H(await R.current.getProofsForMint(l,o,D.current??void 0)),s=r.reduce((e,t)=>{let n=Number(t.amount);return e+(Number.isInteger(n)&&n>0?n:0)},0);if(s<e)throw Error(`Insufficient balance: ${s} sats available`);let c=l;await R.current.writeProofRecovery(c,r,o);let d={proofsWeHave:r};if(n){let e=n.toLowerCase(),t=/^[0-9a-f]{64}$/.test(e)?`02`+e:/^0[23][0-9a-f]{64}$/.test(e)?e:null;if(!t)throw Error(`Invalid recipient P2PK pubkey`);d.pubkey=t,d.includeDleq=!0}let p=i?Zr(i):null;f=!0;let m=await U(p?u.swap(e,r,{proofsWeHave:r,p2pk:p}):u.send(e,r,d),Gt.current,`Send`,()=>setTimeout(()=>At.current(),0));if(!m||!Array.isArray(m.send)||!Array.isArray(m.keep))throw Error(`Mint returned invalid send response`);let h=H(V(m.send)),g=H(V(m.keep));await R.current.writeProofRecovery(c,g,o),h.length>0&&await R.current.writeSendRecovery(c,h,o);let _=s,v=B(h)+B(g);if(B(h)!==e)throw Error(`Mint returned send proofs with incorrect total amount`);if(v>_)throw Error(`Mint returned invalid proofs: outputs exceed inputs`);let y=new Set(r.map(e=>String(e.secret))),b=!d.pubkey&&h.length>0&&h.every(e=>y.has(String(e.secret)))&&g.every(e=>y.has(String(e.secret))),x=0;try{x=u.getFeesForProofs(r)}catch{x=Math.max(1,Math.floor(_*.001))}if(!b&&!je(x,_,5e4))throw Error(`Mint fee exceeds maximum allowed`);let ee=_-v;if(ee<0||!b&&ee>x)throw Error(`Mint returned invalid proofs: fee exceeds reported fee`);if(!b){for(let e of h)if(y.has(String(e.secret)))throw Error(`Mint returned unspent input proofs as send outputs`)}await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(c,g,o),R.current.writeProofStoreTimestamp(c),R.current.clearProofRecovery(c);let S;try{S=ae({mint:c,proofs:h,memo:t,unit:`sat`})}catch(e){w.error(`Token encoding failed — saving recovery data:`,e);try{await R.current.writeSendRecovery(c,h,o)}catch{}throw Error(`Failed to encode token — your proofs have been saved for recovery`)}if(a)try{localStorage.setItem(a.key,JSON.stringify({token:S,...a.metadata??{},dmState:`failed`}))}catch(e){w.warn(`Failed to persist delivery outbox:`,e)}R.current.clearSendRecovery(c);try{await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`send`,amount:e,memo:t||`Cashu send`,mintUrl:l,status:`completed`},o,D.current??void 0)}),await $()}catch(e){w.error(`Failed to record send transaction:`,e),A.current&&k(`Send succeeded but transaction record failed`)}return await Z(),S});return X(l,`out`,e).catch(e=>{w.warn(`NIP-60 send sync deferred/failed:`,e)}),A.current&&K(`Sent ${e} sats`),r}catch(e){w.error(`Send error:`,e);let t=typeof e?.status==`number`?e.status:null,n=typeof e?.message==`string`&&/not enough (funds|balance)/i.test(e.message);St.current=f&&t===null&&!n;let r=typeof e?.message==`string`&&e.message.includes(`timed out`);return A.current&&k(r?`Send timed out — the mint may still have processed it. Check your balance before sending again; if it decreased, the recovery journal will reconcile automatically.`:`Failed to send: ${e.message}`),null}finally{d(),A.current&&O(!1),await G(),(()=>{try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n&&n.startsWith(L.current+`recovery_`)&&e.push(n)}for(let t of e)try{localStorage.removeItem(t)}catch{}}catch{}})()}},[_,b,q,G,Z,$,X]),Sn=(0,C.useCallback)((e,t,n,r,i)=>xn(e,t,n,r,void 0,i),[xn]),Cn=(0,C.useCallback)(async(e,t,n=``,r)=>{let i=t?.toLowerCase()??``;return!/^[0-9a-f]{64}$/.test(i)&&!/^0[23][0-9a-f]{64}$/.test(i)?(k(`Invalid recipient P2PK pubkey`),null):xn(e,n,t,r)},[xn]),wn=(0,C.useCallback)(async(e,t,n=``,r)=>{try{Zr(t)}catch(e){return k(`Invalid escrow lock: ${e?.message??e}`),null}return xn(e,n,void 0,r,t)},[xn]),Tn=(0,C.useCallback)(async(e,t)=>!t||t.length!==64?(k(`Invalid P2PK private key`),0):yn(e,t),[yn]),En=(0,C.useCallback)(async e=>{let t=Y();return t?yn(e,g(t.privkey)):(k(`Set up your Cashu wallet first — no wallet key to 
1sweep locked tokens`),0)},[Y,yn]),Dn=(0,C.useCallback)(()=>Y()?.pubkey??null,[Y]),On=(0,C.useCallback)(async(e,t=`Freedom ID`)=>{let n=E.current,r=bn(e);if(r)return k(r),null;if(typeof t!=`string`)return k(`Description must be a string`),null;if(t.length>1e4)return k(`Description too long (max 10000 chars)`),null;if(!_||!n)return k(`Wallet not initialized`),null;try{O(!0),k(``);let r=c(),i=g(h.getPublicKey(r,!0)),a=(await _.lazyGetMintInfo()).isSupported(20).supported,o=await U(a?_.createLockedMintQuote(e,i,t):_.createMintQuote(e,t),3e4,`Mint quote creation`);if(a&&(o.pubkey!==i||o.amount!==e||o.unit!==`sat`))throw Error(`Mint returned a mismatched protected quote`);let s=a?g(r):void 0,l=N.current,u=l&&!z.current?await jt(o.quote,b,l.signer,{quotePrivateKey:s,extraTags:[J()]}):null;try{await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`mint`,amount:e,memo:`Lightning deposit`,mintUrl:b,status:`pending`,quoteId:o.quote,paymentRequest:o.request,quotePrivateKey:s,quoteEventId:u?.id,expiresAt:typeof o.expiry==`number`&&o.expiry>0?o.expiry*1e3:void 0},n||void 0,D.current??void 0)}),await $()}catch(e){throw w.error(`Failed to record invoice transaction:`,e),Error(`Invoice created but its recovery key could not be saved; do not pay it`)}return u&&l&&(await l.publish(u)||w.warn(`NIP-60 pending mint quote backup could not be published`)),A.current&&K(`Invoice created. Pay it to receive sats.`,4e3),o}catch(e){return A.current&&k(`Failed to create invoice: ${e.message}`),null}finally{A.current&&O(!1),await G()}},[_,b,G,$,J]),kn=(0,C.useCallback)(async(e,t,n=`bolt11`)=>{if(!_||!e)return()=>{};let r=!1,i=!1,a=()=>{},o=()=>{let e=a;a=()=>{},e()},s=()=>{r||i||(r=!0,o(),t())};try{let t=(await _.lazyGetMintInfo()).isSupported(17),r=`${n}_mint_quote`;if(t.supported&&(t.params??[]).some(e=>e.method===n&&e.unit===`sat`&&e.commands.includes(r))){let t=e=>{w.warn(`NUT-17 mint quote subscription failed; manual confirmation remains available:`,e)};if(n===`bolt11`)a=await _.onMintQuotePaid(e,s,t);else{await _.mint.connectWebSocket();let n=_.mint.webSocketConnection;if(n){let r={kind:`bolt12_mint_quote`,filters:[e]},i=t=>{t.quote===e&&t.amount_paid>t.amount_issued&&s()},o=n.createSubscription(r,i,t);a=()=>n.cancelSubscription(o,i,t)}}}}catch(e){w.warn(`NUT-17 unavailable; manual confirmation remains available:`,e)}let c=async()=>{if(!(r||i))try{if(n===`bolt11`){let t=await _.checkMintQuote(e);(t.state===`PAID`||t.state===`ISSUED`)&&s()}else{let t=await _.checkMintQuoteBolt12(e);t.amount_paid>t.amount_issued&&s()}}catch{}},l=setInterval(()=>void c(),4e3);return c(),()=>{i=!0,clearInterval(l),o()}},[_]),An=(0,C.useCallback)(async(e,t=`2140.wtf Cashu deposit`)=>{let n=bn(e);if(n)return k(n),null;let r=nt.current;if(!_||!E.current||!r)return k(`Wallet not initialized`),null;try{O(!0),k(``);let n=c(),r=g(h.getPublicKey(n,!0)),i=await U(_.createMintQuoteBolt12(r,{amount:e,description:t}),3e4,`BOLT12 offer creation`);if(i.pubkey!==r||i.unit!==`sat`||i.amount!==e)throw Error(`Mint returned a mismatched protected BOLT12 quote`);return await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`mint`,amount:e,memo:`BOLT12 deposit`,mintUrl:b,status:`pending`,quoteId:i.quote,expiresAt:typeof i.expiry==`number`&&i.expiry>0?i.expiry*1e3:void 0,bolt12:!0,paymentRequest:i.request,quotePrivateKey:g(n)},E.current,D.current??void 0)}),await $(),K(`BOLT12 offer created. Pay it to receive sats.`,4e3),i}catch(e){return k(`Failed to create BOLT12 offer: ${e.message}`),null}finally{O(!1),await G()}},[_,b,$,G]),jn=(0,C.useCallback)(async(e,t,n=`bolt11`)=>{let r=E.current,i=T.current,a=bn(t);if(a)return k(a),!1;if(!e||typeof e!=`string`)return k(`Invalid quote ID`),!1;if(!_||!r||!i)return k(`Wallet not initialized`),!1;let o=await Si(dt),s=0,c;try{O(!0),k(``);let a=I(b),o=async(n,i=e,a=t)=>{try{let e=await R.current.loadTransactions(r??void 0,D.current??void 0),t=e.findIndex(e=>e.type===`mint`&&e.status===`pending`&&e.mintUrl===b&&(e.quoteId===i||e.amount===a&&!e.quoteId));t>=0&&(await R.current.updateTransactionStatus(e[t].id,n,r??void 0,D.current??void 0),await $())}catch(e){w.error(`Failed to update pending mint transaction status:`,e)}};await R.current.withProofLock(async()=>{let l=n===`bolt12`?await U(_.checkMintQuoteBolt12(e),15e3,`BOLT12 mint quote check`):null,u=l??await U(_.checkMintQuote(e),15e3,`Mint quote check`),d=await R.current.loadPendingMint(a,r,D.current??void 0),f=l?l.amount_paid-l.amount_issued:0;if(l&&(!Number.isSafeInteger(f)||f<0))throw Error(`Mint reported an invali
1d BOLT12 paid amount (${f}). Contact the mint operator if this persists.`);let p=l?f:t,m=l?d?.quoteId===e?`ISSUED`:f>0?`PAID`:`UNPAID`:u?.state;if(m===`UNPAID`&&u&&typeof u.expiry==`number`&&u.expiry>0&&Date.now()>u.expiry*1e3)throw await o(`expired`),Error(`Mint quote has expired. Create a new invoice.`);if(m===`UNPAID`)throw Error(`${l?`Offer`:`Invoice`} not yet paid. Pay it first, then try again.`);if(!u||m!==`PAID`&&m!==`ISSUED`)throw Error(`Payment is still being processed. Wait a moment and try again.`);let h=await R.current.loadMintedQuotes(r,D.current??void 0);if(n===`bolt11`&&h.includes(e))throw Error(`This quote has already been minted`);let v=(await R.current.loadTransactions(r,D.current??void 0)).find(t=>t.type===`mint`&&t.quoteId===e);c=v?.quoteEventId;let y=v?.quotePrivateKey;if(d&&d.quoteId!==e){let e;try{e=await U(_.restore(d.counterStart,100),6e4,`Recover interrupted mint`)}catch(e){throw Error(`A previous mint from this wallet was interrupted and could not be recovered (${e?.message??`restore failed`}). Try again once the mint is reachable.`)}let t=H(e?.proofs??[]);if(t.length>0){let e=H(V([...H(await R.current.getProofsForMint(a,r,D.current??void 0)),...t]));await R.current.saveProofsForMint(a,e,r),R.current.writeProofStoreTimestamp(a),d.method===`bolt12`?await R.current.addTransaction({type:`mint`,amount:B(t),memo:`BOLT12 deposit`,mintUrl:a,status:`completed`,quoteId:d.quoteId,bolt12:!0},r,D.current??void 0):(await R.current.writeMintedQuote(d.quoteId,r),await o(`completed`,d.quoteId,d.amount))}let n=await R.current.loadMintCounter(a);await R.current.saveMintCounter(a,Math.max(n,d.counterStart+100)),await R.current.clearPendingMint(a)}let x,ee=!1;if(m===`ISSUED`){let t=d&&d.quoteId===e?d.counterStart:await R.current.loadMintCounter(a);if(x=H((await U(_.restore(t,100),6e4,`Restore issued proofs`))?.proofs??[]),x.length===0)throw await o(`failed`),Error(`This quote was already issued by the mint, but the proofs could not be recovered. Contact support with your quote ID.`);ee=!0;let n=await R.current.loadMintCounter(a);await R.current.saveMintCounter(a,Math.max(n,t+100)),await R.current.clearPendingMint(a)}else{let t=await R.current.loadMintCounter(a);if(await R.current.writePendingMint(a,{quoteId:e,counterStart:t,amount:p,timestamp:Date.now(),method:n},r),x=await U(l?_.mintProofsBolt12(p,l,y??g(nt.current.privkey),{counter:t}):typeof u.pubkey==`string`&&y?_.mintProofs(p,u,{counter:t,privateKey:y}):_.mintProofs(p,e,{counter:t}),6e4,`Mint proofs`,()=>setTimeout(()=>At.current(),0)),!Array.isArray(x)||x.length===0)throw Error(`Mint returned no proofs`);await R.current.saveMintCounter(a,t+x.length)}n===`bolt11`&&await R.current.writeMintedQuote(e,r),await R.current.writeProofRecovery(a,H(x),r);let S=B(x);if(s=S,!ee&&S!==p)throw Error(`Mint returned proofs with incorrect total amount`);let te=H(await R.current.getProofsForMint(a,r,D.current??void 0)),ne=new Set(_.keysets.filter(e=>e.active).map(e=>e.id)),re=Ie(x,{activeKeysetIds:ne,localSecrets:new Set(te.map(e=>String(e?.secret))),getKeyset:e=>_.keys.get(e),requireDleq:!0});if(!re.valid)throw Error(re.reason);let ie=await U(an(a,x,i),15e3,`Check minted proof states`);if(ie.length!==x.length)throw Error(`Mint returned spent proofs`);x=H(ie);let ae=H(V([...te,...x]));await R.current.writeProofRecovery(a,ae,r),await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(a,ae,r),R.current.writeProofStoreTimestamp(a),R.current.clearProofRecovery(a),await R.current.clearPendingMint(a),await R.current.withTxLock(async()=>{let t=await R.current.loadTransactions(r,D.current??void 0),i=t.findIndex(t=>t.type===`mint`&&t.status===`pending`&&t.mintUrl===b&&(t.quoteId===e||t.amount===S&&!t.quoteId));i>=0&&n===`bolt11`?await R.current.updateTransactionStatus(t[i].id,`completed`,r,D.current??void 0):await R.current.addTransaction({type:`mint`,amount:S,memo:n===`bolt12`?`BOLT12 deposit`:`Lightning deposit`,mintUrl:b,status:`completed`,quoteId:e,bolt12:n===`bolt12`||void 0},r,D.current??void 0)}),await $(),await Z()});let l=await X(I(b),`in`,s),u=N.current;if(l&&c&&u&&!z.current){let e=await Ot([c],u.signer,`mint quote completed`,[J(),[`k`,String(rt)]]);e&&await u.publish(e)}return A.current&&K(`${s} sats minted successfully!`),!0}catch(e){return A.current&&k(`Mint failed: ${e.message}`),!1}finally{o(),A.current&&O(!1),await G()}},[_,b,G,Z,$,X,an,J]),Mn=(0,C.useCallback)(async e=>{let t=e.trim(),{amountMsats:n}=de(t);if(!n||!Number.isSafeInteger(n)||n%1e3!=0)return k(`NUT-15 requires a valid BOLT11 invoice with a whole-sat amount`),null;let r=T.current;if(!r||!E.current)return k(`Wallet not initialized`),null;try{O(!0),k(``);let e=(await Promise.all(Object.entries(fe).map(async([e,t])=>
1{if(!Number.isSafeInteger(t)||t<=1)return null;try{let n=await q(e,r),i=(await n.lazyGetMintInfo()).isSupported(15);return i.supported&&(i.params??[]).some(e=>e.method===`bolt11`&&e.unit===`sat`)?{mintUrl:I(e),balanceSats:t,wallet:n}:null}catch(t){return w.warn(`Skipping unavailable NUT-15 mint:`,e,t),null}}))).filter(e=>e!==null),i=hi(n,e,we),a=new Map(e.map(e=>[e.mintUrl,e])),o=await Promise.all(i.map(async e=>{let n=a.get(e.mintUrl);if(!n)throw Error(`NUT-15 allocation referenced an unavailable mint`);let r=await U(n.wallet.createMultiPathMeltQuote(t,e.amountMsats),3e4,`NUT-15 melt quote creation`),i=Number(r.amount),o=Number(r.fee_reserve);if(i!==e.amountSats||!Number.isSafeInteger(o)||o<0||r.state&&r.state!==`UNPAID`)throw Error(`Mint returned an invalid NUT-15 quote for ${e.mintUrl}`);if(i+o>e.balanceSats)throw Error(`NUT-15 fees exceed the available balance at ${e.mintUrl}`);if(!je(o,e.balanceSats,5e4))throw Error(`NUT-15 fee reserve exceeds the wallet limit at ${e.mintUrl}`);return{...e,quote:r}}));return{id:globalThis.crypto.randomUUID(),invoice:t,amountSats:n/1e3,totalFeeReserveSats:o.reduce((e,t)=>e+Number(t.quote.fee_reserve),0),createdAt:Date.now(),legs:o}}catch(e){return A.current&&k(`Multi-mint payment unavailable: ${e instanceof Error?e.message:`unknown error`}`),null}finally{A.current&&O(!1)}},[fe,q]),Nn=(0,C.useCallback)(async e=>{let t=T.current,n=E.current;if(!t||!n)return k(`Wallet not initialized`),{success:!1,amount:0};let r=de(e.invoice),i=e.legs.map(e=>I(e.mintUrl));if(Date.now()-e.createdAt>600*1e3||e.legs.length<2||e.legs.length>4||new Set(i).size!==i.length||r.amountMsats!==e.amountSats*1e3||e.legs.reduce((e,t)=>e+t.amountMsats,0)!==r.amountMsats)return k(`This multi-mint payment plan is invalid or expired. Create a new plan.`),{success:!1,amount:0};let a=await Si(dt);try{O(!0),k(``);let r=await R.current.withProofLock(async()=>{let r=await R.current.loadTransactions(n,D.current??void 0),a=[];for(let[o,s]of e.legs.entries()){let e=i[o];if(r.some(t=>t.type===`melt`&&t.status===`pending`&&I(t.mintUrl)===e))throw Error(`Another payment from ${e} is still resolving`);if((await R.current.loadMeltInputRecovery(e,n,D.current??void 0))?.proofs.length)throw Error(`A previous payment from ${e} is still resolving`);let c=await q(e,t),l=H(await R.current.getProofsForMint(e,n,D.current??void 0)),u=Number(s.quote.amount),d=Number(s.quote.fee_reserve);if(u!==s.amountSats||s.amountMsats!==u*1e3||s.quote.state&&s.quote.state!==`UNPAID`)throw Error(`Stale or invalid quote from ${e}`);let f=c.selectProofsToSend(l,u+d,!0),p=H(V(f.send)),m=H(V(f.keep)),h=B(p);if(h<u+d||!je(d,h,5e4))throw Error(`Insufficient balance or excessive fee at ${e}`);a.push({leg:s,mintUrl:e,wallet:c,original:l,selected:p,keep:m,inputAmount:h})}try{for(let e of a){await R.current.writeMeltInputRecovery(e.mintUrl,e.selected,n);let t=await R.current.loadMeltInputRecovery(e.mintUrl,n,D.current??void 0);if(!t||t.proofs.length!==e.selected.length)throw Error(`Could not durably journal ${e.mintUrl}`);await R.current.saveProofsForMint(e.mintUrl,e.keep,n),R.current.writeProofStoreTimestamp(e.mintUrl)}for(let t of a)t.txId=await R.current.addTransaction({type:`melt`,amount:t.leg.amountSats,memo:`Multi-mint Lightning payment (pending)`,mintUrl:t.mintUrl,status:`pending`,quoteId:t.leg.quote.quote,expiresAt:typeof t.leg.quote.expiry==`number`?t.leg.quote.expiry*1e3:void 0,mppGroupId:e.id,mppAmountMsats:t.leg.amountMsats,mppLegCount:a.length},n,D.current??void 0)}catch(e){for(let e of a)await R.current.saveProofsForMint(e.mintUrl,e.original,n),R.current.clearMeltInputRecovery(e.mintUrl);throw e}let o=await Promise.allSettled(a.map(e=>U(e.wallet.meltProofs(e.leg.quote,e.selected),6e4,`NUT-15 melt leg`))),s=!1,c=!1;for(let[e,t]of o.entries()){let r=a[e];if(t.status===`rejected`){s=!0;continue}try{let e=t.value;if(!e||!Array.isArray(e.change))throw Error(`Invalid melt response`);let i=H(V(e.change)),a=Ie(i,{activeKeysetIds:new Set(r.wallet.keysets.filter(e=>e.active).map(e=>e.id)),localSecrets:new Set([...r.selected,...r.keep].map(e=>String(e?.secret))),getKeyset:e=>r.wallet.keys.get(e),requireDleq:!0});
1if(!a.valid)throw Error(a.reason);i.length&&await R.current.writeMeltChangeRecovery(r.mintUrl,i,n);let o=B(i),l=Number(r.leg.quote.fee_reserve);if(o>r.inputAmount-r.leg.amountSats||o<r.inputAmount-r.leg.amountSats-l)throw Error(`Invalid melt change amount`);let u=e.quote?.state;u===`UNPAID`?(await R.current.saveProofsForMint(r.mintUrl,r.original,n),R.current.clearMeltInputRecovery(r.mintUrl),R.current.clearMeltChangeRecovery(r.mintUrl),r.txId&&await R.current.updateTransactionStatus(r.txId,`failed`,n,D.current??void 0),c=!0):u===`PAID`?(await R.current.saveProofsForMint(r.mintUrl,H(V([...r.keep,...i])),n),R.current.clearMeltInputRecovery(r.mintUrl),R.current.clearMeltChangeRecovery(r.mintUrl),r.txId&&await R.current.updateTransactionStatus(r.txId,`completed`,n,D.current??void 0)):(await R.current.saveProofsForMint(r.mintUrl,H(V([...r.keep,...i])),n),s=!0),R.current.writeProofStoreTimestamp(r.mintUrl)}catch(e){w.warn(`NUT-15 leg requires reconciliation:`,r.mintUrl,e),s=!0}}return await R.current.assertProofLockOwnership(),{pending:s,failed:c}});await Z(),await $();for(let t of e.legs)r.failed||await X(I(t.mintUrl),`out`,t.amountSats);return r.pending?K(`Multi-mint payment submitted — resolving all legs`):r.failed?k(`Multi-mint payment failed. Any unresolved legs will keep reconciling.`):K(`Multi-mint payment sent!`),{success:!r.failed,amount:r.failed?0:e.amountSats,pending:r.pending||void 0}}catch(e){return w.error(`NUT-15 payment failed:`,e),A.current&&k(`Multi-mint payment failed: ${e instanceof Error?e.message:`unknown error`}`),{success:!1,amount:0}}finally{a(),A.current&&O(!1),await G()}},[Z,q,$,X,G]),Pn=(0,C.useCallback)(async e=>{let t=typeof e==`string`?e.trim():``;if(!t||t.length<10||t.length>1e4||!t.toLowerCase().startsWith(`ln`))return k(`Invalid Lightning invoice`),{success:!1,amount:0};if(!_||!E.current)return k(`Wallet not initialized`),{success:!1,amount:0};let n=await Si(dt);try{O(!0),k(``);let{amount:t,preimage:n,quote:r,state:i}=await R.current.withProofLock(async()=>{let t=await U(_.createMeltQuote(e),3e4,`Melt quote creation`),n=H(await R.current.getProofsForMint(I(b),E.current,D.current??void 0)),r=n.reduce((e,t)=>{let n=Number(t.amount);return e+(Number.isInteger(n)&&n>0?n:0)},0),i=Number(t.amount)||0,a=Number(t.fee_reserve)||0,o=i+a;if(r<o)throw Error(`Need ${o} sats (inc. fee), have ${r}`);let s=t.state;if(s&&s!==`UNPAID`)throw Error(`Melt quote is not available: ${s}`);if(!je(a,r,5e4))throw Error(`Melt fee reserve exceeds maximum allowed`);let c=I(b);try{if((await R.current.loadTransactions(E.current,D.current??void 0)).some(e=>e.type===`melt`&&e.status===`pending`&&I(e.mintUrl)===c))throw Error(`Another payment from this mint is still resolving — wait for it to finish before paying again.`);let e=await R.current.loadMeltInputRecovery(c,E.current,D.current??void 0);if(e&&e.proofs.length>0)throw Error(`A previous payment from this mint is still resolving — wait for it to finish before paying again.`)}catch(e){if(typeof e?.message==`string`&&e.message.includes(`still resolving`))throw e;w.warn(`Pending-melt guard check failed; proceeding:`,e)}let l=_.selectProofsToSend(n,o,!0),u=H(V(l.send)),d=H(V(l.keep)),f=B(u);if(f<o)throw Error(`Selected proofs insufficient: need ${o}, selected ${f}`);if(!je(a,f,5e4))throw Error(`Melt fee reserve exceeds maximum allowed for selected proofs`);await R.current.writeMeltInputRecovery(c,u,E.current);let p=async()=>{try{await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`melt`,amount:i,memo:`Lightning payment (outcome unknown — resolving)`,mintUrl:b,status:`pending`,quoteId:t.quote,expiresAt:typeof t.expiry==`number`&&t.expiry>0?t.expiry*1e3:void 0},E.current,D.current??void 0)})}catch(e){w.error(`Failed to record pending melt tx:`,e)}},m;try{m=await U(_.meltProofs(t,u),6e4,`Melt proofs`)}catch(e){throw await p(),e}let h;try{if(!m||!Array.isArray(m.change))throw Error(`Mint returned invalid melt response`);h=H(V(m.change));let e=new Set(_.keysets.filter(e=>e.active).map(e=>e.id)),t=new Set([...u,...d].map(e=>String(e?.secret))),n=Ie(h,{activeKeysetIds:e,localSecrets:t,getKeyset:e=>_.keys.get(e),requireDleq:!0});if(!n.valid)throw Error(`Invalid change proofs: ${n.reason}`);h.length>0&&await R.current.writeMeltChangeRecovery(c,h,E.current);let r=B(m.change);
1if(r>f-i)throw Error(`Mint returned invalid change: exceeds available amount`);if(r<f-i-a)throw Error(`Mint returned invalid change: missing required amount`);let o=f-r-i;if(o<0||o>a||!je(o,f,5e4))throw Error(`Mint returned invalid melt fee`)}catch(e){throw await p(),e}await R.current.assertProofLockOwnership();let g=m.quote?.state,v=Number(t.amount)||0,y=async()=>{try{await R.current.withTxLock(async()=>{g===`UNPAID`?await R.current.addTransaction({type:`melt`,amount:v,memo:`Lightning payment (failed)`,mintUrl:b,status:`failed`,quoteId:t.quote},E.current,D.current??void 0):g===`PENDING`?await R.current.addTransaction({type:`melt`,amount:v,memo:`Lightning payment (pending)`,mintUrl:b,status:`pending`,quoteId:t.quote,expiresAt:typeof t.expiry==`number`&&t.expiry>0?t.expiry*1e3:void 0},E.current,D.current??void 0):g===`PAID`?await R.current.addTransaction({type:`melt`,amount:v,memo:`Lightning payment`,mintUrl:b,status:`completed`,quoteId:t.quote},E.current,D.current??void 0):await R.current.addTransaction({type:`melt`,amount:v,memo:`Lightning payment (pending)`,mintUrl:b,status:`pending`,quoteId:t.quote,expiresAt:typeof t.expiry==`number`&&t.expiry>0?t.expiry*1e3:void 0},E.current,D.current??void 0)}),await $()}catch(e){w.error(`Failed to record melt transaction:`,e),A.current&&k(`Payment result recorded but transaction record failed`)}};if(g===`UNPAID`){let e=await R.current.loadMeltInputRecovery(c,E.current,D.current??void 0);if(e&&e.proofs.length>0){let n=T.current;if(!n)throw Error(`Wallet seed is not available`);let r=e.proofs,i=[];try{let e=await on(c,r,n),t=new Set(e.map(e=>String(e?.secret)));i=H(r.filter(e=>!t.has(String(e?.secret)))),r=e}catch(e){return w.warn(`Could not verify unspent state during melt UNPAID recovery; keeping existing store:`,c,e),await Z(),await y(),{quote:t,amount:v,preimage:m.quote?.payment_preimage||void 0,state:g}}let a=H(V([...d,...r]));if(await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(c,a,E.current),R.current.writeProofStoreTimestamp(c),i.length>0)return await R.current.writeMeltInputRecovery(c,i,E.current),R.current.clearMeltChangeRecovery(c),await Z(),await y(),{quote:t,amount:v,preimage:m.quote?.payment_preimage||void 0,state:g}}return R.current.clearMeltInputRecovery(c),R.current.clearMeltChangeRecovery(c),await Z(),await y(),{quote:t,amount:v,preimage:m.quote?.payment_preimage||void 0,state:g}}let x=H(V([...d,...h]));return g===`PENDING`||g!==`PAID`&&g!==`UNPAID`?(await R.current.saveProofsForMint(c,x,E.current),R.current.writeProofStoreTimestamp(c),await Z(),await y(),{quote:t,amount:v,preimage:m.quote?.payment_preimage||void 0,state:g}):(await R.current.saveProofsForMint(c,x,E.current),R.current.writeProofStoreTimestamp(c),R.current.clearMeltInputRecovery(c),R.current.clearMeltChangeRecovery(c),await Z(),await y(),{quote:t,amount:v,preimage:m.quote?.payment_preimage||void 0,state:g})});return i!==`UNPAID`&&await X(I(b),`out`,t),i===`UNPAID`?(A.current&&k(`Payment failed: invoice was not paid`),{success:!1,amount:0,quote:r}):i===`PENDING`?(A.current&&K(`Payment submitted — waiting for confirmation`),{success:!0,amount:t,preimage:n,pending:!0,quote:r}):i===`PAID`?(A.current&&K(`Payment sent!`),{success:!0,amount:t,preimage:n,quote:r}):(w.warn(`Unknown melt state:`,i),A.current&&K(`Payment submitted — waiting for confirmation`),{success:!0,amount:t,preimage:n,pending:!0,quote:r})}catch(e){return w.error(`Pay error:`,e),A.current&&k(`Payment failed: ${e.message}`),{success:!1,amount:0}}finally{n(),A.current&&O(!1),await G()}},[_,b,G,Z,$,X,on]),Fn=(0,C.useCallback)(async(e,t)=>{let n=typeof e==`string`?e.trim():``;if(!n||!/^lno1[02-9ac-hj-np-z]+$/i.test(n))return k(`Invalid BOLT12 offer`),{success:!1,amount:0};if(!Number.isFinite(t)||t<=0)return k(`Invalid amount`),{success:!1,amount:0};if(!_||!E.current)return k(`Wallet not initialized`),{success:!1,amount:0};let r=await Si(dt);try{O(!0),k(``);let{amount:e,state:r,quote:i}=await R.current.withProofLock(async()=>{let e=await U(_.createMeltQuoteBolt12(n,t*1e3),3e4,`BOLT12 melt quote creation`),r=H(await R.current.getProofsForMint(I(b),E.current,D.
1current??void 0)),i=r.reduce((e,t)=>{let n=Number(t.amount);return e+(Number.isInteger(n)&&n>0?n:0)},0),a=Number(e.amount)||0,o=Number(e.fee_reserve)||0,s=a+o;if(i<s)throw Error(`Need ${s} sats (inc. fee), have ${i}`);let c=e.state;if(c&&c!==`UNPAID`)throw Error(`Melt quote is not available: ${c}`);if(!je(o,i,5e4))throw Error(`Melt fee reserve exceeds maximum allowed`);let l=I(b);try{if((await R.current.loadTransactions(E.current,D.current??void 0)).some(e=>e.type===`melt`&&e.status===`pending`&&I(e.mintUrl)===l))throw Error(`Another payment from this mint is still resolving — wait for it to finish before paying again.`);let e=await R.current.loadMeltInputRecovery(l,E.current,D.current??void 0);if(e&&e.proofs.length>0)throw Error(`A previous payment from this mint is still resolving — wait for it to finish before paying again.`)}catch(e){if(typeof e?.message==`string`&&e.message.includes(`still resolving`))throw e;w.warn(`Pending-melt guard check failed; proceeding:`,e)}let u=_.selectProofsToSend(r,s,!0),d=H(V(u.send)),f=H(V(u.keep)),p=B(d);if(p<s)throw Error(`Selected proofs insufficient: need ${s}, selected ${p}`);if(!je(o,p,5e4))throw Error(`Melt fee reserve exceeds maximum allowed for selected proofs`);await R.current.writeMeltInputRecovery(l,d,E.current);let m=async()=>{try{await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`melt`,amount:a,memo:`BOLT12 offer ${n.slice(0,20)}… (outcome unknown — resolving)`,mintUrl:l,status:`pending`,quoteId:e.quote,expiresAt:typeof e.expiry==`number`&&e.expiry>0?e.expiry*1e3:void 0,bolt12:!0},E.current,D.current??void 0)})}catch(e){w.error(`Failed to record pending BOLT12 melt tx:`,e)}},h;try{h=await U(_.meltProofsBolt12(e,d),6e4,`BOLT12 melt proofs`)}catch(e){throw await m(),e}let g;try{if(!h||!Array.isArray(h.change))throw Error(`Mint returned invalid BOLT12 melt response`);g=H(V(h.change));let e=new Set(_.keysets.filter(e=>e.active).map(e=>e.id)),t=new Set([...d,...f].map(e=>String(e?.secret))),n=Ie(g,{activeKeysetIds:e,localSecrets:t,getKeyset:e=>_.keys.get(e),requireDleq:!0});if(!n.valid)throw Error(`Invalid change proofs: ${n.reason}`);g.length>0&&await R.current.writeMeltChangeRecovery(l,g,E.current);let r=B(h.change);if(r>p-a)throw Error(`Mint returned invalid change: exceeds available amount`);if(r<p-a-o)throw Error(`Mint returned invalid change: missing required amount`);let i=p-r-a;if(i<0||i>o||!je(i,p,5e4))throw Error(`Mint returned invalid BOLT12 melt fee`)}catch(e){throw await m(),e}await R.current.assertProofLockOwnership();let v=h.quote?.state,y=Number(e.amount)||0;if(v===`UNPAID`){let e=await R.current.loadMeltInputRecovery(l,E.current,D.current??void 0),t=T.current;if(e&&e.proofs.length>0&&t)try{let n=await on(l,e.proofs,t),r=new Set(n.map(e=>String(e?.secret))),i=H(e.proofs.filter(e=>!r.has(String(e?.secret)))),a=H(V([...f,...n]));await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(l,a,E.current),R.current.writeProofStoreTimestamp(l),i.length>0?await R.current.writeMeltInputRecovery(l,i,E.current):R.current.clearMeltInputRecovery(l),R.current.clearMeltChangeRecovery(l)}catch(e){w.warn(`Could not verify unspent state during BOLT12 UNPAID recovery; keeping journal:`,l,e)}}else{let e=H(V([...f,...g]));await R.current.saveProofsForMint(l,e,E.current),R.current.writeProofStoreTimestamp(l),v===`PAID`&&(R.current.clearMeltInputRecovery(l),R.current.clearMeltChangeRecovery(l))}return await(async()=>{try{await R.current.withTxLock(async()=>{let t=typeof e.expiry==`number`&&e.expiry>0?e.expiry*1e3:void 0;if(v===`UNPAID`){await R.current.addTransaction({type:`melt`,amount:y,memo:`BOLT12 offer ${n.slice(0,20)}…`,mintUrl:l,status:`failed`,quoteId:e.quote,bolt12:!0},E.current,D.current??void 0);return}let r=v===`PAID`?`completed`:`pending`;await R.current.addTransaction({type:`melt`,amount:y,memo:`BOLT12 offer ${n.slice(0,20)}…`,mintUrl:l,status:r,quoteId:e.quote,expiresAt:t,bolt12:!0},E.current,D.current??void 0)})}catch(e){w.error(`Failed to record BOLT12 melt tx:`,e)}})(),await $(),await Z(),{quote:e,amount:y,state:v}});return r!==`UNPAID`&&await X(I(b),`out`,e),r===`UNPAID`?(A.current&&k(`Payment failed: BOLT12 offer was not paid`),{success:!1,amount:0,quote:i}):r===`PENDING`?(A.current&&K(`BOLT12 payment submitted — waiting for confirmation`),{success:!0,amount:e,quote:i,pending:!0}):r===`PAID`?(A.current&&K(`BOLT12 payment sent!`),{success:!0,amount:e,quote:i}):(w.warn(`Unknown BOLT12 melt state:`,r),A.current&&K(`BOLT12 payment submitted — waiting for confirmation`),{success:!0,amount:e,quote:i,pending:!0})}catch(e){return w.error(`BOLT12 pay error:`,e),A.current&&k(`BOLT12 payment failed: ${e.message}`),{success:!1,amount:0}}finally{r(),A.current&&O(!1),await G()}},[_,b,G,Z,$,on,X]),In=(0,C.useCallback)(async e=>{let t=N.current,n=E.current,r=sn(),i=Y();if(!t||!n||!r||!i||!_){w.warn(`Cannot receive Nutzap: wallet or NIP-60 sync not ready`);return}if(st.current.has(e.id)||await R.current.isProcessedNutzapId(e.id,n,D.current??void 0))return;let o=await Si(dt);
1try{if(!a(e)){w.warn(`Rejected Nutzap with invalid signature:`,e.id);return}let o=Lt(e);if(!o){w.warn(`Failed to parse Nutzap event:`,e.id);return}if(o.recipient!==t.signer.pubkey){w.warn(`Nutzap recipient does not match current user:`,e.id);return}let s=F(o.mint);if(!s)return;let c=s===F(b)?_:await U(q(s,T.current,!0),15e3,`Foreign mint load`);await R.current.withProofLock(async()=>{let a=H(await R.current.getProofsForMint(s,n,D.current??void 0)),l=ae({mint:s,proofs:o.proofs.map(Ze),unit:`sat`}),u=H(o.proofs),d=B(u),f=0;try{f=c.getFeesForProofs(u)}catch{f=Math.max(1,Math.floor(d*.001))}if(!je(f,d,5e4))throw Error(`Mint fee exceeds maximum allowed`);let p=H(await U(c.receive(l,{proofsWeHave:a,privkey:g(i.privkey),requireDleq:!0}),6e4,`Receive Nutzap`)??[]);if(p.length===0)throw Error(`No proofs received from Nutzap`);await R.current.writeSendRecovery(s,p,n);let m=B(p),h=d-m;if(h<0||h>f)throw Error(`Nutzap redemption returned incorrect amount`);let _=new Set(c.keysets.filter(e=>e.active).map(e=>e.id)),v=Ie(p,{activeKeysetIds:_,localSecrets:new Set(a.map(e=>String(e?.secret))),getKeyset:e=>c.keys.get(e),requireDleq:!0});if(!v.valid)throw Error(v.reason);let y=await U(an(s,p,T.current,!0),15e3,`Check Nutzap proof states`);if(y.length!==p.length)throw Error(`Nutzap proofs are already spent`);p=H(y),await R.current.writeSendRecovery(s,p,n);let b=V([...a,...p]);await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(s,b,n),R.current.writeProofStoreTimestamp(s),R.current.clearSendRecovery(s),await Z(),await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`receive`,amount:m,memo:`Nutzap`,mintUrl:s,status:`completed`},n,D.current??void 0)}),await $();let x=await X(s,`in`,m),ee=await yt(s,n,L.current),S=await Rt(m,s,e.id,e.pubkey,x?.id||ee||``,r,[J()]);S&&await(z.current&&t.publishToRelays?t.publishToRelays([ue],S):t.publish(S)).catch(()=>{})}),st.current.add(e.id);try{await R.current.addProcessedNutzapId(e.id,n,D.current??void 0)}catch(e){w.warn(`Failed to persist processed Nutzap id:`,e)}ye(t=>t.some(t=>t.id===e.id)?t:[e,...t])}catch(t){w.error(`Failed to receive Nutzap:`,e.id,t)}finally{o()}},[_,b,Y,sn,q,an,Z,$,X,J]),Ln=(0,C.useCallback)(async(e,t,n,r)=>{let a=N.current,o=E.current,s=sn();if(!a||!o||!s||!_)return k(`Wallet not initialized`),{status:`failed`};let c=bn(e);if(c)return k(c),{status:`failed`};if(r?.memo!==void 0&&(typeof r.memo!=`string`||r.memo.length>500))return k(`Memo must be a string with max 500 chars`),{status:`failed`};let l;try{let e=i.decode(t.trim());if(e.type===`npub`)l=e.data;else if(e.type===`nprofile`)l=e.data.pubkey;else throw Error(`Unsupported recipient identifier`)}catch{return k(`Invalid recipient npub or nprofile`),{status:`failed`}}let u=F(n),d=W.current.map(e=>e.url);if(!u||!P(u,d))return k(`Selected mint is not allowed`),{status:`failed`};let f=null;try{let e=(z.current&&a.queryRelays?await a.queryRelays([ue],{kinds:[it],authors:[l],limit:5}):await a.query({kinds:[it],authors:[l],limit:5})).filter(e=>Ft(e,l)!==null).sort((e,t)=>t.created_at-e.created_at);f=e.length>0?Ft(e[0],l):null}catch(e){w.error(`Failed to fetch recipient Nutzap info:`,e)}if(!f&&!z.current&&a.queryRelays)try{let e=(await a.queryRelays([gi],{kinds:[it],authors:[l],limit:5})).filter(e=>Ft(e,l)!==null).sort((e,t)=>t.created_at-e.created_at);f=e.length>0?Ft(e[0],l):null}catch(e){w.error(`Failed to fetch recipient Nutzap info from fallback relay:`,e)}if(!f)return k(`Recipient has not published Nutzap preferences`),{status:`failed`};if(!f.mints.includes(u))return k(`Recipient does not accept this mint`),{status:`failed`};let p=(()=>{let e=f.pubkey.toLowerCase();return/^[0-9a-f]{64}$/.test(e)?`02`+e:/^0[23][0-9a-f]{64}$/.test(e)?e:null})();if(!p)return k(`Recipient Nutzap pubkey is invalid`),{status:`failed`};let m=await Si(dt),h=null,g=!1;try{A.current&&O(!0),A.current&&k(``);let t=u===F(n)?_:await U(q(u,T.current,!0),15e3,`Foreign mint load`),i=await R.current.withProofLock(async()=>{let n=V(H(await R.current.getProofsForMint(u,o,D.current??void 0)));if(n.length===0)throw Error(`No proofs available for this mint`);let i=B(n);if(i<e)throw Error(`Insufficient balance: ${i} sats available`);let a=0;try{a=t.getFeesForProofs(n)}catch{a=Math.max(1,Math.floor(i*.001))}if(!je(a,i,5e4))throw Error(`Mint fee exceeds maximum allowed`);await R.current.writeProofRecovery(u,n,o),g=!0;let s=await U(t.send(e,n,{proofsWeHave:n,pubkey:p,includeDleq:!0}),6e4,`Send Nutzap`,()=>setTimeout(()=>At.current(),0));if(!s||!Array.isArray(s.send)||!Array.isArray(s.keep))throw Error(`Mint returned invali
1d Nutzap send response`);let c=H(V(s.send)),l=H(V(s.keep));if(await R.current.writeProofRecovery(u,l,o),c.length>0&&await R.current.writeSendRecovery(u,c,o),h=c,B(c)!==e)throw Error(`Mint returned send proofs with incorrect total amount`);let d=B(c)+B(l);if(d>i)throw Error(`Mint returned invalid proofs: outputs exceed inputs`);let f=i-d;if(f<0||f>a)throw Error(`Mint returned invalid proofs: fee exceeds reported fee`);let m=new Set(n.map(e=>String(e.secret)));for(let e of c)if(m.has(String(e.secret)))throw Error(`Mint returned unspent input proofs as send outputs`);await R.current.assertProofLockOwnership(),await R.current.saveProofsForMint(u,l,o),R.current.writeProofStoreTimestamp(u),R.current.clearProofRecovery(u),await R.current.withTxLock(async()=>{await R.current.addTransaction({type:`send`,amount:e,memo:r?.memo||`Nutzap`,mintUrl:u,status:`completed`},o,D.current??void 0)}),await $(),await Z();try{await X(u,`out`,e)}catch(e){w.error(`NIP-60 Nutzap send sync failed:`,e)}return c}),s={id:``,sendProofs:i,recipientPubkey:l,mintUrl:u,amount:e,memo:r?.memo,zappedEvent:r?.zappedEvent,timestamp:Date.now(),attempts:0,recipientRelays:f.relays},c=null;try{c=await It(l,u,i,a.signer,{memo:r?.memo,zappedEvent:r?.zappedEvent,extraTags:[J()]})}catch(e){w.error(`Failed to build Nutzap event:`,e)}if(!c){s.id=`build-failed-${s.timestamp}`;try{await R.current.savePendingNutzap(s,o,D.current??void 0),R.current.clearSendRecovery(u)}catch(e){w.error(`Failed to save pending Nutzap after build failure:`,e)}return A.current&&k(`Failed to build Nutzap — saved for retry`),{status:`pending`}}if(s.id=c.id,s.event=c,!(z.current&&a.publishToRelays?await a.publishToRelays([`wss://relay.bao.network`],c):await a.publish(c))){s.attempts=1;try{await R.current.savePendingNutzap(s,o,D.current??void 0),R.current.clearSendRecovery(u)}catch(e){w.error(`Failed to save pending Nutzap after publish failure:`,e)}return A.current&&k(`Failed to publish Nutzap — saved for retry`),{status:`pending`}}R.current.clearSendRecovery(u);let d=new Set((z.current?[ue]:a.relays??[]).map(Ci)),m=[...new Set(f.relays.map(e=>e.trim()).filter(e=>e.length>0&&!d.has(Ci(e))))],v=[];if(m.length>0){let e=await wi(c,m),t=new Set(e.map(Ci));if(v=m.filter(e=>!t.has(Ci(e))),v.length>0){w.warn(`Nutzap not yet delivered to recipient relays, saved for retry:`,v);try{await R.current.savePendingNutzap({...s,attempts:1,lastAttemptAt:Date.now(),recipientRelays:v},o,D.current??void 0)}catch(e){w.error(`Failed to save pending Nutzap for relay retry:`,e)}}}if(v.length===0)try{await R.current.removePendingNutzap(c.id,o,D.current??void 0)}catch(e){w.warn(`Failed to clear pending Nutzap after successful publish:`,e)}return A.current&&K(`Sent ${e} sats via Nutzap`),{status:`sent`,eventId:c.id}}catch(t){w.error(`Nutzap send failed:`,t);let n=h;if(n&&n.length>0){let t={id:`post-commit-${Date.now()}`,sendProofs:n,recipientPubkey:l,mintUrl:u,amount:e,memo:r?.memo,zappedEvent:r?.zappedEvent,timestamp:Date.now(),attempts:0,recipientRelays:f.relays};try{await R.current.savePendingNutzap(t,o,D.current??void 0),R.current.clearSendRecovery(u)}catch(e){w.error(`Failed to save pending Nutzap after post-commit validation failure:`,e)}return A.current&&k(`Nutzap paid but hit a post-payment error — saved for retry`),{status:`pending`}}let i=typeof t?.status==`number`?t.status:null,a=typeof t?.message==`string`&&/not enough (funds|balance)/i.test(t.message);if(g&&i===null&&!a){let e=typeof t?.message==`string`&&t.message.includes(`timed out`);return A.current&&k(e?`Nutzap send timed out — the mint may still have processed it. Check your balance before sending again; if it decreased, the payment went through and the recovery journal will reconcile automatically.`:`Nutzap send outcome unknown (${t?.message??t}) — the mint may still have processed it. Check your balance before sending again.`),{status:`unknown`}}return A.current&&k(`Nutzap send failed: ${t.message}`),{status:`failed`}}finally{m(),A.current&&O(!1),await G()}},[_,sn,q,Z,$,X,J,G]),Rn=(0,C.useCallback)(async()=>{let e=N.current,t=E.current;if(!(!e||!t||ct.current)){ct.current=!0;try{let n=await R.current.loadPendingNutzaps(t,D.current??void 0);if(n.length===0)return;let r=Date.now();for(let i of n){if(i.lastAttemptAt&&r-i.lastAttemptAt<6e4)continue;let n=i.event??null;if(n||=await It(i.recipientPubkey,i.mintUrl,i.sendProofs,e.signer,{memo:i.memo,zappedEvent:i.zappedEvent,extraTags:[J()]}),!n)continue;let a=z.current&&e.publishToRelays?await e.publishToRelays([ue],n):await e.publish(n);if(a){let e=i.recipientRelays??[];if(e.length>0){let t=await wi(n,e),r=new Set(t.map(Ci));e=e.filter(e=>!r.has(Ci(e)))}e.length===0?(await R.current.removePendingNutzap(i.id,t,D.current??void 0),w.log(`Published pending Nutzap:`,a)):(w.warn(`Pending Nutzap still undelivered to recipient relays:`,e),await R.current.savePendingNutzap({...i,event:n,attempts:i.attempts+1,lastAttemptAt:r,recipientRelays:e},t,D.current??void 0))}else await R.current.savePendingNutzap({...i,attempts:i.attempts+1,lastAttemptAt:r},t,D.current??void 0)}}catch(e){w.error(`Pending Nutzap reconciliation failed:`,e)}finally{ct.current=!1}}},[J]);(0,C.useEffect)(()=>
1{if(!_||!N.current)return;let e=!1;return(async()=>{e||await Rn()})(),()=>{e=!0}},[_,Rn]);let zn=(0,C.useCallback)(async e=>{let t=E.current,n=T.current;if(!t||!n){k(`Wallet not initialized`);return}if(!e||typeof e!=`object`){k(`Invalid backup payload`);return}try{if(Array.isArray(e.proofs)&&await R.current.withProofLock(async()=>{let r=n;for(let n of e.proofs)if(n&&typeof n.mintUrl==`string`&&n.mintUrl.length>0&&P(n.mintUrl,W.current.map(e=>e.url))&&Array.isArray(n.proofs)&&n.proofs.length>0){let e=I(Ht(n.mintUrl)),i=H(await R.current.getProofsForMint(e,t,D.current??void 0)),a=H(n.proofs);if(r)try{a=H(V(await an(e,a,r)))}catch(t){w.warn(`Could not verify backed-up proofs, skipping restore for mint:`,e,t);continue}let o=V([...i,...a]);await R.current.saveProofsForMint(e,o,t)}}),Array.isArray(e.transactions)&&e.transactions.length>0&&await R.current.withTxLock(async()=>{let n=2**53-1,r=Date.now(),i=e.transactions.filter(e=>R.current.isValidTransaction(e));i=i.filter(e=>e.amount<=n);let a=i.filter(e=>r-e.createdAt>15552e6);a.length>0&&w.warn(`Restore contains ${a.length} transactions older than 180 days`),i=i.slice(0,500);let o=await R.current.loadTransactions(t,D.current??void 0),s=new Set(o.map(e=>e.id)),c=i.filter(e=>!s.has(e.id));c.length>0&&(await R.current.saveTransactions([...o,...c],t),A.current&&_e(await R.current.loadTransactions(t,D.current??void 0)))}),Array.isArray(e.customMints)){let n=e.customMints.filter(e=>e&&typeof e==`object`&&typeof e.url==`string`&&e.url.length>0&&typeof e.name==`string`&&e.name.length>0&&P(e.url));if(n.length>0){let e=Xt([...await R.current.loadCustomMints(t,D.current??void 0),...n],e=>I(e.url));S(e),await R.current.saveCustomMints(e,t)}}if(e.selectedMintUrl){let t=F(e.selectedMintUrl);t&&P(t)?x(t):w.warn(`Backup selected mint URL is not allowed, skipping:`,t)}await Z(void 0,t),A.current&&K(`Wallet restored from backup`)}catch(e){w.error(`Manual restore failed:`,e),A.current&&k(`Restore failed: ${e.message}`)}},[Z,an]),Bn=(0,C.useCallback)(async e=>{if(!_)return null;if(!e||typeof e!=`object`||typeof e.quote!=`string`||e.quote.length===0)return w.error(`checkMintQuote rejected: invalid quote`),null;try{return await U(_.checkMintQuote(e),15e3,`Check mint quote`)}catch(e){return w.error(`Check quote error:`,e),null}},[_]),Vn=(0,C.useCallback)(async e=>{if(!_)return null;if(!e||typeof e!=`object`||typeof e.quote!=`string`||e.quote.length===0)return w.error(`checkMeltQuote rejected: invalid quote`),null;try{return await U(_.checkMeltQuote(e),15e3,`Check melt quote`)}catch(e){return w.error(`Check melt quote error:`,e),null}},[_]),Hn=(0,C.useRef)(!1),Un=(0,C.useCallback)(async()=>{let e=E.current,t=T.current;if(!(!e||!_||!t||Hn.current)){Hn.current=!0;try{let n=(await R.current.loadTransactions(e,D.current??void 0)).filter(e=>e.type===`melt`&&e.status===`pending`&&typeof e.quoteId==`string`&&e.quoteId.length>0);for(let r of n){let n=await q(r.mintUrl,t).catch(()=>null);if(!n)continue;let i=r.bolt12?await U(n.checkMeltQuoteBolt12(r.quoteId),15e3,`Check BOLT12 melt quote`).catch(()=>null):await U(n.checkMeltQuote(r.quoteId),15e3,`Check BOLT11 melt quote`).catch(()=>null),a=i?.state;if(a===`PAID`){await R.current.updateTransactionStatus(r.id,`completed`,e,D.current??void 0);let t=I(r.mintUrl),n=await R.current.loadMeltInputRecovery(t,e,D.current??void 0);if(n&&n.proofs.length>0){let r=new Set(n.proofs.map(e=>String(e?.secret))),i=await Si(dt);try{await R.current.withProofLock(async()=>{let n=H(await R.current.getProofsForMint(t,e,D.current??void 0)),i=n.filter(e=>!r.has(String(e?.secret)));i.length!==n.length&&(await R.current.saveProofsForMint(t,i,e),R.current.writeProofStoreTimestamp(t))})}finally{i()}}R.current.clearMeltInputRecovery(t),R.current.clearMeltChangeRecovery(t),await Z(),A.current&&K(`Lightning payment confirmed`)}else a===`UNPAID`?(await R.current.updateTransactionStatus(r.id,`failed`,e,D.current??void 0),await Yt.current(r.mintUrl),await Z()):a!==`PENDING`&&typeof i?.expiry==`number`&&i.expiry>0&&Date.now()>i.expiry*1e3&&(await R.current.updateTransactionStatus(r.id,`expired`,e,D.current??void 0),await Yt.current(r.mintUrl),await Z())}n.length>0&&await $()}catch(e){w.error(`Pending melt reconciliation failed:`,e)}
1finally{Hn.current=!1}}},[_,q,Z,$]);(0,C.useEffect)(()=>{if(!_||!E.current)return;let e=setInterval(()=>void Un(),1e4);return()=>clearInterval(e)},[_,Un]),(0,C.useEffect)(()=>{if(!_)return;let e=ge.filter(e=>e.type===`melt`&&e.status===`pending`&&I(e.mintUrl)===I(b)&&typeof e.quoteId==`string`&&e.quoteId.length>0);if(e.length===0)return;let t=!0,n=[];return(async()=>{try{let r=(await _.lazyGetMintInfo()).isSupported(17);if(!t||!r.supported)return;await _.mint.connectWebSocket();let i=_.mint.webSocketConnection;if(!t||!i)return;for(let t of[`bolt11`,`bolt12`]){let a=`${t}_melt_quote`,o=e.filter(e=>!!e.bolt12==(t===`bolt12`)).map(e=>e.quoteId);if(!(r.params??[]).some(e=>e.method===t&&e.unit===`sat`&&e.commands.includes(a))||o.length===0)continue;let s={kind:a,filters:o},c=()=>void Un(),l=e=>w.warn(`NUT-17 ${t} melt subscription failed; polling remains active:`,e),u=i.createSubscription(s,c,l);n.push(()=>i.cancelSubscription(u,c,l))}}catch(e){w.warn(`NUT-17 melt subscriptions unavailable; polling remains active:`,e)}})(),()=>{t=!1,n.forEach(e=>e())}},[_,b,ge,Un]);let Wn=(0,C.useCallback)(async()=>{let e=E.current,t=T.current;if(!e||!t)return k(`Wallet seed is not available yet`),0;O(!0),k(``);let n=0;try{for(let r of W.current){let i=I(r.url),a=0;try{let r=await q(i,t),o=await r.getKeySets(),s=[],c=R.current.loadMintCounter(i);for(let e of o.filter(e=>e.unit===`sat`)){let t=await U(r.batchRestore(300,100,0,e.id),vi,`Recover ${new URL(i).hostname}`);s.push(...t.proofs),typeof t.lastCounterWithSignature==`number`&&(c=Math.max(c,t.lastCounterWithSignature+1))}let l=H(s);if(l.length===0)continue;let u=await on(i,l,t);if(u.length===0)continue;let d=await Si(dt);try{await R.current.withProofLock(async()=>{let t=H(await R.current.getProofsForMint(i,e,D.current??void 0)),r=new Set(t.map(e=>String(e.secret))),o=u.filter(e=>!r.has(String(e.secret)));o.length!==0&&(await R.current.saveProofsForMint(i,V([...t,...o]),e),R.current.writeProofStoreTimestamp(i),R.current.saveMintCounter(i,c),a=o.reduce((e,t)=>e+Number(t.amount),0),n+=a)})}finally{d()}a>0&&await X(i,`in`,a)}catch(e){w.warn(`Deterministic Cashu recovery failed for mint:`,i,e)}}return await Z(),n>0?(Ge(`Recovered ${n} sats from your Cashu mints`),await G()):Ge(`No unspent Cashu proofs were found for this wallet seed`),n}finally{A.current&&O(!1)}},[Z,on,q,X,G]),Gn=(0,C.useCallback)(()=>St.current,[]);return{wallet:_,mintUrl:b,allMints:Qt,mintInfo:ce,balances:fe,totalBalance:me,transactions:ge,nutzaps:ve,seedPhrase:Oe.current,isNewWallet:Me,showSeedBackup:Pe,loading:Le,error:He,success:We,backupStatus:be,nip60Status:Se,lastBackupAt:Ee,setMintUrl:gn,addCustomMint:_n,removeCustomMint:vn,handleSeedBackupConfirm:hn,calculateAllBalances:Z,receiveToken:yn,sendToken:xn,sendTokenToOutbox:Sn,wasLastSendAmbiguous:Gn,sendLockedToken:Cn,sendMultisigLockedToken:wn,receiveLockedToken:Tn,sweepWalletLockedToken:En,getWalletP2pkPubkey:Dn,requestInvoice:On,requestBolt12Offer:An,mintFromQuote:jn,watchMintQuote:kn,payInvoice:Pn,prepareMultiPathPayment:Mn,executeMultiPathPayment:Nn,payBolt12:Fn,sendNutzap:Ln,receiveNutzap:In,checkMintQuote:Bn,checkMeltQuote:Vn,restoreFromBackup:zn,recoverFromMints:Wn,clearError:(0,C.useCallback)(()=>k(``),[]),clearSuccess:(0,C.useCallback)(()=>Ge(``),[])}}var Di=30078,Oi=`freedomid:cashu`,ki=`ditto:cashu:v1:`,Ai=8,ji=8e3;function Mi(e){return g(p(new TextEncoder().encode(`${ki}${e}`)).slice(0,Ai))}function Ni(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&typeof t.type==`string`&&typeof t.amount==`number`&&typeof t.memo==`string`&&typeof t.mintUrl==`string`&&typeof t.status==`string`&&typeof t.createdAt==`number`}function Pi(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.mintUrl==`string`&&Array.isArray(t.proofs)}function Fi(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.timestamp!=`number`||!Number.isFinite(t.timestamp)||t.timestamp<0||typeof t.epoch!=`number`||!Number.isFinite(t.epoch)||t.epoch<0||!Array.isArray(t.mints)||!t.mints.every(e=>typeof e==`string`)||!Array.isArray(t.proofs)||!t.proofs.every(Pi)||!Array.isArray(t.transactions)||!t.transactions.every(Ni)||typeof t.selectedMintUrl!=`string`)return!1;if(t.customMints!==void 0){if(!Array.isArray(t.customMints))return!1;for(let e of t.customMints)if(!e||typeof e!=`object`||typeof e.name!=`string`||typeof e.url!=`string`)return!1}return!0}function Ii(e){return Fi(e)?e.version===1:!1}function Li(e){if(!Fi(e))return!1;let t=e;if(t.version!==2||t.nutzapPubkey!==void 0&&typeof t.nutzapPubkey!=`string`||t.mintedQuoteIds!==void 0&&(!Array.isArray(t.mintedQuoteIds)||!t.mintedQuoteIds.every(e=>typeof e==`string`)))return!1;if(t.processedTokenHashes!==void 0){if(!Array.isArray(t.processedTokenHashes))return!1;for(let e of t.processedTokenHashes)if(!e||typeof e!=`object`||typeof e.hash!=`string`||typeof e.expiresAt!=`number`)return!1}return!0}function Ri(e){return Li(e)||Ii(e)?e:null}async function zi(e,t,n){let r=new l;try{return(await r.querySync(t,{kinds:[30078],authors:[e.pubkey],"#d":[n],limit:20},{maxWait:15e3})).filter(e=>a(e)).sort((e,t)=>
1t.created_at-e.created_at)[0]??null}catch(e){return w.warn(`Cashu backup query failed:`,e instanceof Error?e.message:String(e)),null}finally{r.close(t)}}async function Bi(e,t){try{let n=await e.signer.nip44.decrypt(e.pubkey,t.content);return n?Ri(JSON.parse(n))||(w.warn(`Cashu backup: decrypted payload does not match expected shape`),null):(w.warn(`Cashu backup: NIP-44 decryption returned empty`),null)}catch(e){return w.error(`Cashu backup: failed to decrypt:`,e instanceof Error?e.message:String(e)),null}}async function Vi(e,t,n,r){if(!t?.signer?.nip44?.encrypt)return w.warn(`Cashu sync: signer does not support NIP-44`),null;if(n.length===0)return w.warn(`Cashu sync: no relays configured`),null;let i=r??Mi(t.pubkey);try{let r=JSON.stringify(e),o={kind:Di,content:await t.signer.nip44.encrypt(t.pubkey,r),tags:[[`d`,i],[`client`,`2140`]],created_at:Math.floor(Date.now()/1e3)},s=await t.signer.signEvent(o);if(!a(s))return w.error(`Cashu sync: generated event has invalid signature`),null;let c=new l;try{return await Promise.race([Promise.any(n.map(e=>c.publish([e],s))),new Promise((e,t)=>setTimeout(()=>t(Error(`Backup relay timeout`)),ji))]),s.id}catch(e){return w.error(`Cashu sync: failed to publish to any relay:`,e instanceof Error?e.message:String(e)),null}finally{c.close(n)}}catch(e){return w.error(`Cashu sync error:`,e instanceof Error?e.message:String(e)),null}}async function Hi(e,t,n){if(!e?.signer?.nip44?.decrypt)return w.warn(`Cashu restore: signer does not support NIP-44`),null;if(t.length===0)return w.warn(`Cashu restore: no relays configured`),null;let r=await zi(e,t,n??Mi(e.pubkey));if(r)return Bi(e,r);w.log(`Cashu restore: no opaque backup found, trying legacy d-tag`);let i=await zi(e,t,Oi);return i?Bi(e,i):(w.warn(`Cashu restore: no valid backup event found`),null)}export{he as C,w as S,He as _,qr as a,F as b,ti as c,it as d,mt as f,$e as g,Ce as h,oi as i,V as l,Ht as m,Vi as n,Jr as o,Ft as p,Ei as r,ni as s,Hi as t,B as u,O as v,I as x,Be as y};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.