Compare commits
6 Commits
master
...
5376-merge
Author | SHA1 | Date | |
---|---|---|---|
|
e3953a6dca | ||
|
78844f5787 | ||
|
79e2883ebe | ||
|
fdbca80920 | ||
|
64baade3b3 | ||
|
4d06636d83 |
@ -19,8 +19,13 @@ interface WalletAddress {
|
||||
lastSync: number;
|
||||
}
|
||||
|
||||
interface Wallet {
|
||||
interface WalletConfig {
|
||||
url: string;
|
||||
name: string;
|
||||
apiKey: string;
|
||||
}
|
||||
|
||||
interface Wallet extends WalletConfig {
|
||||
addresses: Record<string, WalletAddress>;
|
||||
lastPoll: number;
|
||||
}
|
||||
@ -32,10 +37,10 @@ class WalletApi {
|
||||
private syncing = false;
|
||||
|
||||
constructor() {
|
||||
this.wallets = config.WALLETS.ENABLED ? (config.WALLETS.WALLETS as string[]).reduce((acc, wallet) => {
|
||||
acc[wallet] = { name: wallet, addresses: {}, lastPoll: 0 };
|
||||
this.wallets = (config.WALLETS.WALLETS as WalletConfig[]).reduce((acc, wallet) => {
|
||||
acc[wallet.name] = { ...wallet, addresses: {}, lastPoll: 0 };
|
||||
return acc;
|
||||
}, {} as Record<string, Wallet>) : {};
|
||||
}, {} as Record<string, Wallet>);
|
||||
}
|
||||
|
||||
public getWallet(wallet: string): Record<string, WalletAddress> {
|
||||
@ -52,16 +57,18 @@ class WalletApi {
|
||||
const wallet = this.wallets[walletKey];
|
||||
if (wallet.lastPoll < (Date.now() - POLL_FREQUENCY)) {
|
||||
try {
|
||||
const response = await axios.get(config.MEMPOOL_SERVICES.API + `/wallets/${wallet.name}`);
|
||||
const addresses: Record<string, WalletAddress> = response.data;
|
||||
const addressList: WalletAddress[] = Object.values(addresses);
|
||||
const response = await axios.get(`${wallet.url}/${wallet.name}`, { headers: { 'Authorization': `${wallet.apiKey}` } });
|
||||
const data: { walletBalances: WalletAddress[] } = response.data;
|
||||
const addresses = data.walletBalances;
|
||||
const newAddresses: Record<string, boolean> = {};
|
||||
// sync all current addresses
|
||||
for (const address of addressList) {
|
||||
for (const address of addresses) {
|
||||
await this.$syncWalletAddress(wallet, address);
|
||||
newAddresses[address.address] = true;
|
||||
}
|
||||
// remove old addresses
|
||||
for (const address of Object.keys(wallet.addresses)) {
|
||||
if (!addresses[address]) {
|
||||
if (!newAddresses[address]) {
|
||||
delete wallet.addresses[address];
|
||||
}
|
||||
}
|
||||
@ -86,10 +93,11 @@ class WalletApi {
|
||||
const walletAddress: WalletAddress = {
|
||||
address: address.address,
|
||||
active: address.active,
|
||||
transactions: summary,
|
||||
transactions: await bitcoinApi.$getAddressTransactionSummary(address.address),
|
||||
stats: addressInfo.chain_stats,
|
||||
lastSync: Date.now(),
|
||||
};
|
||||
logger.debug(`Synced ${walletAddress.transactions?.length || 0} transactions for wallet ${wallet.name} address ${address.address}`);
|
||||
wallet.addresses[address.address] = walletAddress;
|
||||
} catch (e) {
|
||||
logger.err(`Error syncing wallet address ${address.address}: ${(e instanceof Error ? e.message : e)}`);
|
||||
@ -142,7 +150,17 @@ class WalletApi {
|
||||
wallet.addresses[address].transactions?.push(txSummary);
|
||||
}
|
||||
if (anyMatch) {
|
||||
walletTransactions[walletKey].push(tx);
|
||||
for (const address of Object.keys({ ...funded, ...spent })) {
|
||||
if (!walletTransactions[walletKey][address]) {
|
||||
walletTransactions[walletKey][address] = [];
|
||||
}
|
||||
walletTransactions[walletKey][address].push({
|
||||
txid: tx.txid,
|
||||
value: (funded[address] ?? 0) - (spent[address] ?? 0),
|
||||
height: block.height,
|
||||
time: block.timestamp,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +164,11 @@ interface IConfig {
|
||||
},
|
||||
WALLETS: {
|
||||
ENABLED: boolean;
|
||||
WALLETS: string[];
|
||||
WALLETS: {
|
||||
url: string;
|
||||
name: string;
|
||||
apiKey: string;
|
||||
}[];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +131,8 @@ export NVM_DIR="${HOME}/.nvm"
|
||||
source "${NVM_DIR}/nvm.sh"
|
||||
|
||||
# what to look for
|
||||
frontends=(mainnet liquid onbtc meta)
|
||||
backends=(mainnet testnet testnet4 signet liquid liquidtestnet onbtc)
|
||||
frontends=(mainnet liquid onbtc bitb meta)
|
||||
backends=(mainnet testnet testnet4 signet liquid liquidtestnet onbtc bitb)
|
||||
frontend_repos=()
|
||||
backend_repos=()
|
||||
|
||||
|
@ -15,7 +15,7 @@ screen -dmS x startx
|
||||
sleep 3
|
||||
|
||||
# start unfurlers for each frontend
|
||||
for site in mainnet liquid onbtc meta;do
|
||||
for site in mainnet liquid onbtc bitb meta;do
|
||||
cd "$HOME/${site}/unfurler" && \
|
||||
echo "starting mempool unfurler: ${site}" && \
|
||||
screen -dmS "unfurler-${site}" sh -c 'while true;do npm run unfurler;sleep 2;done'
|
||||
|
@ -282,6 +282,26 @@ export const networks = {
|
||||
}
|
||||
}
|
||||
},
|
||||
bitb: {
|
||||
title: 'BITB | Bitwise Bitcoin ETF',
|
||||
description: 'BITB provides low-cost access to bitcoin through a professionally managed fund',
|
||||
fallbackImg: '/resources/bitb/bitb-preview.jpg',
|
||||
routes: { // only dynamic routes supported
|
||||
block: routes.block,
|
||||
address: routes.address,
|
||||
tx: routes.tx,
|
||||
mining: {
|
||||
title: "Mining",
|
||||
routes: {
|
||||
pool: routes.mining.routes.pool,
|
||||
}
|
||||
},
|
||||
lightning: {
|
||||
title: "Lightning",
|
||||
routes: routes.lightning.routes,
|
||||
}
|
||||
}
|
||||
},
|
||||
meta: {
|
||||
title: 'Metaplanet Inc.',
|
||||
description: 'Secure the Future with Bitcoin',
|
||||
|
Loading…
x
Reference in New Issue
Block a user