forked from Qortal/qortal
Added mock-up of node management UI
This commit is contained in:
parent
ab9fd681f3
commit
e42c3e60bc
181
src/test/resources/demo-node-ui.html
Normal file
181
src/test/resources/demo-node-ui.html
Normal file
@ -0,0 +1,181 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
#tabs input[type=radio] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#tabs label {
|
||||
display: inline-block;
|
||||
padding: 6px 0 6px 0;
|
||||
margin: 0 -2px;
|
||||
width: 25%; /* =100/tabs number */
|
||||
border-bottom: 1px solid #000;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#tabs label:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#tabs input:checked + label {
|
||||
border: 1px solid #000;
|
||||
border-width: 1px 1px 0 1px;
|
||||
}
|
||||
|
||||
#tabs #tab1:checked ~ #content #content1,
|
||||
#tabs #tab2:checked ~ #content #content2,
|
||||
#tabs #tab3:checked ~ #content #content3,
|
||||
#tabs #tab4:checked ~ #content #content4 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
#tabs #content > div {
|
||||
display: none;
|
||||
padding-top: 20px;
|
||||
text-align: left;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
TABLE TH {
|
||||
background: #ccccff;
|
||||
}
|
||||
|
||||
TABLE TD {
|
||||
background: #eeeeff;
|
||||
}
|
||||
|
||||
.form {
|
||||
display: inline-block;
|
||||
border: 1px solid red;
|
||||
padding: 2px;
|
||||
background: #fff8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// This is empty when page loads. When a private key is decrypted it is saved in here.
|
||||
var cachedPrivateKeys = {};
|
||||
|
||||
function getPrivateKey(address) {
|
||||
// Is it decrypted already?
|
||||
if (cachedPrivateKeys[address] != undefined)
|
||||
return cachedPrivateKeys[address];
|
||||
|
||||
// No: so create pop-up asking for password
|
||||
// Then use password to decrypt key for that address
|
||||
|
||||
// Don't actually use window.prompt!
|
||||
var password = window.prompt("Password to unlock " + address);
|
||||
|
||||
var encryptedPrivateKey = window.localStorage.getItem(address);
|
||||
|
||||
// Do decryption...
|
||||
var privateKey = "decrypted private key";
|
||||
|
||||
cachedPrivateKeys[address] = privateKey;
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="tabs">
|
||||
<input id="tab1" type="radio" name="tabs">
|
||||
<label for="tab1">Peers</label>
|
||||
|
||||
<input id="tab2" type="radio" name="tabs" CHECKED>
|
||||
<label for="tab2">Minting</label>
|
||||
|
||||
<input id="tab3" type="radio" name="tabs">
|
||||
<label for="tab3">Accounts</label>
|
||||
|
||||
<div id="content">
|
||||
<div id="content1">
|
||||
Peers management goes here
|
||||
</div>
|
||||
|
||||
<div id="content2">
|
||||
<div class="form">
|
||||
Minting address: <select><option>QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v</option><option>QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK</option></select>
|
||||
<i><-- filled in from entries found in window.localStorage</i>
|
||||
<br>
|
||||
Recipient address: <input type="text" size="20"><br>
|
||||
Percentage (0 to 100): <input type="text" size="5"><br>
|
||||
<button>Submit</button>
|
||||
<p>
|
||||
<i>
|
||||
"Submit" should then use recipient's address to find recipient's public key.<br>
|
||||
Use recipient's public key to generate proxy private key.<br>
|
||||
Use proxy private key to calculate proxy public key.<br>
|
||||
use proxy public key to build and submit PROXY_FORGING transaction.
|
||||
<p>
|
||||
If minting address's private key is not available decrypted then do pop-up asking for password then decrypt and save into <tt>cachedPrivateKeys</tt>.<br>
|
||||
See <script> code in this page's source.
|
||||
<p>
|
||||
If recipient does not have public key yet (fetch using API) then do pop-up asking if minting account should send small amount of QORA.<br>
|
||||
When recipient receives QORA they need to do a transaction, for example: JOIN_GROUP 2, which will make their public key available from the blockchain/API.
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
Minting relationships: <i>(found by API call GET /addresses/proxying)</i><br>
|
||||
<table>
|
||||
<tr><th>Minting address</th><th>Recipient address</th><th>Percentage</th><th>Blocks</th><th>Status</th><th>Actions</th></tr>
|
||||
|
||||
<tr><td>QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v</td><td>QaUpHNhT3Ygx6avRiKobuLdusppR5biXjL</td><td>20%</td><td>14</td><td>Active</td><td><button>Edit</button><button>Stop</button></td></tr>
|
||||
<tr><td>QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v</td><td>QcFmNxSArv5tWEzCtTKb2Lqc5QkKuQ7RNs</td><td>0%</td><td>3</td><td>Stopped</td><td><button>Edit</button><button>Start</button></td></tr>
|
||||
<tr><td>QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v</td><td>Qci5m9k4rcwe4ruKrZZQKka4FzUUMut3er</td><td>40%</td><td></td><td>Pending</td><td><button>Edit</button><button disabled>Start</button></td></tr>
|
||||
<tr><td>QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v</td><td>QaUpHNhT3Ygx6avRiKobuLdusppR5biXjL</td><td>20%</td><td>14</td><td>Active</td><td><button disabled>Edit</button><button>Stop</button></td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<i>
|
||||
"Active" means proxy private key for minting & recipient pair is listed by API call GET /admin/forgingaccounts.<br>
|
||||
"Pending" means PROXY_FORGING transaction for this relationship has not yet confirmed.<br>
|
||||
"Stopped" means proxy private key is NOT listed by API call GET /admin/forgingaccounts but also that the PROXY_FORGING transaction for this relationship has confirmed.
|
||||
<p>
|
||||
"Edit" button could fill in the form above with current details?
|
||||
<p>
|
||||
"Start" button adds relationship's proxy private key to node via API call POST /admin/forgingaccounts.<br>
|
||||
"Stop" button removes relationship's proxy private key to node via API call DELETE /admin/forgingaccounts.
|
||||
<p>
|
||||
Again, if minting/recipient's private key (to calculate proxy private key to send to API) is not available<br>
|
||||
then do pop-up asking for password to decrypt and save into <tt>cachedPrivateKeys</tt>.
|
||||
<p>
|
||||
Last entry in the table (above) is an example when node is instead run by recipient "QaUpHNhT3Ygx6avRiKobuLdusppR5biXjL" and so "Edit" is disabled.
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<div id="content3">
|
||||
<div class="form">
|
||||
Mnemonic phrase: <input type="text" size="20"><br>
|
||||
Password: <input type="password" size="20"><br>
|
||||
<button>Add minting account</button>
|
||||
<p>
|
||||
<i>
|
||||
Use mnemonic phrase to calculate private key and address.<br>
|
||||
Encrypt private key using password and store with <tt>window.localStorage.setItem(address, encryptedPrivateKey)</tt>.<br>
|
||||
Add address & unencrypted private key to cache, e.g. <tt>cachedPrivateKeys[address] = privateKey</tt>.
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
|
||||
Minting accounts:<br>
|
||||
<table>
|
||||
<tr><th>Address</th><th>Status</th><th>Actions</th></tr>
|
||||
|
||||
<tr><td>QgV4s3xnzLhVBEJxcYui4u4q11yhUHsd9v</td><td>Locked</td><td><button>Remove</button></td></tr>
|
||||
<tr><td>QixPbJUwsaHsVEofJdozU9zgVqkK6aYhrK</td><td>Unlocked</td><td><button>Remove</button></td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<i>
|
||||
Table rows made from addresses found in <tt>window.localStorage</tt> entries and "unlocked" if also in <tt>cachedPrivateKeys</tt>.
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user