Merge: block-detail redesign + QR codes with PoS stats, 2222222 supply, wordmark, hash tooltips
# Conflicts: # static/favicon.ico # static/logo-192.png
This commit is contained in:
Generated
+307
-1
@@ -9,7 +9,8 @@
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"chart.js": "^4.4.0",
|
||||
"leaflet": "^1.9.4"
|
||||
"leaflet": "^1.9.4",
|
||||
"qrcode": "^1.5.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-node": "^5.5.4",
|
||||
@@ -1417,6 +1418,30 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz",
|
||||
@@ -1437,6 +1462,15 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/camelcase": {
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz",
|
||||
@@ -1465,6 +1499,17 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wrap-ansi": "^6.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
@@ -1475,6 +1520,24 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
@@ -1510,6 +1573,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decamelize": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
@@ -1537,6 +1609,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dijkstrajs": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.20.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz",
|
||||
@@ -1636,6 +1720,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/find-up": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"locate-path": "^5.0.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
@@ -1661,6 +1758,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
@@ -1697,6 +1803,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
@@ -2008,6 +2123,18 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-locate": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
|
||||
@@ -2064,6 +2191,51 @@
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-try": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-locate": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"p-limit": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-try": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
@@ -2091,6 +2263,15 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pngjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.8",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
|
||||
@@ -2120,6 +2301,23 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dijkstrajs": "^1.0.1",
|
||||
"pngjs": "^5.0.0",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"bin": {
|
||||
"qrcode": "bin/qrcode"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
|
||||
@@ -2134,6 +2332,21 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/require-main-filename": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.11",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz",
|
||||
@@ -2213,6 +2426,12 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/set-cookie-parser": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.0.1.tgz",
|
||||
@@ -2245,6 +2464,32 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
@@ -2484,6 +2729,67 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/which-module": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "15.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^6.0.0",
|
||||
"decamelize": "^1.2.0",
|
||||
"find-up": "^4.1.0",
|
||||
"get-caller-file": "^2.0.1",
|
||||
"require-directory": "^2.1.1",
|
||||
"require-main-filename": "^2.0.0",
|
||||
"set-blocking": "^2.0.0",
|
||||
"string-width": "^4.2.0",
|
||||
"which-module": "^2.0.0",
|
||||
"y18n": "^4.0.0",
|
||||
"yargs-parser": "^18.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "18.1.3",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/zimmerframe": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.4.tgz",
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"chart.js": "^4.4.0",
|
||||
"leaflet": "^1.9.4"
|
||||
"leaflet": "^1.9.4",
|
||||
"qrcode": "^1.5.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import QRCode from 'qrcode';
|
||||
|
||||
let { data, size = 200 }: { data: string; size?: number } = $props();
|
||||
let canvas: HTMLCanvasElement;
|
||||
|
||||
onMount(() => {
|
||||
if (canvas) {
|
||||
QRCode.toCanvas(canvas, data, {
|
||||
width: size,
|
||||
margin: 2,
|
||||
color: {
|
||||
dark: '#FFFFFF', // White QR code
|
||||
light: '#1a1a2e' // Dark background (tri-bg color)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('QR code generation failed:', err);
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<canvas bind:this={canvas} class="rounded-lg border-2 border-tri-border"></canvas>
|
||||
@@ -1,36 +1,135 @@
|
||||
<script lang="ts">
|
||||
import TxTable from '$lib/components/TxTable.svelte';
|
||||
import { formatAmount, truncateHash } from '$lib/utils';
|
||||
import QRCode from '$lib/components/QRCode.svelte';
|
||||
import { formatAmount, truncateHash, formatNumber } from '$lib/utils';
|
||||
|
||||
let { data } = $props();
|
||||
|
||||
// Copy address to clipboard
|
||||
let copied = $state(false);
|
||||
function copyAddress() {
|
||||
navigator.clipboard.writeText(data.address).then(() => {
|
||||
copied = true;
|
||||
setTimeout(() => copied = false, 2000);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Address {data.address} - Triangles Explorer</title>
|
||||
<meta name="description" content="Triangles address {data.address} - balance, transactions, and QR code" />
|
||||
</svelte:head>
|
||||
|
||||
<div class="mb-6">
|
||||
<h1 class="text-2xl font-bold text-white">Address</h1>
|
||||
<p class="text-tri-accent text-sm font-mono mt-1 break-all">{data.address}</p>
|
||||
</div>
|
||||
|
||||
{#if data.indexError}
|
||||
<div class="bg-tri-yellow/10 border border-tri-yellow/30 rounded-lg p-4 text-tri-yellow text-sm">
|
||||
Address index is not enabled on this node. Start the daemon with <code class="bg-tri-surface px-1 rounded">-addressindex=1</code> to enable address lookups.
|
||||
<div class="mb-6">
|
||||
<h1 class="text-3xl font-bold text-white mb-3">Address Details</h1>
|
||||
<div class="bg-tri-yellow/10 border border-tri-yellow/30 rounded-lg p-4 text-tri-yellow text-sm">
|
||||
Address index is not enabled on this node. Start the daemon with <code class="bg-tri-surface px-1 rounded">-addressindex=1</code> to enable address lookups.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Still show address and QR even if index disabled -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-6">
|
||||
<div class="text-center">
|
||||
<div class="inline-block mb-4">
|
||||
<QRCode data={data.address} size={256} />
|
||||
</div>
|
||||
<div class="font-mono text-sm text-tri-text break-all mb-3">{data.address}</div>
|
||||
<button
|
||||
onclick={copyAddress}
|
||||
class="px-4 py-2 bg-tri-accent hover:bg-tri-accent-light text-white rounded transition-colors text-sm font-medium"
|
||||
>
|
||||
{copied ? '✓ Copied!' : 'Copy Address'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Balance -->
|
||||
{#if data.balance}
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-6 mb-6">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Balance</div>
|
||||
<div class="text-3xl font-bold text-white">
|
||||
{formatAmount(data.balance.balance / 100000000)} <span class="text-tri-muted text-lg">TRI</span>
|
||||
</div>
|
||||
<div class="text-tri-muted text-sm mt-1">
|
||||
Total received: {formatAmount(data.balance.received / 100000000)} TRI
|
||||
<!-- Header -->
|
||||
<div class="mb-6">
|
||||
<h1 class="text-3xl font-bold text-white mb-2">Triangles Address</h1>
|
||||
<p class="text-tri-muted text-sm">View balance, transactions, and QR code</p>
|
||||
</div>
|
||||
|
||||
<!-- Main Grid: QR + Balance Info -->
|
||||
<div class="grid md:grid-cols-3 gap-6 mb-6">
|
||||
<!-- QR Code Card -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-6">
|
||||
<div class="text-center">
|
||||
<h2 class="text-white font-semibold mb-4">QR Code</h2>
|
||||
<div class="inline-block mb-4">
|
||||
<QRCode data={data.address} size={200} />
|
||||
</div>
|
||||
<p class="text-tri-muted text-xs mb-3">Scan to send TRI to this address</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Address & Balance Info -->
|
||||
<div class="md:col-span-2 space-y-4">
|
||||
<!-- Address Display -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-6">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Address</div>
|
||||
<div class="font-mono text-sm text-tri-text break-all mb-3">{data.address}</div>
|
||||
<button
|
||||
onclick={copyAddress}
|
||||
class="px-4 py-2 bg-tri-accent hover:bg-tri-accent-light text-white rounded transition-colors text-sm font-medium"
|
||||
>
|
||||
{copied ? '✓ Copied!' : 'Copy Address'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Balance Stats -->
|
||||
{#if data.balance}
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Balance</div>
|
||||
<div class="text-2xl font-bold text-white">
|
||||
{formatAmount(data.balance.balance / 100000000)}
|
||||
</div>
|
||||
<div class="text-tri-muted text-xs mt-0.5">TRI</div>
|
||||
</div>
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Received</div>
|
||||
<div class="text-2xl font-bold text-tri-green">
|
||||
{formatAmount(data.balance.received / 100000000)}
|
||||
</div>
|
||||
<div class="text-tri-muted text-xs mt-0.5">TRI</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-6">
|
||||
<div class="text-tri-muted text-center">Balance information unavailable</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Additional Stats -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Transactions</div>
|
||||
<div class="text-2xl font-bold text-white">{formatNumber(data.totalTxs)}</div>
|
||||
</div>
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Unspent Outputs</div>
|
||||
<div class="text-2xl font-bold text-white">{formatNumber(data.utxos.length)}</div>
|
||||
</div>
|
||||
{#if data.balance}
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Sent</div>
|
||||
<div class="text-xl font-bold text-tri-yellow">
|
||||
{formatAmount((data.balance.received - data.balance.balance) / 100000000)}
|
||||
</div>
|
||||
<div class="text-tri-muted text-xs mt-0.5">TRI</div>
|
||||
</div>
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Net Activity</div>
|
||||
<div class="text-xl font-bold text-tri-accent">
|
||||
{formatAmount(data.balance.balance / 100000000)}
|
||||
</div>
|
||||
<div class="text-tri-muted text-xs mt-0.5">TRI</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- UTXOs -->
|
||||
{#if data.utxos.length > 0}
|
||||
@@ -50,13 +149,15 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each data.utxos as utxo}
|
||||
<tr class="border-b border-tri-border/50">
|
||||
<tr class="border-b border-tri-border/50 hover:bg-tri-surface/50 transition-colors">
|
||||
<td class="py-2.5 px-3 font-mono text-xs">
|
||||
<a href="/tx/{utxo.txid}" class="text-tri-accent hover:text-tri-accent-light">{truncateHash(utxo.txid, 10)}</a>
|
||||
</td>
|
||||
<td class="py-2.5 px-3 text-center">{utxo.outputIndex}</td>
|
||||
<td class="py-2.5 px-3 text-right font-mono text-tri-green">{formatAmount(utxo.satoshis / 100000000)} TRI</td>
|
||||
<td class="py-2.5 px-3 text-right">{utxo.height}</td>
|
||||
<td class="py-2.5 px-3 text-right">
|
||||
<a href="/blocks/{utxo.height}" class="text-tri-accent hover:text-tri-accent-light">{utxo.height}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
@@ -68,13 +169,13 @@
|
||||
<!-- Transaction History -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg overflow-hidden">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Transactions ({data.totalTxs})</h2>
|
||||
<h2 class="text-white font-semibold">Transaction History ({formatNumber(data.totalTxs)})</h2>
|
||||
</div>
|
||||
{#if data.txs.length > 0}
|
||||
<TxTable txs={data.txs} />
|
||||
{#if data.totalTxs > 50}
|
||||
<div class="px-4 py-3 text-center text-tri-muted text-sm border-t border-tri-border">
|
||||
Showing 50 of {data.totalTxs} transactions
|
||||
Showing 50 of {formatNumber(data.totalTxs)} transactions
|
||||
</div>
|
||||
{/if}
|
||||
{:else}
|
||||
|
||||
@@ -1,88 +1,299 @@
|
||||
<script lang="ts">
|
||||
import TxTable from '$lib/components/TxTable.svelte';
|
||||
import { formatTimestamp, formatDifficulty, blockType, truncateHash } from '$lib/utils';
|
||||
import { formatTimestamp, formatDifficulty, blockType, truncateHash, formatNumber, formatAmount, timeAgo } from '$lib/utils';
|
||||
|
||||
let { data } = $props();
|
||||
const block = data.block;
|
||||
const addresses = data.addresses || [];
|
||||
|
||||
const fields: [string, string][] = [
|
||||
['Height', String(block.height)],
|
||||
['Confirmations', String(block.confirmations)],
|
||||
['Timestamp', formatTimestamp(block.time)],
|
||||
['Type', blockType(block.flags)],
|
||||
['Difficulty', formatDifficulty(block.difficulty)],
|
||||
['Transactions', String(block.tx.length)],
|
||||
['Merkle Root', truncateHash(block.merkleroot, 16)],
|
||||
['Nonce', String(block.nonce)],
|
||||
['Bits', block.bits],
|
||||
['Size', block.size ? `${block.size} bytes` : 'N/A'],
|
||||
['Mint', String(block.mint)],
|
||||
['Flags', block.flags]
|
||||
];
|
||||
// Calculate block reward from transactions
|
||||
const blockReward = block.mint || 0;
|
||||
|
||||
// Block age
|
||||
const blockAge = timeAgo(block.time);
|
||||
const blockDate = formatTimestamp(block.time);
|
||||
|
||||
// Transaction summary
|
||||
const txCount = block.tx.length;
|
||||
const coinbaseTx = data.txs?.find((tx: any) => tx.vin?.[0]?.coinbase);
|
||||
|
||||
// PoS specific data
|
||||
const isPoS = block.flags?.includes('proof-of-stake');
|
||||
const isPoW = block.flags?.includes('proof-of-work');
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Block {block.height} - Triangles Explorer</title>
|
||||
<meta name="description" content="Triangles block {block.height} details: {txCount} transactions, {blockType(block.flags)} block" />
|
||||
</svelte:head>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-white">Block {block.height}</h1>
|
||||
<p class="text-tri-muted text-xs font-mono mt-1 break-all">{block.hash}</p>
|
||||
<!-- Header with navigation -->
|
||||
<div class="mb-6">
|
||||
<div class="flex items-start justify-between mb-3">
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<h1 class="text-3xl font-bold text-white">Block #{formatNumber(block.height)}</h1>
|
||||
<span class="inline-block px-3 py-1 rounded-full text-sm font-medium {isPoS ? 'bg-tri-green/20 text-tri-green border border-tri-green/30' : 'bg-tri-yellow/20 text-tri-yellow border border-tri-yellow/30'}">
|
||||
{blockType(block.flags)}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-tri-muted text-sm mb-1">
|
||||
{blockAge} • {blockDate}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2 shrink-0 ml-4">
|
||||
{#if block.previousblockhash}
|
||||
<a href="/block/{block.previousblockhash}"
|
||||
class="bg-tri-surface border border-tri-border text-tri-text px-4 py-2 rounded hover:border-tri-accent hover:text-tri-accent transition-colors flex items-center gap-1">
|
||||
<span>←</span>
|
||||
<span class="hidden sm:inline">Previous</span>
|
||||
</a>
|
||||
{/if}
|
||||
{#if block.nextblockhash}
|
||||
<a href="/block/{block.nextblockhash}"
|
||||
class="bg-tri-surface border border-tri-border text-tri-text px-4 py-2 rounded hover:border-tri-accent hover:text-tri-accent transition-colors flex items-center gap-1">
|
||||
<span class="hidden sm:inline">Next</span>
|
||||
<span>→</span>
|
||||
</a>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2 shrink-0">
|
||||
{#if block.previousblockhash}
|
||||
<a href="/block/{block.previousblockhash}" class="bg-tri-surface border border-tri-border text-tri-text px-3 py-1.5 rounded text-sm hover:border-tri-accent transition-colors">← Prev</a>
|
||||
{/if}
|
||||
{#if block.nextblockhash}
|
||||
<a href="/block/{block.nextblockhash}" class="bg-tri-surface border border-tri-border text-tri-text px-3 py-1.5 rounded text-sm hover:border-tri-accent transition-colors">Next →</a>
|
||||
{/if}
|
||||
|
||||
<!-- Block Hash -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Block Hash</div>
|
||||
<div class="font-mono text-sm text-tri-text break-all">{block.hash}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Block Info -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg mb-6">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Block Details</h2>
|
||||
<!-- Stats Grid -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Confirmations</div>
|
||||
<div class="text-2xl font-bold text-white">{formatNumber(block.confirmations)}</div>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-px bg-tri-border">
|
||||
{#each fields as [label, value]}
|
||||
<div class="bg-tri-surface px-4 py-3">
|
||||
<span class="text-tri-muted text-xs uppercase tracking-wider">{label}</span>
|
||||
<div class="text-tri-text text-sm mt-0.5 font-mono break-all">{value}</div>
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Transactions</div>
|
||||
<div class="text-2xl font-bold text-white">{txCount}</div>
|
||||
</div>
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Block Reward</div>
|
||||
<div class="text-2xl font-bold text-tri-accent">{formatAmount(blockReward)} <span class="text-base text-tri-muted">TRI</span></div>
|
||||
</div>
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg p-4">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Size</div>
|
||||
<div class="text-2xl font-bold text-white">{formatNumber(block.size || 0)} <span class="text-base text-tri-muted">bytes</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Main Details Grid -->
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-6">
|
||||
<!-- Left Column: Block Information -->
|
||||
<div class="space-y-6">
|
||||
<!-- Basic Info -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Block Information</h2>
|
||||
</div>
|
||||
{/each}
|
||||
<div class="divide-y divide-tri-border">
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Height</div>
|
||||
<div class="text-tri-text font-mono">{formatNumber(block.height)}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Timestamp</div>
|
||||
<div class="text-tri-text">{blockDate}</div>
|
||||
<div class="text-tri-muted text-xs mt-0.5">{blockAge}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Received Time</div>
|
||||
<div class="text-tri-text font-mono">{block.time}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Block Type</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="inline-block px-2 py-1 rounded text-xs font-medium {isPoS ? 'bg-tri-green/20 text-tri-green' : 'bg-tri-yellow/20 text-tri-yellow'}">
|
||||
{blockType(block.flags)}
|
||||
</span>
|
||||
{#if isPoS}
|
||||
<span class="text-tri-muted text-xs">(Stake Proof)</span>
|
||||
{:else if isPoW}
|
||||
<span class="text-tri-muted text-xs">(Work Proof)</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Difficulty</div>
|
||||
<div class="text-tri-text font-mono">{formatDifficulty(block.difficulty)}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Block Reward</div>
|
||||
<div class="text-tri-accent font-semibold">{formatAmount(blockReward)} TRI</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Technical Details -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Technical Details</h2>
|
||||
</div>
|
||||
<div class="divide-y divide-tri-border">
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Version</div>
|
||||
<div class="text-tri-text font-mono">{block.version}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Size</div>
|
||||
<div class="text-tri-text font-mono">{formatNumber(block.size || 0)} bytes</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Nonce</div>
|
||||
<div class="text-tri-text font-mono">{block.nonce}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Bits</div>
|
||||
<div class="text-tri-text font-mono">{block.bits}</div>
|
||||
</div>
|
||||
{#if block.blocktrust}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Block Trust</div>
|
||||
<div class="text-tri-text font-mono">{block.blocktrust}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if block.chaintrust}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Chain Trust</div>
|
||||
<div class="text-tri-text font-mono">{block.chaintrust}</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: Hashes & PoS Info -->
|
||||
<div class="space-y-6">
|
||||
<!-- Hashes -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Cryptographic Hashes</h2>
|
||||
</div>
|
||||
<div class="divide-y divide-tri-border">
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Merkle Root</div>
|
||||
<div class="text-tri-text font-mono text-xs break-all">{block.merkleroot}</div>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Previous Block</div>
|
||||
{#if block.previousblockhash}
|
||||
<a href="/block/{block.previousblockhash}" class="text-tri-accent hover:text-tri-accent-light font-mono text-xs break-all">
|
||||
{block.previousblockhash}
|
||||
</a>
|
||||
{:else}
|
||||
<span class="text-tri-muted text-xs">Genesis Block</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Next Block</div>
|
||||
{#if block.nextblockhash}
|
||||
<a href="/block/{block.nextblockhash}" class="text-tri-accent hover:text-tri-accent-light font-mono text-xs break-all">
|
||||
{block.nextblockhash}
|
||||
</a>
|
||||
{:else}
|
||||
<span class="text-tri-muted text-xs">Latest Block</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PoS-specific Information -->
|
||||
{#if isPoS}
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold flex items-center gap-2">
|
||||
<span class="text-tri-green">●</span>
|
||||
Proof-of-Stake Details
|
||||
</h2>
|
||||
</div>
|
||||
<div class="divide-y divide-tri-border">
|
||||
{#if block.proofhash}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Proof Hash</div>
|
||||
<div class="text-tri-text font-mono text-xs break-all">{block.proofhash}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if block.modifier}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Stake Modifier</div>
|
||||
<div class="text-tri-text font-mono">{block.modifier}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if block.modifierchecksum}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Modifier Checksum</div>
|
||||
<div class="text-tri-text font-mono">{block.modifierchecksum}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if block.entropybit !== undefined}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-1">Entropy Bit</div>
|
||||
<div class="text-tri-text font-mono">{block.entropybit}</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if block.signature}
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-muted text-xs uppercase tracking-wider mb-2">Block Signature</div>
|
||||
<div class="text-tri-text font-mono text-xs break-all">{block.signature}</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Block Flags -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Flags</h2>
|
||||
</div>
|
||||
<div class="px-4 py-3">
|
||||
<div class="text-tri-text font-mono text-sm">{block.flags}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Addresses Involved -->
|
||||
{#if addresses.length > 0}
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg mb-6">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Addresses Involved ({addresses.length})</h2>
|
||||
</div>
|
||||
<div class="px-4 py-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each addresses as addr}
|
||||
<a
|
||||
href="/address/{addr}"
|
||||
class="inline-block font-mono text-xs px-3 py-1.5 rounded bg-tri-surface-dark border border-tri-border text-tri-text hover:text-tri-accent hover:border-tri-accent transition-colors"
|
||||
title={addr}
|
||||
>
|
||||
{addr}
|
||||
</a>
|
||||
{/each}
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg mb-6">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Addresses Involved ({addresses.length})</h2>
|
||||
</div>
|
||||
<div class="px-4 py-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{#each addresses as addr}
|
||||
<a
|
||||
href="/address/{addr}"
|
||||
class="inline-block font-mono text-xs px-3 py-1.5 rounded bg-tri-surface-dark border border-tri-border text-tri-text hover:text-tri-accent hover:border-tri-accent transition-colors"
|
||||
title={addr}
|
||||
>
|
||||
{addr}
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Transactions -->
|
||||
<div class="bg-tri-surface border border-tri-border rounded-lg overflow-hidden">
|
||||
<div class="px-4 py-3 border-b border-tri-border">
|
||||
<h2 class="text-white font-semibold">Transactions ({block.tx.length})</h2>
|
||||
<h2 class="text-white font-semibold">Transactions ({txCount})</h2>
|
||||
</div>
|
||||
<TxTable txs={data.txs} />
|
||||
{#if data.txs && data.txs.length > 0}
|
||||
<TxTable txs={data.txs} />
|
||||
{:else}
|
||||
<div class="px-4 py-8 text-center text-tri-muted">
|
||||
<p>Transaction data loading...</p>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user