@@ -0,0 +1,3 @@
|
||||
These will be removed (or moved) later, but please leave them for now.
|
||||
|
||||
These are experiments that I (Jim) am doing on Reactivity and I don't want to lose this code.
|
||||
@@ -0,0 +1,87 @@
|
||||
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<WalletP2PKHReact> {
|
||||
private rWallets: Array<WalletP2PKHReact> = [];
|
||||
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 };
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
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;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import { writable, derived } from 'svelte/store';
|
||||
import type { Writable, Readable } from 'svelte/store';
|
||||
import { WalletP2PKH, WalletHD } from '../wallet/index.js'; // Adjust import path as needed
|
||||
import type { AddressListUnspent, Blockchain } from '../wallet/index.js'; // Adjust import path as needed
|
||||
import type { Transaction } from '../primitives/index.js';
|
||||
import type { HdPrivateNodeValid } from '@bitauth/libauth';
|
||||
|
||||
export class WalletP2PKHSvelte extends WalletP2PKH {
|
||||
// Svelte stores
|
||||
public unspents: Writable<AddressListUnspent['response']> = writable([]);
|
||||
public transactions: Writable<Array<Transaction>> = writable([]);
|
||||
|
||||
// Derived store for balance
|
||||
public balance: Readable<number> = derived(this.unspents, ($unspents) =>
|
||||
$unspents.reduce((total, unspent) => total + unspent.value, 0)
|
||||
);
|
||||
|
||||
constructor(privateKeyBytes: Uint8Array, electrum: Blockchain) {
|
||||
super(privateKeyBytes, electrum);
|
||||
this.events.on('unspentsUpdated', (unspents) => {
|
||||
this.unspents.set(unspents);
|
||||
});
|
||||
this.events.on('transactionsUpdated', (transactions) => {
|
||||
this.transactions.set(transactions);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function useWalletP2PKHSvelte(
|
||||
privateKeyBytes: Uint8Array,
|
||||
electrum: Blockchain
|
||||
): WalletP2PKHSvelte {
|
||||
return new WalletP2PKHSvelte(privateKeyBytes, electrum);
|
||||
}
|
||||
|
||||
export class WalletHDSvelte extends WalletHD<WalletP2PKHSvelte> {
|
||||
// Svelte stores
|
||||
public shouldMonitor: Writable<boolean> = writable(false);
|
||||
public wallets: Writable<Array<WalletP2PKHSvelte>> = writable([]);
|
||||
|
||||
// Derived store for total balance
|
||||
public balance: Readable<number> = derived(this.wallets, ($wallets) =>
|
||||
$wallets.reduce((total, wallet) => {
|
||||
let walletBalance = 0;
|
||||
wallet.balance.subscribe((value) => (walletBalance = value))();
|
||||
return total + walletBalance;
|
||||
}, 0)
|
||||
);
|
||||
|
||||
constructor(
|
||||
node: HdPrivateNodeValid,
|
||||
electrum: Blockchain,
|
||||
walletFactory = useWalletP2PKHSvelte
|
||||
) {
|
||||
super(node, electrum, walletFactory);
|
||||
this.events.on('walletsUpdated', (wallets) => this.wallets.set(wallets));
|
||||
this.events.on('shouldMonitorUpdated', (shouldMonitor) =>
|
||||
this.shouldMonitor.set(shouldMonitor)
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user