Update stdops
This commit is contained in:
parent
85d57909ae
commit
c9fde067f2
20
index.html
20
index.html
@ -8,27 +8,9 @@
|
|||||||
<script id="floGlobals">
|
<script id="floGlobals">
|
||||||
/* Constants for FLO blockchain operations !!Make sure to add this at begining!! */
|
/* Constants for FLO blockchain operations !!Make sure to add this at begining!! */
|
||||||
const floGlobals = {
|
const floGlobals = {
|
||||||
|
|
||||||
//Required for all
|
|
||||||
blockchain: "FLO",
|
blockchain: "FLO",
|
||||||
|
|
||||||
//Required for blockchain API operators
|
|
||||||
apiURL: {
|
|
||||||
FLO: ['https://livenet.flocha.in/', 'https://flosight.duckdns.org/'],
|
|
||||||
FLO_TEST: ['https://testnet-flosight.duckdns.org/', 'https://testnet.flocha.in/']
|
|
||||||
},
|
|
||||||
|
|
||||||
//Required for Supernode operations
|
|
||||||
SNStorageID: "FNaN9McoBAEFUjkRmNQRYLmBF8SpS7Tgfk",
|
|
||||||
supernodes: {}, //each supnernode must be stored as floID : {uri:<uri>,pubKey:<publicKey>}
|
|
||||||
|
|
||||||
//for app
|
|
||||||
application: "messenger",
|
application: "messenger",
|
||||||
adminID: "FMRsefPydWznGWneLqi4ABeQAJeFvtS3aQ",
|
adminID: "FMRsefPydWznGWneLqi4ABeQAJeFvtS3aQ"
|
||||||
pubKeys: {},
|
|
||||||
contacts: {},
|
|
||||||
appendix: {},
|
|
||||||
expiredKeys: {}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<script src="scripts/lib.js"></script>
|
<script src="scripts/lib.js"></script>
|
||||||
|
|||||||
@ -1,9 +1,54 @@
|
|||||||
(function(EXPORTS) { //floBlockchainAPI v2.3.0
|
(function(EXPORTS) { //floBlockchainAPI v2.3.3
|
||||||
/* FLO Blockchain Operator to send/receive data from blockchain using API calls*/
|
/* FLO Blockchain Operator to send/receive data from blockchain using API calls*/
|
||||||
'use strict';
|
'use strict';
|
||||||
const floBlockchainAPI = EXPORTS;
|
const floBlockchainAPI = EXPORTS;
|
||||||
|
|
||||||
const serverList = floGlobals.apiURL[floGlobals.blockchain].slice(0);
|
const DEFAULT = {
|
||||||
|
blockchain: floGlobals.blockchain,
|
||||||
|
apiURL: {
|
||||||
|
FLO: ['https://livenet.flocha.in/', 'https://flosight.duckdns.org/'],
|
||||||
|
FLO_TEST: ['https://testnet-flosight.duckdns.org', 'https://testnet.flocha.in/']
|
||||||
|
},
|
||||||
|
sendAmt: 0.001,
|
||||||
|
fee: 0.0005,
|
||||||
|
receiverID: floGlobals.adminID
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperties(floBlockchainAPI, {
|
||||||
|
sendAmt: {
|
||||||
|
get: () => DEFAULT.sendAmt,
|
||||||
|
set: amt => !isNaN(amt) ? DEFAULT.sendAmt = amt : null
|
||||||
|
},
|
||||||
|
fee: {
|
||||||
|
get: () => DEFAULT.fee,
|
||||||
|
set: fee => !isNaN(fee) ? DEFAULT.fee = fee : null
|
||||||
|
},
|
||||||
|
defaultReceiver: {
|
||||||
|
get: () => DEFAULT.receiverID,
|
||||||
|
set: floID => DEFAULT.receiverID = floID
|
||||||
|
},
|
||||||
|
blockchain: {
|
||||||
|
get: () => DEFAULT.blockchain
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (floGlobals.sendAmt) floBlockchainAPI.sendAmt = floGlobals.sendAmt;
|
||||||
|
if (floGlobals.fee) floBlockchainAPI.fee = floGlobals.fee;
|
||||||
|
|
||||||
|
Object.defineProperties(floGlobals, {
|
||||||
|
sendAmt: {
|
||||||
|
get: () => DEFAULT.sendAmt,
|
||||||
|
set: amt => !isNaN(amt) ? DEFAULT.sendAmt = amt : null
|
||||||
|
},
|
||||||
|
fee: {
|
||||||
|
get: () => DEFAULT.fee,
|
||||||
|
set: fee => !isNaN(fee) ? DEFAULT.fee = fee : null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const allServerList = new Set(floGlobals.apiURL && floGlobals.apiURL[DEFAULT.blockchain] ? floGlobals.apiURL[DEFAULT.blockchain] : DEFAULT.apiURL[DEFAULT.blockchain]);
|
||||||
|
|
||||||
|
var serverList = Array.from(allServerList);
|
||||||
var curPos = floCrypto.randInt(0, serverList - 1);
|
var curPos = floCrypto.randInt(0, serverList - 1);
|
||||||
|
|
||||||
function fetch_retry(apicall, rm_flosight) {
|
function fetch_retry(apicall, rm_flosight) {
|
||||||
@ -11,17 +56,24 @@
|
|||||||
let i = serverList.indexOf(rm_flosight)
|
let i = serverList.indexOf(rm_flosight)
|
||||||
if (i != -1) serverList.splice(i, 1);
|
if (i != -1) serverList.splice(i, 1);
|
||||||
curPos = floCrypto.randInt(0, serverList.length - 1);
|
curPos = floCrypto.randInt(0, serverList.length - 1);
|
||||||
fetch_api(apicall)
|
fetch_api(apicall, false)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetch_api(apicall) {
|
function fetch_api(apicall, ic = true) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (serverList.length === 0)
|
if (serverList.length === 0) {
|
||||||
reject("No floSight server working");
|
if (ic) {
|
||||||
else {
|
serverList = Array.from(allServerList);
|
||||||
|
curPos = floCrypto.randInt(0, serverList.length - 1);
|
||||||
|
fetch_api(apicall, false)
|
||||||
|
.then(result => resolve(result))
|
||||||
|
.catch(error => reject(error));
|
||||||
|
} else
|
||||||
|
reject("No floSight server working");
|
||||||
|
} else {
|
||||||
let flosight = serverList[curPos];
|
let flosight = serverList[curPos];
|
||||||
fetch(flosight + apicall).then(response => {
|
fetch(flosight + apicall).then(response => {
|
||||||
if (response.ok)
|
if (response.ok)
|
||||||
@ -40,12 +92,17 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
Object.defineProperty(floBlockchainAPI, 'current_server', {
|
Object.defineProperties(floBlockchainAPI, {
|
||||||
get: () => serverList[curPos]
|
serverList: {
|
||||||
|
get: () => Array.from(serverList)
|
||||||
|
},
|
||||||
|
current_server: {
|
||||||
|
get: () => serverList[curPos]
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Promised function to get data from API
|
//Promised function to get data from API
|
||||||
const promisedAPI = floBlockchainAPI.promisedAPI = function(apicall) {
|
const promisedAPI = floBlockchainAPI.promisedAPI = floBlockchainAPI.fetch = function(apicall) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
//console.log(apicall);
|
//console.log(apicall);
|
||||||
fetch_api(apicall)
|
fetch_api(apicall)
|
||||||
@ -77,48 +134,52 @@
|
|||||||
else if (typeof sendAmt !== 'number' || sendAmt <= 0)
|
else if (typeof sendAmt !== 'number' || sendAmt <= 0)
|
||||||
return reject(`Invalid sendAmt : ${sendAmt}`);
|
return reject(`Invalid sendAmt : ${sendAmt}`);
|
||||||
|
|
||||||
//get unconfirmed tx list
|
getBalance(senderAddr).then(balance => {
|
||||||
promisedAPI(`api/addr/${senderAddr}`).then(result => {
|
var fee = DEFAULT.fee;
|
||||||
readTxs(senderAddr, 0, result.unconfirmedTxApperances).then(result => {
|
if (balance < sendAmt + fee)
|
||||||
let unconfirmedSpent = {};
|
return reject("Insufficient FLO balance!");
|
||||||
for (let tx of result.items)
|
//get unconfirmed tx list
|
||||||
if (tx.confirmations == 0)
|
promisedAPI(`api/addr/${senderAddr}`).then(result => {
|
||||||
for (let vin of tx.vin)
|
readTxs(senderAddr, 0, result.unconfirmedTxApperances).then(result => {
|
||||||
if (vin.addr === senderAddr) {
|
let unconfirmedSpent = {};
|
||||||
if (Array.isArray(unconfirmedSpent[vin.txid]))
|
for (let tx of result.items)
|
||||||
unconfirmedSpent[vin.txid].push(vin.vout);
|
if (tx.confirmations == 0)
|
||||||
else
|
for (let vin of tx.vin)
|
||||||
unconfirmedSpent[vin.txid] = [vin.vout];
|
if (vin.addr === senderAddr) {
|
||||||
}
|
if (Array.isArray(unconfirmedSpent[vin.txid]))
|
||||||
//get utxos list
|
unconfirmedSpent[vin.txid].push(vin.vout);
|
||||||
promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => {
|
else
|
||||||
//form/construct the transaction data
|
unconfirmedSpent[vin.txid] = [vin.vout];
|
||||||
var trx = bitjs.transaction();
|
}
|
||||||
var utxoAmt = 0.0;
|
//get utxos list
|
||||||
var fee = floGlobals.fee;
|
promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => {
|
||||||
for (var i = utxos.length - 1;
|
//form/construct the transaction data
|
||||||
(i >= 0) && (utxoAmt < sendAmt + fee); i--) {
|
var trx = bitjs.transaction();
|
||||||
//use only utxos with confirmations (strict_utxo mode)
|
var utxoAmt = 0.0;
|
||||||
if (utxos[i].confirmations || !strict_utxo) {
|
for (var i = utxos.length - 1;
|
||||||
if (utxos[i].txid in unconfirmedSpent && unconfirmedSpent[utxos[i].txid].includes(utxos[i].vout))
|
(i >= 0) && (utxoAmt < sendAmt + fee); i--) {
|
||||||
continue; //A transaction has already used the utxo, but is unconfirmed.
|
//use only utxos with confirmations (strict_utxo mode)
|
||||||
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
if (utxos[i].confirmations || !strict_utxo) {
|
||||||
utxoAmt += utxos[i].amount;
|
if (utxos[i].txid in unconfirmedSpent && unconfirmedSpent[utxos[i].txid].includes(utxos[i].vout))
|
||||||
};
|
continue; //A transaction has already used the utxo, but is unconfirmed.
|
||||||
}
|
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
||||||
if (utxoAmt < sendAmt + fee)
|
utxoAmt += utxos[i].amount;
|
||||||
reject("Insufficient FLO balance!");
|
};
|
||||||
else {
|
}
|
||||||
trx.addoutput(receiverAddr, sendAmt);
|
if (utxoAmt < sendAmt + fee)
|
||||||
var change = utxoAmt - sendAmt - fee;
|
reject("Insufficient FLO: Some UTXOs are unconfirmed");
|
||||||
if (change > 0)
|
else {
|
||||||
trx.addoutput(senderAddr, change);
|
trx.addoutput(receiverAddr, sendAmt);
|
||||||
trx.addflodata(floData.replace(/\n/g, ' '));
|
var change = utxoAmt - sendAmt - fee;
|
||||||
var signedTxHash = trx.sign(privKey, 1);
|
if (change > 0)
|
||||||
broadcastTx(signedTxHash)
|
trx.addoutput(senderAddr, change);
|
||||||
.then(txid => resolve(txid))
|
trx.addflodata(floData.replace(/\n/g, ' '));
|
||||||
.catch(error => reject(error))
|
var signedTxHash = trx.sign(privKey, 1);
|
||||||
}
|
broadcastTx(signedTxHash)
|
||||||
|
.then(txid => resolve(txid))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
}
|
||||||
|
}).catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
@ -126,11 +187,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Write Data into blockchain
|
//Write Data into blockchain
|
||||||
floBlockchainAPI.writeData = function(senderAddr, data, privKey, receiverAddr = floGlobals.adminID, strict_utxo = true) {
|
floBlockchainAPI.writeData = function(senderAddr, data, privKey, receiverAddr = DEFAULT.receiverID, options = {}) {
|
||||||
|
let strict_utxo = options.strict_utxo === false ? false : true,
|
||||||
|
sendAmt = isNaN(options.sendAmt) ? DEFAULT.sendAmt : options.sendAmt;
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (typeof data != "string")
|
if (typeof data != "string")
|
||||||
data = JSON.stringify(data);
|
data = JSON.stringify(data);
|
||||||
sendTx(senderAddr, receiverAddr, floGlobals.sendAmt, privKey, data, strict_utxo)
|
sendTx(senderAddr, receiverAddr, sendAmt, privKey, data, strict_utxo)
|
||||||
.then(txid => resolve(txid))
|
.then(txid => resolve(txid))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
});
|
});
|
||||||
@ -147,7 +210,7 @@
|
|||||||
return reject("Invalid FLO_Data: only printable ASCII characters are allowed");
|
return reject("Invalid FLO_Data: only printable ASCII characters are allowed");
|
||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
var utxoAmt = 0.0;
|
var utxoAmt = 0.0;
|
||||||
var fee = floGlobals.fee;
|
var fee = DEFAULT.fee;
|
||||||
promisedAPI(`api/addr/${floID}/utxo`).then(utxos => {
|
promisedAPI(`api/addr/${floID}/utxo`).then(utxos => {
|
||||||
for (var i = utxos.length - 1; i >= 0; i--)
|
for (var i = utxos.length - 1; i >= 0; i--)
|
||||||
if (utxos[i].confirmations) {
|
if (utxos[i].confirmations) {
|
||||||
@ -171,13 +234,13 @@
|
|||||||
* @param {boolean} preserveRatio (optional) preserve ratio or equal contribution
|
* @param {boolean} preserveRatio (optional) preserve ratio or equal contribution
|
||||||
* @return {Promise}
|
* @return {Promise}
|
||||||
*/
|
*/
|
||||||
floBlockchainAPI.writeDataMultiple = function(senderPrivKeys, data, receivers = [floGlobals.adminID], preserveRatio = true) {
|
floBlockchainAPI.writeDataMultiple = function(senderPrivKeys, data, receivers = [DEFAULT.receiverID], preserveRatio = true) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!Array.isArray(senderPrivKeys))
|
if (!Array.isArray(senderPrivKeys))
|
||||||
return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array");
|
return reject("Invalid senderPrivKeys: SenderPrivKeys must be Array");
|
||||||
if (!preserveRatio) {
|
if (!preserveRatio) {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
let amount = (floGlobals.sendAmt * receivers.length) / senderPrivKeys.length;
|
let amount = (DEFAULT.sendAmt * receivers.length) / senderPrivKeys.length;
|
||||||
senderPrivKeys.forEach(key => tmp[key] = amount);
|
senderPrivKeys.forEach(key => tmp[key] = amount);
|
||||||
senderPrivKeys = tmp;
|
senderPrivKeys = tmp;
|
||||||
}
|
}
|
||||||
@ -185,7 +248,7 @@
|
|||||||
return reject("Invalid receivers: Receivers must be Array");
|
return reject("Invalid receivers: Receivers must be Array");
|
||||||
else {
|
else {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
let amount = floGlobals.sendAmt;
|
let amount = DEFAULT.sendAmt;
|
||||||
receivers.forEach(floID => tmp[floID] = amount);
|
receivers.forEach(floID => tmp[floID] = amount);
|
||||||
receivers = tmp
|
receivers = tmp
|
||||||
}
|
}
|
||||||
@ -288,7 +351,7 @@
|
|||||||
promises.push(getBalance(floID));
|
promises.push(getBalance(floID));
|
||||||
Promise.all(promises).then(results => {
|
Promise.all(promises).then(results => {
|
||||||
let totalBalance = 0,
|
let totalBalance = 0,
|
||||||
totalFee = floGlobals.fee,
|
totalFee = DEFAULT.fee,
|
||||||
balance = {};
|
balance = {};
|
||||||
//Divide fee among sender if not for preserveRatio
|
//Divide fee among sender if not for preserveRatio
|
||||||
if (!preserveRatio)
|
if (!preserveRatio)
|
||||||
|
|||||||
@ -1,8 +1,47 @@
|
|||||||
(function(EXPORTS) { //floCloudAPI v2.2.0a
|
(function(EXPORTS) { //floCloudAPI v2.3.0
|
||||||
/* FLO Cloud operations to send/request application data*/
|
/* FLO Cloud operations to send/request application data*/
|
||||||
'use strict';
|
'use strict';
|
||||||
const floCloudAPI = EXPORTS;
|
const floCloudAPI = EXPORTS;
|
||||||
|
|
||||||
|
const DEFAULT = {
|
||||||
|
SNStorageID: floGlobals.SNStorageID || "FNaN9McoBAEFUjkRmNQRYLmBF8SpS7Tgfk",
|
||||||
|
adminID: floGlobals.adminID,
|
||||||
|
application: floGlobals.application
|
||||||
|
};
|
||||||
|
|
||||||
|
Object.defineProperties(floCloudAPI, {
|
||||||
|
SNStorageID: {
|
||||||
|
get: () => DEFAULT.SNStorageID
|
||||||
|
},
|
||||||
|
adminID: {
|
||||||
|
get: () => DEFAULT.adminID
|
||||||
|
},
|
||||||
|
application: {
|
||||||
|
get: () => DEFAULT.application
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var appObjects, generalData, lastVC;
|
||||||
|
Object.defineProperties(floGlobals, {
|
||||||
|
appObjects: {
|
||||||
|
get: () => appObjects,
|
||||||
|
set: obj => appObjects = obj
|
||||||
|
},
|
||||||
|
generalData: {
|
||||||
|
get: () => generalData,
|
||||||
|
set: data => generalData = data
|
||||||
|
},
|
||||||
|
lastVC: {
|
||||||
|
get: () => lastVC,
|
||||||
|
set: vc => lastVC = vc
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var supernodes = {}; //each supnernode must be stored as floID : {uri:<uri>,pubKey:<publicKey>}
|
||||||
|
Object.defineProperty(floCloudAPI, 'nodes', {
|
||||||
|
get: () => JSON.parse(JSON.stringify(supernodes))
|
||||||
|
});
|
||||||
|
|
||||||
var kBucket;
|
var kBucket;
|
||||||
const K_Bucket = floCloudAPI.K_Bucket = function(masterID, nodeList) {
|
const K_Bucket = floCloudAPI.K_Bucket = function(masterID, nodeList) {
|
||||||
|
|
||||||
@ -98,11 +137,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
floCloudAPI.init = function startCloudProcess(SNStorageID = floGlobals.SNStorageID, nodeList = null) {
|
floCloudAPI.init = function startCloudProcess(nodes) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
nodeList = nodeList || Object.keys(floGlobals.supernodes);
|
supernodes = nodes;
|
||||||
kBucket = new K_Bucket(SNStorageID, nodeList);
|
kBucket = new K_Bucket(DEFAULT.SNStorageID, Object.keys(supernodes));
|
||||||
resolve('Cloud init successful');
|
resolve('Cloud init successful');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
reject(error);
|
reject(error);
|
||||||
@ -118,11 +157,11 @@
|
|||||||
|
|
||||||
function ws_connect(snID) {
|
function ws_connect(snID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!(snID in floGlobals.supernodes))
|
if (!(snID in supernodes))
|
||||||
return reject(`${snID} is not a supernode`)
|
return reject(`${snID} is not a supernode`)
|
||||||
if (_inactive.has(snID))
|
if (_inactive.has(snID))
|
||||||
return reject(`${snID} is not active`)
|
return reject(`${snID} is not active`)
|
||||||
var wsConn = new WebSocket("wss://" + floGlobals.supernodes[snID].uri + "/");
|
var wsConn = new WebSocket("wss://" + supernodes[snID].uri + "/");
|
||||||
wsConn.onopen = evt => resolve(wsConn);
|
wsConn.onopen = evt => resolve(wsConn);
|
||||||
wsConn.onerror = evt => {
|
wsConn.onerror = evt => {
|
||||||
_inactive.add(snID)
|
_inactive.add(snID)
|
||||||
@ -135,7 +174,7 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (_inactive.size === kBucket.list.length)
|
if (_inactive.size === kBucket.list.length)
|
||||||
return reject('Cloud offline');
|
return reject('Cloud offline');
|
||||||
if (!(snID in floGlobals.supernodes))
|
if (!(snID in supernodes))
|
||||||
snID = kBucket.closestNode(snID);
|
snID = kBucket.closestNode(snID);
|
||||||
ws_connect(snID)
|
ws_connect(snID)
|
||||||
.then(node => resolve(node))
|
.then(node => resolve(node))
|
||||||
@ -155,7 +194,7 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (_inactive.has(snID))
|
if (_inactive.has(snID))
|
||||||
return reject(`${snID} is not active`);
|
return reject(`${snID} is not active`);
|
||||||
let fetcher, sn_url = "https://" + floGlobals.supernodes[snID].uri;
|
let fetcher, sn_url = "https://" + supernodes[snID].uri;
|
||||||
if (typeof data === "string")
|
if (typeof data === "string")
|
||||||
fetcher = fetch(sn_url + "?" + data);
|
fetcher = fetch(sn_url + "?" + data);
|
||||||
else if (typeof data === "object" && data.method === "POST")
|
else if (typeof data === "object" && data.method === "POST")
|
||||||
@ -173,7 +212,7 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (_inactive.size === kBucket.list.length)
|
if (_inactive.size === kBucket.list.length)
|
||||||
return reject('Cloud offline');
|
return reject('Cloud offline');
|
||||||
if (!(snID in floGlobals.supernodes))
|
if (!(snID in supernodes))
|
||||||
snID = kBucket.closestNode(snID);
|
snID = kBucket.closestNode(snID);
|
||||||
fetch_API(snID, data)
|
fetch_API(snID, data)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
@ -289,8 +328,8 @@
|
|||||||
|
|
||||||
const filterKey = util.filterKey = function(type, options) {
|
const filterKey = util.filterKey = function(type, options) {
|
||||||
return type + (options.comment ? ':' + options.comment : '') +
|
return type + (options.comment ? ':' + options.comment : '') +
|
||||||
'|' + (options.group || options.receiverID || floGlobals.adminID) +
|
'|' + (options.group || options.receiverID || DEFAULT.adminID) +
|
||||||
'|' + (options.application || floGlobals.application);
|
'|' + (options.application || DEFAULT.application);
|
||||||
}
|
}
|
||||||
|
|
||||||
const lastCommit = {};
|
const lastCommit = {};
|
||||||
@ -298,7 +337,7 @@
|
|||||||
value: objName => JSON.parse(lastCommit[objName])
|
value: objName => JSON.parse(lastCommit[objName])
|
||||||
});
|
});
|
||||||
Object.defineProperty(lastCommit, 'set', {
|
Object.defineProperty(lastCommit, 'set', {
|
||||||
value: objName => lastCommit[objName] = JSON.stringify(floGlobals.appObjects[objName])
|
value: objName => lastCommit[objName] = JSON.stringify(appObjects[objName])
|
||||||
});
|
});
|
||||||
|
|
||||||
function updateObject(objectName, dataSet) {
|
function updateObject(objectName, dataSet) {
|
||||||
@ -306,22 +345,22 @@
|
|||||||
console.log(dataSet)
|
console.log(dataSet)
|
||||||
let vcList = Object.keys(dataSet).sort();
|
let vcList = Object.keys(dataSet).sort();
|
||||||
for (let vc of vcList) {
|
for (let vc of vcList) {
|
||||||
if (vc < floGlobals.lastVC[objectName] || dataSet[vc].type !== objectName)
|
if (vc < lastVC[objectName] || dataSet[vc].type !== objectName)
|
||||||
continue;
|
continue;
|
||||||
switch (dataSet[vc].comment) {
|
switch (dataSet[vc].comment) {
|
||||||
case "RESET":
|
case "RESET":
|
||||||
if (dataSet[vc].message.reset)
|
if (dataSet[vc].message.reset)
|
||||||
floGlobals.appObjects[objectName] = dataSet[vc].message.reset;
|
appObjects[objectName] = dataSet[vc].message.reset;
|
||||||
break;
|
break;
|
||||||
case "UPDATE":
|
case "UPDATE":
|
||||||
if (dataSet[vc].message.diff)
|
if (dataSet[vc].message.diff)
|
||||||
floGlobals.appObjects[objectName] = diff.merge(floGlobals.appObjects[objectName], dataSet[vc].message.diff);
|
appObjects[objectName] = diff.merge(appObjects[objectName], dataSet[vc].message.diff);
|
||||||
}
|
}
|
||||||
floGlobals.lastVC[objectName] = vc;
|
lastVC[objectName] = vc;
|
||||||
}
|
}
|
||||||
lastCommit.set(objectName);
|
lastCommit.set(objectName);
|
||||||
compactIDB.writeData("appObjects", floGlobals.appObjects[objectName], objectName);
|
compactIDB.writeData("appObjects", appObjects[objectName], objectName);
|
||||||
compactIDB.writeData("lastVC", floGlobals.lastVC[objectName], objectName);
|
compactIDB.writeData("lastVC", lastVC[objectName], objectName);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
@ -330,15 +369,15 @@
|
|||||||
function storeGeneral(fk, dataSet) {
|
function storeGeneral(fk, dataSet) {
|
||||||
try {
|
try {
|
||||||
console.log(dataSet)
|
console.log(dataSet)
|
||||||
if (typeof floGlobals.generalData[fk] !== "object")
|
if (typeof generalData[fk] !== "object")
|
||||||
floGlobals.generalData[fk] = {}
|
generalData[fk] = {}
|
||||||
for (let vc in dataSet) {
|
for (let vc in dataSet) {
|
||||||
floGlobals.generalData[fk][vc] = dataSet[vc];
|
generalData[fk][vc] = dataSet[vc];
|
||||||
if (dataSet[vc].log_time > floGlobals.lastVC[fk])
|
if (dataSet[vc].log_time > lastVC[fk])
|
||||||
floGlobals.lastVC[fk] = dataSet[vc].log_time;
|
lastVC[fk] = dataSet[vc].log_time;
|
||||||
}
|
}
|
||||||
compactIDB.writeData("lastVC", floGlobals.lastVC[fk], fk)
|
compactIDB.writeData("lastVC", lastVC[fk], fk)
|
||||||
compactIDB.writeData("generalData", floGlobals.generalData[fk], fk)
|
compactIDB.writeData("generalData", generalData[fk], fk)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
}
|
}
|
||||||
@ -359,14 +398,14 @@
|
|||||||
let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e);
|
let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e);
|
||||||
var request = {
|
var request = {
|
||||||
floID: myFloID,
|
floID: myFloID,
|
||||||
application: options.application || floGlobals.application,
|
application: options.application || DEFAULT.application,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
status: true,
|
status: true,
|
||||||
pubKey: myPubKey
|
pubKey: myPubKey
|
||||||
}
|
}
|
||||||
let hashcontent = ["time", "application", "floID"].map(d => request[d]).join("|");
|
let hashcontent = ["time", "application", "floID"].map(d => request[d]).join("|");
|
||||||
request.sign = floCrypto.signData(hashcontent, myPrivKey);
|
request.sign = floCrypto.signData(hashcontent, myPrivKey);
|
||||||
liveRequest(options.refID || floGlobals.adminID, request, callback)
|
liveRequest(options.refID || DEFAULT.adminID, request, callback)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
@ -380,10 +419,10 @@
|
|||||||
let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e);
|
let callback = options.callback instanceof Function ? options.callback : (d, e) => console.debug(d, e);
|
||||||
let request = {
|
let request = {
|
||||||
status: false,
|
status: false,
|
||||||
application: options.application || floGlobals.application,
|
application: options.application || DEFAULT.application,
|
||||||
trackList: trackList
|
trackList: trackList
|
||||||
}
|
}
|
||||||
liveRequest(options.refID || floGlobals.adminID, request, callback)
|
liveRequest(options.refID || DEFAULT.adminID, request, callback)
|
||||||
.then(result => resolve(result))
|
.then(result => resolve(result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
@ -394,11 +433,11 @@
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var data = {
|
var data = {
|
||||||
senderID: myFloID,
|
senderID: myFloID,
|
||||||
receiverID: options.receiverID || floGlobals.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
pubKey: myPubKey,
|
pubKey: myPubKey,
|
||||||
message: encodeMessage(message),
|
message: encodeMessage(message),
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
application: options.application || floGlobals.application,
|
application: options.application || DEFAULT.application,
|
||||||
type: type,
|
type: type,
|
||||||
comment: options.comment || ""
|
comment: options.comment || ""
|
||||||
}
|
}
|
||||||
@ -415,9 +454,9 @@
|
|||||||
const requestApplicationData = floCloudAPI.requestApplicationData = function(type, options = {}) {
|
const requestApplicationData = floCloudAPI.requestApplicationData = function(type, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var request = {
|
var request = {
|
||||||
receiverID: options.receiverID || floGlobals.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
senderID: options.senderID || undefined,
|
senderID: options.senderID || undefined,
|
||||||
application: options.application || floGlobals.application,
|
application: options.application || DEFAULT.application,
|
||||||
type: type,
|
type: type,
|
||||||
comment: options.comment || undefined,
|
comment: options.comment || undefined,
|
||||||
lowerVectorClock: options.lowerVectorClock || undefined,
|
lowerVectorClock: options.lowerVectorClock || undefined,
|
||||||
@ -451,7 +490,7 @@
|
|||||||
pubKey: myPubKey,
|
pubKey: myPubKey,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
delete: (Array.isArray(vectorClocks) ? vectorClocks : [vectorClocks]),
|
delete: (Array.isArray(vectorClocks) ? vectorClocks : [vectorClocks]),
|
||||||
application: options.application || floGlobals.application
|
application: options.application || DEFAULT.application
|
||||||
}
|
}
|
||||||
let hashcontent = ["time", "application", "delete"]
|
let hashcontent = ["time", "application", "delete"]
|
||||||
.map(d => delreq[d]).join("|")
|
.map(d => delreq[d]).join("|")
|
||||||
@ -517,7 +556,7 @@
|
|||||||
if (!floGlobals.subAdmins.includes(myFloID))
|
if (!floGlobals.subAdmins.includes(myFloID))
|
||||||
return reject("Only subAdmins can tag data")
|
return reject("Only subAdmins can tag data")
|
||||||
var request = {
|
var request = {
|
||||||
receiverID: options.receiverID || floGlobals.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
requestorID: myFloID,
|
requestorID: myFloID,
|
||||||
pubKey: myPubKey,
|
pubKey: myPubKey,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
@ -536,7 +575,7 @@
|
|||||||
floCloudAPI.noteApplicationData = function(vectorClock, note, options = {}) {
|
floCloudAPI.noteApplicationData = function(vectorClock, note, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var request = {
|
var request = {
|
||||||
receiverID: options.receiverID || floGlobals.adminID,
|
receiverID: options.receiverID || DEFAULT.adminID,
|
||||||
requestorID: myFloID,
|
requestorID: myFloID,
|
||||||
pubKey: myPubKey,
|
pubKey: myPubKey,
|
||||||
time: Date.now(),
|
time: Date.now(),
|
||||||
@ -569,8 +608,8 @@
|
|||||||
floCloudAPI.requestGeneralData = function(type, options = {}) {
|
floCloudAPI.requestGeneralData = function(type, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
var fk = filterKey(type, options)
|
var fk = filterKey(type, options)
|
||||||
floGlobals.lastVC[fk] = parseInt(floGlobals.lastVC[fk]) || 0;
|
lastVC[fk] = parseInt(lastVC[fk]) || 0;
|
||||||
options.afterTime = options.afterTime || floGlobals.lastVC[fk];
|
options.afterTime = options.afterTime || lastVC[fk];
|
||||||
if (options.callback instanceof Function) {
|
if (options.callback instanceof Function) {
|
||||||
let new_options = Object.create(options)
|
let new_options = Object.create(options)
|
||||||
new_options.callback = (d, e) => {
|
new_options.callback = (d, e) => {
|
||||||
@ -592,7 +631,7 @@
|
|||||||
//request an object data from supernode cloud
|
//request an object data from supernode cloud
|
||||||
floCloudAPI.requestObjectData = function(objectName, options = {}) {
|
floCloudAPI.requestObjectData = function(objectName, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
options.lowerVectorClock = options.lowerVectorClock || floGlobals.lastVC[objectName] + 1;
|
options.lowerVectorClock = options.lowerVectorClock || lastVC[objectName] + 1;
|
||||||
options.senderID = [false, null].includes(options.senderID) ? null :
|
options.senderID = [false, null].includes(options.senderID) ? null :
|
||||||
options.senderID || floGlobals.subAdmins;
|
options.senderID || floGlobals.subAdmins;
|
||||||
options.mostRecent = true;
|
options.mostRecent = true;
|
||||||
@ -609,7 +648,7 @@
|
|||||||
requestApplicationData(objectName, options).then(dataSet => {
|
requestApplicationData(objectName, options).then(dataSet => {
|
||||||
updateObject(objectName, objectifier(dataSet));
|
updateObject(objectName, objectifier(dataSet));
|
||||||
delete options.comment;
|
delete options.comment;
|
||||||
options.lowerVectorClock = floGlobals.lastVC[objectName] + 1;
|
options.lowerVectorClock = lastVC[objectName] + 1;
|
||||||
delete options.mostRecent;
|
delete options.mostRecent;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
let new_options = Object.create(options);
|
let new_options = Object.create(options);
|
||||||
@ -620,7 +659,7 @@
|
|||||||
} else {
|
} else {
|
||||||
requestApplicationData(objectName, options).then(dataSet => {
|
requestApplicationData(objectName, options).then(dataSet => {
|
||||||
updateObject(objectName, objectifier(dataSet))
|
updateObject(objectName, objectifier(dataSet))
|
||||||
resolve(floGlobals.appObjects[objectName])
|
resolve(appObjects[objectName])
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
}
|
}
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
@ -644,7 +683,7 @@
|
|||||||
floCloudAPI.resetObjectData = function(objectName, options = {}) {
|
floCloudAPI.resetObjectData = function(objectName, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let message = {
|
let message = {
|
||||||
reset: floGlobals.appObjects[objectName]
|
reset: appObjects[objectName]
|
||||||
}
|
}
|
||||||
options.comment = 'RESET';
|
options.comment = 'RESET';
|
||||||
sendApplicationData(message, objectName, options).then(result => {
|
sendApplicationData(message, objectName, options).then(result => {
|
||||||
@ -658,7 +697,7 @@
|
|||||||
floCloudAPI.updateObjectData = function(objectName, options = {}) {
|
floCloudAPI.updateObjectData = function(objectName, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let message = {
|
let message = {
|
||||||
diff: diff.find(lastCommit.get(objectName), floGlobals.appObjects[
|
diff: diff.find(lastCommit.get(objectName), appObjects[
|
||||||
objectName])
|
objectName])
|
||||||
}
|
}
|
||||||
options.comment = 'UPDATE';
|
options.comment = 'UPDATE';
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
(function(EXPORTS) { //floDapps v2.2.0a
|
(function(EXPORTS) { //floDapps v2.2.1
|
||||||
/* General functions for FLO Dapps*/
|
/* General functions for FLO Dapps*/
|
||||||
//'use strict';
|
//'use strict';
|
||||||
const floDapps = EXPORTS;
|
const floDapps = EXPORTS;
|
||||||
@ -72,8 +72,8 @@
|
|||||||
|
|
||||||
startUpFunctions.push(function readSupernodeListFromAPI() {
|
startUpFunctions.push(function readSupernodeListFromAPI() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
compactIDB.readData("lastTx", floGlobals.SNStorageID, "floDapps").then(lastTx => {
|
compactIDB.readData("lastTx", floCloudAPI.SNStorageID, "floDapps").then(lastTx => {
|
||||||
floBlockchainAPI.readData(floGlobals.SNStorageID, {
|
floBlockchainAPI.readData(floCloudAPI.SNStorageID, {
|
||||||
ignoreOld: lastTx,
|
ignoreOld: lastTx,
|
||||||
sentOnly: true,
|
sentOnly: true,
|
||||||
pattern: "SuperNodeStorage"
|
pattern: "SuperNodeStorage"
|
||||||
@ -85,10 +85,9 @@
|
|||||||
for (sn in content.newNodes)
|
for (sn in content.newNodes)
|
||||||
compactIDB.writeData("supernodes", content.newNodes[sn], sn, "floDapps");
|
compactIDB.writeData("supernodes", content.newNodes[sn], sn, "floDapps");
|
||||||
}
|
}
|
||||||
compactIDB.writeData("lastTx", result.totalTxs, floGlobals.SNStorageID, "floDapps");
|
compactIDB.writeData("lastTx", result.totalTxs, floCloudAPI.SNStorageID, "floDapps");
|
||||||
compactIDB.readAllData("supernodes", "floDapps").then(result => {
|
compactIDB.readAllData("supernodes", "floDapps").then(result => {
|
||||||
floGlobals.supernodes = result;
|
floCloudAPI.init(result)
|
||||||
floCloudAPI.init()
|
|
||||||
.then(result => resolve("Loaded Supernode list\n" + result))
|
.then(result => resolve("Loaded Supernode list\n" + result))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
})
|
})
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
(function(GLOBAL) { //lib v1.2.2
|
(function(GLOBAL) { //lib v1.2.2a
|
||||||
'use strict';
|
'use strict';
|
||||||
/* Utility Libraries required for Standard operations
|
/* Utility Libraries required for Standard operations
|
||||||
* All credits for these codes belong to their respective creators, moderators and owners.
|
* All credits for these codes belong to their respective creators, moderators and owners.
|
||||||
* For more info (including license and terms of use), please visit respective source.
|
* For more info (including license and terms of use), please visit respective source.
|
||||||
*/
|
*/
|
||||||
GLOBAL.cryptocoin = floGlobals.blockchain;
|
GLOBAL.cryptocoin = (typeof floGlobals === 'undefined' ? null : floGlobals.blockchain) || 'FLO';
|
||||||
|
|
||||||
//Crypto.js
|
//Crypto.js
|
||||||
(function() {
|
(function() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user