diff --git a/cashu.ts b/cashu.ts index 51f987d..4717e81 100644 --- a/cashu.ts +++ b/cashu.ts @@ -8,6 +8,7 @@ export default class PortalBtcWalletCashu { private npubCash: NpubCash; private cashuTxns: CashuTxn[] = []; private proofs: Proof[] = []; + private onBalanceUpdated: (() => void) | null = null; get txns() { return this.cashuTxns; @@ -25,14 +26,14 @@ export default class PortalBtcWalletCashu { constructor( mnemonic: string, private cashuStore: CashuStore, - private meltThreshold: number, ) { this.npubCash = new NpubCash(mnemonic); } - async init() { + async init(onBalanceUpdated: () => void) { this.cashuTxns = await this.cashuStore.getTxns(); this.proofs = await this.cashuStore.getProofs(); + this.onBalanceUpdated = onBalanceUpdated; } async redeemCashuQuotes() { @@ -52,6 +53,7 @@ export default class PortalBtcWalletCashu { if (!proofs.done || typeof proofs.value === "undefined") return []; this.proofs.push(...proofs.value); await this.persistState(); + this.onBalanceUpdated?.(); return proofs.value; } @@ -83,6 +85,7 @@ export default class PortalBtcWalletCashu { status: "complete", }); await this.persistState(); + this.onBalanceUpdated?.(); } async redeemToken(token: string): Promise { @@ -99,5 +102,6 @@ export default class PortalBtcWalletCashu { status: "complete", }); await this.persistState(); + this.onBalanceUpdated?.(); } } diff --git a/index.ts b/index.ts index 76bb43d..20fd4f6 100644 --- a/index.ts +++ b/index.ts @@ -89,7 +89,6 @@ export default class PortalBtcWallet { this.cashuSDK = new PortalBtcWalletCashu( mnemonic, cashuStore, - cashuMeltThreshold, ); } @@ -105,6 +104,7 @@ export default class PortalBtcWallet { console.log(e); } this.refreshBreezBalances(); + this.emitEvent("balanceUpdated"); }, }); setLogger({ @@ -114,7 +114,7 @@ export default class PortalBtcWallet { } }, }); - await this.cashuSDK.init(); + await this.cashuSDK.init(() => this.emitEvent("balanceUpdated")); await this.redeemCashuQuotes(); await this.maybeMelt(); } @@ -134,6 +134,7 @@ export default class PortalBtcWallet { (this.cashuBalance % this.cashuMeltThreshold); const invoice = await this.generateBolt11Invoice(cashuAmountToSwapToLiquid); await this.cashuSDK.meltProofsToPayInvoice(invoice); + this.emitEvent("balanceUpdated"); } /** @@ -173,6 +174,7 @@ export default class PortalBtcWallet { async redeemToken(token: string): Promise { await this.cashuSDK.redeemToken(token); await this.maybeMelt(); + this.emitEvent("balanceUpdated"); } /** @@ -317,6 +319,7 @@ export default class PortalBtcWallet { try { if (parsedPayment.type === "bolt11") { yield* this.payBolt11Invoice(parsedPayment, destination, amount); + this.emitEvent("balanceUpdated"); return; } @@ -342,6 +345,7 @@ export default class PortalBtcWallet { parsedPayment.type === "liquidAddress" ) { yield* this.payChainAddress(parsedPayment, amount); + this.emitEvent("balanceUpdated"); return; } @@ -369,6 +373,7 @@ export default class PortalBtcWallet { status: PaymentStatus.PaymentSent, error: null, }; + this.emitEvent("balanceUpdated"); return; } catch (e: unknown) { if (e instanceof Error) { @@ -406,4 +411,28 @@ export default class PortalBtcWallet { ); return sortedPayments.slice(offset, offset + limit); } + + private eventListeners: Record void)[]> = {}; + + /** + * Adds an event listener + * + * @param event - The event to listen for + * @param listener - The listener function + */ + addEventListeners(event: "balanceUpdated", listener: () => void) { + if (!this.eventListeners[event]) { + this.eventListeners[event] = []; + } + this.eventListeners[event].push(listener); + } + + private emitEvent(event: "balanceUpdated") { + if (this.loggingEnabled) { + console.log(`[${event}]`); + } + for (const listener of this.eventListeners[event] ?? []) { + listener(); + } + } }