window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction; window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange; if (!window.indexedDB) { window.alert("Your browser doesn't support a stable version of IndexedDB.") } var contacts = []; var receiverID,senderID; var selfwebsocket; var privKey = prompt("Enter Private Key : ") var wallets = { ecparams: EllipticCurve.getSECCurveByName("secp256k1"), getPubKeyHex: function(privateKeyHex){ var key = new Bitcoin.ECKey(privateKeyHex); if(key.priv == null){ alert("Invalid Private key"); return; } key.setCompressed(true); var pubkeyHex = key.getPubKeyHex(); return pubkeyHex; }, sign: function (msg, privateKeyHex) { var key = new Bitcoin.ECKey(privateKeyHex); key.setCompressed(true); var privateKeyArr = key.getBitcoinPrivateKeyByteArray(); privateKey = BigInteger.fromByteArrayUnsigned(privateKeyArr); var messageHash = Crypto.SHA256(msg); var messageHashBigInteger = new BigInteger(messageHash); var messageSign = Bitcoin.ECDSA.sign(messageHashBigInteger, key.priv); var sighex = Crypto.util.bytesToHex(messageSign); return sighex; }, verify: function (msg, signatureHex, publicKeyHex) { var msgHash = Crypto.SHA256(msg); var messageHashBigInteger = new BigInteger(msgHash); var sigBytes = Crypto.util.hexToBytes(signatureHex); var signature = Bitcoin.ECDSA.parseSig(sigBytes); var publicKeyPoint = this.ecparams.getCurve().decodePointHex(publicKeyHex); var verify = Bitcoin.ECDSA.verifyRaw(messageHashBigInteger, signature.r, signature.s, publicKeyPoint); return verify; } } function convertStringToInt(string){ return parseInt(string,10); } function userDataStartUp(){ console.log("StartUp"); getDatafromAPI().then(function (result) { console.log(result); getuserID().then(function(result){ console.log(result); getDatafromIDB().then(function(result){ contacts = arrayToObject(result); console.log(contacts); displayContacts(); readMsgfromIDB().then(function(result){ console.log(result); initselfWebSocket(); }).catch(function(error){ console.log(error.message); }); //startChats(); }).catch(function (error) { console.log(error.message); }); }).catch(function (error) { console.log(error.message); }); }).catch(function (error) { console.log(error.message); }); } function arrayToObject(array){ obj = {}; array.forEach(element => { obj[element.floID] = {onionAddr : element.onionAddr, name : element.name}; }); return obj; } function storedata(data){ return new Promise( function(resolve, reject) { var idb = indexedDB.open("FLO_Chat"); idb.onerror = function(event) { console.log("Error in opening IndexedDB!"); }; idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction('contacts', "readwrite").objectStore('contacts'); objectRequest = obs.put(data); objectRequest.onerror = function(event) { reject(Error('Error occured: Unable to store data')); }; objectRequest.onsuccess = function(event) { resolve('Data saved OK'); db.close(); }; }; } ); } function getDatafromAPI(){ return new Promise( function(resolve, reject) { var addr = "F6LUnwRRjFuEW97Y4av31eLqqVMK9FrgE2"; var idb = indexedDB.open("FLO_Chat"); idb.onerror = function(event) { console.log("Error in opening IndexedDB!"); }; idb.onupgradeneeded = function(event) { var objectStore = event.target.result.createObjectStore("contacts",{ keyPath: 'floID' }); objectStore.createIndex('onionAddr', 'onionAddr', { unique: true }); objectStore.createIndex('name', 'name', { unique: false }); var objectStore2 = event.target.result.createObjectStore("lastTx"); }; idb.onsuccess = function(event) { var db = event.target.result; //window["wait"] = addrList.length; var lastTx = db.transaction('lastTx', "readwrite").objectStore('lastTx'); //addrList.forEach(function(addr){ console.log(addr); new Promise(function(res,rej){ var lastTxReq = lastTx.get(addr); lastTxReq.onsuccess = function(event){ var lasttx = event.target.result; if(lasttx === undefined){ lasttx = 0; } res(lasttx); } }).then(function(lasttx){ var response = ajax("GET",`api/addrs/${addr}/txs`); var nRequired = JSON.parse(response).totalItems - lasttx; console.log(nRequired); while(true && nRequired){ var response = ajax("GET",`api/addrs/${addr}/txs?from=0&to=${nRequired}`); response = JSON.parse(response); if (nRequired + lasttx != response.totalItems ){ nRequired = response.totalItems - lasttx; continue; } response.items.reverse().forEach(function(tx){ try { //if (tx.vin[0].addr != addr) //return; var data = JSON.parse(tx.floData).FLO_chat; if(data !== undefined){ data = {floID : tx.vin[0].addr, onionAddr : data.onionAddr, name : data.name}; storedata(data).then(function (response) { }).catch(function (error) { console.log(error.message); }); } } catch (e) { //console.log(e) } }); var obs = db.transaction('lastTx', "readwrite").objectStore('lastTx'); obs.put(response.totalItems,addr); break; } window["wait"]--; db.close(); resolve('retrived data from API'); }); }; } ); } function getuserID(){ return new Promise( function(resolve,reject){ var idb = indexedDB.open("FLO_Chat"); idb.onerror = function(event) { console.log("Error in opening IndexedDB!"); }; idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction('lastTx', "readwrite").objectStore('lastTx'); new Promise(function(res,rej){ var getReq = obs.get('userID'); getReq.onsuccess = function(event){ var userID = event.target.result; if(userID === undefined){ userID = prompt("Enter A Valid Flo ID!"); while(!validateAddr(userID)){ userID = prompt("Retry!Enter A Valid Flo ID!"); } var obs2 = db.transaction('contacts', "readwrite").objectStore('contacts'); var getReq2 = obs2.get(userID); getReq2.onsuccess = function(event){ var data = event.target.result; console.log(window.location.host); //console.log(data.onionAddr); if(data === undefined) var reg = confirm('FLO ID is not registers to FLO chat!\nRegister FLO ID?'); else if(data.onionAddr == window.location.host) res(userID); else var reg = confirm('FLO ID is registered to another onion!\nChange FLO ID to this onion?'); if(reg) if(registerID(userID,window.location.host)) res(userID); rej('Unable to register userID!\nTry again later!'); } } else res(userID); } }).then(function(result){ console.log(result); var obs = db.transaction('lastTx', "readwrite").objectStore('lastTx'); senderID = result; obs.put(result,'userID'); db.close(); resolve('userID Initiated') }).catch(function(error){ db.close(); console.log(error.message); reject('userID Initiation Failed'); }); }; } ); } function getDatafromIDB(){ return new Promise( function(resolve,reject){ var idb = indexedDB.open("FLO_Chat"); idb.onerror = function(event) { reject("Error in opening IndexedDB!"); }; idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction("contacts", "readwrite").objectStore("contacts"); var getReq = obs.getAll(); getReq.onsuccess = function(event){ resolve(event.target.result); } getReq.onerror = function(event){ reject('Unable to read contacts!') } db.close(); }; } ); } function readMsgfromIDB(){ return new Promise( function(resolve,reject){ var disp = document.getElementById("conversation"); for(floID in contacts){ var createLi = document.createElement('div'); createLi.setAttribute("id", floID); createLi.setAttribute("class", "message-inner"); createLi.style.display = 'none'; disp.appendChild(createLi); } var idb = indexedDB.open("FLO_Chat",2); idb.onerror = function(event) { reject("Error in opening IndexedDB!"); }; idb.onupgradeneeded = function(event) { var objectStore = event.target.result.createObjectStore("messages",{ keyPath: 'time' }); objectStore.createIndex('text', 'text', { unique: false }); objectStore.createIndex('floID', 'floID', { unique: false }); objectStore.createIndex('type', 'type', { unique: false }); }; idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction("messages", "readwrite").objectStore("messages"); obs.openCursor().onsuccess = function(event) { var cursor = event.target.result; if(cursor) { var chat = document.getElementById(cursor.value.floID); if(cursor.value.type == "R"){ var msgdiv = document.createElement('div'); msgdiv.setAttribute("class", "row message-body"); msgdiv.innerHTML = `
`; chat.appendChild(msgdiv); }else if(cursor.value.type == "S"){ var msgdiv = document.createElement('div'); msgdiv.setAttribute("class", "row message-body"); msgdiv.innerHTML = ``; chat.appendChild(msgdiv); } cursor.continue(); } else { console.log('Entries all displayed.'); resolve("Read Msg from IDB"); } }; db.close(); }; } ); } function storeMsg(data){ var idb = indexedDB.open("FLO_Chat",2); idb.onerror = function(event) { console.log("Error in opening IndexedDB!"); }; idb.onupgradeneeded = function(event) { var objectStore = event.target.result.createObjectStore("messages",{ keyPath: 'time' }); objectStore.createIndex('text', 'text', { unique: false }); objectStore.createIndex('floID', 'floID', { unique: false }); objectStore.createIndex('type', 'type', { unique: false }); }; idb.onsuccess = function(event) { var db = event.target.result; var obs = db.transaction("messages", "readwrite").objectStore("messages"); obs.add(data); db.close(); }; } function displayContacts(){ console.log('displayContacts'); var listElement = document.getElementById('contact-display'); for(floID in contacts){ var createLi = document.createElement('div'); createLi.setAttribute("name", floID); createLi.setAttribute("onClick", 'changeReceiver(this)'); createLi.setAttribute("class", "row sideBar-body"); createLi.innerHTML = `