Monitor data : Independent addresses and Label feature

Monitor data now reads the local data from indexedDB and displays them before refreshing for new data using API.
Each address can now be refreshed or removed independently.
Added a feature to store label of address in local data.
This commit is contained in:
Sai Raj 2019-02-04 16:23:09 +05:30 committed by GitHub
parent cc690d61b4
commit ac86b0a37d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,6 +2,11 @@
<html> <html>
<head> <head>
<title>FLO walletless</title> <title>FLO walletless</title>
<style>
table, th, td {
border: 1px solid black;
}
</style>
</head> </head>
<body> <body>
<script> <script>
@ -9,7 +14,9 @@
const testnet = `https://testnet.flocha.in`; const testnet = `https://testnet.flocha.in`;
let server = mainnet; let server = mainnet;
window["loadwait"] = false;
window["refreshwait"] = false;
const fee = 0.0005; const fee = 0.0005;
</script> </script>
<h1>FLO</h1> <h1>FLO</h1>
@ -18,15 +25,15 @@
<button id="getDataBtn" onclick="getDataMode();">Monitor FLO Data</button> <button id="getDataBtn" onclick="getDataMode();">Monitor FLO Data</button>
<br/> <br/>
<div id="addrGen"> <div id="addrGen">
<h2>Address Generator</h2> <h2>Address Generator</h2>
<button id="GenNewAddrBtn" onclick="GenNewAddr();">Generate New Address</button> <button id="GenNewAddrBtn" onclick="GenNewAddr();">Generate New Address</button>
<button id="RecoverAddrBtn" onclick="RecoverAddr();">Recover FLO Address</button><br/><br/> <button id="RecoverAddrBtn" onclick="RecoverAddr();">Recover FLO Address</button><br/><br/>
<table id="addrDisp" border="1"><tr><td><b>FLO Address</b></td><td><b>Secret (or) Private Key</b></td></tr></table> <table id="addrDisp"><tr><td><b>FLO Address</b></td><td><b>Secret (or) Private Key</b></td></tr></table>
</div> </div>
<div id="sendData"> <div id="sendData">
<h2>Send FLO Data</h2> <h2>Send FLO Data</h2>
<label for="getBal_addr">Enter sender address : </label> <label for="getBal_addr">Enter sender address : </label>
@ -39,64 +46,61 @@
<textarea rows="15" cols="70" id="flotextdata"></textarea><br/> <textarea rows="15" cols="70" id="flotextdata"></textarea><br/>
<button id="sendBtn" onclick="sendTransaction()" disabled>Send</button> <button id="sendBtn" onclick="sendTransaction()" disabled>Send</button>
</div> </div>
<div id="getData"> <div id="getData">
<h2>Monitor FLO Data</h2> <h2>Monitor FLO Data</h2>
Enter Address : <input type="text" id="getAddr"><br/> Enter Address : <input type="text" id="getAddr"><br/>
<button id="getData" onclick="monitorData()">Monitor Data</button><br/> <button id="getData" onclick="monitorData()">Monitor Data</button><br/>
<button id="clearLocalData" onclick="clearLocalData()">Clear Local Data</button> <button id="clearLocalData" onclick="clearLocalData()">Clear Local Data</button>
<div id="dispMsg"><h3>Received FLO Data : </h3><br/><table id="dispfloData" border="1"><tr><td>Sender</td><td>Receiver</td><td>Time</td><td>FLO data</td></tr><table></div> <div id="dispMsg"><h3>Received FLO Data : </h3><br/></div>
</div> </div>
<script> <script>
addrGenMode(); //default start addrGenMode(); //default start
function clearLocalData() function clearLocalData()
{ {
var table = document.getElementById("dispfloData"); document.getElementById("dispMsg").innerHTML = '<h3>Received FLO Data : </h3><br/>';
for(var i = table.rows.length - 1; i > 0; i--)
table.deleteRow(i);
var DBDeleteRequest = window.indexedDB.deleteDatabase("FLO_Walletless"); var DBDeleteRequest = window.indexedDB.deleteDatabase("FLO_Walletless");
DBDeleteRequest.onsuccess = function(event) { DBDeleteRequest.onsuccess = function(event) {
console.log("Database deleted successfully"); console.log("Database deleted successfully");
alert("Successfully Cleared Local Data!"); alert("Successfully Cleared Local Data!");
console.log(event.result);
}; };
} }
function addrGenMode(){ function addrGenMode(){
document.getElementById("addrGenBtn").disabled = true; document.getElementById("addrGenBtn").disabled = true;
document.getElementById("sendDataBtn").disabled = false; document.getElementById("sendDataBtn").disabled = false;
document.getElementById("getDataBtn").disabled = false; document.getElementById("getDataBtn").disabled = false;
document.getElementById("addrGen").style.display = 'block'; document.getElementById("addrGen").style.display = 'block';
document.getElementById("sendData").style.display = 'none'; document.getElementById("sendData").style.display = 'none';
document.getElementById("getData").style.display = 'none'; document.getElementById("getData").style.display = 'none';
} }
function sendDataMode(){ function sendDataMode(){
document.getElementById("addrGenBtn").disabled = false; document.getElementById("addrGenBtn").disabled = false;
document.getElementById("sendDataBtn").disabled = true; document.getElementById("sendDataBtn").disabled = true;
document.getElementById("getDataBtn").disabled = false; document.getElementById("getDataBtn").disabled = false;
document.getElementById("addrGen").style.display = 'none'; document.getElementById("addrGen").style.display = 'none';
document.getElementById("sendData").style.display = 'block'; document.getElementById("sendData").style.display = 'block';
document.getElementById("getData").style.display = 'none'; document.getElementById("getData").style.display = 'none';
} }
function getDataMode(){ function getDataMode(){
document.getElementById("addrGenBtn").disabled = false; document.getElementById("addrGenBtn").disabled = false;
document.getElementById("sendDataBtn").disabled = false; document.getElementById("sendDataBtn").disabled = false;
document.getElementById("getDataBtn").disabled = true; document.getElementById("getDataBtn").disabled = true;
document.getElementById("addrGen").style.display = 'none'; document.getElementById("addrGen").style.display = 'none';
document.getElementById("sendData").style.display = 'none'; document.getElementById("sendData").style.display = 'none';
document.getElementById("getData").style.display = 'block'; document.getElementById("getData").style.display = 'block';
} }
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
/*! /*!
* Crypto-JS v2.5.4 Crypto.js * Crypto-JS v2.5.4 Crypto.js
@ -246,13 +250,13 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
}; };
})(); })();
} }
</script> </script>
<!-- SHA1 --> <!-- SHA1 -->
<script type="text/javascript"> <script type="text/javascript">
//Adding SHA1 to fix basic PKBDF2 //Adding SHA1 to fix basic PKBDF2
/* /*
* Crypto-JS v2.5.4 * Crypto-JS v2.5.4
@ -594,11 +598,11 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
<script type="text/javascript"> <script type="text/javascript">
/*! /*!
* Random number generator with ArcFour PRNG * Random number generator with ArcFour PRNG
* *
* NOTE: For best results, put code like * NOTE: For best results, put code like
* <body onclick='SecureRandom.seedTime();' onkeypress='SecureRandom.seedTime();'> * <body onclick='SecureRandom.seedTime();' onkeypress='SecureRandom.seedTime();'>
* in your main HTML document. * in your main HTML document.
* *
* Copyright Tom Wu, bitaddress.org BSD License. * Copyright Tom Wu, bitaddress.org BSD License.
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
*/ */
@ -2571,7 +2575,7 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
* Basic Javascript Elliptic Curve implementation * Basic Javascript Elliptic Curve implementation
* Ported loosely from BouncyCastle's Java EC code * Ported loosely from BouncyCastle's Java EC code
* Only Fp curves implemented for now * Only Fp curves implemented for now
* *
* Copyright Tom Wu, bitaddress.org BSD License. * Copyright Tom Wu, bitaddress.org BSD License.
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE * http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
*/ */
@ -2633,7 +2637,7 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
/** /**
* return a sqrt root - the routine verifies that the calculation * return a sqrt root - the routine verifies that the calculation
* returns the right value - if none exists it returns null. * returns the right value - if none exists it returns null.
* *
* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) * Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
* Ported to JavaScript by bitaddress.org * Ported to JavaScript by bitaddress.org
*/ */
@ -2929,7 +2933,7 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol. var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol.
var enc = ec.integerToBytes(x, len); var enc = ec.integerToBytes(x, len);
// when compressed prepend byte depending if y point is even or odd // when compressed prepend byte depending if y point is even or odd
if (compressed) { if (compressed) {
if (y.isEven()) { if (y.isEven()) {
enc.unshift(0x02); enc.unshift(0x02);
@ -3402,7 +3406,7 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
btrx.addflodata = function (txcomments) { // flochange - this whole function needs to be done btrx.addflodata = function (txcomments) { // flochange - this whole function needs to be done
this.floData = txcomments; this.floData = txcomments;
return this.floData; //flochange .. returning the txcomments -- check if the function return will assign return this.floData; //flochange .. returning the txcomments -- check if the function return will assign
} }
@ -3694,13 +3698,13 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
buffer = buffer.concat(scriptBytes); buffer = buffer.concat(scriptBytes);
} }
buffer = buffer.concat(bitjs.numToBytes(parseInt(this.locktime),4)); buffer = buffer.concat(bitjs.numToBytes(parseInt(this.locktime),4));
flohex = ascii_to_hexa(this.floData); flohex = ascii_to_hexa(this.floData);
floDataCount = this.floData.length; floDataCount = this.floData.length;
//flochange -- creating unique data character count logic for floData. This string is prefixed before actual floData string in Raw Transaction //flochange -- creating unique data character count logic for floData. This string is prefixed before actual floData string in Raw Transaction
if (floDataCount <= 16) { if (floDataCount <= 16) {
floDataCountString = floDataCount.toString(16); floDataCountString = floDataCount.toString(16);
floDataCountString = "0"+ floDataCountString; floDataCountString = "0"+ floDataCountString;
} else if (floDataCount < 253) { } else if (floDataCount < 253) {
floDataCountString = floDataCount.toString(16); floDataCountString = floDataCount.toString(16);
@ -3841,8 +3845,8 @@ if (typeof Crypto == "undefined" || !Crypto.util) {
})(); })();
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
/* /*
Copyright (c) 2011 Stefan Thomas Copyright (c) 2011 Stefan Thomas
@ -3861,7 +3865,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
'object' === typeof module ? module.exports : (window.Bitcoin = {}) 'object' === typeof module ? module.exports : (window.Bitcoin = {})
); );
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
//https://raw.github.com/bitcoinjs/bitcoinjs-lib/c952aaeb3ee472e3776655b8ea07299ebed702c7/src/base58.js //https://raw.github.com/bitcoinjs/bitcoinjs-lib/c952aaeb3ee472e3776655b8ea07299ebed702c7/src/base58.js
(function (Bitcoin) { (function (Bitcoin) {
@ -4132,7 +4136,7 @@ Bitcoin.ECDSA = (function () {
* Parses a byte array containing a DER-encoded signature. * Parses a byte array containing a DER-encoded signature.
* *
* This function will return an object of the form: * This function will return an object of the form:
* *
* { * {
* r: BigInteger, * r: BigInteger,
* s: BigInteger * s: BigInteger
@ -4372,19 +4376,19 @@ Bitcoin.ECKey = (function () {
} else if ("string" == typeof input) { } else if ("string" == typeof input) {
var bytes = null; var bytes = null;
try{ try{
// This part is edited for FLO. FLO WIF are always compressed WIF. FLO WIF (private key) starts with R for mainnet and c for testnet. // This part is edited for FLO. FLO WIF are always compressed WIF. FLO WIF (private key) starts with R for mainnet and c for testnet.
if((server == mainnet && /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(input)) || if((server == mainnet && /^R[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(input)) ||
(server == testnet && /^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(input))) { (server == testnet && /^c[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{51}$/.test(input))) {
bytes = ECKey.decodeCompressedWalletImportFormat(input); bytes = ECKey.decodeCompressedWalletImportFormat(input);
this.compressed = true; this.compressed = true;
} }
/* /*
if (ECKey.isWalletImportFormat(input)) { if (ECKey.isWalletImportFormat(input)) {
bytes = ECKey.decodeWalletImportFormat(input); bytes = ECKey.decodeWalletImportFormat(input);
} else if (ECKey.isCompressedWalletImportFormat(input)) { } else if (ECKey.isCompressedWalletImportFormat(input)) {
bytes = ECKey.decodeCompressedWalletImportFormat(input); bytes = ECKey.decodeCompressedWalletImportFormat(input);
this.compressed = true; this.compressed = true;
} else if (ECKey.isMiniFormat(input)) { } else if (ECKey.isMiniFormat(input)) {
@ -4426,7 +4430,7 @@ Bitcoin.ECKey = (function () {
this.setError(exc2); this.setError(exc2);
} }
}; };
if(server == mainnet) if(server == mainnet)
ECKey.privateKeyPrefix = 0xA3; //(Bitcoin mainnet 0x80 testnet 0xEF) (FLO mainnet 0xA3 163 D) ECKey.privateKeyPrefix = 0xA3; //(Bitcoin mainnet 0x80 testnet 0xEF) (FLO mainnet 0xA3 163 D)
else if(server == testnet) else if(server == testnet)
@ -4525,7 +4529,7 @@ Bitcoin.ECKey = (function () {
return this; return this;
}; };
// Sipa Private Key Wallet Import Format // Sipa Private Key Wallet Import Format
ECKey.prototype.getBitcoinWalletImportFormat = function () { ECKey.prototype.getBitcoinWalletImportFormat = function () {
var bytes = this.getBitcoinPrivateKeyByteArray(); var bytes = this.getBitcoinPrivateKeyByteArray();
if (bytes == null) return ""; if (bytes == null) return "";
@ -4537,12 +4541,12 @@ Bitcoin.ECKey = (function () {
return privWif; return privWif;
}; };
// Private Key Hex Format // Private Key Hex Format
ECKey.prototype.getBitcoinHexFormat = function () { ECKey.prototype.getBitcoinHexFormat = function () {
return Crypto.util.bytesToHex(this.getBitcoinPrivateKeyByteArray()).toString().toUpperCase(); return Crypto.util.bytesToHex(this.getBitcoinPrivateKeyByteArray()).toString().toUpperCase();
}; };
// Private Key Base64 Format // Private Key Base64 Format
ECKey.prototype.getBitcoinBase64Format = function () { ECKey.prototype.getBitcoinBase64Format = function () {
return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray()); return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray());
}; };
@ -4551,7 +4555,7 @@ Bitcoin.ECKey = (function () {
if (this.priv == null) return null; if (this.priv == null) return null;
// Get a copy of private key as a byte array // Get a copy of private key as a byte array
var bytes = this.priv.toByteArrayUnsigned(); var bytes = this.priv.toByteArrayUnsigned();
// zero pad if private key is less than 32 bytes // zero pad if private key is less than 32 bytes
while (bytes.length < 32) bytes.unshift(0x00); while (bytes.length < 32) bytes.unshift(0x00);
return bytes; return bytes;
}; };
@ -4795,7 +4799,7 @@ Bitcoin.Util = {
request.open(method,url , false); request.open(method,url , false);
request.onload = function () { request.onload = function () {
if (request.readyState == 4 && request.status == 200) if (request.readyState == 4 && request.status == 200)
result = this.response; result = this.response;
else { else {
console.log('error'); console.log('error');
result = false; result = false;
@ -4805,7 +4809,7 @@ Bitcoin.Util = {
console.log(result); console.log(result);
return result; return result;
} }
function validateAddr(inputtxt) { function validateAddr(inputtxt) {
try{ try{
var addr = new Bitcoin.Address(inputtxt); var addr = new Bitcoin.Address(inputtxt);
@ -4815,7 +4819,7 @@ Bitcoin.Util = {
return false; return false;
} }
} }
function verifyWIF(wif,addr){ function verifyWIF(wif,addr){
try { try {
var key = new Bitcoin.ECKey(wif); var key = new Bitcoin.ECKey(wif);
@ -4836,9 +4840,9 @@ Bitcoin.Util = {
} }
} }
</script> </script>
<script> <script>
function GenNewAddr(){ function GenNewAddr(){
try { try {
var key = new Bitcoin.ECKey(false); var key = new Bitcoin.ECKey(false);
@ -4853,7 +4857,7 @@ Bitcoin.Util = {
var cell1 = row.insertCell(0); var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1); var cell2 = row.insertCell(1);
cell1.innerHTML = bitcoinAddress; cell1.innerHTML = bitcoinAddress;
cell2.innerHTML = privateKeyWif; cell2.innerHTML = privateKeyWif;
} }
catch (e) { catch (e) {
// browser does not have sufficient JavaScript support to generate a bitcoin address // browser does not have sufficient JavaScript support to generate a bitcoin address
@ -4861,7 +4865,7 @@ Bitcoin.Util = {
console.log("error"); console.log("error");
} }
} }
function RecoverAddr(){ function RecoverAddr(){
try { try {
wif = prompt("Enter Secret (or) Private Key :"); wif = prompt("Enter Secret (or) Private Key :");
@ -4885,7 +4889,7 @@ Bitcoin.Util = {
var cell1 = row.insertCell(0); var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1); var cell2 = row.insertCell(1);
cell1.innerHTML = bitcoinAddress; cell1.innerHTML = bitcoinAddress;
cell2.innerHTML = privateKeyWif; cell2.innerHTML = privateKeyWif;
} }
catch (e) { catch (e) {
// browser does not have sufficient JavaScript support to generate a bitcoin address // browser does not have sufficient JavaScript support to generate a bitcoin address
@ -4893,7 +4897,7 @@ Bitcoin.Util = {
} }
} }
</script> </script>
<script> <script>
var getBal_btn = document.getElementById("getBal_btn"); var getBal_btn = document.getElementById("getBal_btn");
getBal_btn.onclick = function () { getBal_btn.onclick = function () {
@ -4908,7 +4912,7 @@ Bitcoin.Util = {
let addrList = addrs.split(','); let addrList = addrs.split(',');
addrList = Array.from(new Set(addrList)); addrList = Array.from(new Set(addrList));
var result = ""; var result = "";
var totBal = 0; var totBal = 0.0;
var flag = 0; var flag = 0;
addrList.forEach(function(addr){ addrList.forEach(function(addr){
if (!validateAddr(addr)){ if (!validateAddr(addr)){
@ -4917,47 +4921,44 @@ Bitcoin.Util = {
} }
var response = ajax("GET",`api/addr/${addr}/balance`); var response = ajax("GET",`api/addr/${addr}/balance`);
if(response){ if(response){
result += `<input type="radio" name="sender" value=${addr} checked> ${addr} ${response} <br/>\n`; result += `<tr><td><input type="radio" name="sender" value=${addr} checked></td><td>${addr}</td><td>${response}</td></tr> \n`;
totBal+=response; totBal+=parseFloat(response);
flag = 1; flag = 1;
}else{ }else{
console.log("error : connection failed!"); console.log("error : connection failed!");
alert("error : connection failed!"); alert("error : connection failed!");
} }
}); });
if(flag==0){ if(flag==0){
document.getElementById("sendBtn").disabled = true; document.getElementById("sendBtn").disabled = true;
return ; return ;
} }
result+=`\nTotal Balance : ${totBal}`; dispBal.innerHTML = `<table>${result}<tr><td colspan="2">Total Balance :</td><td>${totBal}</tr></table>`;
dispBal.innerHTML = result;
document.getElementById("sendBtn").disabled = false; document.getElementById("sendBtn").disabled = false;
} }
</script> </script>
<script> <script>
function sendTransaction(){ function sendTransaction(){
var radioButtons = document.getElementsByName("sender"); var radioButtons = document.getElementsByName("sender");
var sender; var sender;
for (var x = 0; x < radioButtons.length; x++) for (var x = 0; x < radioButtons.length; x++)
if (radioButtons[x].checked) if (radioButtons[x].checked)
sender=radioButtons[x].value; sender=radioButtons[x].value;
var receiver = document.getElementById("sendReceiver").value; var receiver = document.getElementById("sendReceiver").value;
if (!validateAddr(receiver)){ if (!validateAddr(receiver)){
alert(`Invalid address : ${receiver}`); alert(`Invalid address : ${receiver}`);
return; return;
} }
var trx = bitjs.transaction(); var trx = bitjs.transaction();
var sendAmt = parseFloat(document.getElementById("sendAmt").value); var sendAmt = parseFloat(document.getElementById("sendAmt").value);
var utxoAmt = 0.0; var utxoAmt = 0.0;
console.log(sender+":"+sendAmt);
var x = sendAmt+fee; var x = sendAmt+fee;
console.log(x);
var response = ajax("GET",`api/addr/${sender}/utxo`); var response = ajax("GET",`api/addr/${sender}/utxo`);
var utxos = JSON.parse(response); var utxos = JSON.parse(response);
for(var x = utxos.length-1; x >= 0; x--){ for(var x = utxos.length-1; x >= 0; x--){
@ -4965,24 +4966,22 @@ Bitcoin.Util = {
var txid = utxos[x].txid; var txid = utxos[x].txid;
var index = utxos[x].vout; var index = utxos[x].vout;
var scriptPubKey = utxos[x].scriptPubKey; var scriptPubKey = utxos[x].scriptPubKey;
var bal = utxos[x].amount var bal = utxos[x].amount;
console.log(""+utxoAmt+"::"+txid + " : " + index +" : "+scriptPubKey +":"+bal);
trx.addinput(txid, index, scriptPubKey) trx.addinput(txid, index, scriptPubKey)
utxoAmt += bal; utxoAmt += bal;
}else }else
break; break;
} }
console.log(utxoAmt+":"+(sendAmt+fee));
if(utxoAmt < sendAmt+fee){ if(utxoAmt < sendAmt+fee){
alert("Insufficient balance!"); alert("Insufficient balance!");
return; return;
} }
trx.addoutput(receiver, sendAmt); trx.addoutput(receiver, sendAmt);
console.log(receiver+":"+ sendAmt); console.log(receiver+":"+ sendAmt);
var change = utxoAmt-sendAmt-fee; var change = utxoAmt-sendAmt-fee;
if(change>0) if(change>0)
trx.addoutput(sender, change); trx.addoutput(sender, change);
@ -4990,7 +4989,6 @@ Bitcoin.Util = {
var sendFloData = document.getElementById("flotextdata").value; var sendFloData = document.getElementById("flotextdata").value;
trx.addflodata(sendFloData); trx.addflodata(sendFloData);
console.log(sendFloData);
var wif = prompt("Enter private key"); var wif = prompt("Enter private key");
if (wif.length<1||!verifyWIF(wif,sender)){ if (wif.length<1||!verifyWIF(wif,sender)){
alert("Invalid Private key!"); alert("Invalid Private key!");
@ -5010,7 +5008,7 @@ Bitcoin.Util = {
alert("Empty Signature"); alert("Empty Signature");
return false; return false;
} }
var params = `{"rawtx":"${signedTxHash}"}`; var params = `{"rawtx":"${signedTxHash}"}`;
var result; var result;
http.open('POST', url, false); http.open('POST', url, false);
@ -5026,130 +5024,223 @@ Bitcoin.Util = {
} else { } else {
console.log(http.responseText); console.log(http.responseText);
result = http.response; result = http.response;
} }
} }
http.send(params); http.send(params);
return result; return result;
} }
</script> </script>
<script> <script>
var waitForGlobal = function(param, callback) {
if (!window[param]) {
callback();
} else {
setTimeout(function() {
waitForGlobal(param, callback);
}, 100);
}
};
function monitorData(){ function monitorData(){
var addrList = document.getElementById("getAddr").value; var addrList = document.getElementById("getAddr").value;
addrList = addrList.split(','); addrList = addrList.split(',');
addrList = Array.from(new Set(addrList)); addrList = Array.from(new Set(addrList));
//clear the table var dispMsg = document.getElementById("dispMsg") ;
var table = document.getElementById("dispfloData"); window["refreshwait"] = addrList.length;
for(var i = table.rows.length - 1; i > 0; i--)
table.deleteRow(i);
addrList.forEach(function(addr){ addrList.forEach(function(addr){
if (!validateAddr(addr)){ if (!validateAddr(addr)){
alert(`Invalid address : ${addr}`); alert(`Invalid address : ${addr}`);
window["refreshwait"] -= 1;
return; return;
} }
var addrData = document.getElementById(addr);
var idbtmp = indexedDB.open("FLO_Walletless"); if(addrData){
idbtmp.onerror = function(event) { refreshdata(addrData);
console.log("Error in opening IndexedDB1!"); window["refreshwait"] -= 1;
}; return;
idbtmp.onupgradeneeded = function(event) { }
console.log("up");
}; waitForGlobal("loadwait", function() {
idbtmp.onsuccess = function(event) { window["loadwait"] = true;
var db = event.target.result; var idbtmp = indexedDB.open("FLO_Walletless");
var version = db.version; idbtmp.onerror = function(event) {
console.log("."+db.version); console.log("Error in opening IndexedDB!");
if(!db.objectStoreNames.contains(addr)) window["loadwait"] = false;
version = db.version + 1; };
db.close(); idbtmp.onupgradeneeded = function(event) {
console.log(":"+version); var objectStore = event.target.result.createObjectStore('Label');
var idb = indexedDB.open("FLO_Walletless",version); //objectStore.createIndex("label", "label", { unique: false });
idb.onerror = function(event) { };
console.log("Error in opening IndexedDB!"); idbtmp.onsuccess = function(event) {
}; var db = event.target.result;
idb.onupgradeneeded = function(event) {
var objectStore = event.target.result.createObjectStore(addr, { keyPath: "tx", autoIncrement:true }); if(!db.objectStoreNames.contains(addr)){
objectStore.createIndex("time", "time", { unique: false }); var newaddr = true;
objectStore.createIndex("sender", "sender", { unique: false }); var version = db.version + 1;
objectStore.createIndex("receiver", "receiver", { unique: false }); }
objectStore.createIndex("floData", "floData", { unique: false });
objectStore.createIndex("txid", "txid", { unique: true }); else {
}; var newaddr = false;
idb.onsuccess = function(event) { var version = db.version;
}
var db = event.target.result; db.close();
var obs = db.transaction(addr, "readwrite").objectStore(addr); var idb = indexedDB.open("FLO_Walletless",version);
var countRequest = obs.count(); idb.onerror = function(event) {
countRequest.onsuccess = function() { console.log("Error in opening IndexedDB!");
console.log(countRequest.result); };
var response = ajax("GET",`api/addrs/${addr}/txs`); idb.onupgradeneeded = function(event) {
var nRequired = JSON.parse(response).totalItems - countRequest.result; var objectStore = event.target.result.createObjectStore(addr, { keyPath: "tx", autoIncrement:true });
console.log(nRequired); objectStore.createIndex("time", "time", { unique: false });
objectStore.createIndex("sender", "sender", { unique: false });
while(true && nRequired){ objectStore.createIndex("receiver", "receiver", { unique: false });
var response = ajax("GET",`api/addrs/${addr}/txs?from=0&to=${nRequired}`); objectStore.createIndex("floData", "floData", { unique: false });
response = JSON.parse(response); objectStore.createIndex("txid", "txid", { unique: true });
if (nRequired + countRequest.result != response.totalItems ){ };
nRequired = response.totalItems - countRequest.result; idb.onsuccess = function(event) {
continue; //window["loadwait"] = false;
} var db = event.target.result;
console.log("Yes"); var obslabel = db.transaction('Label', "readwrite").objectStore('Label');
var i=1; if(newaddr)
response.items.reverse().forEach(function(tx){ obslabel.add('',addr);
console.log(""+tx.time +":" +i); i++;
obs.put({time : tx.time, txid : tx.txid, sender : tx.vin[0].addr, receiver:tx.vout[0].scriptPubKey.addresses[0],floData : tx.floData}); var dispMsgAddr = document.createElement('div');
}); dispMsgAddr.id = addr;
break; dispMsgAddr.innerHTML = `<hr><h4>${addr}</h4>Label : <input type="text" id="label" disabled><br>
} <button onclick="editLabel(this.parentNode)" style="display:block;">edit</button>
<button onclick="saveLabel(this.parentNode)" style="display:none;">save</button>
var flag = false; <br>
var table=document.getElementById("dispfloData"); <button onclick="refreshdata(this.parentNode)">refresh</button>
var cursorRequest = obs.openCursor(); <button onclick="removedata(this.parentNode)">remove</button><br>`;
cursorRequest.onsuccess = function(event) {
var cursor = event.target.result;
//console.log("g"); var labelRequest = obslabel.get(addr);
if(cursor) { labelRequest.onsuccess = function(event){
// cursor.value contains the current record being iterated through dispMsgAddr.getElementsByTagName('input')[0].value = labelRequest.result;
// this is where you'd do something with the result };
console.log(cursor.value.sender+":"+cursor.value.receiver+":"+cursor.value.time+":"+cursor.value.txid+":"+cursor.value.floData);
var time = new Date(cursor.value.time*1000); var table = document.createElement('table');
var row = table.insertRow(1) ; dispMsgAddr.appendChild(table);
row.insertCell(0).innerHTML = cursor.value.sender; dispMsg.appendChild(dispMsgAddr);
row.insertCell(1).innerHTML = cursor.value.receiver;
row.insertCell(2).innerHTML = time; var row = table.insertRow(0) ;
row.insertCell(3).innerHTML = cursor.value.floData; row.insertCell(0).innerHTML = 'Sender';
flag = true; row.insertCell(1).innerHTML = 'Receiver';
//tmpResult = '<tr><td>'++'</td><td>'++'</td><td>'++'</td><td>'++'</td></tr>' + tmpResult; row.insertCell(2).innerHTML = 'Time';
cursor.continue(); row.insertCell(3).innerHTML = 'floData';
} else {
var obs = db.transaction(addr, "readwrite").objectStore(addr);
if(!flag){
var row1 = table.insertRow(1) ; var cursorRequest = obs.openCursor();
var cell1 = row1.insertCell(0); cursorRequest.onsuccess = function(event) {
cell1.innerHTML= "Sorry! No Flo Data received!"; var cursor = event.target.result;
cell1.colSpan = 4 if(cursor) {
} // cursor.value contains the current record being iterated through
var row2 = table.insertRow(1) ; // this is where you'd do something with the result
var cell2 = row2.insertCell(0); //console.log(cursor.value.sender+":"+cursor.value.receiver+":"+cursor.value.time+":"+cursor.value.txid+":"+cursor.value.floData);
cell2.innerHTML= '<b><center>'+addr+'</center></b>'; var time = new Date(cursor.value.time*1000);
cell2.colSpan = 4 var row = table.insertRow(1) ;
row.insertCell(0).innerHTML = cursor.value.sender;
} row.insertCell(1).innerHTML = cursor.value.receiver;
}; row.insertCell(2).innerHTML = time;
}; row.insertCell(3).innerHTML = cursor.value.floData;
//tmpResult = '<tr><td>'++'</td><td>'++'</td><td>'++'</td><td>'++'</td></tr>' + tmpResult;
db.close(); cursor.continue();
}; } else {
refreshdata(dispMsgAddr);
} }
};
db.close();
window["refreshwait"] -= 1;
};
window["loadwait"] = false;
};
});
});
});
} }
</script> </script>
<script>
function refreshdata(param){
var addr = param.id;
var table = param.getElementsByTagName('table')[0];
var row = table.insertRow(1) ;
var cell = row.insertCell(0);
cell.innerHTML = "<center>Refreshing...</center>";
cell.colSpan = 4;
waitForGlobal("refreshwait", function() {
var idb = indexedDB.open("FLO_Walletless");
idb.onerror = function(event) {
console.log("Error in opening IndexedDB!");
};
idb.onsuccess = function(event) {
var db = event.target.result;
var obs = db.transaction(addr, "readwrite").objectStore(addr);
var countRequest = obs.count();
countRequest.onsuccess = function() {
console.log(countRequest.result);
var response = ajax("GET",`api/addrs/${addr}/txs`);
var nRequired = JSON.parse(response).totalItems - countRequest.result;
console.log(nRequired);
while(true && nRequired){
var response = ajax("GET",`api/addrs/${addr}/txs?from=0&to=${nRequired}`);
response = JSON.parse(response);
if (nRequired + countRequest.result != response.totalItems ){
nRequired = response.totalItems - countRequest.result;
continue;
}
response.items.reverse().forEach(function(tx){
obs.put({time : tx.time, txid : tx.txid, sender : tx.vin[0].addr, receiver:tx.vout[0].scriptPubKey.addresses[0],floData : tx.floData});
var time = new Date(tx.time*1000);
var row = table.insertRow(2) ;
row.insertCell(0).innerHTML = tx.vin[0].addr;
row.insertCell(1).innerHTML = tx.vout[0].scriptPubKey.addresses[0];
row.insertCell(2).innerHTML = time;
row.insertCell(3).innerHTML = tx.floData;
});
break;
}
table.deleteRow(1);
};
db.close();
};
});
}
function removedata(param){
param.parentNode.removeChild(param);
}
function editLabel(param){
param.getElementsByTagName('input')[0].disabled = false;
param.getElementsByTagName('button')[0].style.display = "none";
param.getElementsByTagName('button')[1].style.display = "block";
}
function saveLabel(param){
label = param.getElementsByTagName('input')[0];
label.disabled = true;
label = label.value;
param.getElementsByTagName('button')[0].style.display = "block";
param.getElementsByTagName('button')[1].style.display = "none";
var idb = indexedDB.open("FLO_Walletless");
idb.onerror = function(event) {
console.log("Error in opening IndexedDB!");
};
idb.onsuccess = function(event) {
var db = event.target.result;
var obslabel = db.transaction('Label', "readwrite").objectStore('Label');
obslabel.put(label,param.id);
db.close();
}
}
</script>
</body> </body>
</html> </html>