diff --git a/index.html b/index.html
index c5f2e4d..2425010 100644
--- a/index.html
+++ b/index.html
@@ -16,6 +16,7 @@
+
diff --git a/scripts/btcOperator.js b/scripts/btcOperator.js
index 170be20..591cd0a 100644
--- a/scripts/btcOperator.js
+++ b/scripts/btcOperator.js
@@ -1,4 +1,4 @@
-(function(EXPORTS) { //btcOperator v1.0.7b
+(function(EXPORTS) { //btcOperator v1.0.7c
/* BTC Crypto and API Operator */
const btcOperator = EXPORTS;
@@ -268,26 +268,28 @@
const TMP_FEE = 0.00001;
function createTransaction(senders, redeemScripts, receivers, amounts, fee, change_addr) {
- let auto_fee = false,
- total_amount = parseFloat(amounts.reduce((t, a) => t + a, 0).toFixed(8));
- if (fee === null) {
- auto_fee = true;
- fee = TMP_FEE;
- }
- const tx = coinjs.transaction();
- addUTXOs(tx, senders, redeemScripts, total_amount + fee).then(result => {
- if (result > 0)
- return reject("Insufficient Balance");
- let change = addOutputs(tx, receivers, amounts, Math.abs(result), change_addr);
- if (!auto_fee)
- return resolve(tx);
- autoFeeCalc(tx).then(fee_calc => {
- fee = Math.round((fee * 1) * 1e8); //satoshi convertion
- if (!change)
- tx.addoutput(change_addr, 0);
- editFee(tx, fee, fee_calc);
- resolve(tx);
- }).catch(error => reject(error))
+ return new Promise((resolve, reject) => {
+ let auto_fee = false,
+ total_amount = parseFloat(amounts.reduce((t, a) => t + a, 0).toFixed(8));
+ if (fee === null) {
+ auto_fee = true;
+ fee = TMP_FEE;
+ }
+ const tx = coinjs.transaction();
+ addUTXOs(tx, senders, redeemScripts, total_amount + fee).then(result => {
+ if (result > 0)
+ return reject("Insufficient Balance");
+ let change = addOutputs(tx, receivers, amounts, Math.abs(result), change_addr);
+ if (!auto_fee)
+ return resolve(tx);
+ autoFeeCalc(tx).then(fee_calc => {
+ fee = Math.round((fee * 1) * 1e8); //satoshi convertion
+ if (!change)
+ tx.addoutput(change_addr, 0);
+ editFee(tx, fee, fee_calc);
+ resolve(tx);
+ }).catch(error => reject(error))
+ })
})
}
@@ -306,14 +308,17 @@
continue;
required_amount -= parseFloat(utxos[i].value);
var script;
- if (rs) { //redeemScript for segwit/bech32
+ if (!rs || !rs.length) //legacy script
+ script = utxos[i].script_hex;
+ else if (((rs.match(/^00/) && rs.length == 44)) || (rs.length == 40 && rs.match(/^[a-f0-9]+$/gi))) {
+ //redeemScript for segwit/bech32
let s = coinjs.script();
s.writeBytes(Crypto.util.hexToBytes(rs));
s.writeOp(0);
s.writeBytes(coinjs.numToBytes((utxos[i].value * 100000000).toFixed(0), 8));
script = Crypto.util.bytesToHex(s.buffer);
- } else //legacy script
- script = utxos[i].script_hex;
+ } else //redeemScript for multisig
+ script = rs;
tx.addinput(utxos[i].txid, utxos[i].output_no, script, 0xfffffffd /*sequence*/ ); //0xfffffffd for Replace-by-fee
}
addUTXOs(tx, senders, redeemScripts, required_amount, n + 1)
@@ -466,7 +471,7 @@
})
}
- btcOperator.signTx = function(tx, privKeys) {
+ function deserializeTx(tx) {
if (typeof tx === 'string' || Array.isArray(tx)) {
try {
tx = coinjs.transaction().deserialize(tx);
@@ -475,16 +480,45 @@
}
} else if (typeof tx !== 'object' || typeof tx.sign !== 'function')
throw "Invalid transaction object";
+ return tx;
+ }
+ btcOperator.signTx = function(tx, privkeys, sighashtype = 1) {
+ tx = deserializeTx(tx);
if (!Array.isArray(privkeys))
privkeys = [privkeys];
- for (let i in privKeys)
- if (privKeys[i].length === 64)
- privkeys[i] = coinjs.privkey2wif(privKeys[i]);
- new Set(privKeys).forEach(key => console.debug("Signing key:", key, tx.sign(key, 1 /*sighashtype*/ ))); //Sign the tx using private key WIF
+ for (let i in privkeys)
+ if (privkeys[i].length === 64)
+ privkeys[i] = coinjs.privkey2wif(privkeys[i]);
+ new Set(privkeys).forEach(key => tx.sign(key, sighashtype)); //Sign the tx using private key WIF
return tx.serialize();
}
+ btcOperator.checkSigned = function(tx, bool = true) {
+ tx = deserializeTx(tx);
+ let n = [];
+ for (let i in tx.ins) {
+ var s = tx.extractScriptKey(i);
+ if (s['type'] !== 'multisig')
+ n.push(s.signed == 'true' || (tx.witness[i] && tx.witness[i].length == 2))
+ else {
+ var rs = coinjs.script().decodeRedeemScript(s.script);
+ let x = {
+ s: s['signatures'],
+ r: rs['signaturesRequired'],
+ t: rs['pubkeys'].length
+ };
+ if (x.r > x.t)
+ throw "signaturesRequired is more than publicKeys";
+ else if (x.s < x.r)
+ n.push(x);
+ else
+ n.push(true);
+ }
+ }
+ return bool ? !(n.filter(x => x !== true).length) : n;
+ }
+
btcOperator.getTx = txid => new Promise((resolve, reject) => {
fetch_api(`get_tx/BTC/${txid}`)
.then(result => resolve(result.data))
diff --git a/scripts/floCloudAPI.js b/scripts/floCloudAPI.js
index 01560a1..402c0c5 100644
--- a/scripts/floCloudAPI.js
+++ b/scripts/floCloudAPI.js
@@ -1,4 +1,4 @@
-(function(EXPORTS) { //floCloudAPI v2.4.2b
+(function(EXPORTS) { //floCloudAPI v2.4.2c
/* FLO Cloud operations to send/request application data*/
'use strict';
const floCloudAPI = EXPORTS;
@@ -384,7 +384,7 @@
if (!address)
return;
var bytes;
- if (address.length == 34) { //legacy encoding
+ if (address.length == 33 || address.length == 34) { //legacy encoding
let decode = bitjs.Base58.decode(address);
bytes = decode.slice(0, decode.length - 4);
let checksum = decode.slice(decode.length - 4),
diff --git a/scripts/floCrypto.js b/scripts/floCrypto.js
index 4ab4d5c..01921d1 100644
--- a/scripts/floCrypto.js
+++ b/scripts/floCrypto.js
@@ -1,4 +1,4 @@
-(function(EXPORTS) { //floCrypto v2.3.0a
+(function(EXPORTS) { //floCrypto v2.3.3b
/* FLO Crypto Operators */
'use strict';
const floCrypto = EXPORTS;
@@ -7,6 +7,7 @@
const ecparams = EllipticCurve.getSECCurveByName("secp256k1");
const ascii_alternatives = `‘ '\n’ '\n“ "\n” "\n– --\n— ---\n≥ >=\n≤ <=\n≠ !=\n× *\n÷ /\n← <-\n→ ->\n↔ <->\n⇒ =>\n⇐ <=\n⇔ <=>`;
const exponent1 = () => p.add(BigInteger.ONE).divide(BigInteger("4"));
+ coinjs.compressed = true; //defaulting coinjs compressed to true;
function calculateY(x) {
let exp = exponent1();
@@ -121,12 +122,8 @@
//Sign data using private-key
floCrypto.signData = function(data, privateKeyHex) {
var key = new Bitcoin.ECKey(privateKeyHex);
- key.setCompressed(true);
- var privateKeyArr = key.getBitcoinPrivateKeyByteArray();
- var privateKey = BigInteger.fromByteArrayUnsigned(privateKeyArr);
var messageHash = Crypto.SHA256(data);
- var messageHashBigInteger = new BigInteger(messageHash);
- var messageSign = Bitcoin.ECDSA.sign(messageHashBigInteger, key.priv);
+ var messageSign = Bitcoin.ECDSA.sign(messageHash, key.priv);
var sighex = Crypto.util.bytesToHex(messageSign);
return sighex;
}
@@ -134,11 +131,9 @@
//Verify signatue of the data using public-key
floCrypto.verifySign = function(data, signatureHex, publicKeyHex) {
var msgHash = Crypto.SHA256(data);
- var messageHashBigInteger = new BigInteger(msgHash);
var sigBytes = Crypto.util.hexToBytes(signatureHex);
- var signature = Bitcoin.ECDSA.parseSig(sigBytes);
var publicKeyPoint = ecparams.getCurve().decodePointHex(publicKeyHex);
- var verify = Bitcoin.ECDSA.verifyRaw(messageHashBigInteger, signature.r, signature.s, publicKeyPoint);
+ var verify = Bitcoin.ECDSA.verify(msgHash, sigBytes, publicKeyPoint);
return verify;
}
@@ -153,8 +148,23 @@
}
}
- Object.defineProperty(floCrypto, 'newID', {
- get: () => generateNewID()
+ Object.defineProperties(floCrypto, {
+ newID: {
+ get: () => generateNewID()
+ },
+ tmpID: {
+ get: () => {
+ let bytes = Crypto.util.randomBytes(20);
+ bytes.unshift(bitjs.pub);
+ var hash = Crypto.SHA256(Crypto.SHA256(bytes, {
+ asBytes: true
+ }), {
+ asBytes: true
+ });
+ var checksum = hash.slice(0, 4);
+ return bitjs.Base58.encode(bytes.concat(checksum));
+ }
+ }
});
//Returns public-key from private-key
@@ -182,6 +192,25 @@
}
}
+ floCrypto.getAddress = function(privateKeyHex, strict = false) {
+ if (!privateKeyHex)
+ return;
+ var key = new Bitcoin.ECKey(privateKeyHex);
+ if (key.priv == null)
+ return null;
+ key.setCompressed(true);
+ let pubKey = key.getPubKeyHex(),
+ version = bitjs.Base58.decode(privateKeyHex)[0];
+ switch (version) {
+ case coinjs.priv: //BTC
+ return coinjs.bech32Address(pubKey).address;
+ case bitjs.priv: //FLO
+ return bitjs.pubkey2address(pubKey);
+ default:
+ return strict ? false : bitjs.pubkey2address(pubKey); //default to FLO address (if strict=false)
+ }
+ }
+
//Verify the private-key for the given public-key or flo-ID
floCrypto.verifyPrivKey = function(privateKeyHex, pubKey_floID, isfloID = true) {
if (!privateKeyHex || !pubKey_floID)
@@ -202,18 +231,117 @@
}
}
- //Check if the given Address is valid or not
- floCrypto.validateFloID = floCrypto.validateAddr = function(inpAddr) {
- if (!inpAddr)
+ //Check if the given flo-id is valid or not
+ floCrypto.validateFloID = function(floID) {
+ if (!floID)
return false;
try {
- let addr = new Bitcoin.Address(inpAddr);
+ let addr = new Bitcoin.Address(floID);
return true;
} catch {
return false;
}
}
+ //Check if the given address (any blockchain) is valid or not
+ floCrypto.validateAddr = function(address, std = true, bech = true) {
+ if (address.length == 33 || address.length == 34) { //legacy or segwit encoding
+ if (std === false)
+ return false;
+ let decode = bitjs.Base58.decode(address);
+ var raw = decode.slice(0, decode.length - 4),
+ checksum = decode.slice(decode.length - 4);
+ var hash = Crypto.SHA256(Crypto.SHA256(raw, {
+ asBytes: true
+ }), {
+ asBytes: true
+ });
+ if (hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3])
+ return false;
+ else if (std === true || (!Array.isArray(std) && std === raw[0]) || (Array.isArray(std) && std.includes(raw[0])))
+ return true;
+ else
+ return false;
+ } else if (address.length == 42 || address.length == 62) { //bech encoding
+ if (bech === false)
+ return false;
+ let decode = coinjs.bech32_decode(address);
+ if (!decode)
+ return false;
+ var raw = decode.data;
+ if (bech === true || (!Array.isArray(bech) && bech === raw[0]) || (Array.isArray(bech) && bech.includes(raw[0])))
+ return true;
+ else
+ return false;
+ } else //unknown length
+ return false;
+ }
+
+ //Check the public-key for the address (any blockchain)
+ floCrypto.verifyPubKey = function(pubKeyHex, address) {
+ let pub_hash = Crypto.util.bytesToHex(ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(pubKeyHex), {
+ asBytes: true
+ })));
+ if (address.length == 33 || address.length == 34) { //legacy encoding
+ let decode = bitjs.Base58.decode(address);
+ var raw = decode.slice(0, decode.length - 4),
+ checksum = decode.slice(decode.length - 4);
+ var hash = Crypto.SHA256(Crypto.SHA256(raw, {
+ asBytes: true
+ }), {
+ asBytes: true
+ });
+ if (hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3])
+ return false;
+ raw.shift();
+ return pub_hash === Crypto.util.bytesToHex(raw);
+ } else if (address.length == 42 || address.length == 62) { //bech encoding
+ let decode = coinjs.bech32_decode(address);
+ if (!decode)
+ return false;
+ var raw = decode.data;
+ raw.shift();
+ raw = coinjs.bech32_convert(raw, 5, 8, false);
+ return pub_hash === Crypto.util.bytesToHex(raw);
+ } else //unknown length
+ return false;
+ }
+
+ //Convert the given address (any blockchain) to equivalent floID
+ floCrypto.toFloID = function(address) {
+ if (!address)
+ return;
+ var bytes;
+ if (address.length == 33 || address.length == 34) { //legacy encoding
+ let decode = bitjs.Base58.decode(address);
+ bytes = decode.slice(0, decode.length - 4);
+ let checksum = decode.slice(decode.length - 4),
+ hash = Crypto.SHA256(Crypto.SHA256(bytes, {
+ asBytes: true
+ }), {
+ asBytes: true
+ });
+ hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3] ?
+ bytes = undefined : bytes.shift();
+ } else if (address.length == 42) { //bech encoding
+ let decode = coinjs.bech32_decode(address);
+ if (decode) {
+ bytes = decode.data;
+ bytes.shift();
+ bytes = coinjs.bech32_convert(bytes, 5, 8, false);
+ }
+ }
+ if (!bytes)
+ return;
+ bytes.unshift(bitjs.pub);
+ let hash = Crypto.SHA256(Crypto.SHA256(bytes, {
+ asBytes: true
+ }), {
+ asBytes: true
+ });
+ return bitjs.Base58.encode(bytes.concat(hash.slice(0, 4)));
+ }
+
//Split the str using shamir's Secret and Returns the shares
floCrypto.createShamirsSecretShares = function(str, total_shares, threshold_limit) {
try {
diff --git a/scripts/floDapps.js b/scripts/floDapps.js
index 0e92708..1da58b8 100644
--- a/scripts/floDapps.js
+++ b/scripts/floDapps.js
@@ -1,8 +1,144 @@
-(function(EXPORTS) { //floDapps v2.2.1
+(function(EXPORTS) { //floDapps v2.3.2c
/* General functions for FLO Dapps*/
- //'use strict';
+ 'use strict';
const floDapps = EXPORTS;
+ const DEFAULT = {
+ root: "floDapps",
+ application: floGlobals.application,
+ adminID: floGlobals.adminID
+ };
+
+ Object.defineProperties(floDapps, {
+ application: {
+ get: () => DEFAULT.application
+ },
+ adminID: {
+ get: () => DEFAULT.adminID
+ },
+ root: {
+ get: () => DEFAULT.root
+ }
+ });
+
+ var user_priv_raw, aes_key, user_priv_wrap; //private variable inside capsule
+ const raw_user = {
+ get private() {
+ if (!user_priv_raw)
+ throw "User not logged in";
+ return Crypto.AES.decrypt(user_priv_raw, aes_key);
+ }
+ }
+
+ var user_id, user_public, user_private;
+ const user = floDapps.user = {
+ get id() {
+ if (!user_id)
+ throw "User not logged in";
+ return user_id;
+ },
+ get public() {
+ if (!user_public)
+ throw "User not logged in";
+ return user_public;
+ },
+ get private() {
+ if (!user_private)
+ throw "User not logged in";
+ else if (user_private instanceof Function)
+ return user_private();
+ else
+ return Crypto.AES.decrypt(user_private, aes_key);
+ },
+ sign(message) {
+ return floCrypto.signData(message, raw_user.private);
+ },
+ decrypt(data) {
+ return floCrypto.decryptData(data, raw_user.private);
+ },
+ encipher(message) {
+ return Crypto.AES.encrypt(message, raw_user.private);
+ },
+ decipher(data) {
+ return Crypto.AES.decrypt(data, raw_user.private);
+ },
+ get db_name() {
+ return "floDapps#" + user.id;
+ },
+ lock() {
+ user_private = user_priv_wrap;
+ },
+ async unlock() {
+ if (await user.private === raw_user.private)
+ user_private = user_priv_raw;
+ },
+ clear() {
+ user_id = user_public = user_private = undefined;
+ user_priv_raw = aes_key = undefined;
+ delete user.contacts;
+ delete user.pubKeys;
+ delete user.messages;
+ }
+ };
+
+ Object.defineProperties(window, {
+ myFloID: {
+ get: () => {
+ try {
+ return user.id;
+ } catch {
+ return;
+ }
+ }
+ },
+ myUserID: {
+ get: () => {
+ try {
+ return user.id;
+ } catch {
+ return;
+ }
+ }
+ },
+ myPubKey: {
+ get: () => {
+ try {
+ return user.public;
+ } catch {
+ return;
+ }
+ }
+ },
+ myPrivKey: {
+ get: () => {
+ try {
+ return user.private;
+ } catch {
+ return;
+ }
+ }
+ }
+ });
+
+ var subAdmins, settings
+ Object.defineProperties(floGlobals, {
+ subAdmins: {
+ get: () => subAdmins
+ },
+ settings: {
+ get: () => settings
+ },
+ contacts: {
+ get: () => user.contacts
+ },
+ pubKeys: {
+ get: () => user.pubKeys
+ },
+ messages: {
+ get: () => user.messages
+ }
+ })
+
function initIndexedDB() {
return new Promise((resolve, reject) => {
var obs_g = {
@@ -28,41 +164,41 @@
}
//add other given objectStores
initIndexedDB.appObs = initIndexedDB.appObs || {}
- for (o in initIndexedDB.appObs)
+ for (let o in initIndexedDB.appObs)
if (!(o in obs_a))
obs_a[o] = initIndexedDB.appObs[o]
Promise.all([
- compactIDB.initDB(floGlobals.application, obs_a),
- compactIDB.initDB("floDapps", obs_g)
+ compactIDB.initDB(DEFAULT.application, obs_a),
+ compactIDB.initDB(DEFAULT.root, obs_g)
]).then(result => {
- compactIDB.setDefaultDB(floGlobals.application)
+ compactIDB.setDefaultDB(DEFAULT.application)
resolve("IndexedDB App Storage Initated Successfully")
}).catch(error => reject(error));
})
}
- function initUserDB(floID) {
+ function initUserDB() {
return new Promise((resolve, reject) => {
var obs = {
contacts: {},
pubKeys: {},
messages: {}
}
- compactIDB.initDB(`floDapps#${floID}`, obs).then(result => {
+ compactIDB.initDB(user.db_name, obs).then(result => {
resolve("UserDB Initated Successfully")
}).catch(error => reject('Init userDB failed'));
})
}
- function loadUserDB(floID) {
+ function loadUserDB() {
return new Promise((resolve, reject) => {
var loadData = ["contacts", "pubKeys", "messages"]
var promises = []
for (var i = 0; i < loadData.length; i++)
- promises[i] = compactIDB.readAllData(loadData[i], `floDapps#${floID}`)
+ promises[i] = compactIDB.readAllData(loadData[i], user.db_name)
Promise.all(promises).then(results => {
for (var i = 0; i < loadData.length; i++)
- floGlobals[loadData[i]] = results[i]
+ user[loadData[i]] = results[i]
resolve("Loaded Data from userDB")
}).catch(error => reject('Load userDB failed'))
})
@@ -72,7 +208,7 @@
startUpFunctions.push(function readSupernodeListFromAPI() {
return new Promise((resolve, reject) => {
- compactIDB.readData("lastTx", floCloudAPI.SNStorageID, "floDapps").then(lastTx => {
+ compactIDB.readData("lastTx", floCloudAPI.SNStorageID, DEFAULT.root).then(lastTx => {
floBlockchainAPI.readData(floCloudAPI.SNStorageID, {
ignoreOld: lastTx,
sentOnly: true,
@@ -80,14 +216,14 @@
}).then(result => {
for (var i = result.data.length - 1; i >= 0; i--) {
var content = JSON.parse(result.data[i]).SuperNodeStorage;
- for (sn in content.removeNodes)
- compactIDB.removeData("supernodes", sn, "floDapps");
- for (sn in content.newNodes)
- compactIDB.writeData("supernodes", content.newNodes[sn], sn, "floDapps");
+ for (let sn in content.removeNodes)
+ compactIDB.removeData("supernodes", sn, DEFAULT.root);
+ for (let sn in content.newNodes)
+ compactIDB.writeData("supernodes", content.newNodes[sn], sn, DEFAULT.root);
}
- compactIDB.writeData("lastTx", result.totalTxs, floCloudAPI.SNStorageID, "floDapps");
- compactIDB.readAllData("supernodes", "floDapps").then(result => {
- floCloudAPI.init(result)
+ compactIDB.writeData("lastTx", result.totalTxs, floCloudAPI.SNStorageID, DEFAULT.root);
+ compactIDB.readAllData("supernodes", DEFAULT.root).then(nodes => {
+ floCloudAPI.init(nodes)
.then(result => resolve("Loaded Supernode list\n" + result))
.catch(error => reject(error))
})
@@ -98,14 +234,14 @@
startUpFunctions.push(function readAppConfigFromAPI() {
return new Promise((resolve, reject) => {
- compactIDB.readData("lastTx", `${floGlobals.application}|${floGlobals.adminID}`, "floDapps").then(lastTx => {
- floBlockchainAPI.readData(floGlobals.adminID, {
+ compactIDB.readData("lastTx", `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root).then(lastTx => {
+ floBlockchainAPI.readData(DEFAULT.adminID, {
ignoreOld: lastTx,
sentOnly: true,
- pattern: floGlobals.application
+ pattern: DEFAULT.application
}).then(result => {
for (var i = result.data.length - 1; i >= 0; i--) {
- var content = JSON.parse(result.data[i])[floGlobals.application];
+ var content = JSON.parse(result.data[i])[DEFAULT.application];
if (!content || typeof content !== "object")
continue;
if (Array.isArray(content.removeSubAdmin))
@@ -118,11 +254,11 @@
for (let l in content.settings)
compactIDB.writeData("settings", content.settings[l], l)
}
- compactIDB.writeData("lastTx", result.totalTxs, `${floGlobals.application}|${floGlobals.adminID}`, "floDapps");
+ compactIDB.writeData("lastTx", result.totalTxs, `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root);
compactIDB.readAllData("subAdmins").then(result => {
- floGlobals.subAdmins = Object.keys(result);
+ subAdmins = Object.keys(result);
compactIDB.readAllData("settings").then(result => {
- floGlobals.settings = result;
+ settings = result;
resolve("Read app configuration from blockchain");
})
})
@@ -186,7 +322,7 @@
});
const getPrivateKeyCredentials = () => new Promise((resolve, reject) => {
- var indexArr = localStorage.getItem(`${floGlobals.application}#privKey`)
+ var indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
if (indexArr) {
readSharesFromIDB(JSON.parse(indexArr))
.then(result => resolve(result))
@@ -197,7 +333,7 @@
if (!result)
return reject("Empty Private Key")
var floID = floCrypto.getFloID(result)
- if (!floID || !floCrypto.validateAddr(floID))
+ if (!floID || !floCrypto.validateFloID(floID))
return reject("Invalid Private Key")
privKey = result;
}).catch(error => {
@@ -210,7 +346,7 @@
var shares = floCrypto.createShamirsSecretShares(privKey, threshold, threshold)
writeSharesToIDB(shares).then(resultIndexes => {
//store index keys in localStorage
- localStorage.setItem(`${floGlobals.application}#privKey`, JSON.stringify(resultIndexes))
+ localStorage.setItem(`${DEFAULT.application}#privKey`, JSON.stringify(resultIndexes))
//also add a dummy privatekey to the IDB
var randomPrivKey = floCrypto.generateNewID().privKey
var randomThreshold = floCrypto.randInt(10, 20)
@@ -242,9 +378,14 @@
getPrivateKeyCredentials().then(key => {
checkIfPinRequired(key).then(privKey => {
try {
- myPrivKey = privKey
- myPubKey = floCrypto.getPubKeyHex(myPrivKey)
- myFloID = floCrypto.getFloID(myPubKey)
+ user_public = floCrypto.getPubKeyHex(privKey);
+ user_id = floCrypto.getAddress(privKey);
+ floCloudAPI.user(user_id, privKey); //Set user for floCloudAPI
+ user_priv_wrap = () => checkIfPinRequired(key);
+ let n = floCrypto.randInt(12, 20);
+ aes_key = floCrypto.randString(n);
+ user_priv_raw = Crypto.AES.encrypt(privKey, aes_key);
+ user_private = user_priv_wrap;
resolve('Login Credentials loaded successful')
} catch (error) {
console.log(error)
@@ -305,8 +446,8 @@
});
let p2 = new Promise((res, rej) => {
callAndLog(getCredentials()).then(r => {
- callAndLog(initUserDB(myFloID)).then(r => {
- callAndLog(loadUserDB(myFloID))
+ callAndLog(initUserDB()).then(r => {
+ callAndLog(loadUserDB())
.then(r => res(true))
.catch(e => rej(false))
}).catch(e => rej(false))
@@ -315,7 +456,10 @@
Promise.all([p1, p2])
.then(r => resolve('App Startup finished successful'))
.catch(e => reject('App Startup failed'))
- }).catch(error => reject("App database initiation failed"))
+ }).catch(error => {
+ startUpLog(false, error);
+ reject("App database initiation failed")
+ })
})
}
@@ -331,10 +475,10 @@
floDapps.storeContact = function(floID, name) {
return new Promise((resolve, reject) => {
- if (!floCrypto.validateAddr(floID))
+ if (!floCrypto.validateFloID(floID))
return reject("Invalid floID!")
- compactIDB.writeData("contacts", name, floID, `floDapps#${myFloID}`).then(result => {
- floGlobals.contacts[floID] = name;
+ compactIDB.writeData("contacts", name, floID, user.db_name).then(result => {
+ user.contacts[floID] = name;
resolve("Contact stored")
}).catch(error => reject(error))
});
@@ -342,14 +486,14 @@
floDapps.storePubKey = function(floID, pubKey) {
return new Promise((resolve, reject) => {
- if (floID in floGlobals.pubKeys)
+ if (floID in user.pubKeys)
return resolve("pubKey already stored")
- if (!floCrypto.validateAddr(floID))
+ if (!floCrypto.validateFloID(floID))
return reject("Invalid floID!")
if (floCrypto.getFloID(pubKey) != floID)
return reject("Incorrect pubKey")
- compactIDB.writeData("pubKeys", pubKey, floID, `floDapps#${myFloID}`).then(result => {
- floGlobals.pubKeys[floID] = pubKey;
+ compactIDB.writeData("pubKeys", pubKey, floID, user.db_name).then(result => {
+ user.pubKeys[floID] = pubKey;
resolve("pubKey stored")
}).catch(error => reject(error))
});
@@ -359,11 +503,11 @@
return new Promise((resolve, reject) => {
let options = {
receiverID: floID,
- application: "floDapps",
- comment: floGlobals.application
+ application: DEFAULT.root,
+ comment: DEFAULT.application
}
- if (floID in floGlobals.pubKeys)
- message = floCrypto.encryptData(JSON.stringify(message), floGlobals.pubKeys[floID])
+ if (floID in user.pubKeys)
+ message = floCrypto.encryptData(JSON.stringify(message), user.pubKeys[floID])
floCloudAPI.sendApplicationData(message, "Message", options)
.then(result => resolve(result))
.catch(error => reject(error))
@@ -372,20 +516,21 @@
floDapps.requestInbox = function(callback) {
return new Promise((resolve, reject) => {
- let lastVC = Object.keys(floGlobals.messages).sort().pop()
+ let lastVC = Object.keys(user.messages).sort().pop()
let options = {
- receiverID: myFloID,
- application: "floDapps",
+ receiverID: user.id,
+ application: DEFAULT.root,
lowerVectorClock: lastVC + 1
}
+ let privKey = raw_user.private;
options.callback = (d, e) => {
for (let v in d) {
try {
if (d[v].message instanceof Object && "secret" in d[v].message)
- d[v].message = floCrypto.decryptData(d[v].message, myPrivKey)
+ d[v].message = floCrypto.decryptData(d[v].message, privKey)
} catch (error) {}
- compactIDB.writeData("messages", d[v], v, `floDapps#${myFloID}`)
- floGlobals.messages[v] = d[v]
+ compactIDB.writeData("messages", d[v], v, user.db_name)
+ user.messages[v] = d[v]
}
if (callback instanceof Function)
callback(d, e)
@@ -404,14 +549,14 @@
if (!addList && !rmList && !settings)
return reject("No configuration change")
var floData = {
- [floGlobals.application]: {
+ [DEFAULT.application]: {
addSubAdmin: addList,
removeSubAdmin: rmList,
settings: settings
}
}
var floID = floCrypto.getFloID(adminPrivKey)
- if (floID != floGlobals.adminID)
+ if (floID != DEFAULT.adminID)
reject('Access Denied for Admin privilege')
else
floBlockchainAPI.writeData(floID, JSON.stringify(floData), adminPrivKey)
@@ -422,9 +567,9 @@
const clearCredentials = floDapps.clearCredentials = function() {
return new Promise((resolve, reject) => {
- compactIDB.clearData('credentials', floGlobals.application).then(result => {
- localStorage.removeItem(`${floGlobals.application}#privKey`)
- myPrivKey = myPubKey = myFloID = undefined;
+ compactIDB.clearData('credentials', DEFAULT.application).then(result => {
+ localStorage.removeItem(`${DEFAULT.application}#privKey`);
+ user.clear();
resolve("privKey credentials deleted!")
}).catch(error => reject(error))
})
@@ -433,7 +578,7 @@
floDapps.deleteUserData = function(credentials = false) {
return new Promise((resolve, reject) => {
let p = []
- p.push(compactIDB.deleteDB(`floDapps#${myFloID}`))
+ p.push(compactIDB.deleteDB(user.db_name))
if (credentials)
p.push(clearCredentials())
Promise.all(p)
@@ -444,10 +589,10 @@
floDapps.deleteAppData = function() {
return new Promise((resolve, reject) => {
- compactIDB.deleteDB(floGlobals.application).then(result => {
- localStorage.removeItem(`${floGlobals.application}#privKey`)
- myPrivKey = myPubKey = myFloID = undefined;
- compactIDB.removeData('lastTx', `${floGlobals.application}|${floGlobals.adminID}`, 'floDapps')
+ compactIDB.deleteDB(DEFAULT.application).then(result => {
+ localStorage.removeItem(`${DEFAULT.application}#privKey`)
+ user.clear();
+ compactIDB.removeData('lastTx', `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root)
.then(result => resolve("App database(local) deleted"))
.catch(error => reject(error))
}).catch(error => reject(error))
@@ -455,17 +600,17 @@
}
floDapps.securePrivKey = function(pwd) {
- return new Promise((resolve, reject) => {
- let indexArr = localStorage.getItem(`${floGlobals.application}#privKey`)
+ return new Promise(async (resolve, reject) => {
+ let indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
if (!indexArr)
return reject("PrivKey not found");
indexArr = JSON.parse(indexArr)
- let encryptedKey = Crypto.AES.encrypt(myPrivKey, pwd);
+ let encryptedKey = Crypto.AES.encrypt(await user.private, pwd);
let threshold = indexArr.length;
let shares = floCrypto.createShamirsSecretShares(encryptedKey, threshold, threshold)
let promises = [];
let overwriteFn = (share, index) =>
- compactIDB.writeData("credentials", share, index, floGlobals.application);
+ compactIDB.writeData("credentials", share, index, DEFAULT.application);
for (var i = 0; i < threshold; i++)
promises.push(overwriteFn(shares[i], indexArr[i]));
Promise.all(promises)
@@ -494,7 +639,7 @@
})
}
return new Promise((resolve, reject) => {
- var indexArr = localStorage.getItem(`${floGlobals.application}#privKey`)
+ var indexArr = localStorage.getItem(`${DEFAULT.application}#privKey`)
console.info(indexArr)
if (!indexArr)
reject('No login credentials found')
@@ -535,7 +680,7 @@
filteredResult[d] = JSON.parse(JSON.stringify(floGlobals.generalData[fk][d]))
}
if (options.decrypt) {
- let decryptionKey = (options.decrypt === true) ? myPrivKey : options.decrypt;
+ let decryptionKey = (options.decrypt === true) ? raw_user.private : options.decrypt;
if (!Array.isArray(decryptionKey))
decryptionKey = [decryptionKey];
for (let f in filteredResult) {
@@ -561,14 +706,14 @@
syncData.oldDevice = () => new Promise((resolve, reject) => {
let sync = {
- contacts: floGlobals.contacts,
- pubKeys: floGlobals.pubKeys,
- messages: floGlobals.messages
+ contacts: user.contacts,
+ pubKeys: user.pubKeys,
+ messages: user.messages
}
- let message = Crypto.AES.encrypt(JSON.stringify(sync), myPrivKey)
+ let message = Crypto.AES.encrypt(JSON.stringify(sync), raw_user.private)
let options = {
- receiverID: myFloID,
- application: "floDapps"
+ receiverID: user.id,
+ application: DEFAULT.root
}
floCloudAPI.sendApplicationData(message, "syncData", options)
.then(result => resolve(result))
@@ -577,20 +722,20 @@
syncData.newDevice = () => new Promise((resolve, reject) => {
var options = {
- receiverID: myFloID,
- senderID: myFloID,
- application: "floDapps",
+ receiverID: user.id,
+ senderID: user.id,
+ application: DEFAULT.root,
mostRecent: true,
}
floCloudAPI.requestApplicationData("syncData", options).then(response => {
let vc = Object.keys(response).sort().pop()
- let sync = JSON.parse(Crypto.AES.decrypt(response[vc].message, myPrivKey))
+ let sync = JSON.parse(Crypto.AES.decrypt(response[vc].message, raw_user.private))
let promises = []
- let store = (key, val, obs) => promises.push(compactIDB.writeData(obs, val, key, `floDapps#${floID}`));
+ let store = (key, val, obs) => promises.push(compactIDB.writeData(obs, val, key, user.db_name));
["contacts", "pubKeys", "messages"].forEach(c => {
for (let i in sync[c]) {
store(i, sync[c][i], c)
- floGlobals[c][i] = sync[c][i]
+ user[c][i] = sync[c][i]
}
})
Promise.all(promises)
diff --git a/scripts/lib.js b/scripts/lib.js
index d2fd11d..1ae4ca2 100644
--- a/scripts/lib.js
+++ b/scripts/lib.js
@@ -1,4 +1,4 @@
-(function(GLOBAL) { //lib v1.3.0b
+(function(GLOBAL) { //lib v1.3.0c
'use strict';
/* Utility Libraries required for Standard operations
* All credits for these codes belong to their respective creators, moderators and owners.
@@ -7814,7 +7814,7 @@
} else if (this.ins[index].script.chunks[0] == 0 && this.ins[index].script.chunks[this.ins[index].script.chunks.length - 1][this.ins[index].script.chunks[this.ins[index].script.chunks.length - 1].length - 1] == 174) { // OP_CHECKMULTISIG
// multisig script, with signature(s) included
var sigcount = 0;
- for (i = 1; i < this.ins[index].script.chunks.length - 1; i++) {
+ for (let i = 1; i < this.ins[index].script.chunks.length - 1; i++) {
if (this.ins[index].script.chunks[i] != 0) {
sigcount++;
}
@@ -8057,8 +8057,8 @@
s.writeOp(0);
- for (x in pubkeyList) {
- for (y in sigsList) {
+ for (let x in pubkeyList) {
+ for (let y in sigsList) {
this.ins[index].script.buffer = redeemScript;
sighash = Crypto.util.hexToBytes(this.transactionHash(index, sigsList[y].slice(-1)[0] * 1));
if (coinjs.verifySignature(sighash, sigsList[y], pubkeyList[x])) {