add balance updated event

This commit is contained in:
Danny Morabito 2025-07-09 13:07:38 +02:00
parent 0aec49b25b
commit 15202e5339
Signed by: dannym
GPG key ID: 7CC8056A5A04557E
2 changed files with 37 additions and 4 deletions

View file

@ -8,6 +8,7 @@ export default class PortalBtcWalletCashu {
private npubCash: NpubCash; private npubCash: NpubCash;
private cashuTxns: CashuTxn[] = []; private cashuTxns: CashuTxn[] = [];
private proofs: Proof[] = []; private proofs: Proof[] = [];
private onBalanceUpdated: (() => void) | null = null;
get txns() { get txns() {
return this.cashuTxns; return this.cashuTxns;
@ -25,14 +26,14 @@ export default class PortalBtcWalletCashu {
constructor( constructor(
mnemonic: string, mnemonic: string,
private cashuStore: CashuStore, private cashuStore: CashuStore,
private meltThreshold: number,
) { ) {
this.npubCash = new NpubCash(mnemonic); this.npubCash = new NpubCash(mnemonic);
} }
async init() { async init(onBalanceUpdated: () => void) {
this.cashuTxns = await this.cashuStore.getTxns(); this.cashuTxns = await this.cashuStore.getTxns();
this.proofs = await this.cashuStore.getProofs(); this.proofs = await this.cashuStore.getProofs();
this.onBalanceUpdated = onBalanceUpdated;
} }
async redeemCashuQuotes() { async redeemCashuQuotes() {
@ -52,6 +53,7 @@ export default class PortalBtcWalletCashu {
if (!proofs.done || typeof proofs.value === "undefined") return []; if (!proofs.done || typeof proofs.value === "undefined") return [];
this.proofs.push(...proofs.value); this.proofs.push(...proofs.value);
await this.persistState(); await this.persistState();
this.onBalanceUpdated?.();
return proofs.value; return proofs.value;
} }
@ -83,6 +85,7 @@ export default class PortalBtcWalletCashu {
status: "complete", status: "complete",
}); });
await this.persistState(); await this.persistState();
this.onBalanceUpdated?.();
} }
async redeemToken(token: string): Promise<void> { async redeemToken(token: string): Promise<void> {
@ -99,5 +102,6 @@ export default class PortalBtcWalletCashu {
status: "complete", status: "complete",
}); });
await this.persistState(); await this.persistState();
this.onBalanceUpdated?.();
} }
} }

View file

@ -89,7 +89,6 @@ export default class PortalBtcWallet {
this.cashuSDK = new PortalBtcWalletCashu( this.cashuSDK = new PortalBtcWalletCashu(
mnemonic, mnemonic,
cashuStore, cashuStore,
cashuMeltThreshold,
); );
} }
@ -105,6 +104,7 @@ export default class PortalBtcWallet {
console.log(e); console.log(e);
} }
this.refreshBreezBalances(); this.refreshBreezBalances();
this.emitEvent("balanceUpdated");
}, },
}); });
setLogger({ 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.redeemCashuQuotes();
await this.maybeMelt(); await this.maybeMelt();
} }
@ -134,6 +134,7 @@ export default class PortalBtcWallet {
(this.cashuBalance % this.cashuMeltThreshold); (this.cashuBalance % this.cashuMeltThreshold);
const invoice = await this.generateBolt11Invoice(cashuAmountToSwapToLiquid); const invoice = await this.generateBolt11Invoice(cashuAmountToSwapToLiquid);
await this.cashuSDK.meltProofsToPayInvoice(invoice); await this.cashuSDK.meltProofsToPayInvoice(invoice);
this.emitEvent("balanceUpdated");
} }
/** /**
@ -173,6 +174,7 @@ export default class PortalBtcWallet {
async redeemToken(token: string): Promise<void> { async redeemToken(token: string): Promise<void> {
await this.cashuSDK.redeemToken(token); await this.cashuSDK.redeemToken(token);
await this.maybeMelt(); await this.maybeMelt();
this.emitEvent("balanceUpdated");
} }
/** /**
@ -317,6 +319,7 @@ export default class PortalBtcWallet {
try { try {
if (parsedPayment.type === "bolt11") { if (parsedPayment.type === "bolt11") {
yield* this.payBolt11Invoice(parsedPayment, destination, amount); yield* this.payBolt11Invoice(parsedPayment, destination, amount);
this.emitEvent("balanceUpdated");
return; return;
} }
@ -342,6 +345,7 @@ export default class PortalBtcWallet {
parsedPayment.type === "liquidAddress" parsedPayment.type === "liquidAddress"
) { ) {
yield* this.payChainAddress(parsedPayment, amount); yield* this.payChainAddress(parsedPayment, amount);
this.emitEvent("balanceUpdated");
return; return;
} }
@ -369,6 +373,7 @@ export default class PortalBtcWallet {
status: PaymentStatus.PaymentSent, status: PaymentStatus.PaymentSent,
error: null, error: null,
}; };
this.emitEvent("balanceUpdated");
return; return;
} catch (e: unknown) { } catch (e: unknown) {
if (e instanceof Error) { if (e instanceof Error) {
@ -406,4 +411,28 @@ export default class PortalBtcWallet {
); );
return sortedPayments.slice(offset, offset + limit); return sortedPayments.slice(offset, offset + limit);
} }
private eventListeners: Record<string, (() => 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();
}
}
} }