kenshin-samourai
4 years ago
41 changed files with 2622 additions and 10564 deletions
@ -0,0 +1,17 @@ |
|||||
|
{ |
||||
|
// Use IntelliSense to learn about possible attributes. |
||||
|
// Hover to view descriptions of existing attributes. |
||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 |
||||
|
"version": "0.2.0", |
||||
|
"configurations": [ |
||||
|
{ |
||||
|
"type": "node", |
||||
|
"request": "launch", |
||||
|
"name": "Launch Program", |
||||
|
"skipFiles": [ |
||||
|
"<node_internals>/**" |
||||
|
], |
||||
|
"program": "${workspaceFolder}/accounts/index.js" |
||||
|
} |
||||
|
] |
||||
|
} |
@ -1,587 +0,0 @@ |
|||||
/*! |
|
||||
* Bootstrap v3.3.7 (http://getbootstrap.com) |
|
||||
* Copyright 2011-2016 Twitter, Inc. |
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) |
|
||||
*/ |
|
||||
.btn-default, |
|
||||
.btn-primary, |
|
||||
.btn-success, |
|
||||
.btn-info, |
|
||||
.btn-warning, |
|
||||
.btn-danger { |
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); |
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); |
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); |
|
||||
} |
|
||||
.btn-default:active, |
|
||||
.btn-primary:active, |
|
||||
.btn-success:active, |
|
||||
.btn-info:active, |
|
||||
.btn-warning:active, |
|
||||
.btn-danger:active, |
|
||||
.btn-default.active, |
|
||||
.btn-primary.active, |
|
||||
.btn-success.active, |
|
||||
.btn-info.active, |
|
||||
.btn-warning.active, |
|
||||
.btn-danger.active { |
|
||||
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); |
|
||||
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); |
|
||||
} |
|
||||
.btn-default.disabled, |
|
||||
.btn-primary.disabled, |
|
||||
.btn-success.disabled, |
|
||||
.btn-info.disabled, |
|
||||
.btn-warning.disabled, |
|
||||
.btn-danger.disabled, |
|
||||
.btn-default[disabled], |
|
||||
.btn-primary[disabled], |
|
||||
.btn-success[disabled], |
|
||||
.btn-info[disabled], |
|
||||
.btn-warning[disabled], |
|
||||
.btn-danger[disabled], |
|
||||
fieldset[disabled] .btn-default, |
|
||||
fieldset[disabled] .btn-primary, |
|
||||
fieldset[disabled] .btn-success, |
|
||||
fieldset[disabled] .btn-info, |
|
||||
fieldset[disabled] .btn-warning, |
|
||||
fieldset[disabled] .btn-danger { |
|
||||
-webkit-box-shadow: none; |
|
||||
box-shadow: none; |
|
||||
} |
|
||||
.btn-default .badge, |
|
||||
.btn-primary .badge, |
|
||||
.btn-success .badge, |
|
||||
.btn-info .badge, |
|
||||
.btn-warning .badge, |
|
||||
.btn-danger .badge { |
|
||||
text-shadow: none; |
|
||||
} |
|
||||
.btn:active, |
|
||||
.btn.active { |
|
||||
background-image: none; |
|
||||
} |
|
||||
.btn-default { |
|
||||
text-shadow: 0 1px 0 #fff; |
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); |
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); |
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #dbdbdb; |
|
||||
border-color: #ccc; |
|
||||
} |
|
||||
.btn-default:hover, |
|
||||
.btn-default:focus { |
|
||||
background-color: #e0e0e0; |
|
||||
background-position: 0 -15px; |
|
||||
} |
|
||||
.btn-default:active, |
|
||||
.btn-default.active { |
|
||||
background-color: #e0e0e0; |
|
||||
border-color: #dbdbdb; |
|
||||
} |
|
||||
.btn-default.disabled, |
|
||||
.btn-default[disabled], |
|
||||
fieldset[disabled] .btn-default, |
|
||||
.btn-default.disabled:hover, |
|
||||
.btn-default[disabled]:hover, |
|
||||
fieldset[disabled] .btn-default:hover, |
|
||||
.btn-default.disabled:focus, |
|
||||
.btn-default[disabled]:focus, |
|
||||
fieldset[disabled] .btn-default:focus, |
|
||||
.btn-default.disabled.focus, |
|
||||
.btn-default[disabled].focus, |
|
||||
fieldset[disabled] .btn-default.focus, |
|
||||
.btn-default.disabled:active, |
|
||||
.btn-default[disabled]:active, |
|
||||
fieldset[disabled] .btn-default:active, |
|
||||
.btn-default.disabled.active, |
|
||||
.btn-default[disabled].active, |
|
||||
fieldset[disabled] .btn-default.active { |
|
||||
background-color: #e0e0e0; |
|
||||
background-image: none; |
|
||||
} |
|
||||
.btn-primary { |
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%); |
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88)); |
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #245580; |
|
||||
} |
|
||||
.btn-primary:hover, |
|
||||
.btn-primary:focus { |
|
||||
background-color: #265a88; |
|
||||
background-position: 0 -15px; |
|
||||
} |
|
||||
.btn-primary:active, |
|
||||
.btn-primary.active { |
|
||||
background-color: #265a88; |
|
||||
border-color: #245580; |
|
||||
} |
|
||||
.btn-primary.disabled, |
|
||||
.btn-primary[disabled], |
|
||||
fieldset[disabled] .btn-primary, |
|
||||
.btn-primary.disabled:hover, |
|
||||
.btn-primary[disabled]:hover, |
|
||||
fieldset[disabled] .btn-primary:hover, |
|
||||
.btn-primary.disabled:focus, |
|
||||
.btn-primary[disabled]:focus, |
|
||||
fieldset[disabled] .btn-primary:focus, |
|
||||
.btn-primary.disabled.focus, |
|
||||
.btn-primary[disabled].focus, |
|
||||
fieldset[disabled] .btn-primary.focus, |
|
||||
.btn-primary.disabled:active, |
|
||||
.btn-primary[disabled]:active, |
|
||||
fieldset[disabled] .btn-primary:active, |
|
||||
.btn-primary.disabled.active, |
|
||||
.btn-primary[disabled].active, |
|
||||
fieldset[disabled] .btn-primary.active { |
|
||||
background-color: #265a88; |
|
||||
background-image: none; |
|
||||
} |
|
||||
.btn-success { |
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); |
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); |
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #3e8f3e; |
|
||||
} |
|
||||
.btn-success:hover, |
|
||||
.btn-success:focus { |
|
||||
background-color: #419641; |
|
||||
background-position: 0 -15px; |
|
||||
} |
|
||||
.btn-success:active, |
|
||||
.btn-success.active { |
|
||||
background-color: #419641; |
|
||||
border-color: #3e8f3e; |
|
||||
} |
|
||||
.btn-success.disabled, |
|
||||
.btn-success[disabled], |
|
||||
fieldset[disabled] .btn-success, |
|
||||
.btn-success.disabled:hover, |
|
||||
.btn-success[disabled]:hover, |
|
||||
fieldset[disabled] .btn-success:hover, |
|
||||
.btn-success.disabled:focus, |
|
||||
.btn-success[disabled]:focus, |
|
||||
fieldset[disabled] .btn-success:focus, |
|
||||
.btn-success.disabled.focus, |
|
||||
.btn-success[disabled].focus, |
|
||||
fieldset[disabled] .btn-success.focus, |
|
||||
.btn-success.disabled:active, |
|
||||
.btn-success[disabled]:active, |
|
||||
fieldset[disabled] .btn-success:active, |
|
||||
.btn-success.disabled.active, |
|
||||
.btn-success[disabled].active, |
|
||||
fieldset[disabled] .btn-success.active { |
|
||||
background-color: #419641; |
|
||||
background-image: none; |
|
||||
} |
|
||||
.btn-info { |
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); |
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); |
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #28a4c9; |
|
||||
} |
|
||||
.btn-info:hover, |
|
||||
.btn-info:focus { |
|
||||
background-color: #2aabd2; |
|
||||
background-position: 0 -15px; |
|
||||
} |
|
||||
.btn-info:active, |
|
||||
.btn-info.active { |
|
||||
background-color: #2aabd2; |
|
||||
border-color: #28a4c9; |
|
||||
} |
|
||||
.btn-info.disabled, |
|
||||
.btn-info[disabled], |
|
||||
fieldset[disabled] .btn-info, |
|
||||
.btn-info.disabled:hover, |
|
||||
.btn-info[disabled]:hover, |
|
||||
fieldset[disabled] .btn-info:hover, |
|
||||
.btn-info.disabled:focus, |
|
||||
.btn-info[disabled]:focus, |
|
||||
fieldset[disabled] .btn-info:focus, |
|
||||
.btn-info.disabled.focus, |
|
||||
.btn-info[disabled].focus, |
|
||||
fieldset[disabled] .btn-info.focus, |
|
||||
.btn-info.disabled:active, |
|
||||
.btn-info[disabled]:active, |
|
||||
fieldset[disabled] .btn-info:active, |
|
||||
.btn-info.disabled.active, |
|
||||
.btn-info[disabled].active, |
|
||||
fieldset[disabled] .btn-info.active { |
|
||||
background-color: #2aabd2; |
|
||||
background-image: none; |
|
||||
} |
|
||||
.btn-warning { |
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); |
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); |
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #e38d13; |
|
||||
} |
|
||||
.btn-warning:hover, |
|
||||
.btn-warning:focus { |
|
||||
background-color: #eb9316; |
|
||||
background-position: 0 -15px; |
|
||||
} |
|
||||
.btn-warning:active, |
|
||||
.btn-warning.active { |
|
||||
background-color: #eb9316; |
|
||||
border-color: #e38d13; |
|
||||
} |
|
||||
.btn-warning.disabled, |
|
||||
.btn-warning[disabled], |
|
||||
fieldset[disabled] .btn-warning, |
|
||||
.btn-warning.disabled:hover, |
|
||||
.btn-warning[disabled]:hover, |
|
||||
fieldset[disabled] .btn-warning:hover, |
|
||||
.btn-warning.disabled:focus, |
|
||||
.btn-warning[disabled]:focus, |
|
||||
fieldset[disabled] .btn-warning:focus, |
|
||||
.btn-warning.disabled.focus, |
|
||||
.btn-warning[disabled].focus, |
|
||||
fieldset[disabled] .btn-warning.focus, |
|
||||
.btn-warning.disabled:active, |
|
||||
.btn-warning[disabled]:active, |
|
||||
fieldset[disabled] .btn-warning:active, |
|
||||
.btn-warning.disabled.active, |
|
||||
.btn-warning[disabled].active, |
|
||||
fieldset[disabled] .btn-warning.active { |
|
||||
background-color: #eb9316; |
|
||||
background-image: none; |
|
||||
} |
|
||||
.btn-danger { |
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); |
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); |
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #b92c28; |
|
||||
} |
|
||||
.btn-danger:hover, |
|
||||
.btn-danger:focus { |
|
||||
background-color: #c12e2a; |
|
||||
background-position: 0 -15px; |
|
||||
} |
|
||||
.btn-danger:active, |
|
||||
.btn-danger.active { |
|
||||
background-color: #c12e2a; |
|
||||
border-color: #b92c28; |
|
||||
} |
|
||||
.btn-danger.disabled, |
|
||||
.btn-danger[disabled], |
|
||||
fieldset[disabled] .btn-danger, |
|
||||
.btn-danger.disabled:hover, |
|
||||
.btn-danger[disabled]:hover, |
|
||||
fieldset[disabled] .btn-danger:hover, |
|
||||
.btn-danger.disabled:focus, |
|
||||
.btn-danger[disabled]:focus, |
|
||||
fieldset[disabled] .btn-danger:focus, |
|
||||
.btn-danger.disabled.focus, |
|
||||
.btn-danger[disabled].focus, |
|
||||
fieldset[disabled] .btn-danger.focus, |
|
||||
.btn-danger.disabled:active, |
|
||||
.btn-danger[disabled]:active, |
|
||||
fieldset[disabled] .btn-danger:active, |
|
||||
.btn-danger.disabled.active, |
|
||||
.btn-danger[disabled].active, |
|
||||
fieldset[disabled] .btn-danger.active { |
|
||||
background-color: #c12e2a; |
|
||||
background-image: none; |
|
||||
} |
|
||||
.thumbnail, |
|
||||
.img-thumbnail { |
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|
||||
} |
|
||||
.dropdown-menu > li > a:hover, |
|
||||
.dropdown-menu > li > a:focus { |
|
||||
background-color: #e8e8e8; |
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); |
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.dropdown-menu > .active > a, |
|
||||
.dropdown-menu > .active > a:hover, |
|
||||
.dropdown-menu > .active > a:focus { |
|
||||
background-color: #2e6da4; |
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); |
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.navbar-default { |
|
||||
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); |
|
||||
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); |
|
||||
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-radius: 4px; |
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); |
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); |
|
||||
} |
|
||||
.navbar-default .navbar-nav > .open > a, |
|
||||
.navbar-default .navbar-nav > .active > a { |
|
||||
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); |
|
||||
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2)); |
|
||||
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); |
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); |
|
||||
} |
|
||||
.navbar-brand, |
|
||||
.navbar-nav > li > a { |
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .25); |
|
||||
} |
|
||||
.navbar-inverse { |
|
||||
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); |
|
||||
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); |
|
||||
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||
background-repeat: repeat-x; |
|
||||
border-radius: 4px; |
|
||||
} |
|
||||
.navbar-inverse .navbar-nav > .open > a, |
|
||||
.navbar-inverse .navbar-nav > .active > a { |
|
||||
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%); |
|
||||
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f)); |
|
||||
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); |
|
||||
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); |
|
||||
} |
|
||||
.navbar-inverse .navbar-brand, |
|
||||
.navbar-inverse .navbar-nav > li > a { |
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); |
|
||||
} |
|
||||
.navbar-static-top, |
|
||||
.navbar-fixed-top, |
|
||||
.navbar-fixed-bottom { |
|
||||
border-radius: 0; |
|
||||
} |
|
||||
@media (max-width: 767px) { |
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a, |
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover, |
|
||||
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus { |
|
||||
color: #fff; |
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); |
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
} |
|
||||
.alert { |
|
||||
text-shadow: 0 1px 0 rgba(255, 255, 255, .2); |
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); |
|
||||
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); |
|
||||
} |
|
||||
.alert-success { |
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); |
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); |
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #b2dba1; |
|
||||
} |
|
||||
.alert-info { |
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); |
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); |
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #9acfea; |
|
||||
} |
|
||||
.alert-warning { |
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); |
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); |
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #f5e79e; |
|
||||
} |
|
||||
.alert-danger { |
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); |
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); |
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #dca7a7; |
|
||||
} |
|
||||
.progress { |
|
||||
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); |
|
||||
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); |
|
||||
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.progress-bar { |
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%); |
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090)); |
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.progress-bar-success { |
|
||||
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); |
|
||||
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); |
|
||||
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.progress-bar-info { |
|
||||
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); |
|
||||
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); |
|
||||
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.progress-bar-warning { |
|
||||
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); |
|
||||
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); |
|
||||
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.progress-bar-danger { |
|
||||
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); |
|
||||
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); |
|
||||
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.progress-bar-striped { |
|
||||
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); |
|
||||
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); |
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); |
|
||||
} |
|
||||
.list-group { |
|
||||
border-radius: 4px; |
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .075); |
|
||||
} |
|
||||
.list-group-item.active, |
|
||||
.list-group-item.active:hover, |
|
||||
.list-group-item.active:focus { |
|
||||
text-shadow: 0 -1px 0 #286090; |
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%); |
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a)); |
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #2b669a; |
|
||||
} |
|
||||
.list-group-item.active .badge, |
|
||||
.list-group-item.active:hover .badge, |
|
||||
.list-group-item.active:focus .badge { |
|
||||
text-shadow: none; |
|
||||
} |
|
||||
.panel { |
|
||||
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); |
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .05); |
|
||||
} |
|
||||
.panel-default > .panel-heading { |
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|
||||
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); |
|
||||
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.panel-primary > .panel-heading { |
|
||||
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|
||||
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4)); |
|
||||
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.panel-success > .panel-heading { |
|
||||
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); |
|
||||
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); |
|
||||
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.panel-info > .panel-heading { |
|
||||
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); |
|
||||
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); |
|
||||
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.panel-warning > .panel-heading { |
|
||||
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); |
|
||||
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); |
|
||||
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.panel-danger > .panel-heading { |
|
||||
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); |
|
||||
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); |
|
||||
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
} |
|
||||
.well { |
|
||||
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); |
|
||||
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); |
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); |
|
||||
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); |
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); |
|
||||
background-repeat: repeat-x; |
|
||||
border-color: #dcdcdc; |
|
||||
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); |
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); |
|
||||
} |
|
||||
/*# sourceMappingURL=bootstrap-theme.css.map */ |
|
File diff suppressed because it is too large
@ -0,0 +1,147 @@ |
|||||
|
<div id="addresses-tool"> |
||||
|
<h1>ADDRESSES TOOL</h1> |
||||
|
|
||||
|
<div class="box-context">Check if an address is tracked by your Dojo. Import and track a new address. Rescan the full history of an address.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<!-- ADDRESS SEARCH FORM --> |
||||
|
<div id="addresses-tool-search-form" class="fullwidth box"> |
||||
|
<div class="box-body"> |
||||
|
<span>Check if </span> |
||||
|
<input id="address" type="text" placeholder="address"> |
||||
|
<span> is tracked by your Dojo </span> |
||||
|
<button id="btn-address-search-go" class="btn btn-success" type="button">GO</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- ADDRESS IMPORT --> |
||||
|
<div id="addresses-tool-import" class="fullwidth box"> |
||||
|
<div class="box-body"> |
||||
|
<div> |
||||
|
<span>This address isn't tracked by your Dojo.</span> |
||||
|
</div> |
||||
|
<div class="spacer20"></div> |
||||
|
<div> |
||||
|
<span>Do you want to import </span> |
||||
|
<span id="import-address"></span> |
||||
|
<span> and track its activity?</span> |
||||
|
<button id="btn-address-import-go" class="btn btn-success" type="button">IMPORT</button> |
||||
|
<button id="btn-address-import-cancel" class="btn btn-success" type="button">CANCEL</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- ADDRESS DETAILS --> |
||||
|
<div id="addresses-tool-details"> |
||||
|
<div id="addresses-tool-header" class="row box-main"> |
||||
|
<div class="fullwidth box"> |
||||
|
<div id="addr-value" class="box-body center"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="addresses-tool-actions" class="row box-main"> |
||||
|
<div class="center"> |
||||
|
<button id="btn-address-details-rescan" class="btn btn-success" type="button">RESCAN THIS ADDRESS</button> |
||||
|
<button id="btn-address-details-reset" class="btn btn-success" type="button">SEARCH ANOTHER ADDRESS</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="addresses-rescans-actions" class="row box-main"> |
||||
|
<div class="center"> |
||||
|
<span>Do you want to rescan this address?</span> |
||||
|
<button id="btn-address-rescan-go" class="btn btn-success" type="button">RESCAN</button> |
||||
|
<button id="btn-address-rescan-cancel" class="btn btn-success" type="button">CANCEL</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="addresses-tool-details-row1" class="row box-main"> |
||||
|
<!-- GENERAL INFO --> |
||||
|
<div id="box-general" class="fullwidth box"> |
||||
|
<div class="box-header">GENERAL INFO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Balance</td> |
||||
|
<td class="table-value" id="addr-balance"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of Txs</td> |
||||
|
<td class="table-value" id="addr-nb-txs"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of UTXOs</td> |
||||
|
<td class="table-value" id="addr-nb-utxos"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Segwit</td> |
||||
|
<td class="table-value" id="addr-segwit"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Address Type</td> |
||||
|
<td class="table-value" id="addr-type"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="addresses-tool-details-row2" class="row box-main"> |
||||
|
<!-- HD ADDRESS INFO --> |
||||
|
<div id="box-hd" class="fullwidth box"> |
||||
|
<div class="box-header">DERIVATION INFO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Derivation path</td> |
||||
|
<td class="table-value" id="addr-deriv-path"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label" colspan="2">Derived from</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td id="addr-xpub" colspan="2"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="addresses-tool-details-row3" class="row box-main"> |
||||
|
<!-- TXS LIST --> |
||||
|
<div id="box-txs" class="halfwidth-left box"> |
||||
|
<div class="box-header">MOST RECENT TRANSACTIONS</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table id="addr-table-list-txs"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td></td> |
||||
|
<td></td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- UTXOS LIST --> |
||||
|
<div id="box-utxos" class="halfwidth-right box"> |
||||
|
<div class="box-header">UNSPENT TRANSACTION OUTPUTS</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table id="addr-table-list-utxos"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td></td> |
||||
|
<td></td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script include-js="addresses-tools/addresses-tools.js"></script> |
@ -0,0 +1,228 @@ |
|||||
|
const screenAddressesToolsScript = { |
||||
|
|
||||
|
explorerInfo: null, |
||||
|
currentAddress: null, |
||||
|
|
||||
|
initPage: function() { |
||||
|
this.getExplorerInfo() |
||||
|
// Sets the event handlers
|
||||
|
$('#btn-address-search-go').click(() => {this.searchAddress()}) |
||||
|
$('#btn-address-details-reset').click(() => {this.showSearchForm()}) |
||||
|
$('#btn-address-details-rescan').click(() => {this.showRescanForm()}) |
||||
|
$('#btn-address-rescan-go').click(() => {this.rescanAddress()}) |
||||
|
$('#btn-address-rescan-cancel').click(() => {this.hideRescanForm()}) |
||||
|
$('#btn-address-import-go').click(() => {this.importAddress()}) |
||||
|
$('#btn-address-import-cancel').click(() => {this.showSearchForm()}) |
||||
|
$('#addresses-tool').keyup(evt => { |
||||
|
if (evt.keyCode === 13) { |
||||
|
this.searchAddress() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
this.hideRescanForm() |
||||
|
this.showSearchForm() |
||||
|
$("#address").focus() |
||||
|
}, |
||||
|
|
||||
|
getExplorerInfo: function() { |
||||
|
lib_api.getExplorerPairingInfo().then(explorerInfo => { |
||||
|
this.explorerInfo = explorerInfo |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
searchAddress: function() { |
||||
|
lib_msg.displayMessage('Search in progress...'); |
||||
|
const address = $('#address').val() |
||||
|
this.currentAddress = address |
||||
|
return this._searchAddress(address).then(() => { |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
_searchAddress: function(address) { |
||||
|
return lib_api.getAddressInfo(address).then(addressInfo => { |
||||
|
if (addressInfo && addressInfo['tracked']) { |
||||
|
this.setAddressDetails(addressInfo) |
||||
|
this.showAddressDetails() |
||||
|
const jsonData = {'active': address} |
||||
|
return lib_api.getWallet(jsonData).then(walletInfo => { |
||||
|
// Display the txs
|
||||
|
const txs = walletInfo['txs'] |
||||
|
for (let tx of txs) |
||||
|
this.setTxDetails(tx) |
||||
|
// Display the UTXOs
|
||||
|
const utxos = walletInfo['unspent_outputs'].sort((a,b) => { |
||||
|
return a['confirmations'] - b['confirmations'] |
||||
|
}) |
||||
|
$('#addr-nb-utxos').text(utxos.length) |
||||
|
for (let utxo of utxos) |
||||
|
this.setUtxoDetails(utxo) |
||||
|
}) |
||||
|
} else { |
||||
|
lib_msg.displayErrors('address not found') |
||||
|
this.showImportForm(false) |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
throw e |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
importAddress: function() { |
||||
|
lib_msg.displayMessage('Processing address import...'); |
||||
|
const jsonData = {'active': this.currentAddress} |
||||
|
return lib_api.getWallet(jsonData) |
||||
|
.then(result => { |
||||
|
this._searchAddress(this.currentAddress).then(() => { |
||||
|
lib_msg.displayInfo('Import complete') |
||||
|
}) |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
rescanAddress: function() { |
||||
|
lib_msg.displayMessage('Processing address rescan...'); |
||||
|
return lib_api.getAddressRescan(this.currentAddress) |
||||
|
.then(result => { |
||||
|
this.hideRescanForm() |
||||
|
this._searchAddress(this.currentAddress).then(() => { |
||||
|
lib_msg.displayInfo('Rescan complete') |
||||
|
}) |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
setAddressDetails: function(addressInfo) { |
||||
|
$('tr.tx-row').remove() |
||||
|
$('tr.utxo-row').remove() |
||||
|
|
||||
|
$('#addr-value').text(this.currentAddress) |
||||
|
$('#addr-nb-txs').text(addressInfo['n_tx']) |
||||
|
$('#addr-nb-utxos').text('-') |
||||
|
|
||||
|
const balance = parseInt(addressInfo['balance']) / 100000000 |
||||
|
$('#addr-balance').text(`${balance} BTC`) |
||||
|
|
||||
|
const addrType = (addressInfo['type'] == 'hd') ? 'Derived from an XPUB' : 'Loose address' |
||||
|
$('#addr-type').text(addrType) |
||||
|
|
||||
|
if (addressInfo['segwit']) { |
||||
|
$('#addr-segwit').html('✓') |
||||
|
$('#addr-segwit').css('color', '#76d776') |
||||
|
} else { |
||||
|
$('#addr-segwit').text('-') |
||||
|
$('#addr-segwit').css('color', '#f77c7c') |
||||
|
} |
||||
|
|
||||
|
if (addressInfo['type'] == 'hd') { |
||||
|
$('#addr-xpub').text(addressInfo['xpub']) |
||||
|
$('#addr-deriv-path').text(addressInfo['path']) |
||||
|
$('#addresses-tool-details-row2').show() |
||||
|
} else { |
||||
|
$('#addresses-tool-details-row2').hide() |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
setTxDetails: function(tx) { |
||||
|
const txid = tx['hash'] |
||||
|
const txidDisplay = `${txid.substring(0,50)}...` |
||||
|
const amount = parseInt(tx['result']) / 100000000 |
||||
|
const amountLabel = amount < 0 ? amount : `+${amount}` |
||||
|
const amountStyle = amount < 0 ? 'amount-sent' : 'amount-received' |
||||
|
const date = lib_fmt.unixTsToLocaleString(tx['time']) |
||||
|
const txUrl = lib_cmn.getExplorerTxUrl(txid, this.explorerInfo) |
||||
|
|
||||
|
const newRow = `<tr class="tx-row"><td colspan="2"> </td></tr>
|
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label" colspan="2"> |
||||
|
<a href="${txUrl}" target="_blank">${txidDisplay}</a> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label">Amount</td> |
||||
|
<td class="table-value ${amountStyle}">${amountLabel} BTC</td> |
||||
|
</tr> |
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label">Block height</td> |
||||
|
<td class="table-value">${tx['block_height']}</td> |
||||
|
</tr> |
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label">Date</td> |
||||
|
<td class="table-value">${date}</td> |
||||
|
</tr>` |
||||
|
|
||||
|
$('#addr-table-list-txs tr:last').after(newRow) |
||||
|
}, |
||||
|
|
||||
|
setUtxoDetails: function(utxo) { |
||||
|
const txid = utxo['tx_hash'] |
||||
|
const txidVout = `${txid.substring(0,50)}...:${utxo['tx_output_n']}` |
||||
|
const amount = parseInt(utxo['value']) / 100000000 |
||||
|
const txUrl = lib_cmn.getExplorerTxUrl(txid, this.explorerInfo) |
||||
|
|
||||
|
const newRow = `<tr class="utxo-row"><td colspan="2"> </td></tr>
|
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label" colspan="2"> |
||||
|
<a href="${txUrl}" target="_blank">${txidVout}</a> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label">Amount</td> |
||||
|
<td class="table-value">${amount} BTC</td> |
||||
|
</tr> |
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label">Address</td> |
||||
|
<td class="table-value">${utxo['addr']}</td> |
||||
|
</tr> |
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label">Confirmations</td> |
||||
|
<td class="table-value">${utxo['confirmations']}</td> |
||||
|
</tr>` |
||||
|
|
||||
|
$('#addr-table-list-utxos tr:last').after(newRow) |
||||
|
}, |
||||
|
|
||||
|
showSearchForm: function() { |
||||
|
$('#addresses-tool-details').hide() |
||||
|
$('#addresses-tool-import').hide() |
||||
|
$('#address').val('') |
||||
|
$('#addresses-tool-search-form').show() |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}, |
||||
|
|
||||
|
showImportForm: function() { |
||||
|
$('#addresses-tool-search-form').hide() |
||||
|
$('#addresses-tool-details').hide() |
||||
|
$('#import-address').text(this.currentAddress) |
||||
|
$('#addresses-tool-import').show() |
||||
|
}, |
||||
|
|
||||
|
showAddressDetails: function() { |
||||
|
$('#addresses-tool-search-form').hide() |
||||
|
$('#addresses-tool-import').hide() |
||||
|
$('#addresses-tool-details').show() |
||||
|
}, |
||||
|
|
||||
|
showRescanForm: function() { |
||||
|
$('#addresses-tool-actions').hide() |
||||
|
$('#addresses-rescans-actions').show() |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}, |
||||
|
|
||||
|
hideRescanForm: function() { |
||||
|
$('#addresses-rescans-actions').hide() |
||||
|
$('#addresses-tool-actions').show() |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-addresses-tools', screenAddressesToolsScript) |
@ -0,0 +1,22 @@ |
|||||
|
<div id="blocks-rescan"> |
||||
|
<h1>BLOCKS RESCAN</h1> |
||||
|
|
||||
|
<div class="box-context">Force the Tracker to rescan a range of blocks.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<div id="blocks-rescan-form" class="box fullwidth"> |
||||
|
<div class="box-body"> |
||||
|
<span>Rescan blocks between</span> |
||||
|
<input id="rescan-from-height" type="text" placeholder="height"> |
||||
|
<span> and </span> |
||||
|
<input id="rescan-to-height" type="text" placeholder="height"> |
||||
|
<button id="btn-rescan-go" |
||||
|
class="btn btn-success" |
||||
|
type="button">GO</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<script include-js="blocks-rescan/blocks-rescan.js"></script> |
@ -0,0 +1,45 @@ |
|||||
|
const screenBlocksRescanScript = { |
||||
|
|
||||
|
initPage: function() { |
||||
|
// Sets the event handlers
|
||||
|
$('#btn-rescan-go').click(() => { |
||||
|
this.processRescan() |
||||
|
}) |
||||
|
$('#blocks-rescan').keyup(evt => { |
||||
|
if (evt.keyCode === 13) { |
||||
|
this.processRescan() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
$("#rescan-from-height").focus() |
||||
|
}, |
||||
|
|
||||
|
processRescan: function() { |
||||
|
lib_msg.displayMessage('Processing...'); |
||||
|
|
||||
|
let fromHeight = $("#rescan-from-height").val() |
||||
|
let toHeight = $("#rescan-to-height").val() |
||||
|
fromHeight = parseInt(fromHeight) |
||||
|
toHeight = (toHeight) ? parseInt(toHeight) : fromHeight; |
||||
|
|
||||
|
lib_api.getBlocksRescan(fromHeight, toHeight).then(result => { |
||||
|
if (!result) |
||||
|
return |
||||
|
const fromHeightRes = result['fromHeight'] |
||||
|
const toHeightRes = result['toHeight'] |
||||
|
const msg = `successfully rescanned blocks between height ${fromHeightRes} and height ${toHeightRes}` |
||||
|
lib_msg.displayInfo(msg) |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}).then(() => { |
||||
|
$('#rescan-from-height').val('') |
||||
|
$('#rescan-to-height').val('') |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-blocks-rescan', screenBlocksRescanScript) |
@ -0,0 +1,152 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
|
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<title>DOJO // MAINTENANCE TOOL</title> |
||||
|
<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"> |
||||
|
<link rel="stylesheet" type="text/css" href="../css/bootstrap-theme.min.css"> |
||||
|
<link rel="stylesheet" type="text/css" href="../css/style.css"> |
||||
|
<script src="../lib/jquery-3.5.1.min.js"></script> |
||||
|
<script src="../lib/jquery.qrcode.min.js"></script> |
||||
|
<script src="../conf/index.js"></script> |
||||
|
<script src="../lib/common-script.js"></script> |
||||
|
<script src="../lib/api-wrapper.js"></script> |
||||
|
<script src="../lib/auth-utils.js"></script> |
||||
|
<script src="../lib/format-utils.js"></script> |
||||
|
<script src="../lib/messages.js"></script> |
||||
|
<script src="index.js"></script> |
||||
|
</head> |
||||
|
|
||||
|
<body class="dmt"> |
||||
|
<div id="top-container" class="container" style="display: none"> |
||||
|
<!-- HEADER --> |
||||
|
<div id="header" class="row"> |
||||
|
<div class="col-xs-9"> |
||||
|
<h1 class="title"><span>DOJO // MAINTENANCE TOOL</span> <span id="dojo-version" class="beta">beta</span></h1> |
||||
|
</div> |
||||
|
<div class="col-xs-3 login-box"> |
||||
|
<a id="btn-logout" style="display: inline;" href="#" title="DISCONNECT"> |
||||
|
<img src="../icons/ic_power_settings_new_white_24dp_1x.png" class="mini-icon"/> |
||||
|
</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="spacer30"></div> |
||||
|
|
||||
|
<!-- BODY --> |
||||
|
<div id="body" class="row"> |
||||
|
<!-- MENU --> |
||||
|
<div id="menu" class="col-xs-2"> |
||||
|
<div class="title"> |
||||
|
<h1>MONITORING</h1> |
||||
|
</div> |
||||
|
<ul id="tab-menu_list" class="nav nav-pills nav-stacked"> |
||||
|
<li id="link-welcome" style="display: none;"> |
||||
|
<a href="#">WELCOME</a> |
||||
|
</li> |
||||
|
<li id="link-status"> |
||||
|
<a href="#">DOJO STATUS</a> |
||||
|
</li> |
||||
|
<li id="link-pushtx"> |
||||
|
<a href="#">PUSHTX STATUS</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<div class="spacer20"></div> |
||||
|
<div class="title"> |
||||
|
<h1>TOOLS</h1> |
||||
|
</div> |
||||
|
<ul id="tab-menu_list2" class="nav nav-pills nav-stacked"> |
||||
|
<li id="link-pairing"> |
||||
|
<a href="#">PAIRING</a> |
||||
|
</li> |
||||
|
<li id="link-xpubs-tools"> |
||||
|
<a href="#">XPUBS TOOL</a> |
||||
|
</li> |
||||
|
<li id="link-addresses-tools"> |
||||
|
<a href="#">ADDRESSES TOOL</a> |
||||
|
</li> |
||||
|
<li id="link-txs-tools"> |
||||
|
<a href="#">TRANSACTIONS TOOL</a> |
||||
|
</li> |
||||
|
<li id="link-blocks-rescan"> |
||||
|
<a href="#">BLOCKS RESCAN</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
<div class="spacer20"></div> |
||||
|
<div class="title"> |
||||
|
<h1>HELP</h1> |
||||
|
</div> |
||||
|
<ul id="tab-menu_list3" class="nav nav-pills nav-stacked"> |
||||
|
<li id="link-help-dmt"> |
||||
|
<a href="#">HELP DMT</a> |
||||
|
</li> |
||||
|
<li id="link-dojo-telegram"> |
||||
|
<a href="https://t.me/samourai_dojo" target="_blank">DOJO TELEGRAM CHAT</a> |
||||
|
</li> |
||||
|
<li id="link-wp-telegram"> |
||||
|
<a href="https://t.me/whirlpool_trollbox" target="_blank">WHIRLPOOL TELEGRAM CHAT</a> |
||||
|
</li> |
||||
|
<li id="link-sw-support"> |
||||
|
<a href="https://t.me/SamouraiWallet" target="_blank">SAMOURAI TELEGRAM CHAT</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
<div class="col-xs-1"></div> |
||||
|
<!-- MAIN AREA --> |
||||
|
<div id="main" class="col-xs-9"> |
||||
|
<!-- WELCOME --> |
||||
|
<div id="screen-welcome" |
||||
|
include-html="welcome/welcome.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- STATUS --> |
||||
|
<div id="screen-status" |
||||
|
include-html="status/status.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- PUSH TX --> |
||||
|
<div id="screen-pushtx" |
||||
|
include-html="pushtx/pushtx.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- PAIRING --> |
||||
|
<div id="screen-pairing" |
||||
|
include-html="pairing/pairing.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- XPUBS TOOLS --> |
||||
|
<div id="screen-xpubs-tools" |
||||
|
include-html="xpubs-tools/xpubs-tools.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- ADDRESSES TOOLS --> |
||||
|
<div id="screen-addresses-tools" |
||||
|
include-html="addresses-tools/addresses-tools.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- TRANSACTIONS TOOLS --> |
||||
|
<div id="screen-txs-tools" |
||||
|
include-html="txs-tools/txs-tools.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- BLOCKS RESCAN --> |
||||
|
<div id="screen-blocks-rescan" |
||||
|
include-html="blocks-rescan/blocks-rescan.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
<!-- HELP DMT --> |
||||
|
<div id="screen-help-dmt" |
||||
|
include-html="welcome/welcome.html" |
||||
|
style="display: none"> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- MSG BOX --> |
||||
|
<div id="box-msg" |
||||
|
include-html="msg-box/msg-box.html"> |
||||
|
</div> |
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,116 @@ |
|||||
|
/** |
||||
|
* Global obkjects |
||||
|
*/ |
||||
|
|
||||
|
// Ordered list of screens
|
||||
|
const screens = [ |
||||
|
'#screen-welcome', |
||||
|
'#screen-status', |
||||
|
'#screen-pushtx', |
||||
|
'#screen-pairing', |
||||
|
'#screen-xpubs-tools', |
||||
|
'#screen-addresses-tools', |
||||
|
'#screen-txs-tools', |
||||
|
'#screen-blocks-rescan', |
||||
|
'#screen-help-dmt' |
||||
|
] |
||||
|
|
||||
|
// Ordered list of menu items
|
||||
|
const tabs = [ |
||||
|
'#link-welcome', |
||||
|
'#link-status', |
||||
|
'#link-pushtx', |
||||
|
'#link-pairing', |
||||
|
'#link-xpubs-tools', |
||||
|
'#link-addresses-tools', |
||||
|
'#link-txs-tools', |
||||
|
'#link-blocks-rescan', |
||||
|
'#link-help-dmt' |
||||
|
] |
||||
|
|
||||
|
// Mapping of scripts associaed to screens
|
||||
|
const screenScripts = new Map() |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* UI initialization |
||||
|
*/ |
||||
|
function initTabs() { |
||||
|
// Activates the current tab
|
||||
|
let currentTab = sessionStorage.getItem('activeTab') |
||||
|
if (!currentTab) |
||||
|
currentTab = '#link-status' |
||||
|
$(currentTab).addClass('active') |
||||
|
|
||||
|
// Sets event handlers
|
||||
|
for (let tab of tabs) { |
||||
|
$(tab).click(function() { |
||||
|
$(sessionStorage.getItem('activeTab')).removeClass('active') |
||||
|
sessionStorage.setItem('activeTab', tab) |
||||
|
$(tab).addClass('active') |
||||
|
preparePage() |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function initPages() { |
||||
|
// Dynamic loading of screens and scripts
|
||||
|
lib_cmn.includeHTML(_initPages) |
||||
|
// Dojo version
|
||||
|
let lblVersion = sessionStorage.getItem('lblVersion') |
||||
|
if (lblVersion == null) { |
||||
|
lib_api.getPairingInfo().then(apiInfo => { |
||||
|
lblVersion = 'v' + apiInfo['pairing']['version'] + ' beta' |
||||
|
sessionStorage.setItem('lblVersion', lblVersion) |
||||
|
$('#dojo-version').text(lblVersion) |
||||
|
}) |
||||
|
} else { |
||||
|
$('#dojo-version').text(lblVersion) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function _initPages() { |
||||
|
for (let screen of screens) { |
||||
|
const screenScript = screenScripts.get(screen) |
||||
|
if (screenScript) |
||||
|
screenScript.initPage() |
||||
|
} |
||||
|
preparePage() |
||||
|
$('#top-container').show() |
||||
|
} |
||||
|
|
||||
|
function preparePage() { |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
const activeTab = sessionStorage.getItem('activeTab') |
||||
|
for (let idxTab in tabs) { |
||||
|
const screen = screens[idxTab] |
||||
|
if (tabs[idxTab] == activeTab) { |
||||
|
$(screen).show() |
||||
|
if (screenScripts.has(screen)) |
||||
|
screenScripts.get(screen).preparePage() |
||||
|
} else { |
||||
|
$(screen).hide() |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* Processing on loading completed |
||||
|
*/ |
||||
|
$(document).ready(function() { |
||||
|
// Refresh the access token
|
||||
|
lib_auth.refreshAccessToken() |
||||
|
setInterval(() => { |
||||
|
lib_auth.refreshAccessToken() |
||||
|
}, 300000) |
||||
|
|
||||
|
// Inits menu and pages
|
||||
|
initTabs() |
||||
|
initPages() |
||||
|
|
||||
|
// Set event handlers
|
||||
|
$('#btn-logout').click(function() { |
||||
|
lib_auth.logout() |
||||
|
}) |
||||
|
}) |
@ -0,0 +1,7 @@ |
|||||
|
<div class="row box-msg"> |
||||
|
<div class="col-xs-12"> |
||||
|
<div id="msg" class="msg"></div> |
||||
|
<div id="errors" class="msg-error"></div> |
||||
|
<div id="info" class="msg-info"></div> |
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,33 @@ |
|||||
|
<div id="pairing"> |
||||
|
<h1>PAIRING</h1> |
||||
|
|
||||
|
<div class="box-context">Pair your wallet to your Dojo and to your Block Explorer with a simple QRCode.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<div id="dojo-pairing" class="halfwidth-left box"> |
||||
|
<div class="box-header">DOJO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body" id="qr-container"> |
||||
|
<div class="center">Scan this QRCode with your wallet</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div id="qr-pairing"></div> |
||||
|
<div class="spacer10"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="explorer-pairing" class="halfwidth-right box"> |
||||
|
<div class="box-header">BLOCK EXPLORER</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body" id="qr-explorer-container"> |
||||
|
<div class="center">Scan this QRCode with your wallet</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div id="qr-explorer-pairing"></div> |
||||
|
<div class="spacer10"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<script include-js="pairing/pairing.js"></script> |
@ -0,0 +1,65 @@ |
|||||
|
const screenPairingScript = { |
||||
|
|
||||
|
initPage: function() {}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
this.displayQRPairing() |
||||
|
}, |
||||
|
|
||||
|
loadPairingPayloads: function() { |
||||
|
let result = { |
||||
|
'api': null, |
||||
|
'explorer': null |
||||
|
} |
||||
|
|
||||
|
lib_msg.displayMessage('Loading pairing payloads...'); |
||||
|
|
||||
|
return lib_api.getPairingInfo().then(apiInfo => { |
||||
|
if (apiInfo) { |
||||
|
apiInfo['pairing']['url'] = window.location.protocol + '//' + window.location.host + conf['api']['baseUri'] |
||||
|
result['api'] = apiInfo |
||||
|
} |
||||
|
}).then(() => { |
||||
|
return lib_api.getExplorerPairingInfo() |
||||
|
}).then(explorerInfo => { |
||||
|
if (explorerInfo) |
||||
|
result['explorer'] = explorerInfo |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
return result |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
return result |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
displayQRPairing: function() { |
||||
|
this.loadPairingPayloads().then( |
||||
|
function (result) { |
||||
|
if (result) { |
||||
|
if (result['api']) { |
||||
|
const textJson = JSON.stringify(result['api'], null, 4) |
||||
|
$("#qr-pairing").html('') // clear qrcode first
|
||||
|
$('#qr-pairing').qrcode({width: 256, height: 256, text: textJson}) |
||||
|
} |
||||
|
if (result['explorer'] && result['explorer']['pairing']['url']) { |
||||
|
const textJson = JSON.stringify(result['explorer'], null, 4) |
||||
|
$("#qr-explorer-pairing").html('') // clear qrcode first
|
||||
|
$('#qr-explorer-pairing').qrcode({width: 256, height: 256, text: textJson}) |
||||
|
} else { |
||||
|
$("#qr-label").removeClass('halfwidth') |
||||
|
$("#qr-label").addClass('fullwidth') |
||||
|
$("#qr-container").removeClass('halfwidth') |
||||
|
$("#qr-container").addClass('fullwidth') |
||||
|
$("#qr-explorer-label").hide() |
||||
|
$("#qr-explorer-container").hide() |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
function (jqxhr) {} |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-pairing', screenPairingScript) |
@ -0,0 +1,44 @@ |
|||||
|
<div id="pushtx-status"> |
||||
|
<h1>PUSHTX STATUS</h1> |
||||
|
|
||||
|
<div class="box-context">Monitor the transactions pushed through your Dojo.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<div id="txs-pushed" class="box fullwidth"> |
||||
|
<div class="box-header">TRANSACTIONS PUSHED</div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Uptime</td> |
||||
|
<td class="table-value" id="pushed-uptime"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of Transactions</td> |
||||
|
<td class="table-value" id="pushed-count"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Total Amount</td> |
||||
|
<td class="table-value" id="pushed-amount"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<div id="txs-scheduled" class="box fullwidth"> |
||||
|
<div class="box-header">TRANSACTIONS SCHEDULED</div> |
||||
|
<div class="box-body"> |
||||
|
<table id="table-scheduled-txs"> |
||||
|
<thead> |
||||
|
<td colspan="2"></td> |
||||
|
</thead> |
||||
|
<tbody></tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script include-js="pushtx/pushtx.js"></script> |
@ -0,0 +1,90 @@ |
|||||
|
const pushtxScript = { |
||||
|
|
||||
|
processedSchedTxs: new Set(), |
||||
|
|
||||
|
initPage: function() { |
||||
|
// Refresh PushTx status
|
||||
|
setInterval(() => {this.refreshPushTxStatus()}, 60000) |
||||
|
// Refresh ScheduledTxs list
|
||||
|
setInterval(() => {this.refreshScheduledTxsList()}, 60000) |
||||
|
}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
this.refreshPushTxStatus() |
||||
|
this.refreshScheduledTxsList() |
||||
|
}, |
||||
|
|
||||
|
refreshPushTxStatus: function() { |
||||
|
lib_msg.displayMessage('Loading PushTx status info...'); |
||||
|
lib_api.getPushtxStatus().then(pushTxStatus => { |
||||
|
if (pushTxStatus) { |
||||
|
const data = pushTxStatus['data'] |
||||
|
const uptime = lib_cmn.timePeriod(data['uptime']) |
||||
|
$('#pushed-uptime').text(uptime) |
||||
|
$('#pushed-count').text(data['push']['count']) |
||||
|
$('#pushed-amount').text(data['push']['amount']) |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
$('#pushed-uptime').text('-') |
||||
|
$('#pushed-count').text('-') |
||||
|
$('#pushed-amount').text('-') |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
refreshScheduledTxsList: function() { |
||||
|
lib_msg.displayMessage('Loading PushTx orchestrator status info...'); |
||||
|
lib_api.getOrchestratorStatus().then(orchestrStatus => { |
||||
|
if(orchestrStatus) { |
||||
|
const data = orchestrStatus['data'] |
||||
|
for (let tx of data['txs']) { |
||||
|
if (!this.processedSchedTxs.has(tx['schTxid'])) { |
||||
|
this.displayScheduledTx(tx) |
||||
|
this.processedSchedTxs.add(tx['schTxid']) |
||||
|
} |
||||
|
} |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
displayScheduledTx: function(tx) { |
||||
|
const newRow = `<tr><td colspan="2"> </td></tr>
|
||||
|
<tr class="table-value"> |
||||
|
<td class="table-label">TXID</td> |
||||
|
<td class="table-value" id="scheduled-txid">${tx['schTxid']}</td> |
||||
|
</tr> |
||||
|
<tr class="table-value"> |
||||
|
<td class="table-label">Schedule Id</td> |
||||
|
<td class="table-value" id="scheduled-txid">${tx['schID']}</td> |
||||
|
</tr> |
||||
|
<tr class="table-value"> |
||||
|
<td class="table-label">Scheduled for block</td> |
||||
|
<td class="table-value" id="scheduled-trigger">${tx['schTrigger']}</td> |
||||
|
</tr> |
||||
|
<tr class="table-value"> |
||||
|
<td class="table-label">Created on</td> |
||||
|
<td class="table-value" id="scheduled-created">${lib_fmt.unixTsToLocaleString(tx['schCreated'])}</td> |
||||
|
</tr> |
||||
|
<tr class="table-value"> |
||||
|
<td class="table-label">Parent TXID</td> |
||||
|
<td class="table-value" id="scheduled-parent-txid">${tx['schParentTxid']}</td> |
||||
|
</tr> |
||||
|
<tr class="table-value"> |
||||
|
<td class="table-label">Raw Transaction</td> |
||||
|
<td class="table-value" id="scheduled-tx"> |
||||
|
<pre class="raw-tx">${tx['schRaw']}</pre> |
||||
|
</td> |
||||
|
</tr>` |
||||
|
|
||||
|
$('#table-scheduled-txs tr:last').after(newRow) |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-pushtx', pushtxScript) |
@ -0,0 +1,92 @@ |
|||||
|
<div id="status"> |
||||
|
<h1>DOJO STATUS</h1> |
||||
|
|
||||
|
<div class="box-context">Monitor the health of some core components of your Dojo.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<div id="left-column" class="two-columns-left"> |
||||
|
<div id="bitcoind-status" class="fullwidth box"> |
||||
|
<div class="box-header">FULL NODE</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Status</td> |
||||
|
<td class="table-value" id="node-status-ind"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Uptime</td> |
||||
|
<td class="table-value" id="node-uptime"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Latest block</td> |
||||
|
<td class="table-value" id="node-chaintip"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Bitcoind version</td> |
||||
|
<td class="table-value" id="node-version"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Network</td> |
||||
|
<td class="table-value" id="node-network"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Connected nodes</td> |
||||
|
<td class="table-value" id="node-conn"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Network relay fee</td> |
||||
|
<td class="table-value" id="node-relay-fee"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="right-column" class="two-columns-right"> |
||||
|
<div id="tracker-status" class="fullwidth box"> |
||||
|
<div class="box-header">TRACKER</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Status</td> |
||||
|
<td class="table-value" id="tracker-status-ind"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Uptime</td> |
||||
|
<td class="table-value" id="tracker-uptime"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Latest block</td> |
||||
|
<td class="table-value" id="tracker-chaintip"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="web-status" class="fullwidth box"> |
||||
|
<div class="box-header">WEB</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Tor status</td> |
||||
|
<td class="table-value" id="tor-status-ind">✓</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Nginx status</td> |
||||
|
<td class="table-value" id="nginx-status-ind">✓</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Node.js status</td> |
||||
|
<td class="table-value" id="nodejs-status-ind">✓</td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
<script include-js="status/status.js"></script> |
@ -0,0 +1,68 @@ |
|||||
|
const statusScript = { |
||||
|
|
||||
|
initPage: function() { |
||||
|
// Refresh API status
|
||||
|
setInterval(() => {this.refreshApiStatus()}, 60000) |
||||
|
// Refresh PushTx status
|
||||
|
setInterval(() => {this.refreshPushTxStatus()}, 60000) |
||||
|
}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
this.refreshApiStatus() |
||||
|
this.refreshPushTxStatus() |
||||
|
}, |
||||
|
|
||||
|
refreshApiStatus: function() { |
||||
|
lib_msg.displayMessage('Loading API status info...'); |
||||
|
return lib_api.getApiStatus().then(apiStatus => { |
||||
|
if (apiStatus) { |
||||
|
$('#tracker-status-ind').html('✓') |
||||
|
$('#tracker-status-ind').css('color', '#76d776') |
||||
|
$('#tracker-uptime').text(apiStatus['uptime']) |
||||
|
$('#tracker-chaintip').text(apiStatus['blocks']) |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
$('#tracker-status-ind').text('X') |
||||
|
$('#tracker-status-ind').css('color', '#f77c7c') |
||||
|
$('#tracker-uptime').text('-') |
||||
|
$('#tracker-chaintip').text('-') |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
refreshPushTxStatus: function() { |
||||
|
lib_msg.displayMessage('Loading Tracker status info...'); |
||||
|
lib_api.getPushtxStatus().then(pushTxStatus => { |
||||
|
if (pushTxStatus) { |
||||
|
const data = pushTxStatus['data'] |
||||
|
$('#node-status-ind').html('✓') |
||||
|
$('#node-status-ind').css('color', '#76d776') |
||||
|
const uptime = lib_cmn.timePeriod(data['uptime']) |
||||
|
$('#node-uptime').text(uptime) |
||||
|
$('#node-chaintip').text(data['bitcoind']['blocks']) |
||||
|
$('#node-version').text(data['bitcoind']['version']) |
||||
|
const network = data['bitcoind']['testnet'] == true ? 'testnet' : 'mainnet' |
||||
|
$('#node-network').text(network) |
||||
|
$('#node-conn').text(data['bitcoind']['conn']) |
||||
|
$('#node-relay-fee').text(data['bitcoind']['relayfee']) |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
$('#node-status-ind').text('-') |
||||
|
$('#node-status-ind').css('color', '#f77c7c') |
||||
|
$('#node-uptime').text('-') |
||||
|
$('#node-chaintip').text('-') |
||||
|
$('#node-version').text('-') |
||||
|
$('#node-network').text('-') |
||||
|
$('#node-conn').text('-') |
||||
|
$('#node-relay-fee').text('-') |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-status', statusScript) |
@ -0,0 +1,101 @@ |
|||||
|
<div id="txs-tool"> |
||||
|
<h1>TRANSACTIONS TOOL</h1> |
||||
|
|
||||
|
<div class="box-context">Check if a transaction is found in a block or in the mempool of your full node.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<!-- TRANSACTION SEARCH FORM --> |
||||
|
<div id="txs-tool-search-form" class="fullwidth box"> |
||||
|
<div class="box-body"> |
||||
|
<span>Search transaction with this </span> |
||||
|
<input id="txid" type="text" placeholder="TXID"> |
||||
|
<button id="btn-tx-search-go" class="btn btn-success" type="button">GO</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- TRANSACTION DETAILS --> |
||||
|
<div id="txs-tool-details"> |
||||
|
<div id="txs-tool-header" class="row box-main"> |
||||
|
<div class="fullwidth box"> |
||||
|
<div class="box-body center"> |
||||
|
<a id="txid-value" href="" target="_blank"></a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="txs-tool-actions" class="row box-main"> |
||||
|
<div class="center"> |
||||
|
<button id="btn-txs-details-reset" class="btn btn-success" type="button">SEARCH ANOTHER TRANSACTION</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="txs-tool-details-row1" class="row box-main"> |
||||
|
<!-- GENERAL INFO --> |
||||
|
<div id="box-general" class="halfwidth-left box"> |
||||
|
<div class="box-header">GENERAL INFO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">First-seen date</td> |
||||
|
<td class="table-value" id="tx-firstseen"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Found in</td> |
||||
|
<td class="table-value" id="tx-location"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Amount</td> |
||||
|
<td class="table-value" id="tx-amount"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Fees</td> |
||||
|
<td class="table-value" id="tx-fees"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Feerate</td> |
||||
|
<td class="table-value" id="tx-vfeerate"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of inputs</td> |
||||
|
<td class="table-value" id="tx-nb-inputs"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of outputs</td> |
||||
|
<td class="table-value" id="tx-nb-outputs"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- TECHNICAL INFO --> |
||||
|
<div id="box-technical" class="halfwidth-right box"> |
||||
|
<div class="box-header">TECHNICAL INFO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Virtual size</td> |
||||
|
<td class="table-value" id="tx-vsize"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Raw size</td> |
||||
|
<td class="table-value" id="tx-size"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Transaction version</td> |
||||
|
<td class="table-value" id="tx-version"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">nLockTime</td> |
||||
|
<td class="table-value" id="tx-nlocktime"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script include-js="txs-tools/txs-tools.js"></script> |
@ -0,0 +1,117 @@ |
|||||
|
const screenTxsToolsScript = { |
||||
|
|
||||
|
explorerInfo: null, |
||||
|
currentTxid: null, |
||||
|
|
||||
|
initPage: function() { |
||||
|
this.getExplorerInfo() |
||||
|
// Sets the event handlers
|
||||
|
$('#btn-tx-search-go').click(() => {this.searchTx()}) |
||||
|
$('#btn-txs-details-reset').click(() => {this.showSearchForm()}) |
||||
|
$('#txs-tool').keyup(evt => { |
||||
|
if (evt.keyCode === 13) { |
||||
|
this.searchTx() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
this.showSearchForm() |
||||
|
$("#txid").focus() |
||||
|
}, |
||||
|
|
||||
|
getExplorerInfo: function() { |
||||
|
lib_api.getExplorerPairingInfo().then(explorerInfo => { |
||||
|
this.explorerInfo = explorerInfo |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
searchTx: function() { |
||||
|
lib_msg.displayMessage('Search in progress...'); |
||||
|
const txid = $('#txid').val() |
||||
|
this.currentTxid = txid |
||||
|
return this._searchTx(txid).then(() => { |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
_searchTx: function(txid) { |
||||
|
return lib_api.getTransaction(txid).then(txInfo => { |
||||
|
if (txInfo) { |
||||
|
console.log(txInfo) |
||||
|
this.setTxDetails(txInfo) |
||||
|
this.showTxDetails() |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors('No transaction found') |
||||
|
console.log(e) |
||||
|
throw e |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
setTxDetails: function(txInfo) { |
||||
|
$('tr.input-row').remove() |
||||
|
$('tr.output-row').remove() |
||||
|
|
||||
|
const txUrl = lib_cmn.getExplorerTxUrl(this.currentTxid, this.explorerInfo) |
||||
|
$('#txid-value').text(this.currentTxid) |
||||
|
$('#txid-value').attr('href', txUrl) |
||||
|
|
||||
|
const firstseen = lib_fmt.unixTsToLocaleString(txInfo['created']) |
||||
|
$('#tx-firstseen').text(firstseen) |
||||
|
|
||||
|
if (txInfo.hasOwnProperty('block')) |
||||
|
$('#tx-location').text(` Block ${txInfo['block']['height']}`) |
||||
|
else |
||||
|
$('#tx-location').text(' Mempool') |
||||
|
|
||||
|
|
||||
|
const nbInputs = txInfo['inputs'].length |
||||
|
$('#tx-nb-inputs').text(nbInputs) |
||||
|
|
||||
|
const nbOutputs = txInfo['outputs'].length |
||||
|
$('#tx-nb-outputs').text(nbOutputs) |
||||
|
|
||||
|
$('#tx-vfeerate').text(`${txInfo['vfeerate']} sats/vbyte`) |
||||
|
|
||||
|
const fees = parseInt(txInfo['fees']) |
||||
|
$('#tx-fees').text(`${fees} sats`) |
||||
|
|
||||
|
let amount = fees |
||||
|
for (let o of txInfo['outputs']) { |
||||
|
amount += parseInt(o['value']) |
||||
|
} |
||||
|
amount = amount / 100000000 |
||||
|
$('#tx-amount').text(`${amount} BTC`) |
||||
|
|
||||
|
$('#tx-size').text(`${txInfo['size']} bytes`) |
||||
|
$('#tx-vsize').text(`${txInfo['vsize']} vbytes`) |
||||
|
$('#tx-version').text(txInfo['version']) |
||||
|
|
||||
|
let nlocktime = parseInt(txInfo['locktime']) |
||||
|
if (nlocktime < 500000000) { |
||||
|
$('#tx-nlocktime').text(`Block ${nlocktime}`) |
||||
|
} else { |
||||
|
locktime = lib_fmt.unixTsToLocaleString(locktime) |
||||
|
$('#tx-nlocktime').text(locktime) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
showSearchForm: function() { |
||||
|
$('#txs-tool-details').hide() |
||||
|
$('#txid').val('') |
||||
|
$('#txs-tool-search-form').show() |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}, |
||||
|
|
||||
|
showTxDetails: function() { |
||||
|
$('#txs-tool-search-form').hide() |
||||
|
$('#txs-tool-details').show() |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-txs-tools', screenTxsToolsScript) |
@ -0,0 +1,42 @@ |
|||||
|
<div id="welcome"> |
||||
|
<h1>WELCOME!</h1> |
||||
|
|
||||
|
<span>The Dojo's Maintenance Tool (DMT for short) provides a set of tools for monitoring and maintaining your Dojo.</span> |
||||
|
|
||||
|
<span class="items-category ">MONITORING</span> |
||||
|
|
||||
|
<span class="item">DOJO STATUS</span> |
||||
|
<span class="item-descr">A dashboard for monitoring the health of some components of your Dojo.</span> |
||||
|
|
||||
|
<span class="item">PUSHTX STATUS</span> |
||||
|
<span class="item-descr">A dashboard for monitoring the transactions pushed through your Dojo.</span> |
||||
|
|
||||
|
<span class="items-category ">TOOLS</span> |
||||
|
|
||||
|
<span class="item">PAIRING</span> |
||||
|
<span class="item-descr">Pair your wallet to your Dojo by scanning a QRCode.</span> |
||||
|
|
||||
|
<span class="item">XPUBS TOOL</span> |
||||
|
<span class="item-descr">Everything you need to manage your XPUBs manually.<br/>Check if a XPUB is tracked by your Dojo. Import and track a XPUB. Rescan the full history of a XPUB.</span> |
||||
|
|
||||
|
<span class="item">ADDRESSES TOOL</span> |
||||
|
<span class="item-descr">Everything you need to manage your addresses manually.<br/>Check if an address is tracked by your Dojo. Import and track an address. Rescan the full history of an address.</span> |
||||
|
|
||||
|
<span class="item">TRANSACTIONS TOOL</span> |
||||
|
<span class="item-descr">Check if a transaction is found in a block or in the mempool of your full node.</span> |
||||
|
|
||||
|
<span class="item">BLOCKS RESCAN</span> |
||||
|
<span class="item-descr">Rescan the transactions confirmed by the blocks in a given range.</span> |
||||
|
|
||||
|
<span class="items-category ">HELP</span> |
||||
|
|
||||
|
<span class="item">DOJO TELEGRAM CHAT</span> |
||||
|
<span class="item-descr">Get support from the community for all things related to your Dojo (requires Telegram).</span> |
||||
|
|
||||
|
<span class="item">WHIRLPOOL TELEGRAM CHAT</span> |
||||
|
<span class="item-descr">Get support from the community for all things related to Whirlpool (requires Telegram).</span> |
||||
|
|
||||
|
<span class="item">SW TELEGRAM CHAT</span> |
||||
|
<span class="item-descr">Get support from the community for all things related to your Samourai Wallet (requires Telegram).</span> |
||||
|
|
||||
|
</div> |
@ -0,0 +1,177 @@ |
|||||
|
<div id="xpubs-tool"> |
||||
|
<h1>XPUBS TOOL</h1> |
||||
|
|
||||
|
<div class="box-context">Check if a XPUB is tracked by your Dojo. Import and track a new XPUB. Rescan the full history of a XPUB.</div> |
||||
|
|
||||
|
<div class="row box-main"> |
||||
|
<!-- XPUB SEARCH FORM --> |
||||
|
<div id="xpubs-tool-search-form" class="fullwidth box"> |
||||
|
<div class="box-body"> |
||||
|
<span>Check if </span> |
||||
|
<input id="xpub" type="text" placeholder="XPUB"> |
||||
|
<span> is tracked by your Dojo </span> |
||||
|
<button id="btn-xpub-search-go" |
||||
|
class="btn btn-success" |
||||
|
type="button">GO</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- XPUB IMPORT --> |
||||
|
<div id="xpubs-tool-import" class="fullwidth box"> |
||||
|
<div class="box-body"> |
||||
|
<div id="import-deriv-first-import-msg"> |
||||
|
<span>This XPUB isn't tracked by your Dojo. Do you want to import it and track its activity?</span> |
||||
|
</div> |
||||
|
<div id="import-deriv-reimport-msg"> |
||||
|
<span>This XPUB is already tracked by your Dojo. Do you want to reimport it with a new derivation type?</span> |
||||
|
</div> |
||||
|
<div class="spacer20"></div> |
||||
|
<div> |
||||
|
<span>Import </span> |
||||
|
<span id="import-xpub"></span> |
||||
|
<span> with a </span> |
||||
|
<select id="import-deriv-type" type="select" value="auto"> |
||||
|
<option value="auto" selected>auto</option> |
||||
|
<option value="bip44">BIP44</option> |
||||
|
<option value="bip49">BIP49</option> |
||||
|
<option value="bip84">BIP84</option> |
||||
|
</select> |
||||
|
<span> derivation</span> |
||||
|
<button id="btn-xpub-import-go" class="btn btn-success" type="button">IMPORT</button> |
||||
|
<button id="btn-xpub-import-cancel" class="btn btn-success" type="button">CANCEL</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- XPUB DETAILS --> |
||||
|
<div id="xpubs-tool-details"> |
||||
|
<div id="xpubs-tool-header" class="row box-main"> |
||||
|
<div class="fullwidth box"> |
||||
|
<div id="xpub-value" class="box-body center"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="xpubs-tool-actions" class="row box-main"> |
||||
|
<div class="center"> |
||||
|
<button id="btn-xpub-details-rescan" class="btn btn-success" type="button">RESCAN THIS XPUB</button> |
||||
|
<button id="btn-xpub-details-retype" class="btn btn-success" type="button">RETYPE THIS XPUB</button> |
||||
|
<button id="btn-xpub-details-reset" class="btn btn-success" type="button">SEARCH ANOTHER XPUB</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="xpubs-rescans-actions" class="row box-main"> |
||||
|
<div class="center"> |
||||
|
<span>Rescan this xpub starting at index</span> |
||||
|
<input id="rescan-start-idx" type="text" value="0" placeholder="index"> |
||||
|
<span> with a lookahead of </span> |
||||
|
<input id="rescan-lookahead" type="text" value="100" placeholder="#addresses"> |
||||
|
<span> addresses</span> |
||||
|
<button id="btn-xpub-rescan-go" class="btn btn-success" type="button">RESCAN</button> |
||||
|
<button id="btn-xpub-rescan-cancel" class="btn btn-success" type="button">CANCEL</button> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="xpubs-tool-details-row1" class="row box-main"> |
||||
|
<!-- GENERAL INFO --> |
||||
|
<div id="box-general" class="halfwidth-left box"> |
||||
|
<div class="box-header">GENERAL INFO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Derivation Type</td> |
||||
|
<td class="table-value" id="xpub-deriv-type"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Balance</td> |
||||
|
<td class="table-value" id="xpub-balance"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of Txs</td> |
||||
|
<td class="table-value" id="xpub-nb-txs"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Number of UTXOs</td> |
||||
|
<td class="table-value" id="xpub-nb-utxos"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Tracked since</td> |
||||
|
<td class="table-value" id="xpub-import-date"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- DERIVATION INFO --> |
||||
|
<div id="box-derivation" class="halfwidth-right box"> |
||||
|
<div class="box-header">XPUB DERIVATION INFO</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table> |
||||
|
<tr> |
||||
|
<td class="table-label">Account</td> |
||||
|
<td class="table-value" id="xpub-deriv-account"></td> |
||||
|
<td class="table-label">Depth</td> |
||||
|
<td class="table-value" id="xpub-deriv-depth"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
<div class="spacer10"></div> |
||||
|
<table id="table-deriv-idx"> |
||||
|
<tr> |
||||
|
<td class="table-label" colspan="2">First unused indices</td> |
||||
|
<td class="table-label" colspan="2">Last derived indices</td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">External</td> |
||||
|
<td class="table-value" id="xpub-idx-unused-ext"></td> |
||||
|
<td class="table-label">External</td> |
||||
|
<td class="table-value" id="xpub-idx-derived-ext"></td> |
||||
|
</tr> |
||||
|
<tr> |
||||
|
<td class="table-label">Internal</td> |
||||
|
<td class="table-value" id="xpub-idx-unused-int"></td> |
||||
|
<td class="table-label">Internal</td> |
||||
|
<td class="table-value" id="xpub-idx-derived-int"></td> |
||||
|
</tr> |
||||
|
</table> |
||||
|
<div class="spacer10"></div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div id="xpubs-tool-details-row2" class="row box-main"> |
||||
|
<!-- TXS LIST --> |
||||
|
<div id="box-txs" class="halfwidth-left box"> |
||||
|
<div class="box-header">MOST RECENT TRANSACTIONS</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table id="xpub-table-list-txs"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td></td> |
||||
|
<td></td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!-- UTXOS LIST --> |
||||
|
<div id="box-utxos" class="halfwidth-right box"> |
||||
|
<div class="box-header">UNSPENT TRANSACTION OUTPUTS</div> |
||||
|
<div class="spacer10"></div> |
||||
|
<div class="box-body"> |
||||
|
<table id="xpub-table-list-utxos"> |
||||
|
<tbody> |
||||
|
<tr> |
||||
|
<td></td> |
||||
|
<td></td> |
||||
|
</tr> |
||||
|
</tbody> |
||||
|
</table> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<script include-js="xpubs-tools/xpubs-tools.js"></script> |
@ -0,0 +1,249 @@ |
|||||
|
const screenXpubsToolsScript = { |
||||
|
|
||||
|
explorerInfo: null, |
||||
|
currentXpub: null, |
||||
|
|
||||
|
initPage: function() { |
||||
|
this.getExplorerInfo() |
||||
|
// Sets the event handlers
|
||||
|
$('#btn-xpub-search-go').click(() => {this.searchXpub()}) |
||||
|
$('#btn-xpub-details-reset').click(() => {this.showSearchForm()}) |
||||
|
$('#btn-xpub-details-rescan').click(() => {this.showRescanForm()}) |
||||
|
$('#btn-xpub-rescan-go').click(() => {this.rescanXpub()}) |
||||
|
$('#btn-xpub-rescan-cancel').click(() => {this.hideRescanForm()}) |
||||
|
$('#btn-xpub-import-go').click(() => {this.importXpub()}) |
||||
|
$('#btn-xpub-details-retype').click(() => {this.showImportForm(true)}) |
||||
|
$('#btn-xpub-import-cancel').click(() => {this.showSearchForm()}) |
||||
|
$('#xpubs-tool').keyup(evt => { |
||||
|
if (evt.keyCode === 13) { |
||||
|
this.searchXpub() |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
preparePage: function() { |
||||
|
this.hideRescanForm() |
||||
|
this.showSearchForm() |
||||
|
$("#xpub").focus() |
||||
|
}, |
||||
|
|
||||
|
getExplorerInfo: function() { |
||||
|
lib_api.getExplorerPairingInfo().then(explorerInfo => { |
||||
|
this.explorerInfo = explorerInfo |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
searchXpub: function() { |
||||
|
lib_msg.displayMessage('Search in progress...'); |
||||
|
const xpub = $('#xpub').val() |
||||
|
this.currentXpub = xpub |
||||
|
return this._searchXpub(xpub).then(() => { |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
_searchXpub: function(xpub) { |
||||
|
return lib_api.getXpubInfo(xpub).then(xpubInfo => { |
||||
|
if (xpubInfo && xpubInfo['tracked']) { |
||||
|
this.setXpubDetails(xpubInfo) |
||||
|
this.showXpubDetails() |
||||
|
const jsonData = {'active': xpub} |
||||
|
return lib_api.getWallet(jsonData).then(walletInfo => { |
||||
|
// Display the txs
|
||||
|
const txs = walletInfo['txs'] |
||||
|
for (let tx of txs) |
||||
|
this.setTxDetails(tx) |
||||
|
// Display the UTXOs
|
||||
|
const utxos = walletInfo['unspent_outputs'].sort((a,b) => { |
||||
|
return a['confirmations'] - b['confirmations'] |
||||
|
}) |
||||
|
$('#xpub-nb-utxos').text(utxos.length) |
||||
|
for (let utxo of utxos) |
||||
|
this.setUtxoDetails(utxo) |
||||
|
}) |
||||
|
} else { |
||||
|
lib_msg.displayErrors('xpub not found') |
||||
|
this.showImportForm(false) |
||||
|
} |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
throw e |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
importXpub: function() { |
||||
|
lib_msg.displayMessage('Processing xpub import...'); |
||||
|
|
||||
|
const jsonData = { |
||||
|
'xpub': this.currentXpub, |
||||
|
'type': 'restore', |
||||
|
'force': true |
||||
|
} |
||||
|
|
||||
|
const derivType = $('#import-deriv-type').val() |
||||
|
if (derivType == 'bip49' || derivType == 'bip84') { |
||||
|
jsonData['segwit'] = derivType |
||||
|
} else if (derivType == 'auto') { |
||||
|
if (this.currentXpub.startsWith('ypub')) |
||||
|
jsonData['segwit'] = 'bip49' |
||||
|
else if (this.currentXpub.startsWith('zpub')) |
||||
|
jsonData['segwit'] = 'bip84' |
||||
|
} |
||||
|
|
||||
|
return lib_api.postXpub(jsonData) |
||||
|
.then(result => { |
||||
|
this._searchXpub(this.currentXpub).then(() => { |
||||
|
lib_msg.displayInfo('Import complete') |
||||
|
}) |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
rescanXpub: function() { |
||||
|
lib_msg.displayMessage('Processing xpub rescan...'); |
||||
|
let startIdx = $('#rescan-start-idx').val() |
||||
|
startIdx = (startIdx == null) ? 0 : parseInt(startIdx) |
||||
|
let lookahead = $('#rescan-lookahead').val() |
||||
|
lookahead = (lookahead == null) ? 100 : parseInt(lookahead) |
||||
|
return lib_api.getXpubRescan(this.currentXpub, lookahead, startIdx) |
||||
|
.then(result => { |
||||
|
this.hideRescanForm() |
||||
|
this._searchXpub(this.currentXpub).then(() => { |
||||
|
lib_msg.displayInfo('Rescan complete') |
||||
|
}) |
||||
|
}).catch(e => { |
||||
|
lib_msg.displayErrors(lib_msg.extractJqxhrErrorMsg(e)) |
||||
|
console.log(e) |
||||
|
}) |
||||
|
}, |
||||
|
|
||||
|
setXpubDetails: function(xpubInfo) { |
||||
|
$('tr.tx-row').remove() |
||||
|
$('tr.utxo-row').remove() |
||||
|
|
||||
|
$('#xpub-value').text(this.currentXpub) |
||||
|
$('#xpub-import-date').text(xpubInfo['created']) |
||||
|
$('#xpub-deriv-type').text(xpubInfo['derivation']) |
||||
|
$('#xpub-nb-txs').text(xpubInfo['n_tx']) |
||||
|
$('#xpub-nb-utxos').text('-') |
||||
|
const balance = parseInt(xpubInfo['balance']) / 100000000 |
||||
|
$('#xpub-balance').text(`${balance} BTC`) |
||||
|
$('#xpub-deriv-account').text(xpubInfo['account']) |
||||
|
$('#xpub-deriv-depth').text(xpubInfo['depth']) |
||||
|
$('#xpub-idx-unused-ext').text(xpubInfo['unused']['external']) |
||||
|
$('#xpub-idx-derived-ext').text(xpubInfo['derived']['external']) |
||||
|
$('#xpub-idx-unused-int').text(xpubInfo['unused']['internal']) |
||||
|
$('#xpub-idx-derived-int').text(xpubInfo['derived']['internal']) |
||||
|
}, |
||||
|
|
||||
|
setTxDetails: function(tx) { |
||||
|
const txid = tx['hash'] |
||||
|
const txidDisplay = `${txid.substring(0,50)}...` |
||||
|
const amount = parseInt(tx['result']) / 100000000 |
||||
|
const amountLabel = amount < 0 ? amount : `+${amount}` |
||||
|
const amountStyle = amount < 0 ? 'amount-sent' : 'amount-received' |
||||
|
const date = lib_fmt.unixTsToLocaleString(tx['time']) |
||||
|
const txUrl = lib_cmn.getExplorerTxUrl(txid, this.explorerInfo) |
||||
|
|
||||
|
const newRow = `<tr class="tx-row"><td colspan="2"> </td></tr>
|
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label" colspan="2"> |
||||
|
<a href="${txUrl}" target="_blank">${txidDisplay}</a> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label">Amount</td> |
||||
|
<td class="table-value ${amountStyle}">${amountLabel} BTC</td> |
||||
|
</tr> |
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label">Block height</td> |
||||
|
<td class="table-value">${tx['block_height']}</td> |
||||
|
</tr> |
||||
|
<tr class="tx-row"> |
||||
|
<td class="table-label">Date</td> |
||||
|
<td class="table-value">${date}</td> |
||||
|
</tr>` |
||||
|
|
||||
|
$('#xpub-table-list-txs tr:last').after(newRow) |
||||
|
}, |
||||
|
|
||||
|
setUtxoDetails: function(utxo) { |
||||
|
const txid = utxo['tx_hash'] |
||||
|
const txidVout = `${txid.substring(0,50)}...:${utxo['tx_output_n']}` |
||||
|
const amount = parseInt(utxo['value']) / 100000000 |
||||
|
const txUrl = lib_cmn.getExplorerTxUrl(txid, this.explorerInfo) |
||||
|
|
||||
|
const newRow = `<tr class="utxo-row"><td colspan="2"> </td></tr>
|
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label" colspan="2"> |
||||
|
<a href="${txUrl}" target="_blank">${txidVout}</a> |
||||
|
</td> |
||||
|
</tr> |
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label">Amount</td> |
||||
|
<td class="table-value">${amount} BTC</td> |
||||
|
</tr> |
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label">Address</td> |
||||
|
<td class="table-value">${utxo['addr']}</td> |
||||
|
</tr> |
||||
|
<tr class="utxo-row"> |
||||
|
<td class="table-label">Confirmations</td> |
||||
|
<td class="table-value">${utxo['confirmations']}</td> |
||||
|
</tr>` |
||||
|
|
||||
|
$('#xpub-table-list-utxos tr:last').after(newRow) |
||||
|
}, |
||||
|
|
||||
|
showSearchForm: function() { |
||||
|
$('#xpubs-tool-details').hide() |
||||
|
$('#xpubs-tool-import').hide() |
||||
|
$('#xpub').val('') |
||||
|
$('#xpubs-tool-search-form').show() |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}, |
||||
|
|
||||
|
showImportForm: function(isReimport) { |
||||
|
$('#xpubs-tool-search-form').hide() |
||||
|
$('#xpubs-tool-details').hide() |
||||
|
|
||||
|
if (isReimport) { |
||||
|
$('#import-deriv-first-import-msg').hide() |
||||
|
$('#import-deriv-reimport-msg').show() |
||||
|
} else { |
||||
|
$('#import-deriv-reimport-msg').hide() |
||||
|
$('#import-deriv-first-import-msg').show() |
||||
|
} |
||||
|
|
||||
|
const xpubLen = this.currentXpub.length |
||||
|
const xpubShortLbl = `"${this.currentXpub.substring(0, 20)}...${this.currentXpub.substring(xpubLen-20, xpubLen)}"` |
||||
|
$('#import-xpub').text(xpubShortLbl) |
||||
|
$('#xpubs-tool-import').show() |
||||
|
}, |
||||
|
|
||||
|
showXpubDetails: function() { |
||||
|
$('#xpubs-tool-search-form').hide() |
||||
|
$('#xpubs-tool-import').hide() |
||||
|
$('#xpubs-tool-details').show() |
||||
|
}, |
||||
|
|
||||
|
showRescanForm: function() { |
||||
|
$('#xpubs-tool-actions').hide() |
||||
|
$('#xpubs-rescans-actions').show() |
||||
|
lib_msg.cleanMessagesUi() |
||||
|
}, |
||||
|
|
||||
|
hideRescanForm: function() { |
||||
|
$('#xpubs-rescans-actions').hide() |
||||
|
$('#xpubs-tool-actions').show() |
||||
|
}, |
||||
|
|
||||
|
} |
||||
|
|
||||
|
screenScripts.set('#screen-xpubs-tools', screenXpubsToolsScript) |
After Width: | Height: | Size: 17 KiB |
File diff suppressed because it is too large
@ -1,51 +1,125 @@ |
|||||
lib_cmn = { |
const lib_cmn = { |
||||
// Utils functions
|
// Utils functions
|
||||
hasProperty: function(obj, propName) { |
hasProperty: function(obj, propName) { |
||||
/* Checks if an object has a property with given name */ |
/* Checks if an object has a property with given name */ |
||||
if ( (obj == null) || (!propName) ) |
if ( (obj == null) || (!propName) ) |
||||
return false; |
return false |
||||
else if (obj.hasOwnProperty('propName') || propName in obj) |
else if (obj.hasOwnProperty('propName') || propName in obj) |
||||
return true; |
return true |
||||
else |
else |
||||
return false; |
return false |
||||
}, |
}, |
||||
|
|
||||
// Go to default page
|
// Go to default page
|
||||
goToDefaultPage: function() { |
goToDefaultPage: function() { |
||||
const baseUri = conf['adminTool']['baseUri']; |
const baseUri = conf['adminTool']['baseUri'] |
||||
sessionStorage.setItem('activeTab', '#link-pairing'); |
sessionStorage.setItem('activeTab', '#link-status') |
||||
window.location = baseUri + '/tool/'; |
window.location = baseUri + '/dmt/' |
||||
}, |
}, |
||||
|
|
||||
// Go to home page
|
// Go to home page
|
||||
goToHomePage: function() { |
goToHomePage: function() { |
||||
sessionStorage.setItem('activeTab', null); |
sessionStorage.setItem('activeTab', null) |
||||
window.location = conf['adminTool']['baseUri'] + '/'; |
window.location = conf['adminTool']['baseUri'] + '/' |
||||
}, |
}, |
||||
|
|
||||
// Loads html snippet
|
// Get Transaction url on selected explorer
|
||||
|
getExplorerTxUrl: function(txid, explorerInfo) { |
||||
|
if (explorerInfo == null) |
||||
|
return null |
||||
|
else if (explorerInfo['pairing']['type'] == 'explorer.oxt') |
||||
|
return `${explorerInfo['pairing']['url']}/transaction/${txid}` |
||||
|
else if (explorerInfo['pairing']['type'] == 'explorer.btc_rpc_explorer') |
||||
|
return `http://${explorerInfo['pairing']['url']}/tx/${txid}` |
||||
|
else |
||||
|
return null |
||||
|
}, |
||||
|
|
||||
|
// Loads html snippets
|
||||
includeHTML: function(cb) { |
includeHTML: function(cb) { |
||||
let self = this; |
let self = this |
||||
let z, i, elmnt, file, xhttp; |
let z, i, elmnt, file, xhttp |
||||
z = document.getElementsByTagName('*'); |
z = document.getElementsByTagName('*') |
||||
|
for (i = 0; i < z.length; i++) { |
||||
|
elmnt = z[i] |
||||
|
file = elmnt.getAttribute('include-html') |
||||
|
if (file) { |
||||
|
xhttp = new XMLHttpRequest() |
||||
|
xhttp.onreadystatechange = function() { |
||||
|
if (this.readyState == 4 && this.status == 200) { |
||||
|
elmnt.innerHTML = this.responseText |
||||
|
elmnt.removeAttribute('include-html') |
||||
|
self.includeHTML(cb) |
||||
|
self.includeJs(elmnt) |
||||
|
} |
||||
|
} |
||||
|
xhttp.open('GET', file, true) |
||||
|
xhttp.send() |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
if (cb) cb() |
||||
|
}, |
||||
|
|
||||
|
// Loads js snippets
|
||||
|
includeJs: function(element) { |
||||
|
let self = this |
||||
|
let z, i, elmnt, file, xhttp |
||||
|
z = element.querySelectorAll('script') |
||||
for (i = 0; i < z.length; i++) { |
for (i = 0; i < z.length; i++) { |
||||
elmnt = z[i]; |
elmnt = z[i] |
||||
file = elmnt.getAttribute('include-html'); |
file = elmnt.getAttribute('include-js') |
||||
if (file) { |
if (file) { |
||||
xhttp = new XMLHttpRequest(); |
xhttp = new XMLHttpRequest() |
||||
xhttp.onreadystatechange = function() { |
xhttp.onreadystatechange = function() { |
||||
if (this.readyState == 4 && this.status == 200) { |
if (this.readyState == 4 && this.status == 200) { |
||||
elmnt.innerHTML = this.responseText; |
const newElmnt = document.createElement('script') |
||||
elmnt.removeAttribute('include-html'); |
newElmnt.textContent = this.responseText |
||||
self.includeHTML(cb); |
if (elmnt.parentNode) { |
||||
|
elmnt.parentNode.insertBefore(newElmnt, elmnt.nextSibling) |
||||
|
elmnt.parentNode.removeChild(elmnt) |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
xhttp.open('GET', file, true); |
xhttp.open('GET', file, true) |
||||
xhttp.send(); |
xhttp.send() |
||||
return; |
return |
||||
} |
} |
||||
} |
} |
||||
if (cb) cb(); |
}, |
||||
|
|
||||
|
pad10: function(v) { |
||||
|
return (v < 10) ? `0${v}` : `${v}` |
||||
|
}, |
||||
|
|
||||
|
pad100: function(v) { |
||||
|
if (v < 10) return `00${v}` |
||||
|
if (v < 100) return `0${v}` |
||||
|
return `${v}` |
||||
|
}, |
||||
|
|
||||
|
timePeriod: function(period, milliseconds) { |
||||
|
milliseconds = !!milliseconds |
||||
|
|
||||
|
const whole = Math.floor(period) |
||||
|
const ms = 1000*(period - whole) |
||||
|
const s = whole % 60 |
||||
|
const m = (whole >= 60) ? Math.floor(whole / 60) % 60 : 0 |
||||
|
const h = (whole >= 3600) ? Math.floor(whole / 3600) % 24 : 0 |
||||
|
const d = (whole >= 86400) ? Math.floor(whole / 86400) : 0 |
||||
|
|
||||
|
const parts = [this.pad10(h), this.pad10(m), this.pad10(s)] |
||||
|
|
||||
|
if (d > 0) |
||||
|
parts.splice(0, 0, this.pad100(d)) |
||||
|
|
||||
|
const str = parts.join(':') |
||||
|
|
||||
|
if (milliseconds) { |
||||
|
return str + '.' + this.pad100(ms) |
||||
|
} else { |
||||
|
return str |
||||
|
} |
||||
} |
} |
||||
|
|
||||
} |
} |
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,39 +1,41 @@ |
|||||
var lib_msg = { |
const lib_msg = { |
||||
|
|
||||
// Extracts jqxhr error message
|
// Extracts jqxhr error message
|
||||
extractJqxhrErrorMsg: function(jqxhr) { |
extractJqxhrErrorMsg: function(jqxhr) { |
||||
let hasErrorMsg = ('responseJSON' in jqxhr) && |
let hasErrorMsg = ('responseJSON' in jqxhr) && |
||||
(jqxhr['responseJSON'] != null) && |
(jqxhr['responseJSON'] != null) && |
||||
('message' in jqxhr['responseJSON']); |
('error' in jqxhr['responseJSON']) |
||||
|
|
||||
return hasErrorMsg ? jqxhr['responseJSON']['message'] : jqxhr.statusText; |
return hasErrorMsg ? jqxhr['responseJSON']['error'] : jqxhr.statusText |
||||
}, |
}, |
||||
|
|
||||
// UI functions
|
// UI functions
|
||||
addTextinID: function(text, id){ |
addTextinID: function(text, id){ |
||||
$(id).html(text.toUpperCase()); |
$(id).html(text.toUpperCase()) |
||||
}, |
}, |
||||
|
|
||||
displayMessage: function(text){ |
displayMessage: function(text){ |
||||
this.addTextinID('', '#errors'); |
this.addTextinID('', '#errors') |
||||
this.addTextinID('', '#info'); |
this.addTextinID('', '#info') |
||||
this.addTextinID(text, '#msg'); |
this.addTextinID(text, '#msg') |
||||
}, |
}, |
||||
|
|
||||
displayErrors: function(text){ |
displayErrors: function(text){ |
||||
this.addTextinID('', '#msg'); |
this.addTextinID('', '#msg') |
||||
this.addTextinID('', '#info'); |
this.addTextinID('', '#info') |
||||
this.addTextinID(text, '#errors'); |
this.addTextinID(text, '#errors') |
||||
}, |
}, |
||||
|
|
||||
displayInfo: function(text){ |
displayInfo: function(text){ |
||||
this.addTextinID('', '#msg'); |
this.addTextinID('', '#msg') |
||||
this.addTextinID('', '#errors'); |
this.addTextinID('', '#errors') |
||||
this.addTextinID(text, '#info'); |
this.addTextinID(text, '#info') |
||||
}, |
}, |
||||
|
|
||||
cleanMessagesUi: function() { |
cleanMessagesUi: function() { |
||||
this.addTextinID('', '#msg'); |
this.addTextinID('', '#msg') |
||||
this.addTextinID('', '#errors'); |
this.addTextinID('', '#errors') |
||||
this.addTextinID('', '#info'); |
this.addTextinID('', '#info') |
||||
} |
} |
||||
} |
|
||||
|
} |
||||
|
@ -1,132 +0,0 @@ |
|||||
<!DOCTYPE html> |
|
||||
<html lang="en"> |
|
||||
|
|
||||
<head> |
|
||||
<meta charset="utf-8"> |
|
||||
<title>DOJO // MAINTENANCE TOOL</title> |
|
||||
<link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"> |
|
||||
<link rel="stylesheet" type="text/css" href="../css/bootstrap-theme.min.css"> |
|
||||
<link rel="stylesheet" type="text/css" href="../css/style.css"> |
|
||||
<script src="../lib/jquery-3.2.1.min.js"></script> |
|
||||
<script src="../lib/jquery.qrcode.min.js"></script> |
|
||||
<script src="../conf/index.js"></script> |
|
||||
<script src="../lib/common-script.js"></script> |
|
||||
<script src="../lib/api-wrapper.js"></script> |
|
||||
<script src="../lib/auth-utils.js"></script> |
|
||||
<script src="../lib/format-utils.js"></script> |
|
||||
<script src="index.js"></script> |
|
||||
</head> |
|
||||
|
|
||||
<body> |
|
||||
<div id="info-xpub" class="container"> |
|
||||
<!-- HEADER --> |
|
||||
<div id="header" class="row"> |
|
||||
<div class="col-xs-9"> |
|
||||
<h1 class="title"><span>DOJO // MAINTENANCE TOOL</span> <span id="dojo-version" class="beta">beta</span></h1> |
|
||||
</div> |
|
||||
<div class="col-xs-3 login-box"> |
|
||||
<a id="btn-logout" style="display: inline;" href="#" title="DISCONNECT"> |
|
||||
<img src="../icons/ic_power_settings_new_white_24dp_1x.png" class="mini-icon"/> |
|
||||
</a> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<div class="spacer60"></div> |
|
||||
|
|
||||
<!-- TAB MENU --> |
|
||||
<div id="tab-menu" class="row"> |
|
||||
<div class="col-xs-12" > |
|
||||
<ul id="tab-menu_list" class="nav nav-pills"> |
|
||||
<li id="link-pairing"> |
|
||||
<a href="#">PAIRING</a> |
|
||||
</li> |
|
||||
<li id="link-status-api"> |
|
||||
<a href="#">API</a> |
|
||||
</li> |
|
||||
<li id="link-status-pushtx"> |
|
||||
<a href="#">PUSHTX</a> |
|
||||
</li> |
|
||||
<li id="link-orchestrator"> |
|
||||
<a href="#">ORCHESTRATOR</a> |
|
||||
</li> |
|
||||
<li id="link-info-xpub"> |
|
||||
<a href="#">XPUB INFO</a> |
|
||||
</li> |
|
||||
<li id="link-rescan-xpub"> |
|
||||
<a href="#">XPUB RESCAN</a> |
|
||||
</li> |
|
||||
<li id="link-xpub"> |
|
||||
<a href="#">XPUB</a> |
|
||||
</li> |
|
||||
<li id="link-info-address"> |
|
||||
<a href="#">ADDR. INFO</a> |
|
||||
</li> |
|
||||
<li id="link-rescan-address"> |
|
||||
<a href="#">ADDR. RESCAN</a> |
|
||||
</li> |
|
||||
<li id="link-wallet"> |
|
||||
<a href="#">WALLET</a> |
|
||||
</li> |
|
||||
<li id="link-tx"> |
|
||||
<a href="#">TX</a> |
|
||||
</li> |
|
||||
<li id="link-rescan-blocks"> |
|
||||
<a href="#">BLOCKS RESCAN</a> |
|
||||
</li> |
|
||||
</ul> |
|
||||
</div> |
|
||||
</div> |
|
||||
|
|
||||
<!-- BODY --> |
|
||||
<div id="body" class="row"> |
|
||||
<div class="col-xs-1"></div> |
|
||||
<div class="col-xs-10 json-data-container"> |
|
||||
<!-- PAIRING --> |
|
||||
<div id="screen-pairing"> |
|
||||
<div class="row"> |
|
||||
<div id="qr-label" class="halfwidth"> |
|
||||
PAIR YOUR WALLET WITH YOUR DOJO |
|
||||
</div> |
|
||||
<div id="qr-explorer-label" class="halfwidth"> |
|
||||
PAIR YOUR WALLET WITH YOUR BLOCK EXPLORER |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="row"> |
|
||||
<div id="qr-container" class="halfwidth"> |
|
||||
<div id="qr-pairing"></div> |
|
||||
</div> |
|
||||
<div id="qr-explorer-container" class="halfwidth"> |
|
||||
<div id="qr-explorer-pairing"></div> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
<!-- MAINTENANCE --> |
|
||||
<div id="form-maintenance"> |
|
||||
<div id="row-form-field"> |
|
||||
<div id="cell-args"> |
|
||||
<input type="text" id="args" placeholder=""> |
|
||||
</div> |
|
||||
<div id="cell-args2"> |
|
||||
<input type="text" id="args2" placeholder=""> |
|
||||
</div> |
|
||||
<div id="cell-args3"> |
|
||||
<input type="text" id="args3" placeholder=""> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div id="row-form-button" class="center"> |
|
||||
<button id="btn-go" |
|
||||
class="btn btn-success" |
|
||||
type="button">GO</button> |
|
||||
</div> |
|
||||
<div class="center"> |
|
||||
<pre id="json-data" style="min-height: 300px"></pre> |
|
||||
</div> |
|
||||
</div> |
|
||||
</div> |
|
||||
<div class="col-xs-1"></div> |
|
||||
</div> |
|
||||
|
|
||||
</div> |
|
||||
</body> |
|
||||
|
|
||||
</html> |
|
@ -1,295 +0,0 @@ |
|||||
/** |
|
||||
* Display Messages |
|
||||
*/ |
|
||||
|
|
||||
function displayInfoMsg(msg) { |
|
||||
const htmlMsg = '<span class="info">' + msg + '</span>'; |
|
||||
$('#json-data').html(htmlMsg); |
|
||||
} |
|
||||
|
|
||||
function displayErrorMsg(msg) { |
|
||||
const htmlMsg = '<span class="error">' + msg + '</span>'; |
|
||||
$('#json-data').html(htmlMsg); |
|
||||
} |
|
||||
|
|
||||
function displayQRPairing() { |
|
||||
const activeTab = sessionStorage.getItem('activeTab'); |
|
||||
processAction(activeTab).then( |
|
||||
function (result) { |
|
||||
if (result) { |
|
||||
if (result['api']) { |
|
||||
const textJson = JSON.stringify(result['api'], null, 4); |
|
||||
$("#qr-pairing").html('') // clear qrcode first
|
|
||||
$('#qr-pairing').qrcode({width: 256, height: 256, text: textJson}); |
|
||||
} |
|
||||
if (result['explorer'] && result['explorer']['pairing']['url']) { |
|
||||
const textJson = JSON.stringify(result['explorer'], null, 4); |
|
||||
$("#qr-explorer-pairing").html('') // clear qrcode first
|
|
||||
$('#qr-explorer-pairing').qrcode({width: 256, height: 256, text: textJson}); |
|
||||
} else { |
|
||||
$("#qr-label").removeClass('halfwidth'); |
|
||||
$("#qr-label").addClass('fullwidth'); |
|
||||
$("#qr-container").removeClass('halfwidth'); |
|
||||
$("#qr-container").addClass('fullwidth'); |
|
||||
$("#qr-explorer-label").hide(); |
|
||||
$("#qr-explorer-container").hide(); |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
function (jqxhr) {} |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* On tab switched |
|
||||
*/ |
|
||||
function initTabs() { |
|
||||
// Activates the current tab
|
|
||||
let currentTab = sessionStorage.getItem('activeTab'); |
|
||||
if (!currentTab) { |
|
||||
currentTab = '#link-pairing'; |
|
||||
} |
|
||||
$(currentTab).addClass('active'); |
|
||||
|
|
||||
const tabs = [ |
|
||||
'#link-pairing', |
|
||||
'#link-status-api', |
|
||||
'#link-status-pushtx', |
|
||||
'#link-orchestrator', |
|
||||
'#link-info-xpub', |
|
||||
'#link-rescan-xpub', |
|
||||
'#link-xpub', |
|
||||
'#link-info-address', |
|
||||
'#link-rescan-address', |
|
||||
'#link-rescan-blocks', |
|
||||
'#link-wallet', |
|
||||
'#link-tx' |
|
||||
]; |
|
||||
|
|
||||
// Sets event handlers
|
|
||||
for (let tab of tabs) { |
|
||||
$(tab).click(function() { |
|
||||
$(sessionStorage.getItem('activeTab')).removeClass('active'); |
|
||||
sessionStorage.setItem('activeTab', tab); |
|
||||
$(tab).addClass('active'); |
|
||||
preparePage(); |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Prepares the page content |
|
||||
*/ |
|
||||
function preparePage() { |
|
||||
const activeTab = sessionStorage.getItem('activeTab'); |
|
||||
|
|
||||
// Dojo version
|
|
||||
let lblVersion = sessionStorage.getItem('lblVersion'); |
|
||||
if (lblVersion == null) { |
|
||||
lib_api.getPairingInfo().then(apiInfo => { |
|
||||
lblVersion = 'v' + apiInfo['pairing']['version'] + ' beta'; |
|
||||
sessionStorage.setItem('lblVersion', lblVersion); |
|
||||
$('#dojo-version').text(lblVersion); |
|
||||
}); |
|
||||
} else { |
|
||||
$('#dojo-version').text(lblVersion); |
|
||||
} |
|
||||
|
|
||||
// Pairing
|
|
||||
if (activeTab == '#link-pairing') { |
|
||||
$('#screen-pairing').show(); |
|
||||
$('#form-maintenance').hide(); |
|
||||
displayQRPairing(); |
|
||||
|
|
||||
// Maintenance screens
|
|
||||
} else { |
|
||||
$('#form-maintenance').show(); |
|
||||
$('#screen-pairing').hide(); |
|
||||
|
|
||||
let placeholder = '', |
|
||||
placeholder2 = '', |
|
||||
placeholder3 = ''; |
|
||||
|
|
||||
$("#cell-args").removeClass('halfwidth'); |
|
||||
$("#cell-args").addClass('fullwidth'); |
|
||||
$("#cell-args2").hide(); |
|
||||
$("#cell-args3").hide(); |
|
||||
|
|
||||
if (activeTab == '#link-status-api' || |
|
||||
activeTab == '#link-status-pushtx' || |
|
||||
activeTab == '#link-orchestrator' |
|
||||
) { |
|
||||
$("#row-form-field").hide(); |
|
||||
$("#row-form-button").hide(); |
|
||||
processGo(); |
|
||||
} else { |
|
||||
$("#row-form-field").show(); |
|
||||
$("#row-form-button").show(); |
|
||||
} |
|
||||
|
|
||||
if (activeTab == '#link-info-xpub') { |
|
||||
placeholder = 'ENTER A XPUB, YPUB OR ZPUB'; |
|
||||
} else if (activeTab == '#link-xpub') { |
|
||||
placeholder = 'ENTER /XPUB URL ARGUMENTS (e.g.: xpub=xpub0123456789&segwit=bip84&type=restore&force=true)'; |
|
||||
} else if (activeTab == '#link-info-address') { |
|
||||
placeholder = 'ENTER A BITCOIN ADDRESS'; |
|
||||
} else if (activeTab == '#link-rescan-address') { |
|
||||
placeholder = 'ENTER A BITCOIN ADDRESS'; |
|
||||
} else if (activeTab == '#link-rescan-blocks') { |
|
||||
$("#cell-args").removeClass('fullwidth'); |
|
||||
$("#cell-args").addClass('halfwidth'); |
|
||||
$("#cell-args2").show(); |
|
||||
placeholder = 'RESCAN BLOCKS FROM HEIGHT...'; |
|
||||
placeholder2 = '...TO HEIGHT (OPTIONAL)'; |
|
||||
} else if (activeTab == '#link-wallet') { |
|
||||
placeholder = 'ENTER /WALLET URL ARGUMENTS (e.g.: active=xpub0123456789&new=address2|address3&pubkey=pubkey4)'; |
|
||||
} else if (activeTab == '#link-tx') { |
|
||||
placeholder = 'ENTER A TRANSACTION TXID'; |
|
||||
} else if (activeTab == '#link-rescan-xpub') { |
|
||||
$("#cell-args").removeClass('fullwidth'); |
|
||||
$("#cell-args").addClass('halfwidth'); |
|
||||
$("#cell-args2").show(); |
|
||||
$("#cell-args3").show(); |
|
||||
placeholder = 'ENTER A XPUB, YPUB OR ZPUB'; |
|
||||
placeholder2 = 'ENTER #ADDR. (DEFAULT=100)'; |
|
||||
placeholder3 = 'ENTER START INDEX (DEFAULT=0)'; |
|
||||
} |
|
||||
|
|
||||
$("#args").attr('placeholder', placeholder); |
|
||||
$('#args').val(''); |
|
||||
$("#args2").attr('placeholder', placeholder2); |
|
||||
$('#args2').val(''); |
|
||||
$("#args3").attr('placeholder', placeholder3); |
|
||||
$('#args3').val(''); |
|
||||
$('#json-data').html(''); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Process action (api calls) |
|
||||
*/ |
|
||||
function processAction(activeTab, args, args2, args3) { |
|
||||
if (activeTab == '#link-pairing') { |
|
||||
//return lib_api.getPairingInfo();
|
|
||||
let result = { |
|
||||
'api': null, |
|
||||
'explorer': null |
|
||||
}; |
|
||||
return lib_api.getPairingInfo().then(apiInfo => { |
|
||||
if (apiInfo) { |
|
||||
apiInfo['pairing']['url'] = window.location.protocol + '//' + window.location.host + conf['api']['baseUri']; |
|
||||
result['api'] = apiInfo; |
|
||||
} |
|
||||
}).then(() => { |
|
||||
return lib_api.getExplorerPairingInfo(); |
|
||||
}).then(explorerInfo => { |
|
||||
if (explorerInfo) |
|
||||
result['explorer'] = explorerInfo; |
|
||||
return result |
|
||||
}).catch(e => { |
|
||||
console.log(e); |
|
||||
return result; |
|
||||
}); |
|
||||
} else if (activeTab == '#link-status-api') { |
|
||||
return lib_api.getApiStatus(); |
|
||||
} else if (activeTab == '#link-status-pushtx') { |
|
||||
return lib_api.getPushtxStatus(); |
|
||||
} else if (activeTab == '#link-orchestrator') { |
|
||||
return lib_api.getOrchestratorStatus(); |
|
||||
} |
|
||||
|
|
||||
if (args == '') { |
|
||||
alert('Argument is mandatory'); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (activeTab == '#link-info-xpub') { |
|
||||
return lib_api.getXpubInfo(args); |
|
||||
} else if (activeTab == '#link-rescan-xpub') { |
|
||||
const nbAddr = (!args2) ? 100 : parseInt(args2); |
|
||||
const startIdx = (!args3) ? 0 : parseInt(args3); |
|
||||
return lib_api.getXpubRescan(args, nbAddr, startIdx); |
|
||||
} else if (activeTab == '#link-info-address') { |
|
||||
return lib_api.getAddressInfo(args); |
|
||||
} else if (activeTab == '#link-rescan-address') { |
|
||||
return lib_api.getAddressRescan(args); |
|
||||
} else if (activeTab == '#link-rescan-blocks') { |
|
||||
const fromHeight = parseInt(args); |
|
||||
const toHeight = (args2) ? parseInt(args2) : fromHeight; |
|
||||
return lib_api.getBlocksRescan(fromHeight, toHeight); |
|
||||
} else if (activeTab == '#link-tx') { |
|
||||
return lib_api.getTransaction(args); |
|
||||
} |
|
||||
|
|
||||
const jsonData = {}; |
|
||||
const aArgs = args.split('&'); |
|
||||
for (let arg of aArgs) { |
|
||||
const aArg = arg.split('='); |
|
||||
jsonData[aArg[0]] = aArg[1]; |
|
||||
} |
|
||||
|
|
||||
if (activeTab == '#link-wallet') |
|
||||
return lib_api.getWallet(jsonData); |
|
||||
else if (activeTab == '#link-xpub') |
|
||||
return lib_api.postXpub(jsonData); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Retrieve information about the xpub |
|
||||
*/ |
|
||||
function processGo() { |
|
||||
const activeTab = sessionStorage.getItem('activeTab'); |
|
||||
const args = $("#args").val(); |
|
||||
const args2 = $("#args2").val(); |
|
||||
const args3 = $("#args3").val(); |
|
||||
|
|
||||
displayInfoMsg('Processing...'); |
|
||||
|
|
||||
let deferred = processAction(activeTab, args, args2, args3); |
|
||||
|
|
||||
deferred.then( |
|
||||
function (result) { |
|
||||
if (!result) |
|
||||
return; |
|
||||
let textJson = lib_fmt.cleanJson(result); |
|
||||
textJson = JSON.stringify(JSON.parse(textJson), null, 4); |
|
||||
textJson = lib_fmt.jsonSyntaxHighlight(textJson); |
|
||||
$('#json-data').html(textJson); |
|
||||
}, |
|
||||
function (jqxhr) { |
|
||||
let hasErrorMsg = |
|
||||
('responseJSON' in jqxhr) && |
|
||||
(jqxhr['responseJSON'] != null) && |
|
||||
('message' in jqxhr['responseJSON']); |
|
||||
|
|
||||
const msg = hasErrorMsg ? jqxhr['responseJSON']['message'] : jqxhr.statusText; |
|
||||
displayErrorMsg(msg); |
|
||||
} |
|
||||
); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Processing on loading completed |
|
||||
*/ |
|
||||
$(document).ready(function() { |
|
||||
// Refresh the access token if needed
|
|
||||
setInterval(() => { |
|
||||
lib_auth.refreshAccessToken(); |
|
||||
}, 300000); |
|
||||
|
|
||||
initTabs(); |
|
||||
preparePage(); |
|
||||
|
|
||||
// Sets the event handlers
|
|
||||
$('#args').keyup(function(evt) { |
|
||||
if (evt.keyCode === 13) { |
|
||||
processGo(); |
|
||||
} |
|
||||
}); |
|
||||
$('#btn-go').click(function() { |
|
||||
processGo(); |
|
||||
}); |
|
||||
$('#btn-logout').click(function() { |
|
||||
lib_auth.logout(); |
|
||||
}); |
|
||||
}); |
|
Loading…
Reference in new issue