+
{{ contributor.name }}
-
+
+
Project Maintainers
-
-
+
+
+
+
+
+ wiz
+
+
+
+
-
Copyright (c) 2019-2021
-
The Mempool Open Source Project
+
+ Copyright (c) 2019-2021
+ The Mempool Open Source Project
+
-
This program is free software: you can redistribute it and/or modify it
-
under the terms of the GNU Affero General Public License as published by
-
the Free Software Foundation, either version 3 of the License, or (at your
-
option) any later version.
+
+ This program is free software; you can redistribute it and/or modify it under the terms of (at your option) either:
+
-
This program is distributed in the hope that it will be useful, but
-
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
-
License for more details.
-
+
+
1) the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License or any later version approved by a proxy statement published on ; or
+
+
2) the GNU General Public License as published by the Free Software Foundation, either version 3 of the License or any later version approved by a proxy statement published on .
+
-
GNU Affero General Public License v3.0
-
-
Third Party Licenses
+
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the full license terms for more details.
+
diff --git a/frontend/src/app/components/about/about.component.scss b/frontend/src/app/components/about/about.component.scss
index b0b5716e4..8f829f95f 100644
--- a/frontend/src/app/components/about/about.component.scss
+++ b/frontend/src/app/components/about/about.component.scss
@@ -10,7 +10,8 @@
height: 80px;
background-size: 100%, 100%;
border-radius: 50%;
- margin: 10px;
+ margin: 25px;
+ line-height: 32px;
}
.profile_img {
@@ -20,6 +21,20 @@
border: 0;
}
+.community_sponsor {
+ margin: 6px;
+}
+
+.enterprise_sponsor {
+ margin-left: 40px;
+ margin-right: 40px;
+}
+
+.project_contributor {
+ width: 130px;
+ margin: 25px auto;
+}
+
.text-small {
font-size: 12px;
}
@@ -32,4 +47,4 @@
.required {
color: #FF0000;
font-weight: bold;
-}
\ No newline at end of file
+}
diff --git a/frontend/src/app/components/address/address.component.html b/frontend/src/app/components/address/address.component.html
index deb1eb3db..612412afc 100644
--- a/frontend/src/app/components/address/address.component.html
+++ b/frontend/src/app/components/address/address.component.html
@@ -117,7 +117,7 @@
{{ error.error }}
- Consider view this address on the official Mempool website instead:
+ Consider viewing this address on the official Mempool website instead:
https://mempool.space/address/{{ addressString }}
diff --git a/frontend/src/app/components/api-docs/api-docs.component.html b/frontend/src/app/components/api-docs/api-docs.component.html
index 583f89008..306288a91 100644
--- a/frontend/src/app/components/api-docs/api-docs.component.html
+++ b/frontend/src/app/components/api-docs/api-docs.component.html
@@ -105,7 +105,7 @@
Returns the transaction at index :index
within the specified block.
- GET {{ network.val === '' ? '' : '/' + network.val }}/api/block/:hash/txid/raw
+ GET {{ network.val === '' ? '' : '/' + network.val }}/api/block/:hash/raw
Returns the raw block representation in binary.
diff --git a/frontend/src/app/components/transaction/transaction.component.html b/frontend/src/app/components/transaction/transaction.component.html
index 7938429fa..106e49663 100644
--- a/frontend/src/app/components/transaction/transaction.component.html
+++ b/frontend/src/app/components/transaction/transaction.component.html
@@ -137,6 +137,54 @@
+
+
+
+ CPFP
+
+
+
Inputs & Outputs
@@ -279,26 +327,25 @@
{{ tx.fee | number }} sat ( )
- Fee per vByte
+ Fee rate
- {{ tx.fee / (tx.weight / 4) | number : '1.1-1' }} sat/vB
+ {{ tx.feePerVsize | number : '1.1-1' }} sat/vB
-
+
-
- Effective fee
+
+ Effective fee rate
{{ tx.effectiveFeePerVsize | number : '1.1-1' }} sat/vB
-
-
+
+ CPFP
-
-
\ No newline at end of file
+
diff --git a/frontend/src/app/components/transaction/transaction.component.scss b/frontend/src/app/components/transaction/transaction.component.scss
index 18ebaf55b..77b4ccf49 100644
--- a/frontend/src/app/components/transaction/transaction.component.scss
+++ b/frontend/src/app/components/transaction/transaction.component.scss
@@ -26,4 +26,21 @@
h1 {
margin-bottom: 0;
+}
+
+.badge {
+ position: relative;
+ top: -1px;
+}
+
+.btn-small-height {
+ line-height: 1.1;
+}
+
+.arrow-green {
+ color: #1a9436;
+}
+
+.arrow-red {
+ color: #dc3545;
}
\ No newline at end of file
diff --git a/frontend/src/app/components/transaction/transaction.component.ts b/frontend/src/app/components/transaction/transaction.component.ts
index d0c396959..770bcf993 100644
--- a/frontend/src/app/components/transaction/transaction.component.ts
+++ b/frontend/src/app/components/transaction/transaction.component.ts
@@ -9,6 +9,7 @@ import { WebsocketService } from '../../services/websocket.service';
import { AudioService } from 'src/app/services/audio.service';
import { ApiService } from 'src/app/services/api.service';
import { SeoService } from 'src/app/services/seo.service';
+import { CpfpInfo } from 'src/app/interfaces/node-api.interface';
@Component({
selector: 'app-transaction',
@@ -27,6 +28,8 @@ export class TransactionComponent implements OnInit, OnDestroy {
transactionTime = -1;
subscription: Subscription;
rbfTransaction: undefined | Transaction;
+ cpfpInfo: CpfpInfo | null;
+ showCpfpDetails = false;
constructor(
private route: ActivatedRoute,
@@ -77,6 +80,7 @@ export class TransactionComponent implements OnInit, OnDestroy {
if (tx.fee === undefined) {
this.tx.fee = 0;
}
+ this.tx.feePerVsize = tx.fee / (tx.weight / 4);
this.isLoadingTx = false;
this.error = undefined;
this.waitingForTransaction = false;
@@ -97,20 +101,25 @@ export class TransactionComponent implements OnInit, OnDestroy {
} else {
if (tx.effectiveFeePerVsize) {
this.stateService.markBlock$.next({ txFeePerVSize: tx.effectiveFeePerVsize });
+ this.cpfpInfo = {
+ ancestors: tx.ancestors,
+ bestDescendant: tx.bestDescendant,
+ };
} else {
- this.apiService.getCpfpinfo$(this.tx.txid)
+ this.apiService.getCpfpinfo$(this.tx.txid)
.subscribe((cpfpInfo) => {
- let totalWeight = tx.weight + cpfpInfo.ancestors.reduce((prev, val) => prev + val.weight, 0);
- let totalFees = tx.fee + cpfpInfo.ancestors.reduce((prev, val) => prev + val.fee, 0);
+ const lowerFeeParents = cpfpInfo.ancestors.filter((parent) => (parent.fee / (parent.weight / 4)) < tx.feePerVsize);
+ let totalWeight = tx.weight + lowerFeeParents.reduce((prev, val) => prev + val.weight, 0);
+ let totalFees = tx.fee + lowerFeeParents.reduce((prev, val) => prev + val.fee, 0);
if (cpfpInfo.bestDescendant) {
totalWeight += cpfpInfo.bestDescendant.weight;
totalFees += cpfpInfo.bestDescendant.fee;
}
- const effectiveFeePerVsize = totalFees / (totalWeight / 4);
- this.tx.effectiveFeePerVsize = effectiveFeePerVsize;
- this.stateService.markBlock$.next({ txFeePerVSize: effectiveFeePerVsize });
+ this.tx.effectiveFeePerVsize = totalFees / (totalWeight / 4);
+ this.stateService.markBlock$.next({ txFeePerVSize: this.tx.effectiveFeePerVsize });
+ this.cpfpInfo = cpfpInfo;
});
}
}
@@ -183,6 +192,8 @@ export class TransactionComponent implements OnInit, OnDestroy {
this.isLoadingTx = true;
this.rbfTransaction = undefined;
this.transactionTime = -1;
+ this.cpfpInfo = null;
+ this.showCpfpDetails = false;
document.body.scrollTo(0, 0);
this.leaveTransaction();
}
@@ -192,6 +203,10 @@ export class TransactionComponent implements OnInit, OnDestroy {
this.stateService.markBlock$.next({});
}
+ roundToOneDecimal(cpfpTx: any): number {
+ return +(cpfpTx.fee / (cpfpTx.weight / 4)).toFixed(1);
+ }
+
ngOnDestroy() {
this.subscription.unsubscribe();
this.leaveTransaction();
diff --git a/frontend/src/app/components/tx-fee-rating/tx-fee-rating.component.html b/frontend/src/app/components/tx-fee-rating/tx-fee-rating.component.html
index 4bfdf885d..fc6bf8662 100644
--- a/frontend/src/app/components/tx-fee-rating/tx-fee-rating.component.html
+++ b/frontend/src/app/components/tx-fee-rating/tx-fee-rating.component.html
@@ -1,3 +1,3 @@
Optimal
Overpaid {{ overpaidTimes }}x
-
Overpaid {{ overpaidTimes }}x
+
Overpaid {{ overpaidTimes }}x
diff --git a/frontend/src/app/interfaces/electrs.interface.ts b/frontend/src/app/interfaces/electrs.interface.ts
index 1ea0184ae..b09b3fd6d 100644
--- a/frontend/src/app/interfaces/electrs.interface.ts
+++ b/frontend/src/app/interfaces/electrs.interface.ts
@@ -11,7 +11,24 @@ export interface Transaction {
// Custom properties
firstSeen?: number;
+ feePerVsize?: number;
effectiveFeePerVsize?: number;
+ ancestors?: Ancestor[];
+ bestDescendant?: BestDescendant | null;
+ cpfpChecked?: boolean;
+ deleteAfter?: number;
+}
+
+interface Ancestor {
+ txid: string;
+ weight: number;
+ fee: number;
+}
+
+interface BestDescendant {
+ txid: string;
+ weight: number;
+ fee: number;
}
export interface Recent {
diff --git a/frontend/src/index.html b/frontend/src/index.html
index 7f344bc08..10d7ee1ea 100644
--- a/frontend/src/index.html
+++ b/frontend/src/index.html
@@ -6,7 +6,7 @@
-
+
@@ -15,7 +15,7 @@
-
+
diff --git a/frontend/src/locale/messages.xlf b/frontend/src/locale/messages.xlf
index cc70645cc..e2a4e921c 100644
--- a/frontend/src/locale/messages.xlf
+++ b/frontend/src/locale/messages.xlf
@@ -6,7 +6,7 @@
Transaction:
src/app/components/transaction/transaction.component.ts
- 48
+ 51
src/app/bisq/bisq-transaction/bisq-transaction.component.ts
@@ -97,7 +97,7 @@
Inputs & Outputs
src/app/components/transaction/transaction.component.html
- 142
+ 193
src/app/bisq/bisq-transaction/bisq-transaction.component.html
@@ -114,7 +114,7 @@
Details
src/app/components/transaction/transaction.component.html
- 144
+ 195
Transaction Details
transaction.details
@@ -123,11 +123,11 @@
Details
src/app/components/transaction/transaction.component.html
- 150
+ 201
src/app/components/transaction/transaction.component.html
- 226
+ 277
src/app/bisq/bisq-transaction/bisq-transaction.component.html
@@ -143,7 +143,7 @@
Size
src/app/components/transaction/transaction.component.html
- 155
+ 206
Transaction Size
transaction.size
@@ -152,7 +152,11 @@
Virtual size
src/app/components/transaction/transaction.component.html
- 159
+ 210
+
+
+ src/app/components/transaction/transaction.component.html
+ 150
Transaction Virtual Size
transaction.vsize
@@ -161,7 +165,7 @@
Weight
src/app/components/transaction/transaction.component.html
- 163
+ 214
Transaction Weight
transaction.weight
@@ -262,116 +266,77 @@
Transaction ETA in several hours or more
transaction.eta.in-several-hours
-
- Transaction not found.
+
+ Type
src/app/components/transaction/transaction.component.html
- 251
+ 148
- transaction.error.transaction-not-found
+
+ src/app/components/transactions-list/transactions-list.component.html
+ 169
+
+
+ src/app/bisq/bisq-transaction-details/bisq-transaction-details.component.html
+ 25
+
+
+ src/app/bisq/bisq-transactions/bisq-transactions.component.html
+ 19
+
+ transactions-list.vout.scriptpubkey-type
-
- Waiting for it to appear in the mempool...
+
+ TXID
src/app/components/transaction/transaction.component.html
- 252
+ 149
- transaction.error.waiting-for-it-to-appear
+
+ src/app/dashboard/dashboard.component.html
+ 107
+
+ dashboard.latest-transactions.txid
-
- In ~ minutes
+
+ Fee rate
src/app/components/transaction/transaction.component.html
- 267
+ 151
- src/app/components/mempool-blocks/mempool-blocks.component.html
- 41
+ src/app/components/transaction/transaction.component.html
+ 333
- Block Frequency (plural)
- mempool-blocks.eta-of-next-block-plural
+ Transaction fee rate
+ transaction.fee-rate
-
- In ~ minute
+
+ Descendant
src/app/components/transaction/transaction.component.html
- 269
+ 158
-
- src/app/components/mempool-blocks/mempool-blocks.component.html
- 43
-
- Block Frequency
- mempool-blocks.eta-of-next-block
-
-
- block
-
- src/app/components/transaction/transaction.component.html
- 271
-
-
- src/app/components/footer/footer.component.html
- 22
-
- shared.block
-
-
- blocks
-
- src/app/components/transaction/transaction.component.html
- 272
-
-
- src/app/components/mempool-blocks/mempool-blocks.component.html
- 30
-
-
- src/app/components/footer/footer.component.html
- 23
-
- shared.blocks
-
-
- Fee
-
- src/app/components/transaction/transaction.component.html
- 278
-
- Transaction fee
- transaction.fee
-
-
- sat
-
- src/app/components/transaction/transaction.component.html
- 279
-
- Transaction Fee sat
- transaction.fee.sat
-
-
- Fee per vByte
-
- src/app/components/transaction/transaction.component.html
- 282
-
-
- src/app/bisq/bisq-transaction/bisq-transaction.component.html
- 62
-
- Transaction fee
- transaction.fee-per-vbyte
+ Descendant
+ transaction.descendant
sat/vB
src/app/components/transaction/transaction.component.html
- 284
+ 166
src/app/components/transaction/transaction.component.html
- 294
+ 179
+
+
+ src/app/components/transaction/transaction.component.html
+ 335
+
+
+ src/app/components/transaction/transaction.component.html
+ 345
src/app/components/transactions-list/transactions-list.component.html
@@ -428,14 +393,111 @@
sat/vB
shared.sat-vbyte
-
- Effective fee
+
+ Ancestor
src/app/components/transaction/transaction.component.html
- 292
+ 172
- Effective transaction fee
- transaction.effective-fee
+ Transaction Ancestor
+ transaction.ancestor
+
+
+ Transaction not found.
+
+ src/app/components/transaction/transaction.component.html
+ 302
+
+ transaction.error.transaction-not-found
+
+
+ Waiting for it to appear in the mempool...
+
+ src/app/components/transaction/transaction.component.html
+ 303
+
+ transaction.error.waiting-for-it-to-appear
+
+
+ In ~ minutes
+
+ src/app/components/transaction/transaction.component.html
+ 318
+
+
+ src/app/components/mempool-blocks/mempool-blocks.component.html
+ 41
+
+ Block Frequency (plural)
+ mempool-blocks.eta-of-next-block-plural
+
+
+ In ~ minute
+
+ src/app/components/transaction/transaction.component.html
+ 320
+
+
+ src/app/components/mempool-blocks/mempool-blocks.component.html
+ 43
+
+ Block Frequency
+ mempool-blocks.eta-of-next-block
+
+
+ block
+
+ src/app/components/transaction/transaction.component.html
+ 322
+
+
+ src/app/components/footer/footer.component.html
+ 22
+
+ shared.block
+
+
+ blocks
+
+ src/app/components/transaction/transaction.component.html
+ 323
+
+
+ src/app/components/mempool-blocks/mempool-blocks.component.html
+ 30
+
+
+ src/app/components/footer/footer.component.html
+ 23
+
+ shared.blocks
+
+
+ Fee
+
+ src/app/components/transaction/transaction.component.html
+ 329
+
+ Transaction fee
+ transaction.fee
+
+
+ sat
+
+ src/app/components/transaction/transaction.component.html
+ 330
+
+ Transaction Fee sat
+ transaction.fee.sat
+
+
+ Effective fee rate
+
+ src/app/components/transaction/transaction.component.html
+ 343
+
+ Effective transaction fee rate
+ transaction.effective-fee-rate
Coinbase
@@ -557,22 +619,6 @@
ScriptPubKey (HEX)
transactions-list.scriptpubkey.hex
-
- Type
-
- src/app/components/transactions-list/transactions-list.component.html
- 169
-
-
- src/app/bisq/bisq-transaction-details/bisq-transaction-details.component.html
- 25
-
-
- src/app/bisq/bisq-transactions/bisq-transactions.component.html
- 19
-
- transactions-list.vout.scriptpubkey-type
-
data
@@ -1728,14 +1774,6 @@
dashboard.latest-transactions
-
- TXID
-
- src/app/dashboard/dashboard.component.html
- 107
-
- dashboard.latest-transactions.txid
-
Amount
@@ -2354,16 +2392,12 @@
TX Fee Rating is Optimal
tx-fee-rating.optimal
-
- Only ~ sat/vB was needed to get into this block
+
+ Only ~ sat/vB was needed to get into this block
src/app/components/tx-fee-rating/tx-fee-rating.component.html
2
-
- src/app/components/tx-fee-rating/tx-fee-rating.component.html
- 3
-
tx-fee-rating.warning-tooltip
@@ -2372,17 +2406,20 @@
src/app/components/tx-fee-rating/tx-fee-rating.component.html
2
- TX Fee Rating is Warning
- tx-fee-rating.overpaid.warning
-
-
- Overpaid x
src/app/components/tx-fee-rating/tx-fee-rating.component.html
3
- TX Fee Rating is Danger
- tx-fee-rating.overpaid.danger
+ TX Fee Rating is Warning
+ tx-fee-rating.overpaid.warning
+
+
+ Only ~ sat/vB was needed to get into this block
+
+ src/app/components/tx-fee-rating/tx-fee-rating.component.html
+ 3
+
+ tx-fee-rating.warning-tooltip
Just now
@@ -2517,6 +2554,13 @@
97
+
+ Address:
+
+ src/app/bisq/bisq-address/bisq-address.component.ts
+ 39
+
+
BSQ statistics
@@ -2628,13 +2672,6 @@
BSQ token market cap
-
- Address:
-
- src/app/bisq/bisq-address/bisq-address.component.ts
- 39
-
-
Confirmed
@@ -2691,6 +2728,15 @@
Transaction Previous Hash
block.previous_hash
+
+ Fee per vByte
+
+ src/app/bisq/bisq-transaction/bisq-transaction.component.html
+ 62
+
+ Transaction fee
+ transaction.fee-per-vbyte
+
Filter
diff --git a/frontend/src/resources/mempool-space-preview.png b/frontend/src/resources/mempool-space-preview.png
new file mode 100644
index 000000000..bfc59f600
Binary files /dev/null and b/frontend/src/resources/mempool-space-preview.png differ
diff --git a/frontend/src/resources/profile/bluewallet.png b/frontend/src/resources/profile/bluewallet.png
new file mode 100644
index 000000000..30d6493a4
Binary files /dev/null and b/frontend/src/resources/profile/bluewallet.png differ
diff --git a/frontend/src/resources/profile/gemini.svg b/frontend/src/resources/profile/gemini.svg
new file mode 100644
index 000000000..6aeecf1b9
--- /dev/null
+++ b/frontend/src/resources/profile/gemini.svg
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/frontend/src/resources/profile/muun.png b/frontend/src/resources/profile/muun.png
new file mode 100644
index 000000000..91079d821
Binary files /dev/null and b/frontend/src/resources/profile/muun.png differ
diff --git a/frontend/src/resources/profile/sqcrypto.png b/frontend/src/resources/profile/sqcrypto.png
new file mode 100644
index 000000000..26510c9b1
Binary files /dev/null and b/frontend/src/resources/profile/sqcrypto.png differ
diff --git a/frontend/tsconfig.base.json b/frontend/tsconfig.base.json
index 14336bc1a..b12d6068c 100644
--- a/frontend/tsconfig.base.json
+++ b/frontend/tsconfig.base.json
@@ -10,7 +10,7 @@
"module": "es2020",
"moduleResolution": "node",
"importHelpers": true,
- "target": "es2015",
+ "target": "es2020",
"typeRoots": [
"node_modules/@types"
],