Compare commits

..
Author SHA1 Message Date
natsoni b6b3e52436 Shades of green / red on DA blocks 2024-09-02 16:18:23 +02:00
natsoni d04e5128ba Add endpoint for difficulty adjustment by height 2024-09-02 16:16:53 +02:00
softsimon e3c3f31ddb Merge pull request #5494 from vostrnad/zero-multisig
Allow OP_0 in multisig scripts
2024-09-01 10:49:27 +04:00
wiz 70d1f52268 Merge pull request #5489 from mempool/mononaut/the-v3-standard 2024-09-01 02:02:21 +09:00
Vojtěch Strnad e44f30d7a7 Allow OP_0 in multisig scripts 2024-08-31 14:31:55 +02:00
Mononaut 099d84a395 New standardness rules for v3 & anchor outputs, with activation height logic 2024-08-30 23:16:33 +00:00
Mononaut 12285465d9 Add support for anchor output type 2024-08-30 21:39:22 +00:00
softsimon 3bea10ea35 Merge pull request #5484 from mempool/dependabot/npm_and_yarn/frontend/cypress-13.14.0
Bump cypress from 13.13.0 to 13.14.0 in /frontend
2024-08-28 07:00:55 +02:00
dependabot[bot] 1ea45e9e96 Bump cypress from 13.13.0 to 13.14.0 in /frontend
Bumps [cypress](https://github.com/cypress-io/cypress) from 13.13.0 to 13.14.0.
- [Release notes](https://github.com/cypress-io/cypress/releases)
- [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md)
- [Commits](https://github.com/cypress-io/cypress/compare/v13.13.0...v13.14.0)

---
updated-dependencies:
- dependency-name: cypress
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-28 02:59:35 +00:00
softsimon 8c2d0e1d6c Merge pull request #5445 from mempool/mononaut/persistent-goggles
Persist mempool block visualization between pages
2024-08-26 22:14:17 +02:00
softsimon 009fba3dd5 Merge branch 'master' into mononaut/persistent-goggles 2024-08-26 22:05:16 +02:00
softsimon a0fc4861d4 Merge pull request #5460 from mempool/mononaut/v1-audit-improvements
v1 audit improvements
2024-08-26 21:38:37 +02:00
softsimon 62085581dd Merge branch 'master' into mononaut/v1-audit-improvements 2024-08-26 18:45:00 +02:00
softsimon 05efa8c300 Merge pull request #5468 from mempool/dependabot/npm_and_yarn/frontend/elliptic-6.5.7
Bump elliptic from 6.5.4 to 6.5.7 in /frontend
2024-08-26 17:59:21 +02:00
softsimon eee99a6407 Merge pull request #5477 from mempool/mononaut/readme-node-version
[docs] update READMEs to newer node version
2024-08-26 17:58:52 +02:00
Mononaut 98cee4a6cd [docs] update READMEs to newer node version 2024-08-26 15:36:53 +00:00
dependabot[bot] 0302999806 Bump elliptic from 6.5.4 to 6.5.7 in /frontend
Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.4 to 6.5.7.
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.4...v6.5.7)

---
updated-dependencies:
- dependency-name: elliptic
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 14:54:51 +00:00
softsimon 1876d67e74 Merge pull request #5467 from mempool/dependabot/npm_and_yarn/backend/axios-1.7.4
Bump axios from 1.7.2 to 1.7.4 in /backend
2024-08-26 16:53:40 +02:00
softsimon c0bb75e5b1 Merge pull request #5475 from mempool/dependabot/npm_and_yarn/frontend/tslib-2.7.0
Bump tslib from 2.6.2 to 2.7.0 in /frontend
2024-08-26 16:53:26 +02:00
dependabot[bot] 4059a902a1 Bump tslib from 2.6.2 to 2.7.0 in /frontend
Bumps [tslib](https://github.com/Microsoft/tslib) from 2.6.2 to 2.7.0.
- [Release notes](https://github.com/Microsoft/tslib/releases)
- [Commits](https://github.com/Microsoft/tslib/compare/v2.6.2...v2.7.0)

---
updated-dependencies:
- dependency-name: tslib
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 12:42:46 +00:00
dependabot[bot] 4cc19a7235 Bump axios from 1.7.2 to 1.7.4 in /backend
Bumps [axios](https://github.com/axios/axios) from 1.7.2 to 1.7.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.7.2...v1.7.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-08-26 12:42:42 +00:00
wiz c874d642c5 Bump version to 3.1.0-dev 2024-08-26 21:41:26 +09:00
wiz f0af1703da Release v3.0.0 2024-08-24 18:35:41 +09:00
softsimon 5452d7f524 pull from transifex 2024-08-20 09:32:56 +02:00
wiz ff9e2456b9 ops: Tweak build script to support tags 2024-08-20 15:22:16 +09:00
wiz 4e581347c8 Bump version to v3.0.0-rc1 2024-08-20 12:06:11 +09:00
wiz 820777236e Merge pull request #5465 from mempool/orangesurf/update-logos-2024-08-19
Add logo images and references to logos
2024-08-20 12:01:51 +09:00
wiz beeb5eb08c Merge pull request #5466 from mempool/mononaut/fix-about-layout
Fix about page layout
2024-08-20 10:50:04 +09:00
Mononaut b78aca0282 Fix about page layout 2024-08-19 19:46:22 +00:00
orangesurf 9572f2d554 Add logo images and references to logos 2024-08-19 20:13:49 +02:00
softsimon ef13596b59 Merge pull request #5449 from mempool/mononaut/non-acc-effective-fee
fix mined acceleration detection logic on tx pages
2024-08-19 17:10:46 +02:00
wiz 80da024bbb Add hr locale to angular.json 2024-08-19 14:49:36 +09:00
natsoni f75f85f914 Hide fee delta on accelerated tx mined by participating pool with 0 bid boost 2024-08-18 19:43:38 +02:00
natsoni b3ac107b0b clear feeDelta if a tx is mined by non-participating pool 2024-08-18 18:35:30 +02:00
softsimon f8cedaa7a3 Merge pull request #5462 from mempool/natsoni/fix-console-error
Fix accelerated arrow not appearing
2024-08-18 15:47:02 +02:00
natsoni 72bb92dd8b Merge branch 'master' into mononaut/non-acc-effective-fee 2024-08-18 14:27:48 +02:00
natsoni e3c4e219f3 Fix accelerated arrow not appearing 2024-08-18 14:15:56 +02:00
wiz aa3fa4478a Merge pull request #5458 from mempool/mononaut/pool-pie-colors
update pool pie chart color scheme
2024-08-18 12:15:27 +09:00
Mononaut c9171224e1 DB migration to fix bad v1 audits 2024-08-18 02:21:12 +00:00
Mononaut 248cef7718 Improve prioritized transaction detection algorithm 2024-08-18 02:21:05 +00:00
Mononaut 26c03eee88 update pool pie chart color scheme 2024-08-14 14:21:47 +00:00
softsimon db10ab9aae pull from transifex 2024-08-13 10:28:42 +02:00
wiz 2ee7b9531a Merge pull request #5454 from mempool/simon/add-croatian
Add Croatian language
2024-08-13 13:36:00 +09:00
wiz 5f6af83944 Merge pull request #5453 from mempool/mononaut/acceleration-sparkles
acceleration sparkles
2024-08-13 13:33:25 +09:00
softsimon 8d2204a53f Merge pull request #5457 from mempool/mononaut/flow-output-indices
flow diagram zero-indexed inputs & outputs
2024-08-12 23:04:34 +02:00
Mononaut 96bec279a9 flow diagram zero-indexed inputs & outputs 2024-08-12 14:54:51 +00:00
softsimon 5178ae43f6 Add Croatian language 2024-08-12 00:07:48 +02:00
softsimon ca26154426 pull from transifex 2024-08-11 23:51:16 +02:00
Mononaut 021f0b32a1 sparklier sparkles 2024-08-11 20:52:26 +00:00
Mononaut b8cfeb579b make accelerations magical again 2024-08-11 20:38:54 +00:00
softsimon fc5b99f93f Merge pull request #5452 from mempool/mononaut/tx-v1-audit
Implement v1 audit in tx audit API
2024-08-11 00:18:09 +02:00
Mononaut ce4b0ed0f3 Implement v1 audit in tx audit API 2024-08-10 21:57:31 +00:00
Mononaut a31729b8b8 fix feeDelta display logic 2024-08-10 21:56:11 +00:00
Mononaut 79e494150c fix mined acceleration detection logic on tx pages 2024-08-09 14:44:51 +00:00
softsimon b1a43abc0e Merge pull request #5444 from mempool/natsoni/fix-pool-pie-position
Fix pool pie position on safari
2024-08-08 22:20:09 +02:00
softsimon 3e50a3c9e7 pull from transifex 2024-08-08 18:58:59 +02:00
Mononaut 104c7f4285 Persist mempool block visualization between pages 2024-08-08 13:12:31 +00:00
natsoni 132d6204c3 Fix pool pie position on safari 2024-08-08 11:23:56 +02:00
wiz 77c6ad5576 Merge pull request #5438 from mempool/natsoni/hide-fee-delta-on-confirmed
Hide fee delta on accelerated tx if bid boost is 0
2024-08-07 19:38:04 -04:00
wiz 4d35845c18 Merge pull request #5441 from mempool/simon/remove-testnet4-beta
remove testnet4 beta tag
2024-08-07 19:36:55 -04:00
wiz 3d8a4a85f7 Merge pull request #5433 from mempool/simon/remove-mempool-goggles-beta
remove mempool googles [beta] tag
2024-08-07 19:36:45 -04:00
wiz 1545347a45 Merge pull request #5443 from mempool/simon/fix-broken-sponsor-image-proxy
fix broken sponsor image proxy
2024-08-07 18:11:59 -04:00
softsimon 9facf28ba5 pull from transifex 2024-08-07 23:57:11 +02:00
softsimon d6eb98561b Merge pull request #5439 from mempool/natsoni/purple-acc-fee-rate
Consistent purple accelerated fee rate
2024-08-07 23:42:37 +02:00
softsimon 0f688e8347 fix broken sponsor image proxy 2024-08-07 23:41:53 +02:00
wiz 7f53741a7b Merge pull request #5442 from mempool/simon/timesincepaid-sorry-time-increase
increasing time since paid sorry message
2024-08-07 17:19:11 -04:00
softsimon d5672691e1 increasing time since paid sorry message 2024-08-07 22:06:22 +02:00
softsimon e6049c707b remove testnet4 beta tag 2024-08-07 22:03:47 +02:00
natsoni 91e74e769c Purple accelerated fee rate everywhere 2024-08-07 14:19:59 +02:00
natsoni 7f252f06b7 Hide fee delta on accelerated tx with bidBoost=0 2024-08-07 11:11:31 +02:00
softsimon 1b9d3f669d remove mempool googles [beta] tag 2024-08-07 00:30:20 +02:00
wiz ef0ba9a77a ops: Add mempool-update-repo script 2024-08-06 18:30:11 -04:00
wiz 15f10736e2 Merge pull request #5432 from mempool/simon/match-any-onion
match any onion
2024-08-06 18:26:31 -04:00
softsimon 924399df46 match any onion 2024-08-07 00:24:23 +02:00
wiz cddff129b3 Merge pull request #5431 from mempool/simon/fix-services-onion
fix services onion url
2024-08-06 17:29:15 -04:00
softsimon 7c90e8ae06 fix services onion url 2024-08-06 23:27:59 +02:00
wiz 34d996c7cb Merge pull request #5430 from mempool/natsoni/dynamically-show-oob-fee
Immediately show oob fee on accelerated transaction
2024-08-06 15:00:49 -04:00
wiz 641a2ae3ae Remove testnet4 not-yet-finalized warning now that BIP is merged 2024-08-05 15:37:29 -04:00
natsoni 11a849ef28 Immediately show oob fee on accelerated transaction 2024-08-05 21:01:33 +02:00
wiz 7b0347e846 Bump version string to 3.0.0-beta 2024-08-05 14:55:59 -04:00
wiz bb1352ed58 Merge pull request #5427 from mempool/mononaut/fix-other-liquid-migration
fix db migration 75 on liquid
2024-08-05 14:09:36 -04:00
wiz fa6456b92c Merge pull request #5422 from mempool/natsoni/purple-accelerated-rate
Purple accelerated fee rate
2024-08-05 14:09:14 -04:00
wiz bfea19238b Merge pull request #5420 from mempool/natsoni/add-tooltip-acc-fee
Add tooltip to acceleration fee
2024-08-05 14:04:42 -04:00
wiz 36b91cfdfd Merge pull request #5421 from mempool/mononaut/rbf-tracker-redirect
Fix broken pizza rbf link to /tracker
2024-08-05 14:04:20 -04:00
wiz 7b56212064 Merge pull request #5425 from mempool/natsoni/clear-mining-cache-network-change
Clear mining service cache on network change
2024-08-05 14:03:14 -04:00
wiz d4be3c2c4c Merge pull request #5428 from mempool/mononaut/payment-method-click
[accelerator] fix click binding on payment method buttons
2024-08-05 14:02:51 -04:00
wiz 3a9f06f651 Merge pull request #5429 from mempool/mononaut/fix-block-unfurl-loading
Fix stray loading spinner in block unfurl
2024-08-05 14:02:34 -04:00
Mononaut e652eb339d Fix stray loading spinner in block unfurl 2024-08-05 17:08:44 +00:00
softsimon 96435c329f Merge pull request #5426 from mempool/mononaut/fix-liquid-migration
fix liquid db migration
2024-08-05 18:47:26 +02:00
Mononaut 1c69613d65 [accelerator] fix click binding on payment method buttons 2024-08-05 16:15:53 +00:00
Mononaut 3707763e30 fix db migration 75 on liquid 2024-08-05 16:03:22 +00:00
Mononaut b6ce8229f0 fix liquid db migration 2024-08-05 15:49:16 +00:00
natsoni b62ae9b6f6 Clear mining service cache on network change 2024-08-05 15:45:39 +02:00
Mononaut f61ace2f92 Fix broken pizza rbf link to /tracker 2024-08-05 10:31:01 +00:00
natsoni 2b572f2494 Purple accelerated fee rate 2024-08-05 12:20:49 +02:00
natsoni c0e4c1efe1 Fix text wrap 2024-08-05 11:53:01 +02:00
natsoni 8078caaa89 Add tooltip to acceleration fee 2024-08-05 11:36:35 +02:00
wiz 5eb117165f Revert "ops: Remove potentially dangerous env var in rust build process"
This reverts commit a2dcf0d545.
2024-08-04 21:19:44 -04:00
wiz a2dcf0d545 ops: Remove potentially dangerous env var in rust build process 2024-08-04 21:06:36 -04:00
wiz 212d58f917 Change accelerate checkout redirect from /tracker/ to /tx/ 2024-08-04 20:52:49 -04:00
wiz d1eec80afb Delete redirect to /tracker/ for cash.app 2024-08-04 20:45:05 -04:00
wiz 05c6709926 Merge pull request #5417 from mempool/simon/hide-fiat-buttons-correctly
hide fiat buttons correctly
2024-08-04 19:45:07 -04:00
softsimon f1a48db9ee hide fiat buttons correctly 2024-08-05 01:43:58 +02:00
wiz 76ce43d289 Merge pull request #5416 from mempool/simon/enable-acc-button-enterprise
enable accelerator button on enterprise instances
2024-08-04 19:22:33 -04:00
softsimon 51f5b728f3 enable accelerator button on enterprise instances 2024-08-05 01:20:40 +02:00
wiz 8fa1863aff Merge pull request #5415 from mempool/simon/fix-invalid-json-response-requestAcceleration
fix invalid json response from requestAcceleration
2024-08-04 19:12:06 -04:00
softsimon e3d1d9c1c0 fix invalid json response from requestAcceleration 2024-08-05 01:11:18 +02:00
wiz f2f8d91e10 Merge pull request #5410 from mempool/natsoni/show-oob-fee
Show oob fees on tx details
2024-08-04 19:02:20 -04:00
wiz 11ef090846 Merge pull request #5414 from mempool/simon/only-enable-fiat-prod-staging
only enable fiat on prod and staging
2024-08-04 19:01:54 -04:00
softsimon 5cacd2635e only enable fiat on prod, staging and dev 2024-08-05 01:00:58 +02:00
softsimon 1b4780c25b Merge pull request #5409 from mempool/natsoni/fix-truncated-link
Fix truncated link to not refresh full window
2024-08-05 00:16:15 +02:00
softsimon 5ea44f2e7d Merge pull request #5408 from mempool/natsoni/pizza-tracker-fix-crash
Pizza tracker: handle transaction not yet in mempool
2024-08-04 23:39:39 +02:00
softsimon 261c794817 pull from transifex 2024-08-04 23:36:03 +02:00
natsoni de9fae5cd7 Show oob fees on tx details 2024-08-04 17:07:38 +02:00
natsoni 439c52af30 Fix truncated link to not refresh full window 2024-08-04 14:36:42 +02:00
natsoni e378df4158 Fix pizza tracker crash on unseen transaction 2024-08-02 18:52:07 +02:00
107 changed files with 2126 additions and 285 deletions

No files matched your search

+7 -5
View File
@@ -1,5 +1,5 @@
The Mempool Open Source Project®
Copyright (c) 2019-2023 Mempool Space K.K. and other shadowy super-coders
Copyright (c) 2019-2024 Mempool Space K.K. and other shadowy super-coders
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
@@ -12,10 +12,12 @@ or any other contributor to The Mempool Open Source Project.
The Mempool Open Source Project®, Mempool Accelerator™, Mempool Enterprise®,
Mempool Liquidity™, mempool.space®, Be your own explorer™, Explore the full
Bitcoin ecosystem™, Mempool Goggles™, the mempool Logo, the mempool Square logo,
the mempool Blocks logo, the mempool Blocks 3 | 2 logo, the mempool.space Vertical
Logo, and the mempool.space Horizontal logo are registered trademarks or trademarks
of Mempool Space K.K in Japan, the United States, and/or other countries.
Bitcoin ecosystem™, Mempool Goggles™, the mempool Logo, the mempool Square Logo,
the mempool block visualization Logo, the mempool Blocks Logo, the mempool
transaction Logo, the mempool Blocks 3 | 2 Logo, the mempool research Logo,
the mempool.space Vertical Logo, and the mempool.space Horizontal Logo are
registered trademarks or trademarks of Mempool Space K.K in Japan,
the United States, and/or other countries.
See our full Trademark Policy and Guidelines for more details, published on
<https://mempool.space/trademark-policy>.
+1 -1
View File
@@ -77,7 +77,7 @@ Query OK, 0 rows affected (0.00 sec)
#### Build
_Make sure to use Node.js 16.10 and npm 7._
_Make sure to use Node.js 20.x and npm 9.x or newer_
_The build process requires [Rust](https://www.rust-lang.org/tools/install) to be installed._
+10 -9
View File
@@ -1,18 +1,19 @@
{
"name": "mempool-backend",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "mempool-backend",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"hasInstallScript": true,
"license": "GNU Affero General Public License v3.0",
"dependencies": {
"@babel/core": "^7.25.2",
"@mempool/electrum-client": "1.1.9",
"@types/node": "^18.15.3",
"axios": "~1.7.2",
"axios": "~1.7.4",
"bitcoinjs-lib": "~6.1.3",
"crypto-js": "~4.2.0",
"express": "~4.19.2",
@@ -2277,9 +2278,9 @@
}
},
"node_modules/axios": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
@@ -9438,9 +9439,9 @@
"integrity": "sha512-+H+kuK34PfMaI9PNU/NSjBKL5hh/KDM9J72kwYeYEm0A8B1AC4fuCy3qsjnA7lxklgyXsB68yn8Z2xoZEjgwCQ=="
},
"axios": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.4.tgz",
"integrity": "sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw==",
"requires": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "mempool-backend",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
"license": "GNU Affero General Public License v3.0",
"homepage": "https://mempool.space",
@@ -42,7 +42,7 @@
"@babel/core": "^7.25.2",
"@mempool/electrum-client": "1.1.9",
"@types/node": "^18.15.3",
"axios": "~1.7.2",
"axios": "~1.7.4",
"bitcoinjs-lib": "~6.1.3",
"crypto-js": "~4.2.0",
"express": "~4.19.2",
+1 -1
View File
@@ -70,7 +70,7 @@ class AboutRoutes {
res.status(500).end();
}
})
.get(config.MEMPOOL.API_URL_PREFIX + 'services/account/images/:username', async (req, res) => {
.get(config.MEMPOOL.API_URL_PREFIX + 'services/account/images/:username/:md5', async (req, res) => {
const url = `${config.MEMPOOL_SERVICES.API}/${req.originalUrl.replace('/api/v1/services/', '')}`;
try {
const response = await axios.get(url, { responseType: 'stream', timeout: 10000 });
+4 -18
View File
@@ -2,6 +2,7 @@ import config from '../config';
import logger from '../logger';
import { MempoolTransactionExtended, MempoolBlockWithTransactions } from '../mempool.interfaces';
import rbfCache from './rbf-cache';
import transactionUtils from './transaction-utils';
const PROPAGATION_MARGIN = 180; // in seconds, time since a transaction is first seen after which it is assumed to have propagated to all miners
@@ -15,7 +16,8 @@ class Audit {
const matches: string[] = []; // present in both mined block and template
const added: string[] = []; // present in mined block, not in template
const unseen: string[] = []; // present in the mined block, not in our mempool
const prioritized: string[] = []; // higher in the block than would be expected by in-band feerate alone
let prioritized: string[] = []; // higher in the block than would be expected by in-band feerate alone
let deprioritized: string[] = []; // lower in the block than would be expected by in-band feerate alone
const fresh: string[] = []; // missing, but firstSeen or lastBoosted within PROPAGATION_MARGIN
const rbf: string[] = []; // either missing or present, and either part of a full-rbf replacement, or a conflict with the mined block
const accelerated: string[] = []; // prioritized by the mempool accelerator
@@ -133,23 +135,7 @@ class Audit {
totalWeight += tx.weight;
}
// identify "prioritized" transactions
let lastEffectiveRate = 0;
// Iterate over the mined template from bottom to top (excluding the coinbase)
// Transactions should appear in ascending order of mining priority.
for (let i = transactions.length - 1; i > 0; i--) {
const blockTx = transactions[i];
// If a tx has a lower in-band effective fee rate than the previous tx,
// it must have been prioritized out-of-band (in order to have a higher mining priority)
// so exclude from the analysis.
if ((blockTx.effectiveFeePerVsize || 0) < lastEffectiveRate) {
prioritized.push(blockTx.txid);
// accelerated txs may or may not have their prioritized fee rate applied, so don't use them as a reference
} else if (!isAccelerated[blockTx.txid]) {
lastEffectiveRate = blockTx.effectiveFeePerVsize || 0;
}
}
({ prioritized, deprioritized } = transactionUtils.identifyPrioritizedTransactions(transactions, 'effectiveFeePerVsize'));
// transactions missing from near the end of our template are probably not being censored
let overflowWeightRemaining = overflowWeight - (config.MEMPOOL.BLOCK_WEIGHT_UNITS - totalWeight);
+1
View File
@@ -323,6 +323,7 @@ class BitcoinApi implements AbstractBitcoinApi {
'witness_v1_taproot': 'v1_p2tr',
'nonstandard': 'nonstandard',
'multisig': 'multisig',
'anchor': 'anchor',
'nulldata': 'op_return'
};
+8 -8
View File
@@ -219,10 +219,10 @@ class Blocks {
};
}
public summarizeBlockTransactions(hash: string, transactions: TransactionExtended[]): BlockSummary {
public summarizeBlockTransactions(hash: string, height: number, transactions: TransactionExtended[]): BlockSummary {
return {
id: hash,
transactions: Common.classifyTransactions(transactions),
transactions: Common.classifyTransactions(transactions, height),
};
}
@@ -616,7 +616,7 @@ class Blocks {
// add CPFP
const cpfpSummary = calculateGoodBlockCpfp(height, txs, []);
// classify
const { transactions: classifiedTxs } = this.summarizeBlockTransactions(blockHash, cpfpSummary.transactions);
const { transactions: classifiedTxs } = this.summarizeBlockTransactions(blockHash, height, cpfpSummary.transactions);
await BlocksSummariesRepository.$saveTransactions(height, blockHash, classifiedTxs, 2);
if (unclassifiedBlocks[height].version < 2 && targetSummaryVersion === 2) {
const cpfpClusters = await CpfpRepository.$getClustersAt(height);
@@ -653,7 +653,7 @@ class Blocks {
}
const cpfpSummary = calculateGoodBlockCpfp(height, templateTxs?.filter(tx => tx['effectiveFeePerVsize'] != null) as MempoolTransactionExtended[], []);
// classify
const { transactions: classifiedTxs } = this.summarizeBlockTransactions(blockHash, cpfpSummary.transactions);
const { transactions: classifiedTxs } = this.summarizeBlockTransactions(blockHash, height, cpfpSummary.transactions);
const classifiedTxMap: { [txid: string]: TransactionClassified } = {};
for (const tx of classifiedTxs) {
classifiedTxMap[tx.txid] = tx;
@@ -912,7 +912,7 @@ class Blocks {
}
const cpfpSummary: CpfpSummary = calculateGoodBlockCpfp(block.height, transactions, accelerations.map(a => ({ txid: a.txid, max_bid: a.feeDelta })));
const blockExtended: BlockExtended = await this.$getBlockExtended(block, cpfpSummary.transactions);
const blockSummary: BlockSummary = this.summarizeBlockTransactions(block.id, cpfpSummary.transactions);
const blockSummary: BlockSummary = this.summarizeBlockTransactions(block.id, block.height, cpfpSummary.transactions);
this.updateTimerProgress(timer, `got block data for ${this.currentBlockHeight}`);
if (Common.indexingEnabled()) {
@@ -1169,7 +1169,7 @@ class Blocks {
transactions: cpfpSummary.transactions.map(tx => {
let flags: number = 0;
try {
flags = Common.getTransactionFlags(tx);
flags = Common.getTransactionFlags(tx, height);
} catch (e) {
logger.warn('Failed to classify transaction: ' + (e instanceof Error ? e.message : e));
}
@@ -1188,7 +1188,7 @@ class Blocks {
} else {
if (config.MEMPOOL.BACKEND === 'esplora') {
const txs = (await bitcoinApi.$getTxsForBlock(hash)).map(tx => transactionUtils.extendTransaction(tx));
summary = this.summarizeBlockTransactions(hash, txs);
summary = this.summarizeBlockTransactions(hash, height || 0, txs);
summaryVersion = 1;
} else {
// Call Core RPC
@@ -1324,7 +1324,7 @@ class Blocks {
let summaryVersion = 0;
if (config.MEMPOOL.BACKEND === 'esplora') {
const txs = (await bitcoinApi.$getTxsForBlock(cleanBlock.hash)).map(tx => transactionUtils.extendTransaction(tx));
summary = this.summarizeBlockTransactions(cleanBlock.hash, txs);
summary = this.summarizeBlockTransactions(cleanBlock.hash, cleanBlock.height, txs);
summaryVersion = 1;
} else {
// Call Core RPC
+57 -10
View File
@@ -10,7 +10,6 @@ import logger from '../logger';
import { getVarIntLength, opcodes, parseMultisigScript } from '../utils/bitcoin-script';
// Bitcoin Core default policy settings
const TX_MAX_STANDARD_VERSION = 2;
const MAX_STANDARD_TX_WEIGHT = 400_000;
const MAX_BLOCK_SIGOPS_COST = 80_000;
const MAX_STANDARD_TX_SIGOPS_COST = (MAX_BLOCK_SIGOPS_COST / 5);
@@ -200,10 +199,13 @@ export class Common {
*
* returns true early if any standardness rule is violated, otherwise false
* (except for non-mandatory-script-verify-flag and p2sh script evaluation rules which are *not* enforced)
*
* As standardness rules change, we'll need to apply the rules in force *at the time* to older blocks.
* For now, just pull out individual rules into versioned functions where necessary.
*/
static isNonStandard(tx: TransactionExtended): boolean {
static isNonStandard(tx: TransactionExtended, height?: number): boolean {
// version
if (tx.version > TX_MAX_STANDARD_VERSION) {
if (this.isNonStandardVersion(tx, height)) {
return true;
}
@@ -250,6 +252,8 @@ export class Common {
}
} else if (['unknown', 'provably_unspendable', 'empty'].includes(vin.prevout?.scriptpubkey_type || '')) {
return true;
} else if (this.isNonStandardAnchor(tx, height)) {
return true;
}
// TODO: bad-witness-nonstandard
}
@@ -335,6 +339,49 @@ export class Common {
return false;
}
// Individual versioned standardness rules
static V3_STANDARDNESS_ACTIVATION_HEIGHT = {
'testnet4': 42_000,
'testnet': 2_900_000,
'signet': 211_000,
'': 863_500,
};
static isNonStandardVersion(tx: TransactionExtended, height?: number): boolean {
let TX_MAX_STANDARD_VERSION = 3;
if (
height != null
&& this.V3_STANDARDNESS_ACTIVATION_HEIGHT[config.MEMPOOL.NETWORK]
&& height <= this.V3_STANDARDNESS_ACTIVATION_HEIGHT[config.MEMPOOL.NETWORK]
) {
// V3 transactions were non-standard to spend before v28.x (scheduled for 2024/09/30 https://github.com/bitcoin/bitcoin/issues/29891)
TX_MAX_STANDARD_VERSION = 2;
}
if (tx.version > TX_MAX_STANDARD_VERSION) {
return true;
}
return false;
}
static ANCHOR_STANDARDNESS_ACTIVATION_HEIGHT = {
'testnet4': 42_000,
'testnet': 2_900_000,
'signet': 211_000,
'': 863_500,
};
static isNonStandardAnchor(tx: TransactionExtended, height?: number): boolean {
if (
height != null
&& this.ANCHOR_STANDARDNESS_ACTIVATION_HEIGHT[config.MEMPOOL.NETWORK]
&& height <= this.ANCHOR_STANDARDNESS_ACTIVATION_HEIGHT[config.MEMPOOL.NETWORK]
) {
// anchor outputs were non-standard to spend before v28.x (scheduled for 2024/09/30 https://github.com/bitcoin/bitcoin/issues/29891)
return true;
}
return false;
}
static getNonWitnessSize(tx: TransactionExtended): number {
let weight = tx.weight;
let hasWitness = false;
@@ -415,7 +462,7 @@ export class Common {
return flags;
}
static getTransactionFlags(tx: TransactionExtended): number {
static getTransactionFlags(tx: TransactionExtended, height?: number): number {
let flags = tx.flags ? BigInt(tx.flags) : 0n;
// Update variable flags (CPFP, RBF)
@@ -548,7 +595,7 @@ export class Common {
if (hasFakePubkey) {
flags |= TransactionFlags.fake_pubkey;
}
// fast but bad heuristic to detect possible coinjoins
// (at least 5 inputs and 5 outputs, less than half of which are unique amounts, with no address reuse)
const addressReuse = Object.keys(reusedOutputAddresses).reduce((acc, key) => Math.max(acc, (reusedInputAddresses[key] || 0) + (reusedOutputAddresses[key] || 0)), 0) > 1;
@@ -564,17 +611,17 @@ export class Common {
flags |= TransactionFlags.batch_payout;
}
if (this.isNonStandard(tx)) {
if (this.isNonStandard(tx, height)) {
flags |= TransactionFlags.nonstandard;
}
return Number(flags);
}
static classifyTransaction(tx: TransactionExtended): TransactionClassified {
static classifyTransaction(tx: TransactionExtended, height?: number): TransactionClassified {
let flags = 0;
try {
flags = Common.getTransactionFlags(tx);
flags = Common.getTransactionFlags(tx, height);
} catch (e) {
logger.warn('Failed to add classification flags to transaction: ' + (e instanceof Error ? e.message : e));
}
@@ -585,8 +632,8 @@ export class Common {
};
}
static classifyTransactions(txs: TransactionExtended[]): TransactionClassified[] {
return txs.map(Common.classifyTransaction);
static classifyTransactions(txs: TransactionExtended[], height?: number): TransactionClassified[] {
return txs.map(tx => Common.classifyTransaction(tx, height));
}
static stripTransaction(tx: TransactionExtended): TransactionStripped {
+34 -5
View File
@@ -7,7 +7,7 @@ import cpfpRepository from '../repositories/CpfpRepository';
import { RowDataPacket } from 'mysql2';
class DatabaseMigration {
private static currentVersion = 81;
private static currentVersion = 82;
private queryTimeout = 3600_000;
private statisticsAddedIndexed = false;
private uniqueLogs: string[] = [];
@@ -653,9 +653,11 @@ class DatabaseMigration {
await this.$executeQuery('ALTER TABLE `prices` ADD `TRY` float DEFAULT "-1"');
await this.$executeQuery('ALTER TABLE `prices` ADD `ZAR` float DEFAULT "-1"');
await this.$executeQuery('TRUNCATE hashrates');
await this.$executeQuery('TRUNCATE difficulty_adjustments');
await this.$executeQuery(`UPDATE state SET string = NULL WHERE name = 'pools_json_sha'`);
if (isBitcoin === true) {
await this.$executeQuery('TRUNCATE hashrates');
await this.$executeQuery('TRUNCATE difficulty_adjustments');
await this.$executeQuery(`UPDATE state SET string = NULL WHERE name = 'pools_json_sha'`);
}
await this.updateToSchemaVersion(75);
}
@@ -692,12 +694,17 @@ class DatabaseMigration {
await this.updateToSchemaVersion(80);
}
if (databaseSchemaVersion < 81) {
if (databaseSchemaVersion < 81 && isBitcoin === true) {
await this.$executeQuery('ALTER TABLE `blocks_audits` ADD version INT NOT NULL DEFAULT 0');
await this.$executeQuery('ALTER TABLE `blocks_audits` ADD INDEX `version` (`version`)');
await this.$executeQuery('ALTER TABLE `blocks_audits` ADD unseen_txs JSON DEFAULT "[]"');
await this.updateToSchemaVersion(81);
}
if (databaseSchemaVersion < 82 && isBitcoin === true && config.MEMPOOL.NETWORK === 'mainnet') {
await this.$fixBadV1AuditBlocks();
await this.updateToSchemaVersion(82);
}
}
/**
@@ -1312,6 +1319,28 @@ class DatabaseMigration {
logger.warn(`Failed to migrate cpfp transaction data`);
}
}
private async $fixBadV1AuditBlocks(): Promise<void> {
const badBlocks = [
'000000000000000000011ad49227fc8c9ba0ca96ad2ebce41a862f9a244478dc',
'000000000000000000010ac1f68b3080153f2826ffddc87ceffdd68ed97d6960',
'000000000000000000024cbdafeb2660ae8bd2947d166e7fe15d1689e86b2cf7',
'00000000000000000002e1dbfbf6ae057f331992a058b822644b368034f87286',
'0000000000000000000019973b2778f08ad6d21e083302ff0833d17066921ebb',
];
for (const hash of badBlocks) {
try {
await this.$executeQuery(`
UPDATE blocks_audits
SET prioritized_txs = '[]'
WHERE hash = '${hash}'
`, true);
} catch (e) {
continue;
}
}
}
}
export default new DatabaseMigration();
+14 -1
View File
@@ -30,6 +30,7 @@ class MiningRoutes {
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/fee-rates/:interval', this.$getHistoricalBlockFeeRates)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/sizes-weights/:interval', this.$getHistoricalBlockSizeAndWeight)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustments/:interval', this.$getDifficultyAdjustments)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/difficulty-adjustment/:height', this.$getDifficultyAdjustment)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/predictions/:interval', this.$getHistoricalBlocksHealth)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/scores', this.$getBlockAuditScores)
.get(config.MEMPOOL.API_URL_PREFIX + 'mining/blocks/audit/scores/:height', this.$getBlockAuditScores)
@@ -297,6 +298,18 @@ class MiningRoutes {
}
}
private async $getDifficultyAdjustment(req: Request, res: Response) {
try {
const adjustment = await DifficultyAdjustmentsRepository.$getAdjustmentAtHeight(parseInt(req.params.height, 10));
res.header('Pragma', 'public');
res.header('Cache-control', 'public');
res.setHeader('Expires', new Date(Date.now() + 1000 * 300).toUTCString());
res.json(adjustment);
} catch (e) {
res.status(e instanceof Error && e.message === 'not found' ? 204 : 500).send(e instanceof Error ? e.message : e);
}
}
private async $getRewardStats(req: Request, res: Response) {
try {
const response = await mining.$getRewardStats(parseInt(req.params.blockCount, 10));
@@ -470,7 +483,7 @@ class MiningRoutes {
res.setHeader('expires', -1);
try {
accelerationApi.accelerationRequested(req.params.txid);
res.status(200).send('ok');
res.status(200).send();
} catch (e) {
res.status(500).send(e instanceof Error ? e.message : e);
}
+81
View File
@@ -338,6 +338,87 @@ class TransactionUtils {
const positionOfScript = hasAnnex ? witness.length - 3 : witness.length - 2;
return witness[positionOfScript];
}
// calculate the most parsimonious set of prioritizations given a list of block transactions
// (i.e. the most likely prioritizations and deprioritizations)
public identifyPrioritizedTransactions(transactions: any[], rateKey: string): { prioritized: string[], deprioritized: string[] } {
// find the longest increasing subsequence of transactions
// (adapted from https://en.wikipedia.org/wiki/Longest_increasing_subsequence#Efficient_algorithms)
// should be O(n log n)
const X = transactions.slice(1).reverse().map((tx) => ({ txid: tx.txid, rate: tx[rateKey] })); // standard block order is by *decreasing* effective fee rate, but we want to iterate in increasing order (and skip the coinbase)
if (X.length < 2) {
return { prioritized: [], deprioritized: [] };
}
const N = X.length;
const P: number[] = new Array(N);
const M: number[] = new Array(N + 1);
M[0] = -1; // undefined so can be set to any value
let L = 0;
for (let i = 0; i < N; i++) {
// Binary search for the smallest positive l ≤ L
// such that X[M[l]].effectiveFeePerVsize > X[i].effectiveFeePerVsize
let lo = 1;
let hi = L + 1;
while (lo < hi) {
const mid = lo + Math.floor((hi - lo) / 2); // lo <= mid < hi
if (X[M[mid]].rate > X[i].rate) {
hi = mid;
} else { // if X[M[mid]].effectiveFeePerVsize < X[i].effectiveFeePerVsize
lo = mid + 1;
}
}
// After searching, lo == hi is 1 greater than the
// length of the longest prefix of X[i]
const newL = lo;
// The predecessor of X[i] is the last index of
// the subsequence of length newL-1
P[i] = M[newL - 1];
M[newL] = i;
if (newL > L) {
// If we found a subsequence longer than any we've
// found yet, update L
L = newL;
}
}
// Reconstruct the longest increasing subsequence
// It consists of the values of X at the L indices:
// ..., P[P[M[L]]], P[M[L]], M[L]
const LIS: any[] = new Array(L);
let k = M[L];
for (let j = L - 1; j >= 0; j--) {
LIS[j] = X[k];
k = P[k];
}
const lisMap = new Map<string, number>();
LIS.forEach((tx, index) => lisMap.set(tx.txid, index));
const prioritized: string[] = [];
const deprioritized: string[] = [];
let lastRate = X[0].rate;
for (const tx of X) {
if (lisMap.has(tx.txid)) {
lastRate = tx.rate;
} else {
if (Math.abs(tx.rate - lastRate) < 0.1) {
// skip if the rate is almost the same as the previous transaction
} else if (tx.rate <= lastRate) {
prioritized.push(tx.txid);
} else {
deprioritized.push(tx.txid);
}
}
}
return { prioritized, deprioritized };
}
}
export default new TransactionUtils();
@@ -132,11 +132,12 @@ class BlocksAuditRepositories {
firstSeen = tx.time;
}
});
const wasSeen = blockAudit.version === 1 ? !blockAudit.unseenTxs.includes(txid) : (isExpected || isPrioritized || isAccelerated);
return {
seen: isExpected || isPrioritized || isAccelerated,
seen: wasSeen,
expected: isExpected,
added: isAdded,
added: isAdded && (blockAudit.version === 0 || !wasSeen),
prioritized: isPrioritized,
conflict: isConflict,
accelerated: isAccelerated,
+1 -1
View File
@@ -1106,7 +1106,7 @@ class BlocksRepository {
let summaryVersion = 0;
if (config.MEMPOOL.BACKEND === 'esplora') {
const txs = (await bitcoinApi.$getTxsForBlock(dbBlk.id)).map(tx => transactionUtils.extendTransaction(tx));
summary = blocks.summarizeBlockTransactions(dbBlk.id, txs);
summary = blocks.summarizeBlockTransactions(dbBlk.id, dbBlk.height, txs);
summaryVersion = 1;
} else {
// Call Core RPC
@@ -88,6 +88,22 @@ class DifficultyAdjustmentsRepository {
}
}
public async $getAdjustmentAtHeight(height: number): Promise<IndexedDifficultyAdjustment> {
try {
if (isNaN(height)) {
throw new Error(`argument must be a number`);
}
const [rows] = await DB.query(`SELECT * FROM difficulty_adjustments WHERE height = ?`, [height]);
if (!rows[0]) {
throw new Error(`not found`);
}
return rows[0] as IndexedDifficultyAdjustment;
} catch (e: any) {
logger.err(`Cannot get difficulty adjustment from the database. Reason: ${e instanceof Error ? e.message : e}`, logger.tags.mining);
throw e;
}
}
public async $getAdjustmentsHeights(): Promise<number[]> {
try {
const [rows]: any[] = await DB.query(`SELECT height FROM difficulty_adjustments`);
+2 -2
View File
@@ -158,7 +158,7 @@ export function parseMultisigScript(script: string): void | { m: number, n: numb
if (!opN) {
return;
}
if (!opN.startsWith('OP_PUSHNUM_')) {
if (opN !== 'OP_0' && !opN.startsWith('OP_PUSHNUM_')) {
return;
}
const n = parseInt(opN.match(/[0-9]+/)?.[0] || '', 10);
@@ -178,7 +178,7 @@ export function parseMultisigScript(script: string): void | { m: number, n: numb
if (!opM) {
return;
}
if (!opM.startsWith('OP_PUSHNUM_')) {
if (opM !== 'OP_0' && !opM.startsWith('OP_PUSHNUM_')) {
return;
}
const m = parseInt(opM.match(/[0-9]+/)?.[0] || '', 10);
+2 -2
View File
@@ -33,7 +33,7 @@ $ npm run config:defaults:liquid
### 3. Run the Frontend
_Make sure to use Node.js 16.10 and npm 7._
_Make sure to use Node.js 20.x and npm 9.x or newer._
Install project dependencies and run the frontend server:
@@ -70,7 +70,7 @@ Set up the [Mempool backend](../backend/) first, if you haven't already.
### 1. Build the Frontend
_Make sure to use Node.js 16.10 and npm 7._
_Make sure to use Node.js 20.x and npm 9.x or newer._
Build the frontend:
+4
View File
@@ -54,6 +54,10 @@
"translation": "src/locale/messages.fr.xlf",
"baseHref": "/fr/"
},
"hr": {
"translation": "src/locale/messages.hr.xlf",
"baseHref": "/hr/"
},
"ja": {
"translation": "src/locale/messages.ja.xlf",
"baseHref": "/ja/"
@@ -750,7 +750,7 @@
},
"backendInfo": {
"hostname": "node205.tk7.mempool.space",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"gitCommit": "abbc8a134",
"lightning": false
},
+35 -24
View File
@@ -1,12 +1,12 @@
{
"name": "mempool-frontend",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "mempool-frontend",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"license": "GNU Affero General Public License v3.0",
"dependencies": {
"@angular-devkit/build-angular": "^17.3.1",
@@ -32,6 +32,7 @@
"bootstrap": "~4.6.2",
"browserify": "^17.0.0",
"clipboard": "^2.0.11",
"cypress": "^13.14.0",
"domino": "^2.1.6",
"echarts": "~5.5.0",
"esbuild": "^0.23.0",
@@ -42,7 +43,7 @@
"rxjs": "~7.8.1",
"tinyify": "^4.0.0",
"tlite": "^0.1.9",
"tslib": "~2.6.0",
"tslib": "~2.7.0",
"zone.js": "~0.14.4"
},
"devDependencies": {
@@ -62,7 +63,7 @@
"optionalDependencies": {
"@cypress/schematic": "^2.5.0",
"@types/cypress": "^1.1.3",
"cypress": "^13.13.0",
"cypress": "^13.14.0",
"cypress-fail-on-console-error": "~5.1.0",
"cypress-wait-until": "^2.0.1",
"mock-socket": "~9.3.1",
@@ -699,6 +700,11 @@
"node": ">=10"
}
},
"node_modules/@angular-devkit/build-angular/node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/@angular-devkit/build-webpack": {
"version": "0.1703.1",
"resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1703.1.tgz",
@@ -8040,13 +8046,13 @@
"peer": true
},
"node_modules/cypress": {
"version": "13.13.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.0.tgz",
"integrity": "sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==",
"version": "13.14.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.0.tgz",
"integrity": "sha512-r0+nhd033x883YL6068futewUsl02Q7rWiinyAAIBDW/OOTn+UMILWgNuCiY3vtJjd53efOqq5R9dctQk/rKiw==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
"@cypress/request": "^3.0.0",
"@cypress/request": "^3.0.1",
"@cypress/xvfb": "^1.2.4",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
@@ -8805,9 +8811,9 @@
"integrity": "sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg=="
},
"node_modules/elliptic": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
"version": "6.5.7",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
"integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
"dependencies": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
@@ -16925,9 +16931,9 @@
}
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"node_modules/tuf-js": {
"version": "2.2.0",
@@ -18849,6 +18855,11 @@
"requires": {
"lru-cache": "^6.0.0"
}
},
"tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
}
}
},
@@ -24127,12 +24138,12 @@
"peer": true
},
"cypress": {
"version": "13.13.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.13.0.tgz",
"integrity": "sha512-ou/MQUDq4tcDJI2FsPaod2FZpex4kpIK43JJlcBgWrX8WX7R/05ZxGTuxedOuZBfxjZxja+fbijZGyxiLP6CFA==",
"version": "13.14.0",
"resolved": "https://registry.npmjs.org/cypress/-/cypress-13.14.0.tgz",
"integrity": "sha512-r0+nhd033x883YL6068futewUsl02Q7rWiinyAAIBDW/OOTn+UMILWgNuCiY3vtJjd53efOqq5R9dctQk/rKiw==",
"optional": true,
"requires": {
"@cypress/request": "^3.0.0",
"@cypress/request": "^3.0.1",
"@cypress/xvfb": "^1.2.4",
"@types/sinonjs__fake-timers": "8.1.1",
"@types/sizzle": "^2.3.2",
@@ -24723,9 +24734,9 @@
"integrity": "sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg=="
},
"elliptic": {
"version": "6.5.4",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz",
"integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==",
"version": "6.5.7",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz",
"integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==",
"requires": {
"bn.js": "^4.11.9",
"brorand": "^1.1.0",
@@ -30763,9 +30774,9 @@
}
},
"tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="
},
"tuf-js": {
"version": "2.2.0",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "mempool-frontend",
"version": "3.0.0-dev",
"version": "3.1.0-dev",
"description": "Bitcoin mempool visualizer and blockchain explorer backend",
"license": "GNU Affero General Public License v3.0",
"homepage": "https://mempool.space",
@@ -95,7 +95,7 @@
"esbuild": "^0.23.0",
"tinyify": "^4.0.0",
"tlite": "^0.1.9",
"tslib": "~2.6.0",
"tslib": "~2.7.0",
"zone.js": "~0.14.4"
},
"devDependencies": {
@@ -115,7 +115,7 @@
"optionalDependencies": {
"@cypress/schematic": "^2.5.0",
"@types/cypress": "^1.1.3",
"cypress": "^13.13.0",
"cypress": "^13.14.0",
"cypress-fail-on-console-error": "~5.1.0",
"cypress-wait-until": "^2.0.1",
"mock-socket": "~9.3.1",
+1 -1
View File
@@ -151,7 +151,7 @@ export const languages: Language[] = [
{ code: 'fr', name: 'Français' }, // French
// { code: 'gl', name: 'Galego' }, // Galician
{ code: 'ko', name: '한국어' }, // Korean
// { code: 'hr', name: 'Hrvatski' }, // Croatian
{ code: 'hr', name: 'Hrvatski' }, // Croatian
// { code: 'id', name: 'Bahasa Indonesia' },// Indonesian
{ code: 'hi', name: 'हिन्दी' }, // Hindi
{ code: 'ne', name: 'नेपाली' }, // Nepalese
+2 -2
View File
@@ -135,7 +135,7 @@ export function parseMultisigScript(script: string): void | { m: number, n: numb
return;
}
const opN = ops.pop();
if (!opN.startsWith('OP_PUSHNUM_')) {
if (opN !== 'OP_0' && !opN.startsWith('OP_PUSHNUM_')) {
return;
}
const n = parseInt(opN.match(/[0-9]+/)[0], 10);
@@ -152,7 +152,7 @@ export function parseMultisigScript(script: string): void | { m: number, n: numb
}
}
const opM = ops.pop();
if (!opM.startsWith('OP_PUSHNUM_')) {
if (opM !== 'OP_0' && !opM.startsWith('OP_PUSHNUM_')) {
return;
}
const m = parseInt(opM.match(/[0-9]+/)[0], 10);
@@ -53,7 +53,7 @@
<span>Spiral</span>
</a>
<a href="https://foundrydigital.com/" target="_blank" title="Foundry">
<svg xmlns="http://www.w3.org/2000/svg" id="b" data-name="Layer 2" style="zoom: 1;" width="32" height="76" viewBox="0 0 32 76">
<svg xmlns="http://www.w3.org/2000/svg" id="b" data-name="Layer 2" style="zoom: 1;" width="32" height="76" viewBox="0 0 32 76" class="image">
<defs>
<style>
.d {
@@ -125,7 +125,9 @@
<span>Blockstream</span>
</a>
<a href="https://unchained.com/" target="_blank" title="Unchained">
<svg id="Layer_1" width="78" height="78" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156.68 156.68"><defs><style>.cls-unchained-1{fill:#fff;}</style></defs><path class="cls-unchained-1" d="m78.34,0C35.07,0,0,35.07,0,78.34s35.07,78.34,78.34,78.34,78.34-35.07,78.34-78.34S121.6,0,78.34,0ZM20.23,109.5c-4.99-9.28-7.81-19.89-7.81-31.16C12.42,41.93,41.93,12.42,78.34,12.42c33.15,0,60.58,24.46,65.23,56.32h-37.48c-45.29,0-71.19,20.05-85.85,40.76Zm58.11,34.76c-12.42,0-24.04-3.44-33.96-9.41,3.94-8.85,9.11-18.7,15.84-28.9,20.99-31.8,52.2-31.19,76.49-31.19h7.45c.06,1.18.1,2.38.1,3.58,0,36.41-29.51,65.92-65.92,65.92Z"/><path class="cls-unchained-1" d="m91.98,42.4l-3.62-1.18c-3.94-1.29-7.03-4.38-8.32-8.32l-1.18-3.63c-.13-.39-.68-.39-.81,0l-1.18,3.63c-1.29,3.94-4.38,7.03-8.32,8.32l-3.62,1.18c-.39.13-.39.68,0,.81l3.62,1.18c3.94,1.29,7.03,4.38,8.32,8.32l1.18,3.63c.13.39.68.39.81,0l1.18-3.63c1.29-3.94,4.38-7.03,8.32-8.32l3.62-1.18c.39-.13.39-.68,0-.81Z"/></svg>
<svg id="Layer_1" width="78" height="78" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 156.68 156.68" class="image">
<defs><style>.cls-unchained-1{fill:#fff;}</style></defs><path class="cls-unchained-1" d="m78.34,0C35.07,0,0,35.07,0,78.34s35.07,78.34,78.34,78.34,78.34-35.07,78.34-78.34S121.6,0,78.34,0ZM20.23,109.5c-4.99-9.28-7.81-19.89-7.81-31.16C12.42,41.93,41.93,12.42,78.34,12.42c33.15,0,60.58,24.46,65.23,56.32h-37.48c-45.29,0-71.19,20.05-85.85,40.76Zm58.11,34.76c-12.42,0-24.04-3.44-33.96-9.41,3.94-8.85,9.11-18.7,15.84-28.9,20.99-31.8,52.2-31.19,76.49-31.19h7.45c.06,1.18.1,2.38.1,3.58,0,36.41-29.51,65.92-65.92,65.92Z"/><path class="cls-unchained-1" d="m91.98,42.4l-3.62-1.18c-3.94-1.29-7.03-4.38-8.32-8.32l-1.18-3.63c-.13-.39-.68-.39-.81,0l-1.18,3.63c-1.29,3.94-4.38,7.03-8.32,8.32l-3.62,1.18c-.39.13-.39.68,0,.81l3.62,1.18c3.94,1.29,7.03,4.38,8.32,8.32l1.18,3.63c.13.39.68.39.81,0l1.18-3.63c1.29-3.94,4.38-7.03,8.32-8.32l3.62-1.18c.39-.13.39-.68,0-.81Z"/>
</svg>
<span>Unchained</span>
</a>
<a href="https://gemini.com/" target="_blank" title="Gemini">
@@ -150,7 +152,7 @@
<span>Bull Bitcoin</span>
</a>
<a href="https://exodus.com/" target="_blank" title="Exodus">
<svg width="80" height="80" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="80" height="80" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg" class="image">
<circle cx="250" cy="250" r="250" fill="#1F2033"/>
<g clip-path="url(#clip0_2_14)">
<path d="M411.042 178.303L271.79 87V138.048L361.121 196.097L350.612 229.351H271.79V271.648H350.612L361.121 304.903L271.79 362.952V414L411.042 322.989L388.271 250.646L411.042 178.303Z" fill="url(#paint0_linear_2_14)"/>
@@ -435,7 +437,7 @@
Trademark Notice<br>
</div>
<p>
The Mempool Open Source Project&reg;, Mempool Accelerator&trade;, Mempool Enterprise&reg;, Mempool Liquidity&trade;, mempool.space&reg;, Be your own explorer&trade;, Explore the full Bitcoin ecosystem&reg;, Mempool Goggles&trade;, the mempool logo, the mempool Square logo, the mempool Blocks logo, the mempool Blocks 3 | 2 logo, the mempool.space Vertical Logo, and the mempool.space Horizontal logo are either registered trademarks or trademarks of Mempool Space K.K in Japan, the United States, and/or other countries.
The Mempool Open Source Project&reg;, Mempool Accelerator&trade;, Mempool Enterprise&reg;, Mempool Liquidity&trade;, mempool.space&reg;, Be your own explorer&trade;, Explore the full Bitcoin ecosystem&reg;, Mempool Goggles&trade;, the mempool Logo, the mempool Square Logo, the mempool block visualization Logo, the mempool Blocks Logo, the mempool transaction Logo, the mempool Blocks 3 | 2 Logo, the mempool research Logo, the mempool.space Vertical Logo, and the mempool.space Horizontal Logo are either registered trademarks or trademarks of Mempool Space K.K in Japan, the United States, and/or other countries.
</p>
<p>
While our software is available under an open source software license, the copyright license does not include an implied right or license to use our trademarks. See our <a href="https://mempool.space/trademark-policy">Trademark Policy and Guidelines</a> for more details, published on &lt;https://mempool.space/trademark-policy&gt;.
@@ -13,8 +13,6 @@
.image.not-rounded {
border-radius: 0;
width: 60px;
height: 60px;
}
.intro {
@@ -158,9 +156,8 @@
margin: 40px 29px 10px;
&.image.coldcard {
border-radius: 0;
width: auto;
max-height: 50px;
margin: 40px 29px 14px 29px;
height: auto;
margin: 20px 29px 20px;
}
}
}
@@ -403,14 +403,14 @@
}
@if (canPayWithApplePay) {
@if (canPayWithCashapp) { <span class="mt-1 mb-1"></span> }
<div class="paymentMethod mx-2" style="width: 200px; height: 55px">
<img src="/resources/apple-pay.png" height=37 (click)="moveToStep('applepay')">
<div class="paymentMethod mx-2" style="width: 200px; height: 55px" (click)="moveToStep('applepay')">
<img src="/resources/apple-pay.png" height=37>
</div>
}
@if (canPayWithGooglePay) {
@if (canPayWithCashapp || canPayWithApplePay) { <span class="mt-1 mb-1"></span> }
<div class="paymentMethod mx-2" style="width: 200px; height: 55px">
<img src="/resources/google-pay.png" height=37 (click)="moveToStep('googlepay')">
<div class="paymentMethod mx-2" style="width: 200px; height: 55px" (click)="moveToStep('googlepay')">
<img src="/resources/google-pay.png" height=37>
</div>
}
</div>
@@ -525,7 +525,7 @@
<div class="col-sm">
<div class="d-flex flex-row flex-column justify-content-center align-items-center">
<span i18n="accelerator.confirming-acceleration-with-miners">Confirming your acceleration with our mining pool partners...</span>
@if (timeSincePaid > 20000) {
@if (timeSincePaid > 30000) {
<span i18n="accelerator.confirming-acceleration-with-miners">...sorry, this is taking longer than expected...</span>
}
<div class="m-2 spinner-border text-light" style="width: 25px; height: 25px"></div>
@@ -11,6 +11,7 @@ import { MiningStats } from '../../services/mining.service';
import { IAuth, AuthServiceMempool } from '../../services/auth.service';
import { EnterpriseService } from '../../services/enterprise.service';
import { ApiService } from '../../services/api.service';
import { isDevMode } from '@angular/core';
export type PaymentMethod = 'balance' | 'bitcoin' | 'cashapp' | 'applePay' | 'googlePay';
@@ -82,6 +83,13 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
timePaid: number = 0; // time acceleration requested
math = Math;
isMobile: boolean = window.innerWidth <= 767.98;
isProdDomain = ['mempool.space',
'mempool-staging.va1.mempool.space',
'mempool-staging.fmt.mempool.space',
'mempool-staging.fra.mempool.space',
'mempool-staging.tk7.mempool.space',
'mempool-staging.sg1.mempool.space'
].indexOf(document.location.hostname) > -1;
private _step: CheckoutStep = 'summary';
simpleMode: boolean = true;
@@ -398,15 +406,14 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
* Square
*/
insertSquare(): void {
if (!this.isProdDomain && !isDevMode()) {
return;
}
if (window['Square']) {
return;
}
let statsUrl = 'https://sandbox.web.squarecdn.com/v1/square.js';
if (document.location.hostname === 'mempool-staging.fmt.mempool.space' ||
document.location.hostname === 'mempool-staging.va1.mempool.space' ||
document.location.hostname === 'mempool-staging.fra.mempool.space' ||
document.location.hostname === 'mempool-staging.tk7.mempool.space' ||
document.location.hostname === 'mempool.space') {
if (this.isProdDomain) {
statsUrl = '/square/v1/square.js';
}
@@ -416,6 +423,9 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
})();
}
setupSquare(): void {
if (!this.isProdDomain && !isDevMode()) {
return;
}
const init = (): void => {
this.initSquare();
};
@@ -654,11 +664,11 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
amount: costUSD.toFixed(2),
label: 'Total',
pending: true,
productUrl: `${redirectHostname}/tracker/${this.tx.txid}`,
productUrl: `${redirectHostname}/tx/${this.tx.txid}`,
}
});
this.cashAppPay = await this.payments.cashAppPay(paymentRequest, {
redirectURL: `${redirectHostname}/tracker/${this.tx.txid}`,
redirectURL: `${redirectHostname}/tx/${this.tx.txid}`,
referenceId: `accelerator-${this.tx.txid.substring(0, 15)}-${Math.round(new Date().getTime() / 1000)}`
});
@@ -795,7 +805,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
}
get canPayWithCashapp(): boolean {
if (!this.cashappEnabled || !this.conversions) {
if (!this.cashappEnabled || !this.conversions || (!this.isProdDomain && !isDevMode())) {
return false;
}
@@ -811,7 +821,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
}
get canPayWithApplePay(): boolean {
if (!this.applePayEnabled || !this.conversions) {
if (!this.applePayEnabled || !this.conversions || (!this.isProdDomain && !isDevMode())) {
return false;
}
@@ -827,7 +837,7 @@ export class AccelerateCheckout implements OnInit, OnDestroy {
}
get canPayWithGooglePay(): boolean {
if (!this.googlePayEnabled || !this.conversions) {
if (!this.googlePayEnabled || !this.conversions || (!this.isProdDomain && !isDevMode())) {
return false;
}
@@ -26,9 +26,9 @@
<tr *ngIf="accelerationInfo.bidBoost >= 0 || accelerationInfo.feeDelta">
<td class="label" i18n="transaction.out-of-band-fees">Out-of-band fees</td>
@if (accelerationInfo.status === 'accelerated') {
<td style="color: #905cf4;" class="value">{{ accelerationInfo.feeDelta | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
<td class="value oobFees">{{ accelerationInfo.feeDelta | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
} @else {
<td style="color: #905cf4;" class="value">{{ accelerationInfo.bidBoost | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
<td class="value oobFees">{{ accelerationInfo.bidBoost | number }} <span class="symbol" i18n="shared.sat|sat">sat</span></td>
}
</tr>
<tr *ngIf="accelerationInfo.fee && accelerationInfo.weight">
@@ -38,9 +38,9 @@
} @else if (accelerationInfo.status === 'accelerated' || accelerationInfo.status === 'mined') {
<td class="label" i18n="transaction.accelerated-fee-rate|Accelerated transaction fee rate">Accelerated fee rate</td>
@if (accelerationInfo.status === 'accelerated') {
<td class="value"><app-fee-rate [fee]="accelerationInfo.fee + (accelerationInfo.feeDelta || 0)" [weight]="accelerationInfo.weight"></app-fee-rate></td>
<td class="value oobFees"><app-fee-rate [fee]="accelerationInfo.fee + (accelerationInfo.feeDelta || 0)" [weight]="accelerationInfo.weight"></app-fee-rate></td>
} @else {
<td class="value"><app-fee-rate [fee]="accelerationInfo.fee + (accelerationInfo.bidBoost || 0)" [weight]="accelerationInfo.weight"></app-fee-rate></td>
<td class="value oobFees"><app-fee-rate [fee]="accelerationInfo.fee + (accelerationInfo.bidBoost || 0)" [weight]="accelerationInfo.weight"></app-fee-rate></td>
}
}
</tr>
@@ -32,4 +32,8 @@
top: -1px;
margin-right: 3px;
}
.oobFees {
color: #905cf4;
}
}
@@ -1,7 +1,7 @@
@if (chartOnly) {
<ng-container *ngTemplateOutlet="pieChart"></ng-container>
} @else {
<table>
<table style="width: 100%;">
<tbody>
<tr>
<td class="td-width field-label" [class]="chartPositionLeft ? 'chart-left' : ''" i18n="transaction.accelerated-to-feerate|Accelerated to feerate">Accelerated to</td>
@@ -11,9 +11,9 @@
<td class="field-value" [class]="chartPositionLeft ? 'chart-left' : ''">
<div class="effective-fee-container">
@if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize)) {
<app-fee-rate [fee]="accelerationInfo.acceleratedFeeRate"></app-fee-rate>
<app-fee-rate class="oobFees" [fee]="accelerationInfo.acceleratedFeeRate"></app-fee-rate>
} @else {
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
<app-fee-rate class="oobFees" [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
}
</div>
</td>
@@ -61,4 +61,8 @@
& > div, & > div > svg {
overflow: visible !important;
}
}
.oobFees {
color: #905cf4;
}
@@ -67,13 +67,17 @@ export class ActiveAccelerationBox implements OnChanges {
const acceleratingPools = (poolList || []).filter(id => pools[id]).sort((a,b) => pools[a].lastEstimatedHashrate - pools[b].lastEstimatedHashrate);
const totalAcceleratedHashrate = acceleratingPools.reduce((total, pool) => total + pools[pool].lastEstimatedHashrate, 0);
const lightenStep = acceleratingPools.length ? (0.48 / acceleratingPools.length) : 0;
// Find the first pool with at least 1% of the total network hashrate
const firstSignificantPool = acceleratingPools.findIndex(pool => pools[pool].lastEstimatedHashrate > this.miningStats.lastEstimatedHashrate / 100);
const numSignificantPools = acceleratingPools.length - firstSignificantPool;
acceleratingPools.forEach((poolId, index) => {
const pool = pools[poolId];
const poolShare = ((pool.lastEstimatedHashrate / this.miningStats.lastEstimatedHashrate) * 100).toFixed(1);
data.push(getDataItem(
pool.lastEstimatedHashrate,
toRGB(lighten({ r: 147, g: 57, b: 244 }, index * lightenStep)),
index >= firstSignificantPool
? toRGB(lighten({ r: 147, g: 57, b: 244 }, 1 - (index - firstSignificantPool) / (numSignificantPools - 1)))
: 'white',
`<b style="color: white">${pool.name} (${poolShare}%)</b>`,
true,
) as PieSeriesOption);
@@ -0,0 +1,5 @@
<div class="sparkles" #sparkleAnchor>
<div *ngFor="let sparkle of sparkles" class="sparkle" [style]="sparkle.style">
<span class="inner-sparkle" [style]="sparkle.rotation">+</span>
</div>
</div>
@@ -0,0 +1,45 @@
.sparkles {
position: absolute;
top: var(--block-size);
height: 50px;
right: 0;
}
.sparkle {
position: absolute;
color: rgba(152, 88, 255, 0.75);
opacity: 0;
transform: scale(0.8) rotate(0deg);
animation: pop ease 2000ms forwards, sparkle ease 500ms infinite;
}
.inner-sparkle {
display: block;
}
@keyframes pop {
0% {
transform: scale(0.8) rotate(0deg);
opacity: 0;
}
20% {
transform: scale(1) rotate(72deg);
opacity: 1;
}
100% {
transform: scale(0) rotate(360deg);
opacity: 0;
}
}
@keyframes sparkle {
0% {
color: rgba(152, 88, 255, 0.75);
}
50% {
color: rgba(198, 162, 255, 0.75);
}
100% {
color: rgba(152, 88, 255, 0.75);
}
}
@@ -0,0 +1,73 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Input, OnChanges, SimpleChanges, ViewChild } from '@angular/core';
@Component({
selector: 'app-acceleration-sparkles',
templateUrl: './acceleration-sparkles.component.html',
styleUrls: ['./acceleration-sparkles.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AccelerationSparklesComponent implements OnChanges {
@Input() arrow: ElementRef<HTMLDivElement>;
@Input() run: boolean = false;
@ViewChild('sparkleAnchor')
sparkleAnchor: ElementRef<HTMLDivElement>;
constructor(
private cd: ChangeDetectorRef,
) {}
endTimeout: any;
lastSparkle: number = 0;
sparkleWidth: number = 0;
sparkles: any[] = [];
ngOnChanges(changes: SimpleChanges): void {
if (changes.run) {
if (this.endTimeout) {
clearTimeout(this.endTimeout);
this.endTimeout = null;
}
if (this.run) {
this.doSparkle();
} else {
this.endTimeout = setTimeout(() => {
this.sparkles = [];
}, 2000);
}
}
}
doSparkle(): void {
if (this.run) {
const now = performance.now();
if (now - this.lastSparkle > 20) {
this.lastSparkle = now;
if (this.arrow?.nativeElement && this.sparkleAnchor?.nativeElement) {
const anchor = this.sparkleAnchor.nativeElement.getBoundingClientRect().right;
const right = this.arrow.nativeElement.getBoundingClientRect().right;
const dx = (anchor - right) + 30;
const numSparkles = Math.ceil(Math.random() * 3);
for (let i = 0; i < numSparkles; i++) {
this.sparkles.push({
style: {
right: (dx + (Math.random() * 10)) + 'px',
top: (15 + (Math.random() * 30)) + 'px',
},
rotation: {
transform: `rotate(${Math.random() * 360}deg)`,
}
});
}
while (this.sparkles.length > 200) {
this.sparkles.shift();
}
this.cd.markForCheck();
}
}
requestAnimationFrame(() => {
this.doSparkle();
});
}
}
}
@@ -55,7 +55,7 @@ export class AddressLabelsComponent implements OnChanges {
}
handleVin() {
const address = new AddressTypeInfo(this.network || 'mainnet', this.vin.prevout?.scriptpubkey_address, this.vin.prevout?.scriptpubkey_type as AddressType, [this.vin])
const address = new AddressTypeInfo(this.network || 'mainnet', this.vin.prevout?.scriptpubkey_address, this.vin.prevout?.scriptpubkey_type as AddressType, [this.vin]);
if (address?.scripts.size) {
const script = address?.scripts.values().next().value;
if (script.template?.label) {
@@ -1,6 +1,5 @@
<div class="block-filters" [class.filters-active]="activeFilters.length > 0" [class.any-mode]="filterMode === 'or'" [class.menu-open]="menuOpen" [class.small]="cssWidth < 500" [class.vsmall]="cssWidth < 400" [class.tiny]="cssWidth < 200">
<a *ngIf="menuOpen" [routerLink]="['/docs/faq' | relativeUrl]" fragment="how-do-mempool-goggles-work" class="info-badges float-right" i18n-ngbTooltip="Mempool Goggles&trade; tooltip" ngbTooltip="select filter categories to highlight matching transactions">
<span class="badge badge-pill badge-warning beta" i18n="beta">beta</span>
<fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true" size="lg"></fa-icon>
</a>
<div class="filter-bar">
@@ -2,10 +2,12 @@
<div class="graph-alignment" [class.grid-align]="!autofit" [style.gridTemplateColumns]="'repeat(auto-fit, ' + resolution + 'px)'">
<div class="block-overview-graph">
<canvas *browserOnly class="block-overview-canvas" [class.clickable]="!!hoverTx" #blockCanvas></canvas>
<div class="loader-wrapper" [class.hidden]="(!isLoading || disableSpinner) && !unavailable">
<div *ngIf="!unavailable" class="spinner-border ml-3 loading" role="status"></div>
<div *ngIf="!isLoading && unavailable" class="ml-3" i18n="block.not-available">not available</div>
</div>
@if (!disableSpinner) {
<div class="loader-wrapper" [class.hidden]="!isLoading && !unavailable">
<div *ngIf="!unavailable" class="spinner-border ml-3 loading" role="status"></div>
<div *ngIf="!isLoading && unavailable" class="ml-3" i18n="block.not-available">not available</div>
</div>
}
<app-block-overview-tooltip
[tx]="selectedTx || hoverTx"
[cursorPosition]="tooltipPosition"
@@ -198,7 +198,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
}
// initialize the scene without any entry transition
setup(transactions: TransactionStripped[]): void {
setup(transactions: TransactionStripped[], sort: boolean = false): void {
const filtersAvailable = transactions.reduce((flagSet, tx) => flagSet || tx.flags > 0, false);
if (filtersAvailable !== this.filtersAvailable) {
this.setFilterFlags();
@@ -206,7 +206,7 @@ export class BlockOverviewGraphComponent implements AfterViewInit, OnDestroy, On
this.filtersAvailable = filtersAvailable;
if (this.scene) {
this.clearUpdateQueue();
this.scene.setup(transactions);
this.scene.setup(transactions, sort);
this.readyNextFrame = true;
this.start();
this.updateSearchHighlight();
@@ -88,16 +88,19 @@ export default class BlockScene {
}
// set up the scene with an initial set of transactions, without any transition animation
setup(txs: TransactionStripped[]) {
setup(txs: TransactionStripped[], sort: boolean = false) {
// clean up any old transactions
Object.values(this.txs).forEach(tx => {
tx.destroy();
delete this.txs[tx.txid];
});
this.layout = new BlockLayout({ width: this.gridWidth, height: this.gridHeight });
txs.forEach(tx => {
const txView = new TxView(tx, this);
this.txs[tx.txid] = txView;
let txViews = txs.map(tx => new TxView(tx, this));
if (sort) {
txViews = txViews.sort(feeRateDescending);
}
txViews.forEach(txView => {
this.txs[txView.txid] = txView;
this.place(txView);
this.saveGridToScreenPosition(txView);
this.applyTxUpdate(txView, {
@@ -33,7 +33,7 @@ export default class TxView implements TransactionStripped {
flags: number;
bigintFlags?: bigint | null = 0b00000100_00000000_00000000_00000000n;
time?: number;
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'added_prioritized' | 'prioritized' | 'censored' | 'selected' | 'rbf' | 'accelerated';
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'added_prioritized' | 'prioritized' | 'added_deprioritized' | 'deprioritized' | 'censored' | 'selected' | 'rbf' | 'accelerated';
context?: 'projected' | 'actual';
scene?: BlockScene;
@@ -142,6 +142,10 @@ export function defaultColorFunction(
return auditColors.added_prioritized;
case 'prioritized':
return auditColors.prioritized;
case 'added_deprioritized':
return auditColors.added_prioritized;
case 'deprioritized':
return auditColors.prioritized;
case 'selected':
return colors.marginal[levelIndex] || colors.marginal[defaultMempoolFeeColors.length - 1];
case 'accelerated':
@@ -51,7 +51,7 @@
<tr *ngIf="hasEffectiveRate && effectiveRate != null">
<td *ngIf="!this.acceleration" class="label" i18n="transaction.effective-fee-rate|Effective transaction fee rate">Effective fee rate</td>
<td *ngIf="this.acceleration" class="label" i18n="transaction.accelerated-fee-rate|Accelerated transaction fee rate">Accelerated fee rate</td>
<td class="value">
<td class="value" [class.oobFees]="this.acceleration">
<app-fee-rate [fee]="effectiveRate"></app-fee-rate>
</td>
</tr>
@@ -79,6 +79,11 @@
<span class="badge badge-warning" i18n="tx-features.tag.added|Added">Added</span>
<span class="badge badge-warning ml-1" i18n="tx-features.tag.prioritized|Prioritized">Prioritized</span>
</ng-container>
<span *ngSwitchCase="'deprioritized'" class="badge badge-warning" i18n="tx-features.tag.prioritized|Deprioritized">Deprioritized</span>
<ng-container *ngSwitchCase="'added_deprioritized'">
<span class="badge badge-warning" i18n="tx-features.tag.added|Added">Added</span>
<span class="badge badge-warning ml-1" i18n="tx-features.tag.prioritized|Deprioritized">Deprioritized</span>
</ng-container>
<span *ngSwitchCase="'selected'" class="badge badge-warning" i18n="transaction.audit.marginal">Marginal fee rate</span>
<span *ngSwitchCase="'rbf'" class="badge badge-warning" i18n="tx-features.tag.conflict|Conflict">Conflict</span>
<span *ngSwitchCase="'accelerated'" class="badge badge-accelerated" i18n="transaction.audit.accelerated">Accelerated</span>
@@ -27,6 +27,9 @@ th, td {
width: 70%;
text-align: end;
}
&.oobFees {
color: #905cf4;
}
}
.badge.badge-accelerated {
@@ -78,6 +78,25 @@
</ng-template>
</td>
</tr>
<tr *ngIf="this.stateService.network === '' && block.height % 2016 === 0">
<td i18n="mining.difficulty-adjustment">Adjustment</td>
<td>
<ng-container *ngIf="cacheService.daCache[block.height]?.adjustment > 0; else loadingAdjustment">
<div [style.color]="cacheService.daCache[block.height].adjustment > 1 ? 'var(--green)' : (cacheService.daCache[block.height].adjustment < 1 ? 'var(--red)' : '')">
@if (cacheService.daCache[block.height].adjustment > 1) {
<fa-icon class="retarget-sign up" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
} @else if (cacheService.daCache[block.height].adjustment < 1) {
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
}
{{ (cacheService.daCache[block.height].adjustment - 1) * 100 | absolute | number: '1.2-2' }}
<span class="symbol">%</span>
</div>
</ng-container>
<ng-template #loadingAdjustment>
<span class="skeleton-loader" style="max-width: 60px"></span>
</ng-template>
</td>
</tr>
</ng-container>
<ng-template #skeletonRows>
<tr>
@@ -193,6 +212,10 @@
</span>
</td>
</tr>
<tr *ngIf="this.stateService.network === '' && block.height % 2016 === 0">
<td i18n="block.difficulty">Difficulty</td>
<td>{{ block.difficulty | amountShortener: 2 }}</td>
</tr>
</ng-container>
<ng-template #loadingRest>
<tr>
@@ -280,3 +280,11 @@ h1 {
top: -1px;
margin-right: 2px;
}
.retarget-sign {
margin-right: -3px;
&.up {
position: relative;
top: 2px;
}
}
@@ -17,6 +17,7 @@ import { PriceService, Price } from '../../services/price.service';
import { CacheService } from '../../services/cache.service';
import { ServicesApiServices } from '../../services/services-api.service';
import { PreloadService } from '../../services/preload.service';
import { identifyPrioritizedTransactions } from '../../shared/transaction.utils';
@Component({
selector: 'app-block',
@@ -98,7 +99,7 @@ export class BlockComponent implements OnInit, OnDestroy {
private relativeUrlPipe: RelativeUrlPipe,
private apiService: ApiService,
private priceService: PriceService,
private cacheService: CacheService,
public cacheService: CacheService,
private servicesApiService: ServicesApiServices,
private cd: ChangeDetectorRef,
private preloadService: PreloadService,
@@ -524,6 +525,7 @@ export class BlockComponent implements OnInit, OnDestroy {
const isUnseen = {};
const isAdded = {};
const isPrioritized = {};
const isDeprioritized = {};
const isCensored = {};
const isMissing = {};
const isSelected = {};
@@ -535,6 +537,17 @@ export class BlockComponent implements OnInit, OnDestroy {
this.numUnexpected = 0;
if (blockAudit?.template) {
// augment with locally calculated *de*prioritized transactions if possible
const { prioritized, deprioritized } = identifyPrioritizedTransactions(transactions);
// but if the local calculation produces returns unexpected results, don't use it
let useLocalDeprioritized = deprioritized.length < (transactions.length * 0.1);
for (const tx of prioritized) {
if (!isPrioritized[tx] && !isAccelerated[tx]) {
useLocalDeprioritized = false;
break;
}
}
for (const tx of blockAudit.template) {
inTemplate[tx.txid] = true;
if (tx.acc) {
@@ -550,9 +563,14 @@ export class BlockComponent implements OnInit, OnDestroy {
for (const txid of blockAudit.addedTxs) {
isAdded[txid] = true;
}
for (const txid of blockAudit.prioritizedTxs || []) {
for (const txid of blockAudit.prioritizedTxs) {
isPrioritized[txid] = true;
}
if (useLocalDeprioritized) {
for (const txid of deprioritized || []) {
isDeprioritized[txid] = true;
}
}
for (const txid of blockAudit.missingTxs) {
isCensored[txid] = true;
}
@@ -608,6 +626,12 @@ export class BlockComponent implements OnInit, OnDestroy {
} else {
tx.status = 'prioritized';
}
} else if (isDeprioritized[tx.txid]) {
if (isAdded[tx.txid] || (blockAudit.version > 0 && isUnseen[tx.txid])) {
tx.status = 'added_deprioritized';
} else {
tx.status = 'deprioritized';
}
} else if (isAdded[tx.txid] && (blockAudit.version === 0 || isUnseen[tx.txid])) {
tx.status = 'added';
} else if (inTemplate[tx.txid]) {
@@ -1,10 +1,12 @@
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, Input, OnChanges, SimpleChanges } from '@angular/core';
import { Observable, Subscription, delay, filter, tap } from 'rxjs';
import { Observable, Subscription, delay, filter, of, retryWhen, switchMap, take, tap, throwError } from 'rxjs';
import { StateService } from '../../services/state.service';
import { specialBlocks } from '../../app.constants';
import { BlockExtended } from '../../interfaces/node-api.interface';
import { Location } from '@angular/common';
import { CacheService } from '../../services/cache.service';
import { ApiService } from '../../services/api.service';
import { colorFromRetarget } from '../../shared/common.utils';
interface BlockchainBlock extends BlockExtended {
placeholder?: boolean;
@@ -77,6 +79,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
constructor(
public stateService: StateService,
public cacheService: CacheService,
public apiService: ApiService,
private cd: ChangeDetectorRef,
private location: Location,
) {
@@ -334,6 +337,31 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
return this.specialBlocks[height]?.networks.includes(this.stateService.network || 'mainnet') ? true : false;
}
isDA(height: number): boolean {
const isDA = height % 2016 === 0 && this.stateService.network === '';
if (isDA && !this.cacheService.daCache[height]?.exact) {
const estimatedAdjustment = this.cacheService.daCache[height]?.adjustment || 0;
this.cacheService.daCache[height] = { adjustment: estimatedAdjustment, exact: true };
this.apiService.getDifficultyAdjustmentByHeight$(height).pipe(
switchMap(da => {
const blocksAvailable = (this.height || this.chainTip) && this.blockStyles[(this.height || this.chainTip) - height];
return blocksAvailable ? of(da) : throwError(() => new Error());
}),
retryWhen(errors =>
errors.pipe(
delay(1000),
take(3)
)
),
tap((da) => {
this.cacheService.daCache[height] = { adjustment: da?.adjustment || 1, exact: true };
this.blockStyles[(this.height || this.chainTip) - height].background = colorFromRetarget(da?.adjustment);
})
).subscribe();
}
return isDA;
}
getStyleForBlock(block: BlockchainBlock, index: number, animateEnterFrom: number = 0) {
if (!block || block.placeholder) {
return this.getStyleForPlaceholderBlock(index, animateEnterFrom);
@@ -349,7 +377,8 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
return {
left: addLeft + this.blockOffset * index + 'px',
background: `repeating-linear-gradient(
background: this.isDA(block.height) ? colorFromRetarget(this.cacheService.daCache[block.height]?.adjustment || 1) :
`repeating-linear-gradient(
var(--secondary),
var(--secondary) ${greenBackgroundHeight}%,
${this.gradientColors[this.network][0]} ${Math.max(greenBackgroundHeight, 0)}%,
@@ -5,6 +5,7 @@ import { ApiService } from '../../services/api.service';
import { formatNumber } from '@angular/common';
import { selectPowerOfTen } from '../../bitcoin.utils';
import { StateService } from '../../services/state.service';
import { CacheService } from '../../services/cache.service';
@Component({
selector: 'app-difficulty-adjustments-table',
@@ -27,7 +28,8 @@ export class DifficultyAdjustmentsTable implements OnInit {
constructor(
@Inject(LOCALE_ID) public locale: string,
private apiService: ApiService,
public stateService: StateService
public stateService: StateService,
private cacheService: CacheService,
) {
}
@@ -52,6 +54,7 @@ export class DifficultyAdjustmentsTable implements OnInit {
adjustment[2] / selectedPowerOfTen.divider,
this.locale, `1.${decimals}-${decimals}`) + selectedPowerOfTen.unit
});
this.cacheService.daCache[adjustment[1]] = { adjustment: adjustment[3], exact: true };
}
this.isLoading = false;
return tableData.slice(0, 6);
@@ -52,7 +52,7 @@
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['mainnet'] || '')" ngbDropdownItem class="mainnet"><app-svg-images name="bitcoin" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Mainnet</a>
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['signet'] || '/signet')" ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet'] || '/testnet')" ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet4'] || '/testnet4')" ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4 <span class="badge badge-pill badge-warning beta-network" i18n="beta">beta</span></a>
<a [href]="env.MEMPOOL_WEBSITE_URL + urlLanguage + (networkPaths['testnet4'] || '/testnet4')" ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
<h6 class="dropdown-header" i18n="master-page.layer2-networks-header">Layer 2 Networks</h6>
<a ngbDropdownItem class="liquid mr-1" [class.active]="network.val === 'liquid'" [routerLink]="networkPaths['liquid'] || '/'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
<a ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquidtestnet'" [routerLink]="networkPaths['liquidtestnet'] || '/testnet'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
@@ -70,7 +70,7 @@
<a ngbDropdownItem *ngIf="env.MAINNET_ENABLED" class="mainnet" [routerLink]="networkPaths['mainnet'] || '/'"><app-svg-images name="bitcoin" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Mainnet</a>
<a ngbDropdownItem *ngIf="env.SIGNET_ENABLED" class="signet" [class.active]="network.val === 'signet'" [routerLink]="networkPaths['signet'] || '/signet'"><app-svg-images name="signet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Signet</a>
<a ngbDropdownItem *ngIf="env.TESTNET_ENABLED" class="testnet" [class.active]="network.val === 'testnet'" [routerLink]="networkPaths['testnet'] || '/testnet'"><app-svg-images name="testnet" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet3</a>
<a ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet4" [class.active]="network.val === 'testnet4'" [routerLink]="networkPaths['testnet4'] || '/testnet4'"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4 <span class="badge badge-pill badge-warning beta-network" i18n="beta">beta</span></a>
<a ngbDropdownItem *ngIf="env.TESTNET4_ENABLED" class="testnet4" [class.active]="network.val === 'testnet4'" [routerLink]="networkPaths['testnet4'] || '/testnet4'"><app-svg-images name="testnet4" width="22" height="22" viewBox="0 0 65 65" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Testnet4</a>
<a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquid'] || '')" ngbDropdownItem *ngIf="env.LIQUID_ENABLED" class="liquid" [class.active]="network.val === 'liquid'"><app-svg-images name="liquid" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid</a>
<a [href]="env.LIQUID_WEBSITE_URL + urlLanguage + (networkPaths['liquidtestnet'] || '/testnet')" ngbDropdownItem *ngIf="env.LIQUID_TESTNET_ENABLED" class="liquidtestnet" [class.active]="network.val === 'liquid'"><app-svg-images name="liquidtestnet" width="22" height="22" viewBox="0 0 125 125" style="width: 25px; height: 25px;" class="mainnet mr-1"></app-svg-images> Liquid Testnet</a>
</div>
@@ -31,7 +31,7 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
lastBlockHeight: number;
blockIndex: number;
isLoading$ = new BehaviorSubject<boolean>(true);
isLoading$ = new BehaviorSubject<boolean>(false);
timeLtrSubscription: Subscription;
timeLtr: boolean;
chainDirection: string = 'right';
@@ -95,6 +95,7 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
}
}
this.updateBlock({
block: this.blockIndex,
removed,
changed,
added
@@ -110,8 +111,11 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
if (this.blockGraph) {
this.blockGraph.clear(changes.index.currentValue > changes.index.previousValue ? this.chainDirection : this.poolDirection);
}
this.isLoading$.next(true);
this.websocketService.startTrackMempoolBlock(changes.index.currentValue);
if (!this.websocketService.startTrackMempoolBlock(changes.index.currentValue) && this.stateService.mempoolBlockState && this.stateService.mempoolBlockState.block === changes.index.currentValue) {
this.resumeBlock(Object.values(this.stateService.mempoolBlockState.transactions));
} else {
this.isLoading$.next(true);
}
}
}
@@ -153,6 +157,19 @@ export class MempoolBlockOverviewComponent implements OnInit, OnDestroy, OnChang
this.isLoading$.next(false);
}
resumeBlock(transactionsStripped: TransactionStripped[]): void {
if (this.blockGraph) {
this.firstLoad = false;
this.blockGraph.setup(transactionsStripped, true);
this.blockIndex = this.index;
this.isLoading$.next(false);
} else {
requestAnimationFrame(() => {
this.resumeBlock(transactionsStripped);
});
}
}
onTxClick(event: { tx: TransactionStripped, keyModifier: boolean }): void {
const url = new RelativeUrlPipe(this.stateService).transform(`/tx/${event.tx.txid}`);
if (!event.keyModifier) {
@@ -41,6 +41,25 @@
</div>
</td>
</tr>
<tr *ngIf="this.stateService.network === '' && mempoolBlock.height % 2016 === 0">
<td i18n="mining.difficulty-adjustment">Adjustment</td>
<td>
<ng-container *ngIf="cacheService.daCache[mempoolBlock.height]?.adjustment > 0; else loadingAdjustment">
<div [style.color]="cacheService.daCache[mempoolBlock.height].adjustment > 1 ? 'var(--green)' : (cacheService.daCache[mempoolBlock.height].adjustment < 1 ? 'var(--red)' : '')">
@if (cacheService.daCache[mempoolBlock.height].adjustment > 1) {
<fa-icon class="retarget-sign up" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
} @else if (cacheService.daCache[mempoolBlock.height].adjustment < 1) {
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
}
{{ (cacheService.daCache[mempoolBlock.height].adjustment - 1) * 100 | absolute | number: '1.2-2' }}
<span class="symbol">%</span>
</div>
</ng-container>
<ng-template #loadingAdjustment>
<span class="skeleton-loader" style="max-width: 60px"></span>
</ng-template>
</td>
</tr>
</tbody>
</table>
<app-fee-distribution-graph *ngIf="webGlEnabled" [transactions]="mempoolBlockTransactions$ | async" [feeRange]="mempoolBlock.isStack ? mempoolBlock.feeRange : []" [vsize]="mempoolBlock.blockVSize" ></app-fee-distribution-graph>
@@ -36,3 +36,11 @@ h1 {
margin: auto;
}
}
.retarget-sign {
margin-right: -3px;
&.up {
position: relative;
top: 2px;
}
}
@@ -9,6 +9,7 @@ import { Observable, BehaviorSubject } from 'rxjs';
import { SeoService } from '../../services/seo.service';
import { seoDescriptionNetwork } from '../../shared/common.utils';
import { WebsocketService } from '../../services/websocket.service';
import { CacheService } from '../../services/cache.service';
@Component({
selector: 'app-mempool-block',
@@ -30,6 +31,7 @@ export class MempoolBlockComponent implements OnInit, OnDestroy {
public stateService: StateService,
private seoService: SeoService,
private websocketService: WebsocketService,
public cacheService: CacheService,
private cd: ChangeDetectorRef,
@Inject(PLATFORM_ID) private platformId: Object,
) {
@@ -71,7 +73,7 @@ export class MempoolBlockComponent implements OnInit, OnDestroy {
})
);
this.mempoolBlockTransactions$ = this.stateService.liveMempoolBlockTransactions$.pipe(map(txMap => Object.values(txMap)));
this.mempoolBlockTransactions$ = this.stateService.liveMempoolBlockTransactions$.pipe(map(({transactions}) => Object.values(transactions)));
this.network$ = this.stateService.networkChanged$;
}
@@ -51,7 +51,8 @@
</div>
</ng-template>
</div>
<div *ngIf="arrowVisible" id="arrow-up" [ngStyle]="{'right': rightPosition + (blockWidth * 0.3) + containerOffset + 'px', transition: transition }" [class.blink]="txPosition?.accelerated"></div>
<app-acceleration-sparkles [style]="{ position: 'absolute', right: 0}" [arrow]="arrowElement" [run]="acceleratingArrow"></app-acceleration-sparkles>
<div *ngIf="arrowVisible" #arrowUp id="arrow-up" [ngStyle]="{'right': rightPosition + (blockWidth * 0.3) + containerOffset + 'px', transition: transition }" [class.blink]="txPosition?.accelerated"></div>
</div>
</ng-container>
@@ -1,10 +1,10 @@
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, HostListener, Input, OnChanges, SimpleChanges, Output, EventEmitter } from '@angular/core';
import { Subscription, Observable, of, combineLatest } from 'rxjs';
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef, HostListener, Input, OnChanges, SimpleChanges, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
import { Subscription, Observable, of, combineLatest, throwError } from 'rxjs';
import { MempoolBlock } from '../../interfaces/websocket.interface';
import { StateService } from '../../services/state.service';
import { EtaService } from '../../services/eta.service';
import { Router } from '@angular/router';
import { delay, filter, map, switchMap, tap } from 'rxjs/operators';
import { delay, filter, map, retryWhen, switchMap, take, tap } from 'rxjs/operators';
import { feeLevels } from '../../app.constants';
import { specialBlocks } from '../../app.constants';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
@@ -12,6 +12,8 @@ import { Location } from '@angular/common';
import { DifficultyAdjustment, MempoolPosition } from '../../interfaces/node-api.interface';
import { animate, style, transition, trigger } from '@angular/animations';
import { ThemeService } from '../../services/theme.service';
import { CacheService } from '../../services/cache.service';
import { colorFromRetarget } from '../../shared/common.utils';
@Component({
selector: 'app-mempool-blocks',
@@ -77,6 +79,9 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
maxArrowPosition = 0;
rightPosition = 0;
transition = 'background 2s, right 2s, transform 1s';
@ViewChild('arrowUp')
arrowElement: ElementRef<HTMLDivElement>;
acceleratingArrow: boolean = false;
markIndex: number;
txPosition: MempoolPosition;
@@ -90,6 +95,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
constructor(
private router: Router,
public stateService: StateService,
public cacheService: CacheService,
private etaService: EtaService,
private themeService: ThemeService,
private cd: ChangeDetectorRef,
@@ -201,6 +207,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
this.markBlocksSubscription = this.stateService.markBlock$
.subscribe((state) => {
const oldTxPosition = this.txPosition;
this.markIndex = undefined;
this.txPosition = undefined;
this.txFeePerVSize = undefined;
@@ -209,6 +216,12 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
}
if (state.mempoolPosition) {
this.txPosition = state.mempoolPosition;
if (this.txPosition.accelerated && !oldTxPosition?.accelerated) {
this.acceleratingArrow = true;
setTimeout(() => {
this.acceleratingArrow = false;
}, 2000);
}
}
if (state.txFeePerVSize) {
this.txFeePerVSize = state.txFeePerVSize;
@@ -377,6 +390,37 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
this.mempoolBlocksFull.forEach((block, i) => this.mempoolBlockStyles.push(this.getStyleForMempoolBlock(block, i)));
}
isDA(height: number): boolean {
if (this.chainTip === -1) {
return false;
}
const isDA = height % 2016 === 0 && this.stateService.network === '';
if (isDA && !this.cacheService.daCache[height]) {
this.cacheService.daCache[height] = { adjustment: 0 };
this.difficultyAdjustments$.pipe(
filter(da => !!da),
switchMap(da => {
const mempoolBlocksAvailable = this.chainTip && this.mempoolBlockStyles[height - this.chainTip - 1];
return mempoolBlocksAvailable ? of(da) : throwError(() => new Error());
}),
retryWhen(errors =>
errors.pipe(
delay(100),
take(3)
)
),
tap(da => {
const adjustment = parseFloat((1 + da.difficultyChange / 100).toFixed(4));
if (adjustment !== this.cacheService.daCache[height].adjustment) {
this.cacheService.daCache[height].adjustment = adjustment;
this.mempoolBlockStyles[height - this.chainTip - 1].background = colorFromRetarget(adjustment);
}
})
).subscribe();
}
return isDA;
}
getStyleForMempoolBlock(mempoolBlock: MempoolBlock, index: number) {
const emptyBackgroundSpacePercentage = Math.max(100 - mempoolBlock.blockVSize / this.stateService.blockVSize * 100, 0);
const usedBlockSpace = 100 - emptyBackgroundSpacePercentage;
@@ -400,7 +444,7 @@ export class MempoolBlocksComponent implements OnInit, OnChanges, OnDestroy {
return {
'right': this.containerOffset + index * this.blockOffset + 'px',
'background': backgroundGradients.join(',') + ')'
'background': this.isDA(mempoolBlock.height) ? colorFromRetarget(this.cacheService.daCache[mempoolBlock.height]?.adjustment || 1) : backgroundGradients.join(',') + ')'
};
}
@@ -46,7 +46,7 @@
@if (replaced) {
<div class="alert-replaced" role="alert">
<span i18n="transaction.rbf.replacement|RBF replacement">This transaction has been replaced by:</span>
<app-truncate [text]="latestReplacement" [lastChars]="12" [link]="['/tracker/' | relativeUrl, latestReplacement]"></app-truncate>
<app-truncate [text]="latestReplacement" [lastChars]="12" [link]="['/tx/' | relativeUrl, latestReplacement]" [queryParams]="{mode: 'status'}"></app-truncate>
</div>
} @else {
<div class="tracker-bar">
@@ -118,7 +118,7 @@
</div>
<span class="explainer">&nbsp;</span>
} @else {
@if (!tx.status?.confirmed && showAccelerationSummary) {
@if (tx && !tx.status?.confirmed && showAccelerationSummary) {
<ng-container *ngIf="(ETA$ | async) as eta;">
<app-accelerate-checkout
*ngIf="(da$ | async) as da;"
@@ -135,7 +135,7 @@
></app-accelerate-checkout>
</ng-container>
}
<div class="status-panel d-flex flex-column h-100 w-100 justify-content-center align-items-center" [class.small-status]="!tx.status?.confirmed && showAccelerationSummary">
<div class="status-panel d-flex flex-column h-100 w-100 justify-content-center align-items-center" [class.small-status]="tx && !tx.status?.confirmed && showAccelerationSummary">
@if (tx?.acceleration && !tx.status?.confirmed) {
<div class="progress-icon">
<fa-icon [icon]="['fas', 'wand-magic-sparkles']" [fixedWidth]="true"></fa-icon>
@@ -186,7 +186,7 @@
</div>
<div class="footer-link"
[routerLink]="['/tx' | relativeUrl, tx?.txid]"
[routerLink]="['/tx' | relativeUrl, tx?.txid || txId]"
[queryParams]="{ mode: 'details' }"
queryParamsHandling="merge"
>
@@ -293,7 +293,7 @@ export class TrackerComponent implements OnInit, OnDestroy {
})
).subscribe((accelerationHistory) => {
for (const acceleration of accelerationHistory) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional')) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional') && acceleration.pools.includes(acceleration.minedByPoolUniqueId)) {
const boostCost = acceleration.boostCost || acceleration.bidBoost;
acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize;
acceleration.boost = boostCost;
@@ -747,7 +747,7 @@ export class TrackerComponent implements OnInit, OnDestroy {
checkAccelerationEligibility() {
if (this.tx) {
this.tx.flags = getTransactionFlags(this.tx);
this.tx.flags = getTransactionFlags(this.tx, null, null, this.tx.status?.block_time, this.stateService.network);
const replaceableInputs = (this.tx.flags & (TransactionFlags.sighash_none | TransactionFlags.sighash_acp)) > 0n;
const highSigop = (this.tx.sigops * 20) > this.tx.weight;
this.eligibleForAcceleration = !replaceableInputs && !highSigop;
@@ -8,7 +8,7 @@
<div *ngIf="officialMempoolSpace">
<h2>Trademark Policy and Guidelines</h2>
<h5>The Mempool Open Source Project &reg;</h5>
<h6>Updated: July 3, 2024</h6>
<h6>Updated: August 19, 2024</h6>
<br>
<div class="text-left">
@@ -100,11 +100,26 @@
<p>The Mempool Accelerator Logo</p>
<br><br>
<img src="/resources/mempool-research.png" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool research Logo</p>
<br><br>
<app-svg-images name="goggles" height="96px"></app-svg-images>
<br><br>
<p>The Mempool Goggles Logo</p>
<br><br>
<img src="/resources/mempool-transaction.png" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool transaction Logo</p>
<br><br>
<img src="/resources/mempool-block-visualization.png" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool block visualization Logo</p>
<br><br>
<img src="/resources/mempool-blocks-2-3-logo.jpeg" style="width: 500px; max-width: 80%">
<br><br>
<p>The mempool Blocks Logo</p>
@@ -606,7 +606,12 @@
@if (!isLoadingTx) {
<tr>
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee"></app-fiat></span></td>
<td class="text-wrap">{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span>
@if (accelerationInfo?.bidBoost ?? tx.feeDelta > 0) {
<span class="oobFees" i18n-ngbTooltip="Acceleration Fees" ngbTooltip="Acceleration fees paid out-of-band"> +{{ accelerationInfo?.bidBoost ?? tx.feeDelta | number }} </span><span class="symbol" i18n="shared.sat|sat">sat</span>
}
<span class="fiat"><app-fiat [blockConversion]="tx.price" [value]="tx.fee + ((accelerationInfo?.bidBoost ?? tx.feeDelta) || 0)"></app-fiat></span>
</td>
</tr>
} @else {
<ng-container *ngTemplateOutlet="skeletonDetailsRow"></ng-container>
@@ -642,9 +647,9 @@
<td>
<div class="effective-fee-container">
@if (accelerationInfo?.acceleratedFeeRate && (!tx.effectiveFeePerVsize || accelerationInfo.acceleratedFeeRate >= tx.effectiveFeePerVsize || tx.acceleration)) {
<app-fee-rate [fee]="accelerationInfo.acceleratedFeeRate"></app-fee-rate>
<app-fee-rate [class.oobFees]="isAcceleration" [fee]="accelerationInfo.acceleratedFeeRate"></app-fee-rate>
} @else {
<app-fee-rate [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
<app-fee-rate [class.oobFees]="isAcceleration" [fee]="tx.effectiveFeePerVsize"></app-fee-rate>
}
@if (tx?.status?.confirmed && !tx.acceleration && !accelerationInfo && tx.fee && tx.effectiveFeePerVsize) {
@@ -332,3 +332,7 @@
top: -1px;
margin-right: 2px;
}
.oobFees {
color: #905cf4;
}
@@ -358,12 +358,18 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}),
).subscribe((accelerationHistory) => {
for (const acceleration of accelerationHistory) {
if (acceleration.txid === this.txId && (acceleration.status === 'completed' || acceleration.status === 'completed_provisional')) {
const boostCost = acceleration.boostCost || acceleration.bidBoost;
acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize;
acceleration.boost = boostCost;
this.tx.acceleratedAt = acceleration.added;
this.accelerationInfo = acceleration;
if (acceleration.txid === this.txId) {
if (acceleration.status === 'completed' || acceleration.status === 'completed_provisional') {
if (acceleration.pools.includes(acceleration.minedByPoolUniqueId)) {
const boostCost = acceleration.boostCost || acceleration.bidBoost;
acceleration.acceleratedFeeRate = Math.max(acceleration.effectiveFee, acceleration.effectiveFee + boostCost) / acceleration.effectiveVsize;
acceleration.boost = boostCost;
this.tx.acceleratedAt = acceleration.added;
this.accelerationInfo = acceleration;
} else {
this.tx.feeDelta = undefined;
}
}
this.waitingForAccelerationInfo = false;
this.setIsAccelerated();
}
@@ -462,9 +468,23 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
if (txPosition.position.acceleratedBy) {
txPosition.cpfp.acceleratedBy = txPosition.position.acceleratedBy;
}
if (txPosition.position.acceleratedAt) {
txPosition.cpfp.acceleratedAt = txPosition.position.acceleratedAt;
}
if (txPosition.position.feeDelta) {
txPosition.cpfp.feeDelta = txPosition.position.feeDelta;
}
this.setCpfpInfo(txPosition.cpfp);
} else if ((this.tx?.acceleration && txPosition.position.acceleratedBy)) {
this.tx.acceleratedBy = txPosition.position.acceleratedBy;
} else if ((this.tx?.acceleration)) {
if (txPosition.position.acceleratedBy) {
this.tx.acceleratedBy = txPosition.position.acceleratedBy;
}
if (txPosition.position.acceleratedAt) {
this.tx.acceleratedAt = txPosition.position.acceleratedAt;
}
if (txPosition.position.feeDelta) {
this.tx.feeDelta = txPosition.position.feeDelta;
}
}
if (this.stateService.network === '') {
@@ -881,7 +901,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.segwitEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'segwit');
this.taprootEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'taproot');
this.rbfEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'rbf');
this.tx.flags = getTransactionFlags(this.tx);
this.tx.flags = getTransactionFlags(this.tx, null, null, this.tx.status?.block_time, this.stateService.network);
this.filters = this.tx.flags ? toFilters(this.tx.flags).filter(f => f.txPage) : [];
this.checkAccelerationEligibility();
} else {
@@ -43,7 +43,7 @@
<span *ngSwitchCase="'output'" i18n="transaction.output">Output</span>
<span *ngSwitchCase="'fee'" i18n="transaction.fee|Transaction fee">Fee</span>
</ng-container>
<span *ngIf="line.type !== 'fee'"> #{{ line.index + 1 }}</span>
<span *ngIf="line.type !== 'fee'"> #{{ line.index }}</span>
<ng-container [ngSwitch]="line.type">
<span *ngSwitchCase="'input'">
<ng-container *ngIf="line.status?.block_height">
@@ -73,7 +73,7 @@
<app-truncate [text]="line.txid"></app-truncate>
</p>
<ng-container [ngSwitch]="line.type">
<p *ngSwitchCase="'input'"><span i18n="transaction.output">Output</span>&nbsp; #{{ line.vout + 1 }}
<p *ngSwitchCase="'input'"><span i18n="transaction.output">Output</span>&nbsp; #{{ line.vout }}
<ng-container *ngIf="line.status?.block_height">
<ng-container *ngIf="line.blockHeight; else noBlockHeight">
<ng-container *ngTemplateOutlet="nBlocksEarlier; context:{n: line.blockHeight - line?.status?.block_height, connector: true}"></ng-container>
@@ -83,7 +83,7 @@
</ng-template>
</ng-container>
</p>
<p *ngSwitchCase="'output'"><span i18n="transaction.input">Input</span>&nbsp; #{{ line.vin + 1 }}
<p *ngSwitchCase="'output'"><span i18n="transaction.input">Input</span>&nbsp; #{{ line.vin }}
<ng-container *ngIf="line.blockHeight">
<ng-container *ngIf="line?.status?.block_height; else noBlockHeight">
<ng-container *ngTemplateOutlet="nBlocksLater; context:{n: line?.status?.block_height - line.blockHeight, connector: true}"></ng-container>
@@ -3670,6 +3670,39 @@ export const restApiDocsData = [
}
}
},
{
type: "endpoint",
category: "mining",
httpRequestMethod: "GET",
fragment: "get-difficulty-adjustment-by-height",
title: "GET Difficulty Adjustment",
description: {
default: "<p>Returns difficulty adjustment for the block at the specified <code>:blockHeight</code>. If no adjustment happened at that height, an empty response is returned.</p>"
},
urlString: "/v1/mining/difficulty-adjustment/:blockHeight",
showConditions: [""],
showJsExamples: showJsExamplesDefaultFalse,
codeExample: {
default: {
codeTemplate: {
curl: `/api/v1/mining/difficulty-adjustment/%{1}`,
commonJS: ``,
esModule: ``
},
codeSampleMainnet: {
esModule: [],
commonJS: [],
curl: [`756000`],
response: `{
"time": "2022-09-28T02:56:34.000Z",
"height": 756000,
"difficulty": 31360548173144.9,
"adjustment": 0.97863
}`
},
}
}
},
{
type: "endpoint",
category: "mining",
@@ -239,7 +239,7 @@ export interface TransactionStripped {
acc?: boolean;
flags?: number | null;
time?: number;
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'added_prioritized' | 'prioritized' | 'censored' | 'selected' | 'rbf' | 'accelerated';
status?: 'found' | 'missing' | 'sigop' | 'fresh' | 'freshcpfp' | 'added' | 'added_prioritized' | 'prioritized' | 'added_deprioritized' | 'deprioritized' | 'censored' | 'selected' | 'rbf' | 'accelerated';
context?: 'projected' | 'actual';
}
@@ -253,6 +253,8 @@ export interface MempoolPosition {
vsize: number,
accelerated?: boolean,
acceleratedBy?: number[],
acceleratedAt?: number,
feeDelta?: number,
}
export interface AccelerationPosition extends MempoolPosition {
@@ -72,11 +72,13 @@ export interface MempoolBlockWithTransactions extends MempoolBlock {
}
export interface MempoolBlockDelta {
block: number;
added: TransactionStripped[];
removed: string[];
changed: { txid: string, rate: number, flags: number, acc: boolean }[];
}
export interface MempoolBlockState {
block: number;
transactions: TransactionStripped[];
}
export type MempoolBlockUpdate = MempoolBlockDelta | MempoolBlockState;
+1 -1
View File
@@ -13,7 +13,7 @@ class GuardService {
trackerGuard(route: Route, segments: UrlSegment[]): boolean {
const preferredRoute = this.router.getCurrentNavigation()?.extractedUrl.queryParams?.mode;
return preferredRoute !== 'details' && this.navigationService.isInitialLoad() && window.innerWidth <= 767.98;
return (preferredRoute === 'status' || (preferredRoute !== 'details' && this.navigationService.isInitialLoad())) && window.innerWidth <= 767.98;
}
}
+6
View File
@@ -315,6 +315,12 @@ export class ApiService {
);
}
getDifficultyAdjustmentByHeight$(height: number): Observable<any> {
return this.httpClient.get<any>(
this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/difficulty-adjustment/${height}`
);
}
getHistoricalHashrate$(interval: string | undefined): Observable<any> {
return this.httpClient.get<any[]>(
this.apiBaseUrl + this.apiBasePath + `/api/v1/mining/hashrate` +
@@ -23,6 +23,7 @@ export class CacheService {
blockLoading: { [height: number]: boolean } = {};
copiesInBlockQueue: { [height: number]: number } = {};
blockPriorities: number[] = [];
daCache: { [height: number]: { adjustment: number, exact?: boolean } } = {};
constructor(
private stateService: StateService,
@@ -128,6 +129,7 @@ export class CacheService {
this.blockLoading = {};
this.copiesInBlockQueue = {};
this.blockPriorities = [];
this.daCache = {};
}
getCachedBlock(height) {
@@ -30,7 +30,6 @@ export class EnterpriseService {
this.fetchSubdomainInfo();
this.disableSubnetworks();
this.stateService.env.ACCELERATOR = false;
this.stateService.env.ACCELERATOR_BUTTON = false;
} else {
this.insertMatomo();
}
+10 -1
View File
@@ -37,7 +37,11 @@ export class MiningService {
private stateService: StateService,
private apiService: ApiService,
private storageService: StorageService,
) { }
) {
this.stateService.networkChanged$.subscribe((network) => {
this.clearCache();
});
}
/**
* Generate pool ranking stats
@@ -141,4 +145,9 @@ export class MiningService {
totalBlockCount: parseInt(response.headers.get('x-total-count'), 10),
};
}
private clearCache(): void {
this.cache = {};
this.poolsData = [];
}
}
+27 -15
View File
@@ -5,7 +5,7 @@ import { AccelerationDelta, HealthCheckHost, IBackendInfo, MempoolBlock, Mempool
import { Acceleration, AccelerationPosition, BlockExtended, CpfpInfo, DifficultyAdjustment, MempoolPosition, OptimizedMempoolStats, RbfTree, TransactionStripped } from '../interfaces/node-api.interface';
import { Router, NavigationStart } from '@angular/router';
import { isPlatformBrowser } from '@angular/common';
import { filter, map, scan, shareReplay } from 'rxjs/operators';
import { filter, map, scan, share, shareReplay } from 'rxjs/operators';
import { StorageService } from './storage.service';
import { hasTouchScreen } from '../shared/pipes/bytes-pipe/utils';
import { ActiveFilter } from '../shared/filters.utils';
@@ -131,6 +131,7 @@ export class StateService {
latestBlockHeight = -1;
blocks: BlockExtended[] = [];
mempoolSequence: number;
mempoolBlockState: { block: number, transactions: { [txid: string]: TransactionStripped} };
backend$ = new BehaviorSubject<'esplora' | 'electrum' | 'none'>('esplora');
networkChanged$ = new ReplaySubject<string>(1);
@@ -143,7 +144,7 @@ export class StateService {
mempoolInfo$ = new ReplaySubject<MempoolInfo>(1);
mempoolBlocks$ = new ReplaySubject<MempoolBlock[]>(1);
mempoolBlockUpdate$ = new Subject<MempoolBlockUpdate>();
liveMempoolBlockTransactions$: Observable<{ [txid: string]: TransactionStripped}>;
liveMempoolBlockTransactions$: Observable<{ block: number, transactions: { [txid: string]: TransactionStripped} }>;
accelerations$ = new Subject<AccelerationDelta>();
liveAccelerations$: Observable<Acceleration[]>;
txConfirmed$ = new Subject<[string, BlockExtended]>();
@@ -210,6 +211,10 @@ export class StateService {
this.env.MINING_DASHBOARD = false;
}
if (document.location.hostname.endsWith('.onion')) {
this.env.SERVICES_API = 'http://mempoolhqx4isw62xs7abwphsq7ldayuidyx2v2oethdhhj6mlo2r6ad.onion/api/v1/services';
}
if (this.isBrowser) {
this.setNetworkBasedonUrl(window.location.pathname);
this.setLightningBasedonUrl(window.location.pathname);
@@ -227,33 +232,40 @@ export class StateService {
}
});
if (this.referrer === 'https://cash.app/' && window.innerWidth < 850 && window.location.pathname.startsWith('/tx/')) {
this.router.navigate(['/tracker/' + window.location.pathname.slice(4)]);
}
this.liveMempoolBlockTransactions$ = this.mempoolBlockUpdate$.pipe(scan((transactions: { [txid: string]: TransactionStripped }, change: MempoolBlockUpdate): { [txid: string]: TransactionStripped } => {
this.liveMempoolBlockTransactions$ = this.mempoolBlockUpdate$.pipe(scan((acc: { block: number, transactions: { [txid: string]: TransactionStripped } }, change: MempoolBlockUpdate): { block: number, transactions: { [txid: string]: TransactionStripped } } => {
if (isMempoolState(change)) {
const txMap = {};
change.transactions.forEach(tx => {
txMap[tx.txid] = tx;
});
return txMap;
this.mempoolBlockState = {
block: change.block,
transactions: txMap
};
return this.mempoolBlockState;
} else {
change.added.forEach(tx => {
transactions[tx.txid] = tx;
acc.transactions[tx.txid] = tx;
});
change.removed.forEach(txid => {
delete transactions[txid];
delete acc.transactions[txid];
});
change.changed.forEach(tx => {
if (transactions[tx.txid]) {
transactions[tx.txid].rate = tx.rate;
transactions[tx.txid].acc = tx.acc;
if (acc.transactions[tx.txid]) {
acc.transactions[tx.txid].rate = tx.rate;
acc.transactions[tx.txid].acc = tx.acc;
}
});
return transactions;
this.mempoolBlockState = {
block: change.block,
transactions: acc.transactions
};
return this.mempoolBlockState;
}
}, {}));
}, {}),
share()
);
this.liveMempoolBlockTransactions$.subscribe();
// Emits the full list of pending accelerations each time it changes
this.liveAccelerations$ = this.accelerations$.pipe(
+19 -5
View File
@@ -35,6 +35,7 @@ export class WebsocketService {
private isTrackingAddresses: string[] | false = false;
private isTrackingAccelerations: boolean = false;
private trackingMempoolBlock: number;
private stoppingTrackMempoolBlock: any | null = null;
private latestGitCommit = '';
private onlineCheckTimeout: number;
private onlineCheckTimeoutTwo: number;
@@ -203,19 +204,31 @@ export class WebsocketService {
this.websocketSubject.next({ 'track-asset': 'stop' });
}
startTrackMempoolBlock(block: number, force: boolean = false) {
startTrackMempoolBlock(block: number, force: boolean = false): boolean {
if (this.stoppingTrackMempoolBlock) {
clearTimeout(this.stoppingTrackMempoolBlock);
}
// skip duplicate tracking requests
if (force || this.trackingMempoolBlock !== block) {
this.websocketSubject.next({ 'track-mempool-block': block });
this.isTrackingMempoolBlock = true;
this.trackingMempoolBlock = block;
return true;
}
return false;
}
stopTrackMempoolBlock() {
this.websocketSubject.next({ 'track-mempool-block': -1 });
stopTrackMempoolBlock(): void {
if (this.stoppingTrackMempoolBlock) {
clearTimeout(this.stoppingTrackMempoolBlock);
}
this.isTrackingMempoolBlock = false;
this.trackingMempoolBlock = null;
this.stoppingTrackMempoolBlock = setTimeout(() => {
this.stoppingTrackMempoolBlock = null;
this.websocketSubject.next({ 'track-mempool-block': -1 });
this.trackingMempoolBlock = null;
this.stateService.mempoolBlockState = null;
}, 2000);
}
startTrackRbf(mode: 'all' | 'fullRbf') {
@@ -424,6 +437,7 @@ export class WebsocketService {
if (response['projected-block-transactions'].blockTransactions) {
this.stateService.mempoolSequence = response['projected-block-transactions'].sequence;
this.stateService.mempoolBlockUpdate$.next({
block: this.trackingMempoolBlock,
transactions: response['projected-block-transactions'].blockTransactions.map(uncompressTx),
});
} else if (response['projected-block-transactions'].delta) {
@@ -432,7 +446,7 @@ export class WebsocketService {
this.startTrackMempoolBlock(this.trackingMempoolBlock, true);
} else {
this.stateService.mempoolSequence = response['projected-block-transactions'].sequence;
this.stateService.mempoolBlockUpdate$.next(uncompressDeltaChange(response['projected-block-transactions'].delta));
this.stateService.mempoolBlockUpdate$.next(uncompressDeltaChange(this.trackingMempoolBlock, response['projected-block-transactions'].delta));
}
}
}
+11
View File
@@ -17,6 +17,7 @@ export type AddressType = 'fee'
| 'v0_p2wsh'
| 'v1_p2tr'
| 'confidential'
| 'anchor'
| 'unknown'
const ADDRESS_PREFIXES = {
@@ -188,6 +189,12 @@ export class AddressTypeInfo {
const v = vin[0];
this.processScript(new ScriptInfo('scriptpubkey', v.prevout.scriptpubkey, v.prevout.scriptpubkey_asm));
}
} else if (this.type === 'unknown') {
for (const v of vin) {
if (v.prevout?.scriptpubkey === '51024e73') {
this.type = 'anchor';
}
}
}
// and there's nothing more to learn from processing inputs for other types
}
@@ -197,6 +204,10 @@ export class AddressTypeInfo {
if (!this.scripts.size) {
this.processScript(new ScriptInfo('scriptpubkey', output.scriptpubkey, output.scriptpubkey_asm));
}
} else if (this.type === 'unknown') {
if (output.scriptpubkey === '51024e73') {
this.type = 'anchor';
}
}
}
+24 -1
View File
@@ -170,8 +170,9 @@ export function uncompressTx(tx: TransactionCompressed): TransactionStripped {
};
}
export function uncompressDeltaChange(delta: MempoolBlockDeltaCompressed): MempoolBlockDelta {
export function uncompressDeltaChange(block: number, delta: MempoolBlockDeltaCompressed): MempoolBlockDelta {
return {
block,
added: delta.added.map(uncompressTx),
removed: delta.removed,
changed: delta.changed.map(tx => ({
@@ -239,3 +240,25 @@ export function md5(inputString): string {
}
return rh(a)+rh(b)+rh(c)+rh(d);
}
export function colorFromRetarget(da: number): string {
const minDA = 0.95;
const maxDA = 1.05;
const midDA = 1;
const red = { r: 220, g: 53, b: 69 };
const grey = { r: 108, g: 117, b: 125 };
const green = { r: 59, g: 204, b: 73 };
const interpolateColor = (color1, color2, ratio) => {
ratio = Math.min(1, Math.max(0, ratio));
const r = Math.round(color1.r + ratio * (color2.r - color1.r));
const g = Math.round(color1.g + ratio * (color2.g - color1.g));
const b = Math.round(color1.b + ratio * (color2.b - color1.b));
return `rgba(${r}, ${g}, ${b}, 0.7)`;
}
return da <= midDA ?
interpolateColor(red, grey, (da - minDA) / (midDA - minDA)) :
interpolateColor(grey, green, (da - midDA) / (maxDA - midDA));
}
@@ -20,6 +20,9 @@
@case ('multisig') {
<span i18n="address.bare-multisig">bare multisig</span>
}
@case ('anchor') {
<span>anchor</span>
}
@case (null) {
<span>unknown</span>
}
@@ -79,7 +79,7 @@
<p class="category" i18n="footer.networks">Networks</p>
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== '') && (currentNetwork !== 'mainnet')"><a [href]="networkLink('mainnet')" i18n="footer.mainnet-explorer">Mainnet Explorer</a></p>
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet') && env.TESTNET_ENABLED"><a [href]="networkLink('testnet')" i18n="footer.testnet3-explorer">Testnet3 Explorer</a></p>
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet4') && env.TESTNET4_ENABLED"><a [href]="networkLink('testnet4')" i18n="footer.testnet4-explorer">Testnet4 Explorer</a> <span class="badge badge-pill badge-warning beta-network" i18n="beta">beta</span></p>
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'testnet4') && env.TESTNET4_ENABLED"><a [href]="networkLink('testnet4')" i18n="footer.testnet4-explorer">Testnet4 Explorer</a></p>
<p *ngIf="(officialMempoolSpace || (env.BASE_MODULE === 'mempool')) && (currentNetwork !== 'signet') && env.SIGNET_ENABLED"><a [href]="networkLink('signet')" i18n="footer.signet-explorer">Signet Explorer</a></p>
<p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquidtestnet')"><a [href]="networkLink('liquidtestnet')" i18n="footer.liquid-testnet-explorer">Liquid Testnet Explorer</a></p>
<p *ngIf="(officialMempoolSpace || env.LIQUID_ENABLED) && (currentNetwork !== 'liquid')"><a [href]="networkLink('liquid')" i18n="footer.liquid-explorer">Liquid Explorer</a></p>
@@ -5,9 +5,6 @@
@if (stateService.network === 'testnet') {
<span i18n="testnet3-deprecated">Testnet3 is deprecated, and will soon be replaced by <a href="/testnet4">Testnet4</a></span>
}
@if (stateService.network === 'testnet4') {
<span i18n="testnet4-not-finalized">Testnet4 is not yet finalized, and may be reset at anytime.</span>
}
</div>
<button type="button" class="close" (click)="dismissWarning()">
<span aria-hidden="true">&times;</span>
@@ -1,6 +1,6 @@
<span class="truncate" [style.max-width]="maxWidth ? maxWidth + 'px' : null" [style.justify-content]="textAlign" [class.inline]="inline">
<ng-container *ngIf="link">
<a [routerLink]="link" class="truncate-link" [target]="external ? '_blank' : ''">
<a [routerLink]="link" [queryParams]="queryParams" class="truncate-link" [target]="external ? '_blank' : '_self'">
<ng-container *ngIf="rtl; then rtlTruncated; else ltrTruncated;"></ng-container>
</a>
</ng-container>
@@ -10,6 +10,7 @@ export class TruncateComponent {
@Input() text: string;
@Input() link: any = null;
@Input() external: boolean = false;
@Input() queryParams: any = undefined;
@Input() lastChars: number = 4;
@Input() maxWidth: number = null;
@Input() inline: boolean = false;
+3 -2
View File
@@ -166,6 +166,7 @@ export const ScriptTemplates: { [type: string]: (...args: any) => ScriptTemplate
ln_anchor: () => ({ type: 'ln_anchor', label: 'Lightning Anchor' }),
ln_anchor_swept: () => ({ type: 'ln_anchor_swept', label: 'Swept Lightning Anchor' }),
multisig: (m: number, n: number) => ({ type: 'multisig', m, n, label: $localize`:@@address-label.multisig:Multisig ${m}:multisigM: of ${n}:multisigN:` }),
anchor: () => ({ type: 'anchor', label: 'anchor' }),
};
export class ScriptInfo {
@@ -266,7 +267,7 @@ export function parseMultisigScript(script: string): undefined | { m: number, n:
if (!opN) {
return;
}
if (!opN.startsWith('OP_PUSHNUM_')) {
if (opN !== 'OP_0' && !opN.startsWith('OP_PUSHNUM_')) {
return;
}
const n = parseInt(opN.match(/[0-9]+/)?.[0] || '', 10);
@@ -286,7 +287,7 @@ export function parseMultisigScript(script: string): undefined | { m: number, n:
if (!opM) {
return;
}
if (!opM.startsWith('OP_PUSHNUM_')) {
if (opM !== 'OP_0' && !opM.startsWith('OP_PUSHNUM_')) {
return;
}
const m = parseInt(opM.match(/[0-9]+/)?.[0] || '', 10);
+3
View File
@@ -100,6 +100,7 @@ import { MempoolErrorComponent } from './components/mempool-error/mempool-error.
import { AccelerationsListComponent } from '../components/acceleration/accelerations-list/accelerations-list.component';
import { PendingStatsComponent } from '../components/acceleration/pending-stats/pending-stats.component';
import { AccelerationStatsComponent } from '../components/acceleration/acceleration-stats/acceleration-stats.component';
import { AccelerationSparklesComponent } from '../components/acceleration/sparkles/acceleration-sparkles.component';
import { BlockViewComponent } from '../components/block-view/block-view.component';
import { EightBlocksComponent } from '../components/eight-blocks/eight-blocks.component';
@@ -225,6 +226,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
AccelerationsListComponent,
AccelerationStatsComponent,
PendingStatsComponent,
AccelerationSparklesComponent,
HttpErrorComponent,
TwitterWidgetComponent,
FaucetComponent,
@@ -355,6 +357,7 @@ import { OnlyVsizeDirective, OnlyWeightDirective } from './components/weight-dir
AccelerationsListComponent,
AccelerationStatsComponent,
PendingStatsComponent,
AccelerationSparklesComponent,
HttpErrorComponent,
TwitterWidgetComponent,
TwitterLogin,
+135 -6
View File
@@ -1,10 +1,10 @@
import { TransactionFlags } from './filters.utils';
import { getVarIntLength, opcodes, parseMultisigScript, isPoint } from './script.utils';
import { Transaction } from '../interfaces/electrs.interface';
import { CpfpInfo, RbfInfo } from '../interfaces/node-api.interface';
import { CpfpInfo, RbfInfo, TransactionStripped } from '../interfaces/node-api.interface';
import { StateService } from '../services/state.service';
// Bitcoin Core default policy settings
const TX_MAX_STANDARD_VERSION = 2;
const MAX_STANDARD_TX_WEIGHT = 400_000;
const MAX_BLOCK_SIGOPS_COST = 80_000;
const MAX_STANDARD_TX_SIGOPS_COST = (MAX_BLOCK_SIGOPS_COST / 5);
@@ -89,10 +89,13 @@ export function isDERSig(w: string): boolean {
*
* returns true early if any standardness rule is violated, otherwise false
* (except for non-mandatory-script-verify-flag and p2sh script evaluation rules which are *not* enforced)
*
* As standardness rules change, we'll need to apply the rules in force *at the time* to older blocks.
* For now, just pull out individual rules into versioned functions where necessary.
*/
export function isNonStandard(tx: Transaction): boolean {
export function isNonStandard(tx: Transaction, height?: number, network?: string): boolean {
// version
if (tx.version > TX_MAX_STANDARD_VERSION) {
if (isNonStandardVersion(tx, height, network)) {
return true;
}
@@ -139,6 +142,8 @@ export function isNonStandard(tx: Transaction): boolean {
}
} else if (['unknown', 'provably_unspendable', 'empty'].includes(vin.prevout?.scriptpubkey_type || '')) {
return true;
} else if (isNonStandardAnchor(tx, height, network)) {
return true;
}
// TODO: bad-witness-nonstandard
}
@@ -203,6 +208,51 @@ export function isNonStandard(tx: Transaction): boolean {
return false;
}
// Individual versioned standardness rules
const V3_STANDARDNESS_ACTIVATION_HEIGHT = {
'testnet4': 42_000,
'testnet': 2_900_000,
'signet': 211_000,
'': 863_500,
};
function isNonStandardVersion(tx: Transaction, height?: number, network?: string): boolean {
let TX_MAX_STANDARD_VERSION = 3;
if (
height != null
&& network != null
&& V3_STANDARDNESS_ACTIVATION_HEIGHT[network]
&& height <= V3_STANDARDNESS_ACTIVATION_HEIGHT[network]
) {
// V3 transactions were non-standard to spend before v28.x (scheduled for 2024/09/30 https://github.com/bitcoin/bitcoin/issues/29891)
TX_MAX_STANDARD_VERSION = 2;
}
if (tx.version > TX_MAX_STANDARD_VERSION) {
return true;
}
return false;
}
const ANCHOR_STANDARDNESS_ACTIVATION_HEIGHT = {
'testnet4': 42_000,
'testnet': 2_900_000,
'signet': 211_000,
'': 863_500,
};
function isNonStandardAnchor(tx: Transaction, height?: number, network?: string): boolean {
if (
height != null
&& network != null
&& ANCHOR_STANDARDNESS_ACTIVATION_HEIGHT[network]
&& height <= ANCHOR_STANDARDNESS_ACTIVATION_HEIGHT[network]
) {
// anchor outputs were non-standard to spend before v28.x (scheduled for 2024/09/30 https://github.com/bitcoin/bitcoin/issues/29891)
return true;
}
return false;
}
// A witness program is any valid scriptpubkey that consists of a 1-byte push opcode
// followed by a data push between 2 and 40 bytes.
// https://github.com/bitcoin/bitcoin/blob/2c79abc7ad4850e9e3ba32a04c530155cda7f980/src/script/script.cpp#L224-L240
@@ -289,7 +339,7 @@ export function isBurnKey(pubkey: string): boolean {
].includes(pubkey);
}
export function getTransactionFlags(tx: Transaction, cpfpInfo?: CpfpInfo, replacement?: boolean): bigint {
export function getTransactionFlags(tx: Transaction, cpfpInfo?: CpfpInfo, replacement?: boolean, height?: number, network?: string): bigint {
let flags = tx.flags ? BigInt(tx.flags) : 0n;
// Update variable flags (CPFP, RBF)
@@ -439,7 +489,7 @@ export function getTransactionFlags(tx: Transaction, cpfpInfo?: CpfpInfo, replac
flags |= TransactionFlags.batch_payout;
}
if (isNonStandard(tx)) {
if (isNonStandard(tx, height, network)) {
flags |= TransactionFlags.nonstandard;
}
@@ -458,4 +508,83 @@ export function getUnacceleratedFeeRate(tx: Transaction, accelerated: boolean):
} else {
return tx.effectiveFeePerVsize;
}
}
export function identifyPrioritizedTransactions(transactions: TransactionStripped[]): { prioritized: string[], deprioritized: string[] } {
// find the longest increasing subsequence of transactions
// (adapted from https://en.wikipedia.org/wiki/Longest_increasing_subsequence#Efficient_algorithms)
// should be O(n log n)
const X = transactions.slice(1).reverse(); // standard block order is by *decreasing* effective fee rate, but we want to iterate in increasing order (and skip the coinbase)
if (X.length < 2) {
return { prioritized: [], deprioritized: [] };
}
const N = X.length;
const P: number[] = new Array(N);
const M: number[] = new Array(N + 1);
M[0] = -1; // undefined so can be set to any value
let L = 0;
for (let i = 0; i < N; i++) {
// Binary search for the smallest positive l ≤ L
// such that X[M[l]].effectiveFeePerVsize > X[i].effectiveFeePerVsize
let lo = 1;
let hi = L + 1;
while (lo < hi) {
const mid = lo + Math.floor((hi - lo) / 2); // lo <= mid < hi
if (X[M[mid]].rate > X[i].rate) {
hi = mid;
} else { // if X[M[mid]].effectiveFeePerVsize < X[i].effectiveFeePerVsize
lo = mid + 1;
}
}
// After searching, lo == hi is 1 greater than the
// length of the longest prefix of X[i]
const newL = lo;
// The predecessor of X[i] is the last index of
// the subsequence of length newL-1
P[i] = M[newL - 1];
M[newL] = i;
if (newL > L) {
// If we found a subsequence longer than any we've
// found yet, update L
L = newL;
}
}
// Reconstruct the longest increasing subsequence
// It consists of the values of X at the L indices:
// ..., P[P[M[L]]], P[M[L]], M[L]
const LIS: TransactionStripped[] = new Array(L);
let k = M[L];
for (let j = L - 1; j >= 0; j--) {
LIS[j] = X[k];
k = P[k];
}
const lisMap = new Map<string, number>();
LIS.forEach((tx, index) => lisMap.set(tx.txid, index));
const prioritized: string[] = [];
const deprioritized: string[] = [];
let lastRate = 0;
for (const tx of X) {
if (lisMap.has(tx.txid)) {
lastRate = tx.rate;
} else {
if (Math.abs(tx.rate - lastRate) < 0.1) {
// skip if the rate is almost the same as the previous transaction
} else if (tx.rate <= lastRate) {
prioritized.push(tx.txid);
} else {
deprioritized.push(tx.txid);
}
}
}
return { prioritized, deprioritized };
}
+4 -4
View File
@@ -671,7 +671,7 @@
</trans-unit>
<trans-unit id="d2eb45d1cd8cd146b7cb0223ab97a4b03b614060" datatype="html">
<source>sat/vB</source>
<target>ساتوشي/بايت</target>
<target>sat/vB</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">113</context>
@@ -1082,7 +1082,7 @@
</trans-unit>
<trans-unit id="83b8b9dd1ed416447cf8438460a37b0ddeb2677c" datatype="html">
<source>sat</source>
<target>ساتوشي</target>
<target>sat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-fee-graph.component.html</context>
<context context-type="linenumber">15</context>
@@ -6438,7 +6438,7 @@
</trans-unit>
<trans-unit id="31443c29cb161e8aa661eb5035f675746ef95b45" datatype="html">
<source>sats/tx</source>
<target>ساتوشي/عملية</target>
<target>sats/عملية</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
<context context-type="linenumber">33</context>
@@ -7867,7 +7867,7 @@
</trans-unit>
<trans-unit id="60601e02e7c1f6c4dbabd0ef0bb8946003db8dec" datatype="html">
<source>Only ~<x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB was needed to get into this block</source>
<target>كان مطلوب حوالي <x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> ساتوشي/بايت فقط لاضافة هذه المعاملة الى هذه الكتلة</target>
<target>كان مطلوب حوالي <x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB فقط لاضافة هذه المعاملة الى هذه الكتلة</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context>
<context context-type="linenumber">2</context>
+33 -30
View File
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Kaistan ulkopuoliset maksut</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1401,7 +1402,7 @@
</trans-unit>
<trans-unit id="3e322ffba6477484e0dd2e65650fdd70322ea6d0" datatype="html">
<source>Fee rate</source>
<target>Siirtomaksu taso</target>
<target>Siirtomaksutaso</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">36</context>
@@ -1488,7 +1489,7 @@
</trans-unit>
<trans-unit id="7920806087360513675" datatype="html">
<source>No accelerated transaction for this timeframe</source>
<target>Ei nopeutettua transaktiota tällä aikataululla</target>
<target>Ei nopeutettua siirtotapahtumaa tällä aikataululla</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.ts</context>
<context context-type="linenumber">133</context>
@@ -1727,7 +1728,7 @@
</trans-unit>
<trans-unit id="57cde27765d527a0d9195212fa5a7ce06408c827" datatype="html">
<source>Bid Boost</source>
<target>Tarjoustehostin</target>
<target>Bid Boost</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">17</context>
@@ -1792,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>Valmis</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1800,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>Epäonnistui</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
@@ -2299,7 +2302,7 @@
</trans-unit>
<trans-unit id="b2e947b5b892e2d2c5d216b1a198b8bf40da45eb" datatype="html">
<source><x id="INTERPOLATION" equiv-text="of {{ mempoolStats.tx_count + chainStats.tx_count | numb"/> of <x id="INTERPOLATION_1" equiv-text="{{ mempoolStats.tx_count + chainStats.tx_count | number }}"/> transactions</source>
<target><x id="INTERPOLATION" equiv-text="of {{ mempoolStats.tx_count + chainStats.tx_count | numb"/> / <x id="INTERPOLATION_1" equiv-text="{{ mempoolStats.tx_count + chainStats.tx_count | number }}"/> transaktiot</target>
<target><x id="INTERPOLATION" equiv-text="of {{ mempoolStats.tx_count + chainStats.tx_count | numb"/> / <x id="INTERPOLATION_1" equiv-text="{{ mempoolStats.tx_count + chainStats.tx_count | number }}"/> transaktiota</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address.component.html</context>
<context context-type="linenumber">102</context>
@@ -2537,7 +2540,7 @@
</trans-unit>
<trans-unit id="meta.description.liquid.asset" datatype="html">
<source>Browse an overview of the Liquid asset <x id="INTERPOLATION" equiv-text="this.assetContract[1]"/> (<x id="INTERPOLATION" equiv-text="this.assetContract[1]"/>): see issued amount, burned amount, circulating amount, related transactions, and more.</source>
<target>Selaa yleiskatsausta Liquid -varoihin <x id="INTERPOLATION" equiv-text="this.assetContract[1]"/> (<x id="INTERPOLATION" equiv-text="this.assetContract[1]"/>): näet liikkeeseen lasketun määrän, poltetun määrän, kiertävän määrän, asiaan liittyvät tapahtumat ja paljon muuta.</target>
<target>Selaa yleiskatsausta Liquid -varoihin <x id="INTERPOLATION" equiv-text="this.assetContract[1]"/> (<x id="INTERPOLATION" equiv-text="this.assetContract[1]"/>): näet liikkeeseen lasketun määrän, poltetun määrän, kiertävän määrän, asiaan liittyvät siirtotapahtumat ja paljon muuta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/asset/asset.component.ts</context>
<context context-type="linenumber">108</context>
@@ -3146,7 +3149,7 @@
</trans-unit>
<trans-unit id="eb1737af67381ce6f0b347038bb4c65b3deb84be" datatype="html">
<source>Effective fee rate</source>
<target>Todellinen siirtomaksu taso</target>
<target>Todellinen siirtomaksutaso</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-overview-tooltip/block-overview-tooltip.component.html</context>
<context context-type="linenumber">52</context>
@@ -3205,7 +3208,7 @@
</trans-unit>
<trans-unit id="f0136f1a1d77aa656e0ebd0f3c023118dd2a2776" datatype="html">
<source>Marginal fee rate</source>
<target>Marginaali siirtomaksu taso</target>
<target>Marginaali siirtomaksutaso</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-overview-tooltip/block-overview-tooltip.component.html</context>
<context context-type="linenumber">72</context>
@@ -3453,7 +3456,7 @@
</trans-unit>
<trans-unit id="meta.description.liquid.block" datatype="html">
<source>See size, weight, fee range, included transactions, and more for Liquid<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> block <x id="BLOCK_HEIGHT" equiv-text="block.height"/> (<x id="BLOCK_ID" equiv-text="block.id"/>).</source>
<target>Katso koko, paino, maksualue, mukana olevat transaktiot ja paljon muuta Liquid<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> lohkon osalta <x id="BLOCK_HEIGHT" equiv-text="block.height"/>(<x id="BLOCK_ID" equiv-text="block.id"/>).</target>
<target>Katso koko, paino, maksualue, mukana olevat siirtotapahtumat ja paljon muuta Liquid<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> lohkon osalta <x id="BLOCK_HEIGHT" equiv-text="block.height"/>(<x id="BLOCK_ID" equiv-text="block.id"/>).</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-view/block-view.component.ts</context>
<context context-type="linenumber">112</context>
@@ -3469,7 +3472,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.block" datatype="html">
<source>See size, weight, fee range, included transactions, audit (expected v actual), and more for Bitcoin<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> block <x id="BLOCK_HEIGHT" equiv-text="block.height"/> (<x id="BLOCK_ID" equiv-text="block.id"/>).</source>
<target>Katso koko, paino, maksuväli, mukana olevat tapahtumat, tilintarkastus (odotettu vs. todellinen) ja paljon muuta Bitcoinin<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> lohkon osalta <x id="BLOCK_HEIGHT" equiv-text="block.height"/>(<x id="BLOCK_ID" equiv-text="block.id"/>).</target>
<target>Katso koko, paino, maksuväli, mukana olevat siirtotapahtumat, tilintarkastus (odotettu vs. todellinen) ja paljon muuta Bitcoinin<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> lohkon osalta <x id="BLOCK_HEIGHT" equiv-text="block.height"/>(<x id="BLOCK_ID" equiv-text="block.id"/>).</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-view/block-view.component.ts</context>
<context context-type="linenumber">114</context>
@@ -3598,7 +3601,7 @@
</trans-unit>
<trans-unit id="27387c2af5dcaf343a548feba821515f5dc00faa" datatype="html">
<source><x id="INTERPOLATION" equiv-text="transaction&lt;/ng-template&gt; &lt;ng-template #transactionsPlural let-i i18n=&quot;shared.transacti"/> transaction</source>
<target><x id="INTERPOLATION" equiv-text="transaction&lt;/ng-template&gt; &lt;ng-template #transactionsPlural let-i i18n=&quot;shared.transacti"/> transaktio</target>
<target><x id="INTERPOLATION" equiv-text="transaction&lt;/ng-template&gt; &lt;ng-template #transactionsPlural let-i i18n=&quot;shared.transacti"/> siirto</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block-transactions.component.html</context>
<context context-type="linenumber">4</context>
@@ -3619,7 +3622,7 @@
</trans-unit>
<trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html">
<source><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transactions</source>
<target><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transaktiot</target>
<target><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> siirtoa</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block-transactions.component.html</context>
<context context-type="linenumber">5</context>
@@ -4299,7 +4302,7 @@
</trans-unit>
<trans-unit id="9dfdbeb922d811d7b7b3fecd48360a059e52aaba" datatype="html">
<source>Incoming Transactions</source>
<target>Saapuvat tapahtumat</target>
<target>Saapuvat siirtotapahtumat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">55</context>
@@ -4455,7 +4458,7 @@
</trans-unit>
<trans-unit id="aa6ce7e6e6fe5cd080713965451f25bca15a2a25" datatype="html">
<source>Recent Transactions</source>
<target>Viimeaikaiset tapahtumat</target>
<target>Viimeaikaiset siirtotapahtumat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">190</context>
@@ -4527,7 +4530,7 @@
</trans-unit>
<trans-unit id="146442697456175258" datatype="html">
<source>Data</source>
<target>Data</target>
<target>Tiedot</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.ts</context>
<context context-type="linenumber">74</context>
@@ -4807,7 +4810,7 @@
</trans-unit>
<trans-unit id="8c134e132798ec5053a96a5a077056ace15b08d6" datatype="html">
<source>New subsidy</source>
<target>Uusi tuki</target>
<target>Uusi palkkio</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">103</context>
@@ -5690,7 +5693,7 @@
</trans-unit>
<trans-unit id="142e923d3b04186ac6ba23387265d22a2fa404e0" datatype="html">
<source>Lightning Explorer</source>
<target>Salamaverkko selain</target>
<target>Salamaverkkoselain</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/master-page/master-page.component.html</context>
<context context-type="linenumber">95</context>
@@ -5716,7 +5719,7 @@
</trans-unit>
<trans-unit id="meta.description.mempool-block" datatype="html">
<source>See stats for <x id="PH" equiv-text="this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'"/><x id="PH_1" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> transactions in the mempool: fee range, aggregate size, and more. Mempool blocks are updated in real-time as the network receives new transactions.</source>
<target>Katso tilastoja <x id="PH" equiv-text="this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'"/><x id="PH_1" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> tapahtumista mempoolissa: kulualue, kokonaiskoko ja muuta. Mempool-lohkot päivittyvät reaaliajassa, kun verkko vastaanottaa uusia tapahtumia.</target>
<target>Katso tilastoja <x id="PH" equiv-text="this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'"/><x id="PH_1" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> tapahtumista mempoolissa: kulualue, kokonaiskoko ja muuta. Mempool-lohkot päivittyvät reaaliajassa, kun verkko vastaanottaa uusia siirtotapahtumia.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
<context context-type="linenumber">62</context>
@@ -6649,7 +6652,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.mempool" datatype="html">
<source>See mempool size (in MvB) and transactions per second (in vB/s) visualized over time.</source>
<target>Näe mempoolin koko (MvB:ssä) ja transaktiot sekunnissa (vB/s) visualisoituna ajan kuluessa.</target>
<target>Näe mempoolin koko (MvB) ja siirtotapahtumat per sekuntti (vB/s) visualisoituna ajan kuluessa.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/statistics/statistics.component.ts</context>
<context context-type="linenumber">66</context>
@@ -6665,7 +6668,7 @@
</trans-unit>
<trans-unit id="f74d6f23e06c5a75d95a994017c00191c162ba9f" datatype="html">
<source>Test Transactions</source>
<target>Testitapahtumat</target>
<target>Testisiirrot</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">2</context>
@@ -6692,7 +6695,7 @@
</trans-unit>
<trans-unit id="48e4b0c012de5020053ecb26e9ac0d35a1f60688" datatype="html">
<source>Comma-separated list of raw transactions</source>
<target>Pilkuilla eroteltu luettelo raakatapahtumista</target>
<target>Pilkuilla eroteltu luettelo raakasiirroista</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">7</context>
@@ -8001,7 +8004,7 @@
</trans-unit>
<trans-unit id="a706b1ded7506620b153dbcdea8108e6691bbbd9" datatype="html">
<source>Default push: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/><x id="INTERPOLATION" equiv-text="'track-ad"/> action: 'want', data: ['blocks', ...] <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/><x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> to express what you want pushed. Available: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>blocks<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>mempool-blocks<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>live-2h-chart<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, and <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>stats<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>.<x id="LINE_BREAK" ctype="lb" equiv-text="Push transa"/><x id="LINE_BREAK" ctype="lb" equiv-text="Push transa"/>Push transactions related to address: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/><x id="INTERPOLATION" equiv-text="'track-ad"/> 'track-address': '3PbJ...bF9B' <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/><x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> to receive all new transactions containing that address as input or output. Returns an array of transactions. <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>address-transactions<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> for new mempool transactions, and <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>block-transactions<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> for new block confirmed transactions.</source>
<target>Oletus työntö: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/><x id="INTERPOLATION" equiv-text="'track-ad"/>action: 'want', data: ['blocks', ...] <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/><x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>ilmaisemaan, mitä haluat työnnettävän. Käytettävissä: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>blocks<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>mempool-blocks<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>live-2h-chart<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> ja <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>stats<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>.<x id="LINE_BREAK" ctype="lb" equiv-text="Push transa"/><x id="LINE_BREAK" ctype="lb" equiv-text="Push transa"/>Työnnä osoitteeseen liittyvät tapahtumat: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/><x id="INTERPOLATION" equiv-text="'track-ad"/> 'track-address': '3PbJ...bF9B' <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/><x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> vastaanottaa kaikki uudet transaktiot, jotka sisältävät kyseisen osoitteen syötteenä tai tulosteena. Palauttaa transaktioiden joukon. <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>address-transactions<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> uusille mempool-transaktioille ja <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>block-transactions<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> uusille lohkon vahvistetuille transaktioille.</target>
<target>Oletus työntö: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/><x id="INTERPOLATION" equiv-text="'track-ad"/>action: 'want', data: ['blocks', ...] <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/><x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>ilmaisemaan, mitä haluat työnnettävän. Käytettävissä: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>blocks<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>mempool-blocks<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>, <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>live-2h-chart<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> ja <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>stats<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/>.<x id="LINE_BREAK" ctype="lb" equiv-text="Push transa"/><x id="LINE_BREAK" ctype="lb" equiv-text="Push transa"/>Työnnä osoitteeseen liittyvät transaktiot: <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/><x id="INTERPOLATION" equiv-text="'track-ad"/> 'track-address': '3PbJ...bF9B' <x id="INTERPOLATION_1" equiv-text="{{ '}' }}"/><x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> vastaanottaa kaikki uudet transaktiot, jotka sisältävät kyseisen osoitteen syötteenä tai tulosteena. Palauttaa transaktioiden joukon. <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>address-transactions<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> uusille mempool-transaktioille ja <x id="START_TAG_CODE" ctype="x-code" equiv-text="&lt;code&gt;"/>block-transactions<x id="CLOSE_TAG_CODE" ctype="x-code" equiv-text="&lt;/code&gt;"/> uusille lohkon vahvistetuille transaktioille.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
<context context-type="linenumber">120</context>
@@ -8057,7 +8060,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.faq" datatype="html">
<source>Get answers to common questions like: What is a mempool? Why isn't my transaction confirming? How can I run my own instance of The Mempool Open Source Project? And more.</source>
<target>Hanki vastauksia yleisiin kysymyksiin, kuten: Mikä on mempool? Miksi tapahtumani ei vahvistu? Miten voin ajaa omaa The Mempool Open Source Project -instanssia? Ja paljon muuta.</target>
<target>Hanki vastauksia yleisiin kysymyksiin, kuten: Mikä on mempool? Miksi siirtoni ei vahvistu? Miten voin ajaa omaa The Mempool Open Source Project -instanssia? Ja paljon muuta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">47</context>
@@ -8073,7 +8076,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.rest-liquid" datatype="html">
<source>Documentation for the liquid.network REST API service: get info on addresses, transactions, assets, blocks, and more.</source>
<target>Dokumentaatio liquid.network REST API-palvelulle: hae tietoja osoitteista, tapahtumista, omaisuuseristä, lohkoista ja muusta.</target>
<target>Dokumentaatio liquid.network REST API-palvelulle: hae tietoja osoitteista, siirtotapahtumista, omaisuuseristä, lohkoista ja muusta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">53</context>
@@ -8081,7 +8084,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.rest-bitcoin" datatype="html">
<source>Documentation for the mempool.space REST API service: get info on addresses, transactions, blocks, fees, mining, the Lightning network, and more.</source>
<target>Dokumentaatio mempool.space REST API-palvelulle: hae tietoja osoitteista, tapahtumista, lohkoista, maksuista, louhinnasta, Salamaverkosta ja paljon muuta.</target>
<target>Dokumentaatio mempool.space REST API-palvelulle: hae tietoja osoitteista, siirtotapahtumista, lohkoista, maksuista, louhinnasta, Salamaverkosta ja paljon muuta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">55</context>
@@ -8097,7 +8100,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.websocket-liquid" datatype="html">
<source>Documentation for the liquid.network WebSocket API service: get real-time info on blocks, mempools, transactions, addresses, and more.</source>
<target>Dokumentaatio liquid.networkin WebSocket API-palvelulle: hanki reaaliaikaista tietoa lohkoista, mempoolista, tapahtumista, osoitteista ja paljon muuta.</target>
<target>Dokumentaatio liquid.networkin WebSocket API-palvelulle: hanki reaaliaikaista tietoa lohkoista, mempoolista, siirtotapahtumista, osoitteista ja paljon muuta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">61</context>
@@ -8105,7 +8108,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.websocket-bitcoin" datatype="html">
<source>Documentation for the mempool.space WebSocket API service: get real-time info on blocks, mempools, transactions, addresses, and more.</source>
<target>Dokumentaatio mempool.space WebSocket API-palvelulle: hanki reaaliaikaista tietoa lohkoista, mempooleista, tapahtumista, osoitteista ja muusta.</target>
<target>Dokumentaatio mempool.space WebSocket API-palvelulle: hanki reaaliaikaista tietoa lohkoista, mempooleista, siirtotapahtumista, osoitteista ja muusta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">63</context>
@@ -8438,7 +8441,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.channel" datatype="html">
<source>Overview for Lightning channel <x id="PH" equiv-text="params.get('short_id')"/>. See channel capacity, the Lightning nodes involved, related on-chain transactions, and more.</source>
<target>Yleiskatsaus Salamakanavalle <x id="PH" equiv-text="params.get('short_id')"/>. Katso kanavan kapasiteetti, mukana olevat Salamasolmut, liittyvät lohkoketjutapahtumat ja muuta.</target>
<target>Yleiskatsaus Salamakanavalle <x id="PH" equiv-text="params.get('short_id')"/>. Katso kanavan kapasiteetti, mukana olevat salamasolmut, pääketjuun liittyvät siirtotapahtumat ja paljon muuta.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channel/channel-preview.component.ts</context>
<context context-type="linenumber">37</context>
@@ -8728,7 +8731,7 @@
</trans-unit>
<trans-unit id="2c1c39e28735f607d62dbf3272eb792451c265a5" datatype="html">
<source>Med Fee Rate</source>
<target>Keskisuuri siirtomaksu taso</target>
<target>Keskisuuri siirtomaksutaso</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-statistics/channels-statistics.component.html</context>
<context context-type="linenumber">72</context>
@@ -9256,7 +9259,7 @@
</trans-unit>
<trans-unit id="bc84b5a9a70217104a53c7139e30b392be6520b7" datatype="html">
<source>Lease fee rate</source>
<target>Vuokra siirtomaksun taso</target>
<target>Vuokra siirtomaksutaso</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/node/node.component.html</context>
<context context-type="linenumber">190</context>
@@ -9984,7 +9987,7 @@
</trans-unit>
<trans-unit id="8fe988a9cb02c11f99631ca85721d34d67fc32ff" datatype="html">
<source>Why isn't my transaction confirming?</source>
<target>Miksi tapahtumaani ei vahvisteta?</target>
<target>Miksi siirtoani ei vahvisteta?</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">73</context>
File diff suppressed because it is too large. Load diff
+3
View File
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>ネットワーク外手数料</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1792,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>終了</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1800,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>失敗</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
+53
View File
@@ -417,6 +417,7 @@
</trans-unit>
<trans-unit id="1b47ebb11a7dbffd196a704d2325c5c73aea81e6" datatype="html">
<source>Sorry, something went wrong!</source>
<target>죄송합니다, 문제가 생겼습니다!</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">5</context>
@@ -425,6 +426,7 @@
</trans-unit>
<trans-unit id="49b619d43af81067bfcbf7ba4036876a620e9bd8" datatype="html">
<source>We were not able to accelerate this transaction. Please try again later.</source>
<target>이 트랜잭션을 가속할 수 없었습니다. 나중에 다시 시도해 주세요.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">11</context>
@@ -433,6 +435,7 @@
</trans-unit>
<trans-unit id="f4e529ae5ffd73001d1ff4bbdeeb0a72e342e5c8" datatype="html">
<source>Close</source>
<target>닫기</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">18</context>
@@ -445,6 +448,7 @@
</trans-unit>
<trans-unit id="f24773075af97666c0feca0e883c2585712fe597" datatype="html">
<source>Your transaction</source>
<target>내 트랜잭션</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">37</context>
@@ -453,6 +457,7 @@
</trans-unit>
<trans-unit id="bee6b649ee82d9a7cde233070b665eec7c531b1d" datatype="html">
<source>Plus <x id="INTERPOLATION" equiv-text="{{ estimate.txSummary.ancestorCount - 1 }}"/> unconfirmed ancestor(s)</source>
<target>컨펌되지 않은 조상(들) <x id="INTERPOLATION" equiv-text="{{ estimate.txSummary.ancestorCount - 1 }}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">41</context>
@@ -487,6 +492,7 @@
</trans-unit>
<trans-unit id="df89e157bacb4ab32e6ec725bf1eb176dc15201e" datatype="html">
<source>Size in vbytes of this transaction (including unconfirmed ancestors)</source>
<target>트랜잭션 크기 (확인되지 않은 조상 포함)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">51</context>
@@ -495,6 +501,7 @@
</trans-unit>
<trans-unit id="adbeb446bf941afda4d4a923b5e4ce0cf4a1c1b8" datatype="html">
<source>In-band fees</source>
<target>대역 내 수수료</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">55</context>
@@ -620,6 +627,7 @@
</trans-unit>
<trans-unit id="fad137784196a8fdc10588e27ed5d8ae95fe4e79" datatype="html">
<source>Fees already paid by this transaction (including unconfirmed ancestors)</source>
<target>이 트랜잭션이 이미 지불한 수수료 (확인되지 않은 조상 포함)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">62</context>
@@ -628,6 +636,7 @@
</trans-unit>
<trans-unit id="4169a885bc1747a38344bae64e6926c6d7d7ec43" datatype="html">
<source>How much faster?</source>
<target>얼마나 더 빠르게 원하시나요?</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">71</context>
@@ -636,6 +645,7 @@
</trans-unit>
<trans-unit id="d1a62bdb732f1efbfdc8af6fbb4349b89015b5e5" datatype="html">
<source>This will reduce your expected waiting time until the first confirmation to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="START_TAG_APP_TIME" ctype="x-app_time" equiv-text="n&quot; [time]=&quot;etaInfo.acceleratedETA&quot; [fastRender]=&quot;false&quot; [fixedRender]=&quot;true&quot;&gt;"/><x id="CLOSE_TAG_APP_TIME" ctype="x-app_time" equiv-text="&lt;/strong&gt;&lt;/s"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/small&gt;"/></source>
<target>첫 번째 컨펌까지 예상 대기 시간이 <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="START_TAG_APP_TIME" ctype="x-app_time" equiv-text="n&quot; [time]=&quot;etaInfo.acceleratedETA&quot; [fastRender]=&quot;false&quot; [fixedRender]=&quot;true&quot;&gt;"/><x id="CLOSE_TAG_APP_TIME" ctype="x-app_time" equiv-text="&lt;/strong&gt;&lt;/s"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/small&gt;"/>로 단축됩니다</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">76,77</context>
@@ -644,6 +654,7 @@
</trans-unit>
<trans-unit id="a8233de047500bf0f0d9f9f1712ddb071501a283" datatype="html">
<source>Summary</source>
<target>요약</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">100</context>
@@ -652,6 +663,7 @@
</trans-unit>
<trans-unit id="0b537472d5f7518ed2c2c2b747997b0447ec5ee8" datatype="html">
<source>Next block market rate</source>
<target>다음 블록 시장 수수료율</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">109</context>
@@ -682,6 +694,7 @@
</trans-unit>
<trans-unit id="c2836a2964adf9e369ee0a1ce67f991cf2aa435d" datatype="html">
<source>Estimated extra fee required</source>
<target>예측된 추가발생 수수료</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">117</context>
@@ -690,6 +703,7 @@
</trans-unit>
<trans-unit id="6c37b6a6f9e5ec98367ed744afa4b36800aa79ce" datatype="html">
<source>Target rate</source>
<target>목표율</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">131</context>
@@ -698,6 +712,7 @@
</trans-unit>
<trans-unit id="e26d365629446e476b5d437e343b5b02b49adea2" datatype="html">
<source>Extra fee required</source>
<target>필요한 추가 수수료</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">139</context>
@@ -706,6 +721,7 @@
</trans-unit>
<trans-unit id="26e50fa97db4eecde26ff892d725e61ca9201c48" datatype="html">
<source>Mempool Accelerator™ fees</source>
<target>멤풀 엑셀러레이터 수수료</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">153</context>
@@ -714,6 +730,7 @@
</trans-unit>
<trans-unit id="1ec82428244c76064090ea5a55827e3fada82306" datatype="html">
<source>Accelerator Service Fee</source>
<target>엑셀러레이터 서비스 수수료</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">157</context>
@@ -722,6 +739,7 @@
</trans-unit>
<trans-unit id="7d07b80b17dfab3582807759420b8d723c9e4414" datatype="html">
<source>Transaction Size Surcharge</source>
<target>트랜잭션 사이즈에 의한 추가 요금</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">169</context>
@@ -730,6 +748,7 @@
</trans-unit>
<trans-unit id="004732b44df582a2d24e2abbd3f46bc42ae8c546" datatype="html">
<source>Estimated acceleration cost</source>
<target>예상 가속 비용</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">185</context>
@@ -738,6 +757,7 @@
</trans-unit>
<trans-unit id="c9ec95585f57bd87212693db7cb00d9ed70d49b1" datatype="html">
<source>Maximum acceleration cost</source>
<target>최대 가속 비용</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">204</context>
@@ -746,6 +766,7 @@
</trans-unit>
<trans-unit id="990d4cedae650a7a1b53887cfde7ed363e362bb2" datatype="html">
<source>Acceleration cost</source>
<target>가속 비용</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">206</context>
@@ -754,6 +775,7 @@
</trans-unit>
<trans-unit id="f3ff11006f77909b9fca2e0fda0a72b097cd76de" datatype="html">
<source>Available balance</source>
<target>잔액</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">226</context>
@@ -762,6 +784,7 @@
</trans-unit>
<trans-unit id="a67aec1c4d47cdf3a4442a19e616def78fd77388" datatype="html">
<source>Go back</source>
<target>뒤로가기</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">258</context>
@@ -778,6 +801,7 @@
</trans-unit>
<trans-unit id="7d89e94e98140d07d5c2bb12d6166b8b74506eb0" datatype="html">
<source>Accelerate your Bitcoin transaction?</source>
<target>비트코인 트랜잭션 가속하기</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">273</context>
@@ -786,6 +810,7 @@
</trans-unit>
<trans-unit id="eb70970e7741aca891aa54ff4651b050a60b1690" datatype="html">
<source>Wait</source>
<target>기다려 주세요</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">285</context>
@@ -794,6 +819,7 @@
</trans-unit>
<trans-unit id="f6a46cd5ca2087712a145f2c680e2aad5f926eaf" datatype="html">
<source>Confirmation expected</source>
<target>컨펌이 예상됩니다</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">287</context>
@@ -850,6 +876,7 @@
</trans-unit>
<trans-unit id="65fd4251d8ddfe4017d4d83f8cec6f5a80d89289" datatype="html">
<source>Pay</source>
<target>결제하기</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">378</context>
@@ -871,6 +898,7 @@
</trans-unit>
<trans-unit id="3da51e8df074e97a3479c4b2a6d1655529267544" datatype="html">
<source>Failed to load invoice</source>
<target>인보이스 불러오기 실패</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">381</context>
@@ -879,6 +907,7 @@
</trans-unit>
<trans-unit id="13eacf4307fbadcc4ba552641200cdc36997a62c" datatype="html">
<source>Loading invoice...</source>
<target>인보이스 불러오는 중...</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">386</context>
@@ -887,6 +916,7 @@
</trans-unit>
<trans-unit id="63f5d0ec23e3cf4abf6d5221107633c90d8d4a15" datatype="html">
<source>OR</source>
<target>또는</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">394</context>
@@ -895,6 +925,7 @@
</trans-unit>
<trans-unit id="d5380b83d01211f764e7dc17f115cbe2c306793f" datatype="html">
<source>Confirm your payment</source>
<target>결제 내용을 확인해 주세요</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">442</context>
@@ -903,6 +934,7 @@
</trans-unit>
<trans-unit id="23e85f2bac1f2bf2a36125a7cc9232e47d773bca" datatype="html">
<source>Total additional cost</source>
<target>총 추가 비용</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">458</context>
@@ -911,6 +943,7 @@
</trans-unit>
<trans-unit id="ada15d0099ccf0a54d598a658d7a5d9f95af8fc6" datatype="html">
<source>with</source>
<target>결제 방식</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">462</context>
@@ -919,6 +952,7 @@
</trans-unit>
<trans-unit id="c427d1fcbff172397bf8f6fb154e3144f099afdc" datatype="html">
<source>Loading payment method...</source>
<target>결제 방식 불러오는 중...</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">482</context>
@@ -927,6 +961,7 @@
</trans-unit>
<trans-unit id="72ca62832f62c0aeb0c0675d2ac6aa7043ee840d" datatype="html">
<source>Confirming your payment</source>
<target>결제 확인 중</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">500</context>
@@ -935,6 +970,7 @@
</trans-unit>
<trans-unit id="8c8cbda9c5ddde6a4898a80aef46199c946c8895" datatype="html">
<source>We are processing your payment...</source>
<target>결제 진행중...</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">510</context>
@@ -943,6 +979,7 @@
</trans-unit>
<trans-unit id="ea3197c44781ecca4f2adbf7bff229574f192983" datatype="html">
<source>Accelerating your transaction</source>
<target>트랜잭션 가속 중</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">520</context>
@@ -951,6 +988,7 @@
</trans-unit>
<trans-unit id="2279bfb8531701cc176ff6b266c3fa0df3983bce" datatype="html">
<source>Confirming your acceleration with our mining pool partners...</source>
<target>협력 채굴풀들로부터 트랜잭션 가속 확인 중...</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">527</context>
@@ -959,6 +997,7 @@
</trans-unit>
<trans-unit id="d005740e3435cf7e0aad9a67d179ec3b3065205e" datatype="html">
<source>...sorry, this is taking longer than expected...</source>
<target>죄송합니다, 예상보다 오래 걸리고 있습니다...</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">529</context>
@@ -967,6 +1006,7 @@
</trans-unit>
<trans-unit id="afdff27fa38ec3386a7b9bb1b3ff113ed5d7e411" datatype="html">
<source>Your transaction is being accelerated!</source>
<target>트랜잭션이 가속되고 있습니다!</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">538</context>
@@ -983,6 +1023,7 @@
</trans-unit>
<trans-unit id="746506272a06b85cba0efc14907940df4bafdf96" datatype="html">
<source>Calculating cost...</source>
<target>비용 계산 중...</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">563</context>
@@ -991,6 +1032,7 @@
</trans-unit>
<trans-unit id="484e154f1b26e67760d10baa8dddb2c69ddb1990" datatype="html">
<source>customize</source>
<target>커스터마이징</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">569</context>
@@ -999,6 +1041,7 @@
</trans-unit>
<trans-unit id="fc60844faa5ea496fe8b8cfb7620b2bfc733c90b" datatype="html">
<source>Accelerate to ~<x id="INTERPOLATION" equiv-text="{{ x | number : '1.0-0' }}"/> sat/vB</source>
<target>~<x id="INTERPOLATION" equiv-text="{{ x | number : '1.0-0' }}"/>sat/vB로 가속하기</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">572</context>
@@ -1007,6 +1050,7 @@
</trans-unit>
<trans-unit id="913e89d2d1ae354079cccf48b3d3f4ebf2e74080" datatype="html">
<source>Accelerate</source>
<target>가속하기</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">578</context>
@@ -1106,6 +1150,7 @@
</trans-unit>
<trans-unit id="7159011509695804248" datatype="html">
<source>maximum</source>
<target>최대</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts</context>
<context context-type="linenumber">91</context>
@@ -1113,6 +1158,7 @@
</trans-unit>
<trans-unit id="1158292946432597388" datatype="html">
<source>accelerated</source>
<target>가속됨</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts</context>
<context context-type="linenumber">91</context>
@@ -1120,6 +1166,7 @@
</trans-unit>
<trans-unit id="aa28c3afcb8b1a556fc1e1842e48a57f24fd643f" datatype="html">
<source>Status</source>
<target>상태</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">11</context>
@@ -1215,6 +1262,7 @@
</trans-unit>
<trans-unit id="b484583f0ce10f3341ab36750d05271d9d22c9a1" datatype="html">
<source>Accelerated</source>
<target>가속됌</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">16</context>
@@ -1557,6 +1605,7 @@
</trans-unit>
<trans-unit id="cf2ec414465d65ab24b354663d94d051a67e26e9" datatype="html">
<source>Total vSize</source>
<target>총 vSize</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context>
<context context-type="linenumber">20</context>
@@ -6813,6 +6862,7 @@
</trans-unit>
<trans-unit id="cef1d79eace5eb4d2243fad36730e3e65c757bee" datatype="html">
<source>Sent</source>
<target>보내짐</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker-bar.component.html</context>
<context context-type="linenumber">2</context>
@@ -6870,6 +6920,7 @@
</trans-unit>
<trans-unit id="a42474c92670ab75cb387cf44c03b0a4ce0a641a" datatype="html">
<source>Confirmed at</source>
<target>컨펌 블록</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">87</context>
@@ -6878,6 +6929,7 @@
</trans-unit>
<trans-unit id="55b16cd277b9b5de63abe14b475737c753a37b97" datatype="html">
<source>Block height</source>
<target>블록 높이</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">96</context>
@@ -6886,6 +6938,7 @@
</trans-unit>
<trans-unit id="03e7c662ce1c813603ff17d0906e15d256a35a70" datatype="html">
<source>Your transaction has been accelerated</source>
<target>트랜잭션이 가속되었습니다</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">143</context>
+12 -9
View File
@@ -510,7 +510,7 @@
</trans-unit>
<trans-unit id="e4b2d9e6a2ab9e6ca34027ec03beaac42b7badd4" datatype="html">
<source>sats</source>
<target>sats</target>
<target>sat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">57</context>
@@ -881,7 +881,7 @@
</trans-unit>
<trans-unit id="65fd4251d8ddfe4017d4d83f8cec6f5a80d89289" datatype="html">
<source>Pay</source>
<target>Betale</target>
<target>Betal</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">378</context>
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Out-of-band avgifter</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1401,7 +1402,7 @@
</trans-unit>
<trans-unit id="3e322ffba6477484e0dd2e65650fdd70322ea6d0" datatype="html">
<source>Fee rate</source>
<target>Avgift</target>
<target>Avgiftssats</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">36</context>
@@ -1439,7 +1440,7 @@
</trans-unit>
<trans-unit id="8b01e0411c7160bfee109e504c84ecee5079c326" datatype="html">
<source>Accelerated fee rate</source>
<target>Akselerert gebyrsats</target>
<target>Akselerert avgiftssats</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">39</context>
@@ -1792,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>Fullført</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1800,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>Mislyktes</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
@@ -1949,7 +1952,7 @@
</trans-unit>
<trans-unit id="4231517605576357140" datatype="html">
<source>not accelerating</source>
<target>ikke akselererer</target>
<target>akselererer ikke</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/active-acceleration-box/active-acceleration-box.component.ts</context>
<context context-type="linenumber">86</context>
@@ -1957,7 +1960,7 @@
</trans-unit>
<trans-unit id="3590f5c3ef2810f637316edb8aaa86b8e907f152" datatype="html">
<source>pending</source>
<target>Avventer</target>
<target>avventer</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/pending-stats/pending-stats.component.html</context>
<context context-type="linenumber">7</context>
@@ -4843,7 +4846,7 @@
</trans-unit>
<trans-unit id="615ba6c4511a36f93c225c725935fdbf16f162a5" datatype="html">
<source>Amount (sats)</source>
<target>Beløp (sats)</target>
<target>Beløp (sat)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/faucet/faucet.component.html</context>
<context context-type="linenumber">51</context>
@@ -6439,7 +6442,7 @@
</trans-unit>
<trans-unit id="31443c29cb161e8aa661eb5035f675746ef95b45" datatype="html">
<source>sats/tx</source>
<target>sats/tx</target>
<target>sat/tx</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/reward-stats/reward-stats.component.html</context>
<context context-type="linenumber">33</context>
@@ -8142,7 +8145,7 @@
</trans-unit>
<trans-unit id="6acd06bd5a3af583cd46c6d9f7954d7a2b44095e" datatype="html">
<source>mSats</source>
<target>mSats</target>
<target>mSat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
<context context-type="linenumber">35</context>
+7 -4
View File
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Vergoeding buiten blockchain</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1792,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>Voltooid</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1800,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>Mislukt</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
@@ -2088,7 +2091,7 @@
</trans-unit>
<trans-unit id="729754dd19eb9ce0670b0aeb5a6ae60574c2c563" datatype="html">
<source>Address</source>
<target>adres</target>
<target>Adres</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address-preview.component.html</context>
<context context-type="linenumber">3</context>
@@ -3497,7 +3500,7 @@
</trans-unit>
<trans-unit id="07193288a0312875e18f38c3a2486b927a15520a" datatype="html">
<source>Timestamp</source>
<target>Tijdstempel</target>
<target>Tijd</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block-preview.component.html</context>
<context context-type="linenumber">26</context>
@@ -4511,7 +4514,7 @@
</trans-unit>
<trans-unit id="7816493330657272952" datatype="html">
<source>Coinjoin</source>
<target>Samenvoeging</target>
<target>Coinjoin</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.ts</context>
<context context-type="linenumber">73</context>
@@ -5820,7 +5823,7 @@
</trans-unit>
<trans-unit id="2711844b4304254e88358d1761f9c732e5aefc69" datatype="html">
<source>Pools luck (1 week)</source>
<target>Pools geluk (1 week)</target>
<target>Geluk van pool (1 week)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.html</context>
<context context-type="linenumber">9</context>
+9 -6
View File
@@ -1165,7 +1165,7 @@
</trans-unit>
<trans-unit id="1158292946432597388" datatype="html">
<source>accelerated</source>
<target>przyspieszona</target>
<target>przyspieszonych</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts</context>
<context context-type="linenumber">91</context>
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Opłaty poza mempoolem</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1439,7 +1440,7 @@
</trans-unit>
<trans-unit id="8b01e0411c7160bfee109e504c84ecee5079c326" datatype="html">
<source>Accelerated fee rate</source>
<target>Przyspieszony poziom opłat</target>
<target>Poziom opłaty przyspieszonej</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">39</context>
@@ -1457,7 +1458,7 @@
</trans-unit>
<trans-unit id="2c2a527d090d5d030fc130a243135dbc6ba276f0" datatype="html">
<source>Accelerated by</source>
<target>Przyspieszona o</target>
<target>Przyspieszona przez</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">48</context>
@@ -1516,7 +1517,7 @@
</trans-unit>
<trans-unit id="8918254921747459635" datatype="html">
<source>Around block: <x id="PH" equiv-text="ticks[0].data[2]"/></source>
<target>Wokół bloku: <x id="PH" equiv-text="ticks[0].data[2]"/></target>
<target>Około bloku: <x id="PH" equiv-text="ticks[0].data[2]"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-fees-graph/acceleration-fees-graph.component.ts</context>
<context context-type="linenumber">179</context>
@@ -1566,7 +1567,7 @@
</trans-unit>
<trans-unit id="bdb8bbb38e4ca3c73e19dc4167fbe4aec316f818" datatype="html">
<source>Total Bid Boost</source>
<target>Całkowite zwiększenie oferty</target>
<target>Całk. zwiększenie oferty</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context>
<context context-type="linenumber">11</context>
@@ -1792,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>Ukończone</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1800,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>Nieudane</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
@@ -1875,7 +1878,7 @@
</trans-unit>
<trans-unit id="9d202e68dd5064ae2e3d01073267b4db63b16c40" datatype="html">
<source>(all time)</source>
<target>(cały czas)</target>
<target>(cały okres)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">36</context>
+2 -1
View File
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Taxas por fora</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1957,7 +1958,7 @@
</trans-unit>
<trans-unit id="3590f5c3ef2810f637316edb8aaa86b8e907f152" datatype="html">
<source>pending</source>
<target>pendente</target>
<target>pendente(s)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/pending-stats/pending-stats.component.html</context>
<context context-type="linenumber">7</context>
+3
View File
@@ -1393,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Comisioane plătite extern</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1792,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>Efectuat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1800,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>Eșuat</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
+1 -1
View File
@@ -1558,7 +1558,7 @@
</trans-unit>
<trans-unit id="25fbf6e80a945703c906a5a7d8c92e8729c7ab21" datatype="html">
<source>accelerated</source>
<target>accelererad</target>
<target>accelererade</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context>
<context context-type="linenumber">7</context>
+95
View File
@@ -627,6 +627,7 @@
</trans-unit>
<trans-unit id="fad137784196a8fdc10588e27ed5d8ae95fe4e79" datatype="html">
<source>Fees already paid by this transaction (including unconfirmed ancestors)</source>
<target>ค่าธรรมเนียมถูกจ่ายโดยธุรกรรมนี้แล้ว (รวมถึงธุรกรรมก่อนหน้าธุรกรรมนี้ที่ยังไม่ได้รับการยืนยัน)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">62</context>
@@ -661,6 +662,7 @@
</trans-unit>
<trans-unit id="0b537472d5f7518ed2c2c2b747997b0447ec5ee8" datatype="html">
<source>Next block market rate</source>
<target>เรทของบล็อกถัดไป</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">109</context>
@@ -700,6 +702,7 @@
</trans-unit>
<trans-unit id="6c37b6a6f9e5ec98367ed744afa4b36800aa79ce" datatype="html">
<source>Target rate</source>
<target>เรทที่ต้องการ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">131</context>
@@ -708,6 +711,7 @@
</trans-unit>
<trans-unit id="e26d365629446e476b5d437e343b5b02b49adea2" datatype="html">
<source>Extra fee required</source>
<target>ต้องเสียค่าธรรมเนียมเพิ่มเติม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">139</context>
@@ -734,6 +738,7 @@
</trans-unit>
<trans-unit id="7d07b80b17dfab3582807759420b8d723c9e4414" datatype="html">
<source>Transaction Size Surcharge</source>
<target>ค่าธรรมเนียมเพิ่มขนาดธุรกรรม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">169</context>
@@ -760,6 +765,7 @@
</trans-unit>
<trans-unit id="990d4cedae650a7a1b53887cfde7ed363e362bb2" datatype="html">
<source>Acceleration cost</source>
<target>ค่าธรรมเนียมการเร่ง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">206</context>
@@ -803,6 +809,7 @@
</trans-unit>
<trans-unit id="eb70970e7741aca891aa54ff4651b050a60b1690" datatype="html">
<source>Wait</source>
<target>รอ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">285</context>
@@ -811,6 +818,7 @@
</trans-unit>
<trans-unit id="f6a46cd5ca2087712a145f2c680e2aad5f926eaf" datatype="html">
<source>Confirmation expected</source>
<target>จะได้รับการยืนยันภายใน</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">287</context>
@@ -823,6 +831,7 @@
</trans-unit>
<trans-unit id="4adc5f10d717fbcfc9834dcf5eb203c1156db4d7" datatype="html">
<source>Confirmation not expected any time soon</source>
<target>ไม่ได้รับการยืนยันในเร็วๆนี้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">290</context>
@@ -867,6 +876,7 @@
</trans-unit>
<trans-unit id="65fd4251d8ddfe4017d4d83f8cec6f5a80d89289" datatype="html">
<source>Pay</source>
<target>จ่าย</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">378</context>
@@ -888,6 +898,7 @@
</trans-unit>
<trans-unit id="3da51e8df074e97a3479c4b2a6d1655529267544" datatype="html">
<source>Failed to load invoice</source>
<target>ไม่สามารถโหลดใบแจ้งหนี้ได้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">381</context>
@@ -896,6 +907,7 @@
</trans-unit>
<trans-unit id="13eacf4307fbadcc4ba552641200cdc36997a62c" datatype="html">
<source>Loading invoice...</source>
<target>กำลังโหลดใบแจ้งหนี้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">386</context>
@@ -904,6 +916,7 @@
</trans-unit>
<trans-unit id="63f5d0ec23e3cf4abf6d5221107633c90d8d4a15" datatype="html">
<source>OR</source>
<target>หรือ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">394</context>
@@ -912,6 +925,7 @@
</trans-unit>
<trans-unit id="d5380b83d01211f764e7dc17f115cbe2c306793f" datatype="html">
<source>Confirm your payment</source>
<target>ยืนยันการชำระเงิน</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">442</context>
@@ -920,6 +934,7 @@
</trans-unit>
<trans-unit id="23e85f2bac1f2bf2a36125a7cc9232e47d773bca" datatype="html">
<source>Total additional cost</source>
<target>ค่าใช้จ่ายเพิ่มเติมทั้งหมด</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">458</context>
@@ -928,6 +943,7 @@
</trans-unit>
<trans-unit id="ada15d0099ccf0a54d598a658d7a5d9f95af8fc6" datatype="html">
<source>with</source>
<target>กับ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">462</context>
@@ -936,6 +952,7 @@
</trans-unit>
<trans-unit id="c427d1fcbff172397bf8f6fb154e3144f099afdc" datatype="html">
<source>Loading payment method...</source>
<target>กำลังโหลดวิธีการชำระเงิน</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">482</context>
@@ -944,6 +961,7 @@
</trans-unit>
<trans-unit id="72ca62832f62c0aeb0c0675d2ac6aa7043ee840d" datatype="html">
<source>Confirming your payment</source>
<target>กำลังยืนยันการชำระเงินของคุณ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">500</context>
@@ -952,6 +970,7 @@
</trans-unit>
<trans-unit id="8c8cbda9c5ddde6a4898a80aef46199c946c8895" datatype="html">
<source>We are processing your payment...</source>
<target>เรากำลังทำรายการชำระเงินของคุณ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">510</context>
@@ -1020,6 +1039,7 @@
</trans-unit>
<trans-unit id="fc60844faa5ea496fe8b8cfb7620b2bfc733c90b" datatype="html">
<source>Accelerate to ~<x id="INTERPOLATION" equiv-text="{{ x | number : '1.0-0' }}"/> sat/vB</source>
<target>เร่งเป็น ~<x id="INTERPOLATION" equiv-text="{{ x | number : '1.0-0' }}"/> sat/vB</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">572</context>
@@ -1136,6 +1156,7 @@
</trans-unit>
<trans-unit id="1158292946432597388" datatype="html">
<source>accelerated</source>
<target>ถูกเร่ง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-fee-graph.component.ts</context>
<context context-type="linenumber">91</context>
@@ -1504,6 +1525,7 @@
</trans-unit>
<trans-unit id="5238405b3e8e1b72d2732f0ecbd83be35b98cd5d" datatype="html">
<source>Requests</source>
<target>การขอ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context>
<context context-type="linenumber">4</context>
@@ -1603,6 +1625,7 @@
</trans-unit>
<trans-unit id="d932577b535f10c9b3e25aaa430220bb09efc171" datatype="html">
<source> of blocks</source>
<target>ของบล็อก</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/acceleration-stats/acceleration-stats.component.html</context>
<context context-type="linenumber">23</context>
@@ -1611,6 +1634,7 @@
</trans-unit>
<trans-unit id="02573b6980a2d611b4361a2595a4447e390058cd" datatype="html">
<source>Accelerations</source>
<target>การเร่ง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">2</context>
@@ -1752,6 +1776,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>สำเร็จ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1760,6 +1785,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>ล้มเหลว</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
@@ -1805,6 +1831,7 @@
</trans-unit>
<trans-unit id="9467c16588ee9f97dfa4f1dd9c96a02d6dc6e008" datatype="html">
<source>(1 day)</source>
<target>(1 วัน)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">27</context>
@@ -1813,6 +1840,7 @@
</trans-unit>
<trans-unit id="d1c71eabdf119de5aa1d75ea1a8f93a9215dd8ea" datatype="html">
<source>(1 week)</source>
<target>(1 สัปดาห์)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">30</context>
@@ -1821,6 +1849,7 @@
</trans-unit>
<trans-unit id="0efb19c3388cbcc9f3cd257f389843f9ad2a1f31" datatype="html">
<source>(1 month)</source>
<target>(1 เดือน)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">33</context>
@@ -1829,6 +1858,7 @@
</trans-unit>
<trans-unit id="9d202e68dd5064ae2e3d01073267b4db63b16c40" datatype="html">
<source>(all time)</source>
<target>(ทั้งหมด)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerator-dashboard/accelerator-dashboard.component.html</context>
<context context-type="linenumber">36</context>
@@ -2217,6 +2247,7 @@
</trans-unit>
<trans-unit id="8754c2dbc855d18ee90ffff136caedfd64f71e83" datatype="html">
<source>all</source>
<target>ทั้งหมด</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address.component.html</context>
<context context-type="linenumber">84</context>
@@ -2225,6 +2256,7 @@
</trans-unit>
<trans-unit id="6e9a3395f190e740778f523253e1fd6c53259622" datatype="html">
<source>recent</source>
<target>ล่าสุด</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address.component.html</context>
<context context-type="linenumber">87</context>
@@ -2280,6 +2312,7 @@
</trans-unit>
<trans-unit id="c7daf1b7c126095c054f2d3728ae790b0ceef33a" datatype="html">
<source>Confirmed UTXOs</source>
<target>UTXOs ที่ยืนยันแล้ว</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address.component.html</context>
<context context-type="linenumber">257</context>
@@ -2288,6 +2321,7 @@
</trans-unit>
<trans-unit id="ba986bd9e2848d2ef7329394ec87b7f4eaf61118" datatype="html">
<source>Pending UTXOs</source>
<target>UTXOs ที่กำลังดำเนินการ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address.component.html</context>
<context context-type="linenumber">262</context>
@@ -2669,6 +2703,7 @@
</trans-unit>
<trans-unit id="8072922a37fcba13275c2aaed6efb408454cf943" datatype="html">
<source>Change (7d)</source>
<target>เปลี่ยน (7 วัน)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/balance-widget/balance-widget.component.html</context>
<context context-type="linenumber">14</context>
@@ -2681,6 +2716,7 @@
</trans-unit>
<trans-unit id="00b2f0e8008ca3c1240f29cec13a5a1ebea14dd9" datatype="html">
<source>Change (30d)</source>
<target>เปลี่ยน (30 วัน)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/balance-widget/balance-widget.component.html</context>
<context context-type="linenumber">23</context>
@@ -2826,6 +2862,7 @@
</trans-unit>
<trans-unit id="8538305450922736186" datatype="html">
<source>At block <x id="PH" equiv-text="'&lt;b style=&quot;color: white; margin-left: 2px&quot;&gt;' + data[0].axisValue"/></source>
<target>ที่บล็อก <x id="PH" equiv-text="'&lt;b style=&quot;color: white; margin-left: 2px&quot;&gt;' + data[0].axisValue"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-fees-subsidy-graph/block-fees-subsidy-graph.component.ts</context>
<context context-type="linenumber">185</context>
@@ -2833,6 +2870,7 @@
</trans-unit>
<trans-unit id="8807945662832318286" datatype="html">
<source>Around block <x id="PH" equiv-text="'&lt;b style=&quot;color: white; margin-left: 2px&quot;&gt;' + data[0].axisValue"/></source>
<target>ประมาณที่บล็อก <x id="PH" equiv-text="'&lt;b style=&quot;color: white; margin-left: 2px&quot;&gt;' + data[0].axisValue"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-fees-subsidy-graph/block-fees-subsidy-graph.component.ts</context>
<context context-type="linenumber">187</context>
@@ -3142,6 +3180,7 @@
</trans-unit>
<trans-unit id="42795e8b4dc68e08fbf27cf2f7e724bbc2930610" datatype="html">
<source>High sigop count</source>
<target>จำนวน sigop สูง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-overview-tooltip/block-overview-tooltip.component.html</context>
<context context-type="linenumber">73</context>
@@ -3515,6 +3554,7 @@
</trans-unit>
<trans-unit id="27387c2af5dcaf343a548feba821515f5dc00faa" datatype="html">
<source><x id="INTERPOLATION" equiv-text="transaction&lt;/ng-template&gt; &lt;ng-template #transactionsPlural let-i i18n=&quot;shared.transacti"/> transaction</source>
<target><x id="INTERPOLATION" equiv-text="transaction&lt;/ng-template&gt; &lt;ng-template #transactionsPlural let-i i18n=&quot;shared.transacti"/> ธุรกรรม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block-transactions.component.html</context>
<context context-type="linenumber">4</context>
@@ -3535,6 +3575,7 @@
</trans-unit>
<trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html">
<source><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> transactions</source>
<target><x id="INTERPOLATION" equiv-text="transactions&lt;/ng-template&gt; &lt;/h2&gt; &lt;ngb-pagination class=&quot;pagination-container float-ri"/> ธุรกรรม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block-transactions.component.html</context>
<context context-type="linenumber">5</context>
@@ -3930,6 +3971,7 @@
</trans-unit>
<trans-unit id="56ad2f3895f350abdd3cee2d95498deb8819afac" datatype="html">
<source>Error loading block data.</source>
<target>เกิดข้อผิดพลาดในการโหลดข้อมูลบล็อก</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
<context context-type="linenumber">367</context>
@@ -4254,6 +4296,7 @@
</trans-unit>
<trans-unit id="4fe744df6d36b5e9b0afab728b77fc635b99f040" datatype="html">
<source>Recent Replacements</source>
<target>การแทนที่ล่าสุด</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">100</context>
@@ -4266,6 +4309,7 @@
</trans-unit>
<trans-unit id="23c872b0336e20284724607f2887da39bd8142c3" datatype="html">
<source>Previous fee</source>
<target>ค่าธรรมเนียมก่อนหน้า</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">107</context>
@@ -4278,6 +4322,7 @@
</trans-unit>
<trans-unit id="df33bef035883b7afeb388977087f99ab5a54409" datatype="html">
<source>New fee</source>
<target>ค่าธรรมเนียมใหม่</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">108</context>
@@ -4362,6 +4407,7 @@
</trans-unit>
<trans-unit id="aa6ce7e6e6fe5cd080713965451f25bca15a2a25" datatype="html">
<source>Recent Transactions</source>
<target>ธุรกรรมล่าสุด</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">190</context>
@@ -4374,6 +4420,7 @@
</trans-unit>
<trans-unit id="6728a64d6346c29f1b87f19160f6d1c70ca7e894" datatype="html">
<source>Treasury</source>
<target>คลัง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">228</context>
@@ -4382,6 +4429,7 @@
</trans-unit>
<trans-unit id="6aff623d92cd45f847fe6e8de9452647ffe50984" datatype="html">
<source>Treasury Transactions</source>
<target>ธุรกรรมของคลัง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">251</context>
@@ -4390,6 +4438,7 @@
</trans-unit>
<trans-unit id="d5912dcb5ff6c43e081fd2544956d19d39e8fa36" datatype="html">
<source>X Timeline</source>
<target>ช่วงเวลา X</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.html</context>
<context context-type="linenumber">265</context>
@@ -4413,6 +4462,7 @@
</trans-unit>
<trans-unit id="7816493330657272952" datatype="html">
<source>Coinjoin</source>
<target>Coinjoin</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.ts</context>
<context context-type="linenumber">73</context>
@@ -4428,6 +4478,7 @@
</trans-unit>
<trans-unit id="146442697456175258" datatype="html">
<source>Data</source>
<target>ข้อมูล</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/custom-dashboard/custom-dashboard.component.ts</context>
<context context-type="linenumber">74</context>
@@ -4741,6 +4792,7 @@
</trans-unit>
<trans-unit id="615ba6c4511a36f93c225c725935fdbf16f162a5" datatype="html">
<source>Amount (sats)</source>
<target>จำนวน (sats)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/faucet/faucet.component.html</context>
<context context-type="linenumber">51</context>
@@ -5587,6 +5639,7 @@
</trans-unit>
<trans-unit id="ac13afbf96df2d6e9e666c1fe98d75fc6b2242e7" datatype="html">
<source>Faucet</source>
<target>Faucet</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/master-page/master-page.component.html</context>
<context context-type="linenumber">105</context>
@@ -6176,6 +6229,7 @@
</trans-unit>
<trans-unit id="5e3d5a82750902f159122fcca487b07f1af3141f" datatype="html">
<source>RBF Replacements</source>
<target>การแทนที่ RBF</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/rbf-list/rbf-list.component.html</context>
<context context-type="linenumber">2</context>
@@ -6394,6 +6448,7 @@
</trans-unit>
<trans-unit id="fe5317c6c60dd7e0e86f04d22f566f67cf04d404" datatype="html">
<source>Mining Pools</source>
<target>พูลการขุด</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/search-form/search-results/search-results.component.html</context>
<context context-type="linenumber">47</context>
@@ -6454,6 +6509,7 @@
</trans-unit>
<trans-unit id="d0e134a0886ae71207e912575d226525062b62f1" datatype="html">
<source>Clock (Mempool)</source>
<target>นาฬิกา (Mempool)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/statistics/statistics.component.html</context>
<context context-type="linenumber">17</context>
@@ -6528,6 +6584,7 @@
</trans-unit>
<trans-unit id="f74d6f23e06c5a75d95a994017c00191c162ba9f" datatype="html">
<source>Test Transactions</source>
<target>ธุรกรรมทดสอบ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">2</context>
@@ -6545,6 +6602,7 @@
</trans-unit>
<trans-unit id="fec63564786cefc0ca1c650527fdfd859aff4b76" datatype="html">
<source>Raw hex</source>
<target>Raw hex</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">5</context>
@@ -6569,6 +6627,7 @@
</trans-unit>
<trans-unit id="b92fb7ca717f99e787cec47dcf1b6f72ba26d685" datatype="html">
<source>Allowed?</source>
<target>อนุญาติ?</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">23</context>
@@ -6577,6 +6636,7 @@
</trans-unit>
<trans-unit id="975c3b9c864754453576ced3f18d75ed39638c70" datatype="html">
<source>Rejection reason</source>
<target>เหตุผลที่ถูกโต้กลับ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">26</context>
@@ -6729,6 +6789,7 @@
</trans-unit>
<trans-unit id="time-within" datatype="html">
<source>within ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
<target>ภายใน ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">211</context>
@@ -6908,6 +6969,7 @@
</trans-unit>
<trans-unit id="cef1d79eace5eb4d2243fad36730e3e65c757bee" datatype="html">
<source>Sent</source>
<target>ส่งแล้ว</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker-bar.component.html</context>
<context context-type="linenumber">2</context>
@@ -6916,6 +6978,7 @@
</trans-unit>
<trans-unit id="6092bb2a5d8d9aca468a0007bc1af1c21e8f454c" datatype="html">
<source>Soon</source>
<target>เร็วๆนี้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker-bar.component.html</context>
<context context-type="linenumber">6</context>
@@ -6952,6 +7015,7 @@
</trans-unit>
<trans-unit id="dbd3edcb9583d2d5a624f70b4593d785858b6130" datatype="html">
<source>Not any time soon</source>
<target>ไม่ใช่ภายในเร็วๆนี้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">74</context>
@@ -6965,6 +7029,7 @@
</trans-unit>
<trans-unit id="a42474c92670ab75cb387cf44c03b0a4ce0a641a" datatype="html">
<source>Confirmed at</source>
<target>ยืนยันที่</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">87</context>
@@ -6973,6 +7038,7 @@
</trans-unit>
<trans-unit id="55b16cd277b9b5de63abe14b475737c753a37b97" datatype="html">
<source>Block height</source>
<target>ความสูงบล็อก</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">96</context>
@@ -7037,6 +7103,7 @@
</trans-unit>
<trans-unit id="2514309d0421b09a70cf9bf5d59bcc1b82dbec31" datatype="html">
<source>See more details</source>
<target>แสดงข้อมูลเพิ่มเติม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">193</context>
@@ -7121,6 +7188,7 @@
</trans-unit>
<trans-unit id="ec972116b4da9e2c5bc0e6e6586061d60cd13e56" datatype="html">
<source>Hide accelerator</source>
<target>ซ่อนตัวเร่ง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">133</context>
@@ -7129,6 +7197,7 @@
</trans-unit>
<trans-unit id="25fb8afb8c76ae5e793717751d9463001c1e9c01" datatype="html">
<source>RBF Timeline</source>
<target>ช่วงเวลา RBF</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">160</context>
@@ -7138,6 +7207,7 @@
</trans-unit>
<trans-unit id="24588a1469c694836138a72f0e665eb4793c35dc" datatype="html">
<source>Acceleration Timeline</source>
<target>ช่วงเวลาของการเร่ง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">169</context>
@@ -7292,6 +7362,7 @@
</trans-unit>
<trans-unit id="e75410f8ab03085a3dbecf82de6acd9679fefb75" datatype="html">
<source>Expected in Block</source>
<target>คาดว่าในบล็อก</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">522</context>
@@ -7309,6 +7380,7 @@
</trans-unit>
<trans-unit id="08c516e1fe345b4ae1fcae5fd4e5a0cd22e646dd" datatype="html">
<source>Seen in Mempool</source>
<target>พบใน Mempool</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">524</context>
@@ -7326,6 +7398,7 @@
</trans-unit>
<trans-unit id="53d5fe49e4a07a663eb2f26ceeb76afceef86334" datatype="html">
<source>Not seen in Mempool</source>
<target>ไม่พบใน Mempool</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transaction/transaction.component.html</context>
<context context-type="linenumber">526</context>
@@ -7529,6 +7602,7 @@
</trans-unit>
<trans-unit id="395b6ec0ab68cd45fad7ab791393d85d4077f94b" datatype="html">
<source>1 block earlier</source>
<target>1 บล็อกก่อนหน้า</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">123</context>
@@ -7537,6 +7611,7 @@
</trans-unit>
<trans-unit id="f6f7403b9d7495e7282520b50133c3c3843a6b62" datatype="html">
<source>1 block later</source>
<target>1 บล็อกให้หลัง</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">127</context>
@@ -7545,6 +7620,7 @@
</trans-unit>
<trans-unit id="84c7fcc1f282a501eb33fc17a8b2bda177de5a7e" datatype="html">
<source>in the same block</source>
<target>ใยบล็อกเดียวกัน</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">131</context>
@@ -7553,6 +7629,7 @@
</trans-unit>
<trans-unit id="95bf37451da5bff541c9380f803a695f2aac28a2" datatype="html">
<source>blocks earlier</source>
<target>บล็อกก่อนหน้า</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">137</context>
@@ -7561,6 +7638,7 @@
</trans-unit>
<trans-unit id="5a67f718fe7d4f423417d1c0162f1afb24e9dac8" datatype="html">
<source>spent </source>
<target>จ่าย</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">148</context>
@@ -7569,6 +7647,7 @@
</trans-unit>
<trans-unit id="21ea333dd6a24e18e5af771634afbaeeeb369a8d" datatype="html">
<source>blocks later</source>
<target>บล็อกถัดจากนี้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component.html</context>
<context context-type="linenumber">150</context>
@@ -7869,6 +7948,7 @@
</trans-unit>
<trans-unit id="meta.title.docs.faq" datatype="html">
<source>FAQ</source>
<target>ถามตอบ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">46</context>
@@ -7883,6 +7963,7 @@
</trans-unit>
<trans-unit id="meta.title.docs.rest" datatype="html">
<source>REST API</source>
<target>REST API</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">51</context>
@@ -7904,6 +7985,7 @@
</trans-unit>
<trans-unit id="meta.title.docs.websocket" datatype="html">
<source>WebSocket API</source>
<target>WebSocket API</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">59</context>
@@ -7925,6 +8007,7 @@
</trans-unit>
<trans-unit id="meta.title.docs.electrum" datatype="html">
<source>Electrum RPC</source>
<target>Electrum RPC</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">67</context>
@@ -8797,6 +8880,7 @@
</trans-unit>
<trans-unit id="34e302a08660d9860dda71e3f350351d34bda498" datatype="html">
<source>Penalties</source>
<target>บทลงโทษ</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/justice-list/justice-list.component.html</context>
<context context-type="linenumber">4</context>
@@ -9602,6 +9686,7 @@
</trans-unit>
<trans-unit id="2da938f28079d0d1ba372c5290b1bb1c18cf077c" datatype="html">
<source>fee</source>
<target>ค่าธรรมเนียม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/address-type/address-type.component.html</context>
<context context-type="linenumber">3</context>
@@ -9610,6 +9695,7 @@
</trans-unit>
<trans-unit id="fcb99e36a9158520fcf478c949fb704912aa3d4b" datatype="html">
<source>empty</source>
<target>ว่างเปล่า</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/address-type/address-type.component.html</context>
<context context-type="linenumber">6</context>
@@ -9710,6 +9796,7 @@
</trans-unit>
<trans-unit id="51a5e241afdecf2cae3acb567d9fed560a817382" datatype="html">
<source>Test Transaction</source>
<target>ทดสอบธุรกรรม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">64</context>
@@ -9791,6 +9878,7 @@
</trans-unit>
<trans-unit id="692f6e6f4f6afc7f48b8194ab03e1d2155650f00" datatype="html">
<source>Research</source>
<target>วิจัย</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">75</context>
@@ -9817,6 +9905,7 @@
</trans-unit>
<trans-unit id="7dcdb8435f1421b5ad5920a77278d498691faef2" datatype="html">
<source>Testnet3 Explorer</source>
<target>สำรวจ Testnet3</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">81</context>
@@ -9825,6 +9914,7 @@
</trans-unit>
<trans-unit id="46a03052a962e6b21651effc05391e2a4e26946a" datatype="html">
<source>Testnet4 Explorer</source>
<target>ตัวสำรวจ Testnet4</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">82</context>
@@ -9869,6 +9959,7 @@
</trans-unit>
<trans-unit id="8c23995422ac012b80a2369a878b199c39271906" datatype="html">
<source>Clock (Mined)</source>
<target>นาฬิกา (การขุด)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">91</context>
@@ -9877,6 +9968,7 @@
</trans-unit>
<trans-unit id="9a91783e9c0f790ed49edae730f9156070ed9dd5" datatype="html">
<source>Legal</source>
<target>ถูกกฎหมาย</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/global-footer/global-footer.component.html</context>
<context context-type="linenumber">96</context>
@@ -9950,6 +10042,7 @@
</trans-unit>
<trans-unit id="893cb386c7625a411278d5893552adb7558f0d54" datatype="html">
<source>Testnet4 is not yet finalized, and may be reset at anytime.</source>
<target>Testnet4 ยังไม่เสร็จสมบูรณ์ และอาจถูกรีเซ็ตเวลาไหนก็ได้</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/testnet-alert/testnet-alert.component.html</context>
<context context-type="linenumber">9</context>
@@ -9958,6 +10051,7 @@
</trans-unit>
<trans-unit id="6052761358428332094" datatype="html">
<source>Batch payment</source>
<target>กลุ่มธุรกรรม</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/filters.utils.ts</context>
<context context-type="linenumber">108</context>
@@ -10117,6 +10211,7 @@
</trans-unit>
<trans-unit id="address-label.multisig" datatype="html">
<source>Multisig <x id="multisigM" equiv-text="m"/> of <x id="multisigN" equiv-text="n"/></source>
<target>Multisig <x id="multisigM" equiv-text="m"/> จาก <x id="multisigN" equiv-text="n"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/script.utils.ts</context>
<context context-type="linenumber">168</context>
+52
View File
@@ -645,6 +645,7 @@
</trans-unit>
<trans-unit id="d1a62bdb732f1efbfdc8af6fbb4349b89015b5e5" datatype="html">
<source>This will reduce your expected waiting time until the first confirmation to <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="START_TAG_APP_TIME" ctype="x-app_time" equiv-text="n&quot; [time]=&quot;etaInfo.acceleratedETA&quot; [fastRender]=&quot;false&quot; [fixedRender]=&quot;true&quot;&gt;"/><x id="CLOSE_TAG_APP_TIME" ctype="x-app_time" equiv-text="&lt;/strong&gt;&lt;/s"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/small&gt;"/></source>
<target>İlk onaya kadar geçen bekleme süresini <x id="START_TAG_STRONG" ctype="x-strong" equiv-text="&lt;strong&gt;"/><x id="START_TAG_APP_TIME" ctype="x-app_time" equiv-text="n&quot; [time]=&quot;etaInfo.acceleratedETA&quot; [fastRender]=&quot;false&quot; [fixedRender]=&quot;true&quot;&gt;"/><x id="CLOSE_TAG_APP_TIME" ctype="x-app_time" equiv-text="&lt;/strong&gt;&lt;/s"/><x id="CLOSE_TAG_STRONG" ctype="x-strong" equiv-text="&lt;/small&gt;"/>kadar azaltacak.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/accelerate-checkout/accelerate-checkout.component.html</context>
<context context-type="linenumber">76,77</context>
@@ -1392,6 +1393,7 @@
</trans-unit>
<trans-unit id="c3aaae1073e33c932a5c98f98c3520645c0e3a93" datatype="html">
<source>Out-of-band fees</source>
<target>Bant-dışı ücretler</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration-timeline/acceleration-timeline-tooltip.component.html</context>
<context context-type="linenumber">27</context>
@@ -1791,6 +1793,7 @@
</trans-unit>
<trans-unit id="a7c328c4773db932ff14a1954e15e43dca58e7b7" datatype="html">
<source>Completed</source>
<target>Tamamlandı</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">65</context>
@@ -1799,6 +1802,7 @@
</trans-unit>
<trans-unit id="64b582e0d8e3a28331a14d2a1017fa5d6ffb8d93" datatype="html">
<source>Failed</source>
<target>Başarısız oldu</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/acceleration/accelerations-list/accelerations-list.component.html</context>
<context context-type="linenumber">67</context>
@@ -2320,6 +2324,7 @@
</trans-unit>
<trans-unit id="9eb81e2576ffe4e8fb0a303e203040b6ab23cc22" datatype="html">
<source><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="There are too many transactions on this address, more than your backend can handle. See more on &lt;"/>There are too many transactions on this address, more than your backend can handle. See more on <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;/docs/faq#address-lookup-issues&quot;&gt;"/>setting up a stronger backend<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.<x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/><x id="LINE_BREAK" ctype="lb"/><x id="LINE_BREAK" ctype="lb"/> Consider viewing this address on the official Mempool website instead: </source>
<target><x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="There are too many transactions on this address, more than your backend can handle. See more on &lt;"/> Bu adres üzerindeki işlem sayısı arka arayüzününüzün işleyemeyeceği kadar fazla. Daha kuvvetli bir arkayüz için <x id="START_LINK" ctype="x-a" equiv-text="&lt;a href=&quot;/docs/faq#address-lookup-issues&quot;&gt;"/>'ye bakın. <x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.<x id="CLOSE_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;/i&gt;"/><x id="LINE_BREAK" ctype="lb"/><x id="LINE_BREAK" ctype="lb"/> Ya da bu adresi resmi Mempool sitesinde görüntüleyin: </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/address/address.component.html</context>
<context context-type="linenumber">204,207</context>
@@ -2535,6 +2540,7 @@
</trans-unit>
<trans-unit id="meta.description.liquid.asset" datatype="html">
<source>Browse an overview of the Liquid asset <x id="INTERPOLATION" equiv-text="this.assetContract[1]"/> (<x id="INTERPOLATION" equiv-text="this.assetContract[1]"/>): see issued amount, burned amount, circulating amount, related transactions, and more.</source>
<target>Liquid varlığın genel görünümünü incele <x id="INTERPOLATION" equiv-text="this.assetContract[1]"/>(<x id="INTERPOLATION" equiv-text="this.assetContract[1]"/>): üretilen, yakılan, dolaşan miktarlır ve ilişkili işlemleri ve daha fazlasını gör. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/asset/asset.component.ts</context>
<context context-type="linenumber">108</context>
@@ -2800,6 +2806,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.block-fee-rates" datatype="html">
<source>See Bitcoin feerates visualized over time, including minimum and maximum feerates per block along with feerates at various percentiles.</source>
<target>Bitcoin ücret çizelgesinin zaman içindeki değişimini görüntüle. Minimum ve maksimum ücretler ve farklı yüzdelik dilimlerdeki ücretleri görüntüleyebilirsin. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-fee-rates-graph/block-fee-rates-graph.component.ts</context>
<context context-type="linenumber">73</context>
@@ -2824,6 +2831,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.block-fees" datatype="html">
<source>See the average mining fees earned per Bitcoin block visualized in BTC and USD over time.</source>
<target>Bitcoin bloğu başına ortalama madencilik ücretlerinin BTC ve USD cinsi olarak değişimini gör. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-fees-graph/block-fees-graph.component.ts</context>
<context context-type="linenumber">70</context>
@@ -3012,6 +3020,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.block-health" datatype="html">
<source>See Bitcoin block health visualized over time. Block health is a measure of how many expected transactions were included in an actual mined block. Expected transactions are determined using Mempool's re-implementation of Bitcoin Core's transaction selection algorithm.</source>
<target>Bitcoin blok sağlığını zaman içinde görüntüle. Blok sağlığı beklenen işlemlerin kaçının gerçekten bloğa dahil edildiğinin ölçüsüdür. Beklenen işlemler Mempool'un çalıştırdığı Bitcoin Core işlem seçme algoritması ile belirlenir.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-health-graph/block-health-graph.component.ts</context>
<context context-type="linenumber">64</context>
@@ -3298,6 +3307,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.block-rewards" datatype="html">
<source>See Bitcoin block rewards in BTC and USD visualized over time. Block rewards are the total funds miners earn from the block subsidy and fees.</source>
<target>Bitcoin blok ödüllerini BTC ve USD cinsinden zaman içerisinde görüntüle. Blok ödülleri yeni çıkarılan bitcoin ödülleri ve işlem ücretlerinin toplamıdır. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-rewards-graph/block-rewards-graph.component.ts</context>
<context context-type="linenumber">68</context>
@@ -3322,6 +3332,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.block-sizes" datatype="html">
<source>See Bitcoin block sizes (MB) and block weights (weight units) visualized over time.</source>
<target>Bitcoin blok boyutlarını (MB) ve blok ağırlıklarını (ağırlık ünitesi) zaman içinde görselleştir.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-sizes-weights-graph/block-sizes-weights-graph.component.ts</context>
<context context-type="linenumber">65</context>
@@ -3445,6 +3456,7 @@
</trans-unit>
<trans-unit id="meta.description.liquid.block" datatype="html">
<source>See size, weight, fee range, included transactions, and more for Liquid<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> block <x id="BLOCK_HEIGHT" equiv-text="block.height"/> (<x id="BLOCK_ID" equiv-text="block.id"/>).</source>
<target>Liquid <x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> bloğundaki <x id="BLOCK_HEIGHT" equiv-text="block.height"/> (<x id="BLOCK_ID" equiv-text="block.id"/>) boyut, ağırlık, ücret aralığı, dahil edilen işlemler ve daha fazlasını gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-view/block-view.component.ts</context>
<context context-type="linenumber">112</context>
@@ -3460,6 +3472,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.block" datatype="html">
<source>See size, weight, fee range, included transactions, audit (expected v actual), and more for Bitcoin<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> block <x id="BLOCK_HEIGHT" equiv-text="block.height"/> (<x id="BLOCK_ID" equiv-text="block.id"/>).</source>
<target>Bitcoin <x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> block <x id="BLOCK_HEIGHT" equiv-text="block.height"/>(<x id="BLOCK_ID" equiv-text="block.id"/>) için boyut, ağırlıklar, ücret aralığı, dahili işlemler, denetim (beklene vs gerçek) ve daha fazlasını gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block-view/block-view.component.ts</context>
<context context-type="linenumber">114</context>
@@ -3651,6 +3664,7 @@
</trans-unit>
<trans-unit id="e170a90ee0d3a604adf439a60c890caff9152466" datatype="html">
<source>This block does not belong to the main chain, it has been replaced by:</source>
<target>Bu blok ana-zincire dahil değil ve şununla değiştirilebilir: </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
<context context-type="linenumber">5</context>
@@ -4173,6 +4187,7 @@
</trans-unit>
<trans-unit id="meta.description.liquid.blocks" datatype="html">
<source>See the most recent Liquid<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> blocks along with basic stats such as block height, block size, and more.</source>
<target>En güncel Liquid <x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> blokları için blok yüksekliği, blok büyüklüğü vb temel dataları gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.ts</context>
<context context-type="linenumber">71</context>
@@ -4180,6 +4195,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.blocks" datatype="html">
<source>See the most recent Bitcoin<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> blocks along with basic stats such as block height, block reward, block size, and more.</source>
<target>En güncel Bitcoin <x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> blokları için blok yüksekliği, blok büyüklüğü vb temel dataları gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/blocks-list/blocks-list.component.ts</context>
<context context-type="linenumber">73</context>
@@ -5162,6 +5178,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.hashrate" datatype="html">
<source>See hashrate and difficulty for the Bitcoin<x id="PH" equiv-text="seoDescriptionNetwork(this.network)"/> network visualized over time.</source>
<target>Bitcoin ağı <x id="PH" equiv-text="seoDescriptionNetwork(this.network)"/> için hashrate ve zorluk seviyelerinin değişimini zaman içinde gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/hashrate-chart/hashrate-chart.component.ts</context>
<context context-type="linenumber">76</context>
@@ -5189,6 +5206,7 @@
</trans-unit>
<trans-unit id="meta.descriptions.bitcoin.graphs.hashrate-pools" datatype="html">
<source>See Bitcoin mining pool dominance visualized over time: see how top mining pools' share of total hashrate has fluctuated over time.</source>
<target>Madencilik havuzu dominasyonunu değişimini zaman içinde gör : en büyük madencilik havuzlarının toplam havuzdan aldığı payın değişimini incele.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/hashrates-chart-pools/hashrate-chart-pools.component.ts</context>
<context context-type="linenumber">75</context>
@@ -5311,6 +5329,7 @@
</trans-unit>
<trans-unit id="506d3b3e461d170c39745288b9ea96b9ac9b7f78" datatype="html">
<source>Total amount of BTC held in non-dust Federation UTXOs that have expired timelocks</source>
<target>Dust-dışı Federasyon UTXO'larındaki zaman kilidi bitmiş toplam BTC miktarını gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/liquid-reserves-audit/expired-utxos-stats/expired-utxos-stats.component.html</context>
<context context-type="linenumber">5</context>
@@ -5510,6 +5529,7 @@
</trans-unit>
<trans-unit id="3669efae1ff592688b4df067abf0a272e90af226" datatype="html">
<source>Fund / Redemption Tx</source>
<target>Fon/ Amortisman İşlemi</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/liquid-reserves-audit/recent-pegs-list/recent-pegs-list.component.html</context>
<context context-type="linenumber">15</context>
@@ -5581,6 +5601,7 @@
</trans-unit>
<trans-unit id="52b32e9a8be459e6539a9b9214c2a17b23206a6c" datatype="html">
<source>Number of times that the Federation's BTC holdings fall below 95% of the total L-BTC supply</source>
<target>Federasyonun tuttuğu BTC miktarının toplam L-BTC'nin %95'inin altına düşme sayısı</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/liquid-reserves-audit/reserves-ratio-stats/reserves-ratio-stats.component.html</context>
<context context-type="linenumber">6</context>
@@ -5698,6 +5719,7 @@
</trans-unit>
<trans-unit id="meta.description.mempool-block" datatype="html">
<source>See stats for <x id="PH" equiv-text="this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'"/><x id="PH_1" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> transactions in the mempool: fee range, aggregate size, and more. Mempool blocks are updated in real-time as the network receives new transactions.</source>
<target>İşlemler <x id="PH" equiv-text="this.stateService.network==='liquid'||this.stateService.network==='liquidtestnet'?'Liquid':'Bitcoin'"/><x id="PH_1" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> için mempool istatistiklerini göster: ücret aralığı, toplam büyüklük, ve fazlasını gör. Mempool blokları, ağa yeni işlem geldiğinde anlık olarak güncellenir. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
<context context-type="linenumber">62</context>
@@ -5793,6 +5815,7 @@
</trans-unit>
<trans-unit id="meta.description.mining.dashboard" datatype="html">
<source>Get real-time Bitcoin mining stats like hashrate, difficulty adjustment, block rewards, pool dominance, and more.</source>
<target>Anlık olarak hashrate, zorluk seviyesi, blok ödülleri, havuz dominasyonu vb madencilik istatistiklerini görüntüle. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.ts</context>
<context context-type="linenumber">30</context>
@@ -6071,6 +6094,7 @@
</trans-unit>
<trans-unit id="meta.description.mining.pool" datatype="html">
<source>See mining pool stats for <x id="PH" equiv-text="poolStats.pool.name"/>: most recent mined blocks, hashrate over time, total block reward to date, known coinbase addresses, and more.</source>
<target>Madencilik havuzu istatistiklerini <x id="PH" equiv-text="poolStats.pool.name"/>: en son bulunan bloklar, hashrate'in zaman içindeki değişimi, bugüne kadarki toplam ödül miktarı, bilinen Coinbase adresleri vb gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool/pool-preview.component.ts</context>
<context context-type="linenumber">86</context>
@@ -6305,6 +6329,7 @@
</trans-unit>
<trans-unit id="meta.description.rbf-list" datatype="html">
<source>See the most recent RBF replacements on the Bitcoin<x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> network, updated in real-time.</source>
<target>Bitcoin <x id="PH" equiv-text="seoDescriptionNetwork(this.stateService.network)"/> ağı üzerindeki en yeni RBF değişimlerini gerçek zamanlı olarak görüntüle.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/rbf-list/rbf-list.component.ts</context>
<context context-type="linenumber">62</context>
@@ -6618,6 +6643,7 @@
</trans-unit>
<trans-unit id="68d44b7bd049ae93c2bc15973eb5266aec64693e" datatype="html">
<source>Cap outliers</source>
<target>Sınır dışı değerler</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/statistics/statistics.component.html</context>
<context context-type="linenumber">121</context>
@@ -6626,6 +6652,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.graphs.mempool" datatype="html">
<source>See mempool size (in MvB) and transactions per second (in vB/s) visualized over time.</source>
<target>Mempool büyüklüğünün (MvB olarak) ve saniyedeki işlem sayısının (vB/s) zaman içindeki değişimini görselleştir.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/statistics/statistics.component.ts</context>
<context context-type="linenumber">66</context>
@@ -6633,6 +6660,7 @@
</trans-unit>
<trans-unit id="meta.description.tv" datatype="html">
<source>See Bitcoin blocks and mempool congestion in real-time in a simplified format perfect for a TV.</source>
<target>Bitcoin bloklarını ve mempool yoğunluğunu televizyon formatına uygun olarak doğru zamanlı gör</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/television/television.component.ts</context>
<context context-type="linenumber">40</context>
@@ -6667,6 +6695,7 @@
</trans-unit>
<trans-unit id="48e4b0c012de5020053ecb26e9ac0d35a1f60688" datatype="html">
<source>Comma-separated list of raw transactions</source>
<target>Raw-işlem datalarının virgül ile ayrık gösterimi</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/test-transactions/test-transactions.component.html</context>
<context context-type="linenumber">7</context>
@@ -7113,6 +7142,7 @@
</trans-unit>
<trans-unit id="52a68ca949dfcdeaaea81bec4d597256b8ad42b5" datatype="html">
<source>Waiting for your transaction to appear in the mempool</source>
<target>İşleminizin mempool'da gözükemsini bekliyoruz.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">150</context>
@@ -7121,6 +7151,7 @@
</trans-unit>
<trans-unit id="5ad21d21f3e26ddfe0abeed499db5d5c0bd0e325" datatype="html">
<source>Your transaction is in the mempool, but it will not be confirmed for some time.</source>
<target>İşleminiz mempool'da yalnız yakın zamanda onaylanması beklenmiyor.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">156</context>
@@ -7129,6 +7160,7 @@
</trans-unit>
<trans-unit id="809118722b27889f5424609d1779f356bcef2cc2" datatype="html">
<source>Your transaction is near the top of the mempool, and is expected to confirm soon.</source>
<target>İşleminizin mempool'un üst kademesinde, yakında onaylanması bekleniyor.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">162</context>
@@ -7137,6 +7169,7 @@
</trans-unit>
<trans-unit id="ee76deb7716e90b79e557394b1d256079b7ec24e" datatype="html">
<source>Your transaction is expected to confirm in the next block</source>
<target>İşleminizin bir sonraki blokta onaylanması bekleniyor.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.html</context>
<context context-type="linenumber">168</context>
@@ -7188,6 +7221,7 @@
</trans-unit>
<trans-unit id="meta.description.bitcoin.transaction" datatype="html">
<source>Get real-time status, addresses, fees, script info, and more for <x id="PH" equiv-text="network"/><x id="PH_1" equiv-text="seoDescription"/> transaction with txid <x id="PH_2" equiv-text="this.txId"/>.</source>
<target>İşlemler <x id="PH" equiv-text="network"/><x id="PH_1" equiv-text="seoDescription"/> ve işlem id'si <x id="PH_2" equiv-text="this.txId"/> için anlık durum, adresler, ücretler, script vb bilgileri çek.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tracker/tracker.component.ts</context>
<context context-type="linenumber">413</context>
@@ -7923,6 +7957,7 @@
</trans-unit>
<trans-unit id="999bb1a0150c2815a6b4dd64a1850e763603e525" datatype="html">
<source><x id="START_PARAGRAPH" ctype="x-p" equiv-text="For any such requ"/><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space mer"/>mempool.space merely provides data about the Bitcoin network.<x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/> It cannot help you with retrieving funds, wallet issues, etc.<x id="CLOSE_PARAGRAPH" ctype="x-p" equiv-text="&lt;/p&gt;"/><x id="START_PARAGRAPH" ctype="x-p" equiv-text="For any such requ"/>For any such requests, you need to get in touch with the entity that helped make the transaction (wallet software, exchange company, etc).<x id="CLOSE_PARAGRAPH" ctype="x-p" equiv-text="&lt;/p&gt;"/></source>
<target><x id="START_PARAGRAPH" ctype="x-p" equiv-text="For any such requ"/><x id="START_BOLD_TEXT" ctype="x-b" equiv-text="mempool.space mer"/>mempool.space Bitcoin ağı hakkında sadece bilgi sağlar. <x id="CLOSE_BOLD_TEXT" ctype="x-b" equiv-text="&lt;/b&gt;"/>kaybettiğiniz fonları, cüzdanlar ile yaşadığınız sorunları çözmekte yardımcı olamaz. <x id="CLOSE_PARAGRAPH" ctype="x-p" equiv-text="&lt;/p&gt;"/><x id="START_PARAGRAPH" ctype="x-p" equiv-text="For any such requ"/>İşlemler ile ilgili sorun yaşarsanız bu işlemi gerçekleştirdiğiniz entite ile iletişime geçmeniz gerekir. (cüzdan yazılımı, borsa vb)<x id="CLOSE_PARAGRAPH" ctype="x-p" equiv-text="&lt;/p&gt;"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/api-docs/api-docs.component.html</context>
<context context-type="linenumber">15,16</context>
@@ -8025,6 +8060,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.faq" datatype="html">
<source>Get answers to common questions like: What is a mempool? Why isn't my transaction confirming? How can I run my own instance of The Mempool Open Source Project? And more.</source>
<target>Mempool nedir, neden işlemim onaylanmıyor, Açık Kaynak Kodlu Mempool projesinin bir kopyasını nasıl çalıştırabilirim? gibi temel sorulara cevaplar bulun.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">47</context>
@@ -8072,6 +8108,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.websocket-bitcoin" datatype="html">
<source>Documentation for the mempool.space WebSocket API service: get real-time info on blocks, mempools, transactions, addresses, and more.</source>
<target>Mempool.space Websoket API servisi için, bloklardan gerçek-zamanlı bilgi çek, mempoollar, işlemler, adresler vb talepler için dökümantasyon. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">63</context>
@@ -8087,6 +8124,7 @@
</trans-unit>
<trans-unit id="meta.description.docs.electrumrpc" datatype="html">
<source>Documentation for our Electrum RPC interface: get instant, convenient, and reliable access to an Esplora instance.</source>
<target>Electrum RPC için arayüz dökümantasyonu: Esplora'ya anında, kolayca ve emniyetli bir şekilde ulaşın. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/docs/docs/docs.component.ts</context>
<context context-type="linenumber">68</context>
@@ -8403,6 +8441,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.channel" datatype="html">
<source>Overview for Lightning channel <x id="PH" equiv-text="params.get('short_id')"/>. See channel capacity, the Lightning nodes involved, related on-chain transactions, and more.</source>
<target>Lightning Kanalı <x id="PH" equiv-text="params.get('short_id')"/> için genel bakış sağlar. Kanal kapasitesi, bağlantılı Lightning nodeları, alakalı zincir üstü işlemler vb veriler. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channel/channel-preview.component.ts</context>
<context context-type="linenumber">37</context>
@@ -9030,6 +9069,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.dashboard" datatype="html">
<source>Get stats on the Lightning network (aggregate capacity, connectivity, etc), Lightning nodes (channels, liquidity, etc) and Lightning channels (status, fees, etc).</source>
<target>Lightning Network için istatistikleri getir. ( toplam kapasite, bağlantılar vb), Ligthning nodeları (kanallar, likidite) ve Lightning kanalları (durum, ücretler vb) </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.ts</context>
<context context-type="linenumber">34</context>
@@ -9139,6 +9179,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.node" datatype="html">
<source>Overview for the Lightning network node named <x id="PH" equiv-text="node.alias"/>. See channels, capacity, location, fee stats, and more.</source>
<target><x id="PH" equiv-text="node.alias"/> adındaki Lightning ağı nodu için genel bakış. Kanalları, kapasiteyi, lokasyonu, ücret bilgileri ve daha fazlasını gör. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/node/node-preview.component.ts</context>
<context context-type="linenumber">52</context>
@@ -9338,6 +9379,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.node-map" datatype="html">
<source>See the channels of non-Tor Lightning network nodes visualized on a world map. Hover/tap on points on the map for node names and details.</source>
<target>Tor-dışı Lightning ağı nodelarını dünya haritası üzerinde görselleştir. Haritadaki noktaların üzerinde gezerek node adı ve detayları görebilirsiniz.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-channels-map/nodes-channels-map.component.ts</context>
<context context-type="linenumber">74</context>
@@ -9362,6 +9404,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.node-channel-map" datatype="html">
<source>See the locations of non-Tor Lightning network nodes visualized on a world map. Hover/tap on points on the map for node names and details.</source>
<target>Tor-dışı Lightning ağı nodelarını dünya haritası üzerinde görselleştir. Haritadaki noktaların üzerinde gezerek node adı ve detayları görebilirsiniz.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-map/nodes-map.component.ts</context>
<context context-type="linenumber">52</context>
@@ -9369,6 +9412,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.nodes-network" datatype="html">
<source>See the number of Lightning network nodes visualized over time by network: clearnet only (IPv4, IPv6), darknet (Tor, I2p, cjdns), and both.</source>
<target>Ağ türüne göre Lightning ağı nodelarının zaman içerisindeki değişimini göster. Sadece clearnet (IPv4, IPv6), darknet (Tor, I2p, cjdns) ve iki tür bağlantı için. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">74</context>
@@ -9437,6 +9481,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.nodes-country-overview" datatype="html">
<source>See a geographical breakdown of the Lightning network: how many Lightning nodes are hosted in countries around the world, aggregate BTC capacity for each country, and more.</source>
<target>Lightning network ağının coğrafi dağılımını görüntüle. Hangi ülkede kaç tane node bulunuyor, ülkeler için toplam BTC kapasitesi ve dha fazlası.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">47</context>
@@ -9507,6 +9552,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.nodes-country" datatype="html">
<source>Explore all the Lightning nodes hosted in <x id="PH" equiv-text="response.country.en"/> and see an overview of each node's capacity, number of open channels, and more.</source>
<target><x id="PH" equiv-text="response.country.en"/> de çalıştırılan bütün Lightning nodeları içn node kapasitesi, açık node sayısı vb bilgileri incele.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country/nodes-per-country.component.ts</context>
<context context-type="linenumber">44</context>
@@ -9589,6 +9635,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.nodes-per-isp" datatype="html">
<source>Browse the top 100 ISPs hosting Lightning nodes along with stats like total number of nodes per ISP, aggregate BTC capacity per ISP, and more</source>
<target>En fazla Lightning Node'u barındıran 100 ISP'yi ve onların ISP başı toplam node sayısı, ISP'nin toplam BTC kapasitesi vb verilerini incele.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">54</context>
@@ -9651,6 +9698,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.nodes-isp" datatype="html">
<source>Browse all Bitcoin Lightning nodes using the <x id="PH" equiv-text="response.isp"/> [AS<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>] ISP and see aggregate stats like total number of nodes, total capacity, and more for the ISP.</source>
<target><x id="PH" equiv-text="response.isp"/> ISP [AS<x id="PH_1" equiv-text="this.route.snapshot.params.isp"/>] kulanan bütün Lightning nodelarını ve onların toplam node sayısı, toplam kapasites vb görüntüle. </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp/nodes-per-isp-preview.component.ts</context>
<context context-type="linenumber">45</context>
@@ -9706,6 +9754,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.ranking.oldest" datatype="html">
<source>See the oldest nodes on the Lightning network along with their capacity, number of channels, location, etc.</source>
<target>Lightning ağındaki en eski nodları ve bu nodeların kanal sayısı, kapasitesi ve lokasyonunu vb dataları görüntüle.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-ranking/oldest-nodes/oldest-nodes.component.ts</context>
<context context-type="linenumber">28</context>
@@ -9713,6 +9762,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.ranking.liquidity" datatype="html">
<source>See Lightning nodes with the most BTC liquidity deployed along with high-level stats like number of open channels, location, node age, and more.</source>
<target>Lightning ağındaki en fazla BTC likiditesi olan nodelar için açık kanal sayısı, lokasyon, node yaşı vb dataları gör.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-ranking/top-nodes-per-capacity/top-nodes-per-capacity.component.ts</context>
<context context-type="linenumber">35</context>
@@ -9720,6 +9770,7 @@
</trans-unit>
<trans-unit id="meta.description.lightning.ranking.channels" datatype="html">
<source>See Lightning nodes with the most channels open along with high-level stats like total node capacity, node age, and more.</source>
<target>Lightning nodeları için toplam node kapasitesi, node yaşı vb temel dataları görüntüle.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-ranking/top-nodes-per-channels/top-nodes-per-channels.component.ts</context>
<context context-type="linenumber">39</context>
@@ -10093,6 +10144,7 @@
</trans-unit>
<trans-unit id="ba7f0c6fdfa0ab7afc59e9384bca0265d23fb018" datatype="html">
<source>Your balance is too low.<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/>Please <x id="START_LINK" ctype="x-a" equiv-text="&lt;a class=&quot;top-up-link&quot; href=&quot;/services/accelerator/overview&quot;&gt;"/>top up your account<x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</source>
<target>Balansınız çok düşük. <x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/&gt;"/> lütfen <x id="START_LINK" ctype="x-a" equiv-text="&lt;a class=&quot;top-up-link&quot; href=&quot;/services/accelerator/overview&quot;&gt;"/> hesabınıza ekleme yapınız <x id="CLOSE_LINK" ctype="x-a" equiv-text="&lt;/a&gt;"/>.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/components/mempool-error/mempool-error.component.html</context>
<context context-type="linenumber">9</context>
Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Loaded 100 of 107 files, more files were not shown because too many files have changed in this diff. Show more