import React, { useSyncExternalStore, useMemo } from 'react'; import { Blockchain, WalletHD } from '../wallet/index.js'; import { WalletP2PKHReact, useWalletP2PKH } from './wallet-p2pkh-react.js'; import { HdPrivateNodeValid } from '@bitauth/libauth'; class WalletHDReact extends WalletHD { private rWallets: Array = []; private rShouldMonitor: boolean = false; private walletsListeners: Set<() => void> = new Set(); private shouldMonitorListeners: Set<() => void> = new Set(); constructor( node: HdPrivateNodeValid, electrum: Blockchain, walletFactory = (privateKeyBytes: Uint8Array, electrum: Blockchain) => new WalletP2PKHReact(privateKeyBytes, electrum), ) { super(node, electrum, walletFactory); this.events.on('walletsUpdated', (wallets) => { this.rWallets = wallets; this.setupWalletListeners(); this.walletsListeners.forEach((listener) => listener()); }); this.events.on('shouldMonitorUpdated', (shouldMonitor) => { this.rShouldMonitor = shouldMonitor; this.shouldMonitorListeners.forEach((listener) => listener()); }); } subscribeToWallets = (listener: () => void) => { this.walletsListeners.add(listener); return () => { this.walletsListeners.delete(listener); }; }; subscribeToShouldMonitor = (listener: () => void) => { this.shouldMonitorListeners.add(listener); return () => { this.shouldMonitorListeners.delete(listener); }; }; getWallets = () => { return this.rWallets; }; getShouldMonitor = () => { return this.rShouldMonitor; }; private setupWalletListeners() { this.rWallets.forEach((wallet) => { wallet.subscribeToUnspents(() => { this.walletsListeners.forEach((listener) => listener()); }); wallet.subscribeToTransactions(() => { this.walletsListeners.forEach((listener) => listener()); }); }); } } export function useWalletHD(node: HdPrivateNodeValid, electrum: Blockchain) { const walletHD = useMemo( () => new WalletHDReact(node, electrum), [node, electrum], ); const wallets = useSyncExternalStore( walletHD.subscribeToWallets, walletHD.getWallets, ); const shouldMonitor = useSyncExternalStore( walletHD.subscribeToShouldMonitor, walletHD.getShouldMonitor, ); const balance = useMemo(() => { return wallets.reduce((total, wallet) => total + wallet.getBalance(), 0); }, [wallets]); return { walletHD, wallets, shouldMonitor, balance }; }