diff --git a/frontend/src/app/components/addresses-treemap/addresses-treemap.component.ts b/frontend/src/app/components/addresses-treemap/addresses-treemap.component.ts
index 705941caf..f78b4e2e1 100644
--- a/frontend/src/app/components/addresses-treemap/addresses-treemap.component.ts
+++ b/frontend/src/app/components/addresses-treemap/addresses-treemap.component.ts
@@ -39,14 +39,19 @@ export class AddressesTreemap implements OnChanges {
}
prepareChartOptions(): void {
- const maxTxs = this.addresses.reduce((max, address) => Math.max(max, address.chain_stats.tx_count), 0);
const data = this.addresses.map(address => ({
- address: address.address,
- value: address.chain_stats.funded_txo_sum - address.chain_stats.spent_txo_sum,
- stats: address.chain_stats,
- itemStyle: {
- color: lerpColor('#1E88E5', '#D81B60', address.chain_stats.tx_count / maxTxs),
- }
+ address: address.address,
+ value: address.chain_stats.funded_txo_sum - address.chain_stats.spent_txo_sum,
+ stats: address.chain_stats,
+ }));
+ // only consider visible items for the color gradient
+ const totalValue = data.reduce((acc, address) => acc + address.value, 0);
+ const maxTxs = data.filter(address => address.value > (totalValue / 2000)).reduce((max, address) => Math.max(max, address.stats.tx_count), 0);
+ const dataItems = data.map(address => ({
+ ...address,
+ itemStyle: {
+ color: lerpColor('#1E88E5', '#D81B60', address.stats.tx_count / maxTxs),
+ }
}));
this.chartOptions = {
tooltip: {
@@ -64,7 +69,7 @@ export class AddressesTreemap implements OnChanges {
top: 0,
roam: false,
type: 'treemap',
- data: data,
+ data: dataItems,
nodeClick: 'link',
progressive: 100,
tooltip: {
@@ -87,7 +92,7 @@ export class AddressesTreemap implements OnChanges {
${value.data.address}
- Recieved
+ Received
${this.formatValue(value.data.stats.funded_txo_sum)}
diff --git a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts
index 622e6cf3a..eb9818632 100644
--- a/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts
+++ b/frontend/src/app/components/custom-dashboard/custom-dashboard.component.ts
@@ -370,23 +370,47 @@ export class CustomDashboardComponent implements OnInit, OnDestroy, AfterViewIni
const walletName = this.stateService.env.customize.dashboard.widgets.find(w => w.props?.wallet).props.wallet;
this.websocketService.startTrackingWallet(walletName);
- this.walletSummary$ = this.apiService.getWallet$(walletName).pipe(
+ this.walletSummary$ = this.apiService.getWallet$(walletName).pipe(
catchError(e => {
- return of(null);
+ return of({});
}),
- map((walletTransactions) => {
- const transactions = Object.values(walletTransactions).flatMap(wallet => wallet.transactions);
- return this.deduplicateWalletTransactions(transactions);
- }),
- switchMap(initial => this.stateService.walletTransactions$.pipe(
- startWith(null),
- scan((summary, walletTransactions) => {
- if (walletTransactions) {
- const transactions: AddressTxSummary[] = [...summary, ...Object.values(walletTransactions).flat()];
- return this.deduplicateWalletTransactions(transactions);
+ switchMap(wallet => this.stateService.walletTransactions$.pipe(
+ startWith([]),
+ scan((summaries, newTransactions) => {
+ const newSummaries: AddressTxSummary[] = [];
+ for (const tx of newTransactions) {
+ const funded: Record = {};
+ const spent: Record = {};
+ const fundedCount: Record = {};
+ const spentCount: Record = {};
+ for (const vin of tx.vin) {
+ const address = vin.prevout?.scriptpubkey_address;
+ if (address && wallet[address]) {
+ spent[address] = (spent[address] ?? 0) + (vin.prevout?.value ?? 0);
+ spentCount[address] = (spentCount[address] ?? 0) + 1;
+ }
+ }
+ for (const vout of tx.vout) {
+ const address = vout.scriptpubkey_address;
+ if (address && wallet[address]) {
+ funded[address] = (funded[address] ?? 0) + (vout.value ?? 0);
+ fundedCount[address] = (fundedCount[address] ?? 0) + 1;
+ }
+ }
+ for (const address of Object.keys({ ...funded, ...spent })) {
+ // add tx to summary
+ const txSummary: AddressTxSummary = {
+ txid: tx.txid,
+ value: (funded[address] ?? 0) - (spent[address] ?? 0),
+ height: tx.status.block_height,
+ time: tx.status.block_time,
+ };
+ wallet[address].transactions?.push(txSummary);
+ newSummaries.push(txSummary);
+ }
}
- return summary;
- }, initial)
+ return [...summaries, ...this.deduplicateWalletTransactions(newSummaries)];
+ }, this.deduplicateWalletTransactions(Object.values(wallet).flatMap(address => address.transactions)))
)),
share(),
);
diff --git a/frontend/src/app/components/wallet/wallet.component.html b/frontend/src/app/components/wallet/wallet.component.html
index 60cc4e264..52b7b02a5 100644
--- a/frontend/src/app/components/wallet/wallet.component.html
+++ b/frontend/src/app/components/wallet/wallet.component.html
@@ -5,7 +5,7 @@
-
+
-
+
+
+ Confirmed balance
+
+
+
+ Confirmed UTXOs
+ {{ walletStats.utxos }}
+
Total received
-
+
-
- Total sent
-
-
-
-
- Balance
-
-
+
- 2">
+
Balance History
@@ -67,56 +67,16 @@
+
-
-
-
- Transactions
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-