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