Files
xo-stack/experiments/react/wallet-p2pkh-react.ts

75 lines
2.0 KiB
TypeScript

import { useSyncExternalStore } from 'react';
import { Transaction } from '../primitives/index.js';
import {
WalletP2PKH,
Blockchain,
AddressListUnspent,
} from '../wallet/index.js';
export function useWalletP2PKH(
privateKeyBytes: Uint8Array,
electrum: Blockchain,
) {
const wallet = React.useMemo(
() => new WalletP2PKHReact(privateKeyBytes, electrum),
[privateKeyBytes, electrum],
);
const unspents = useSyncExternalStore(
wallet.subscribeToUnspents,
wallet.getUnspents,
);
const transactions = useSyncExternalStore(
wallet.subscribeToTransactions,
wallet.getTransactions,
);
const balance = React.useMemo(() => {
return unspents.reduce((total, unspent) => total + unspent.value, 0);
}, [unspents]);
return { wallet, unspents, transactions, balance };
}
class WalletP2PKHReact extends WalletP2PKH {
private rUnspents: AddressListUnspent['response'] = [];
private rTransactions: Array<Transaction> = [];
private unspentsListeners: Set<() => void> = new Set();
private transactionsListeners: Set<() => void> = new Set();
constructor(privateKeyBytes: Uint8Array, blockchain: Blockchain) {
super(privateKeyBytes, blockchain);
this.events.on('unspentsUpdated', (unspents) => {
this.rUnspents = unspents;
this.unspentsListeners.forEach((listener) => listener());
});
this.events.on('transactionsUpdated', (transactions) => {
this.rTransactions = transactions;
this.transactionsListeners.forEach((listener) => listener());
});
}
subscribeToUnspents = (listener: () => void) => {
this.unspentsListeners.add(listener);
return () => {
this.unspentsListeners.delete(listener);
};
};
subscribeToTransactions = (listener: () => void) => {
this.transactionsListeners.add(listener);
return () => {
this.transactionsListeners.delete(listener);
};
};
getUnspents = () => {
return this.rUnspents;
};
getTransactions = () => {
return this.rTransactions;
};
}