commit
3bb03efa88
@ -1,4 +1,4 @@
|
|||||||
(function (EXPORTS) { //floBlockchainAPI v2.4.3
|
(function (EXPORTS) { //floBlockchainAPI v2.5.1
|
||||||
/* 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;
|
||||||
@ -9,9 +9,9 @@
|
|||||||
FLO: ['https://flosight.duckdns.org/', 'https://flosight.ranchimall.net/'],
|
FLO: ['https://flosight.duckdns.org/', 'https://flosight.ranchimall.net/'],
|
||||||
FLO_TEST: ['https://testnet-flosight.duckdns.org', 'https://testnet.flocha.in/']
|
FLO_TEST: ['https://testnet-flosight.duckdns.org', 'https://testnet.flocha.in/']
|
||||||
},
|
},
|
||||||
sendAmt: 0.001,
|
sendAmt: 0.0003,
|
||||||
fee: 0.0005,
|
fee: 0.0002,
|
||||||
minChangeAmt: 0.0005,
|
minChangeAmt: 0.0002,
|
||||||
receiverID: floGlobals.adminID
|
receiverID: floGlobals.adminID
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
util.Sat_to_FLO = value => parseFloat((value / SATOSHI_IN_BTC).toFixed(8));
|
util.Sat_to_FLO = value => parseFloat((value / SATOSHI_IN_BTC).toFixed(8));
|
||||||
util.FLO_to_Sat = value => parseInt(value * SATOSHI_IN_BTC);
|
util.FLO_to_Sat = value => parseInt(value * SATOSHI_IN_BTC);
|
||||||
|
util.toFixed = value => parseFloat((value).toFixed(8));
|
||||||
|
|
||||||
Object.defineProperties(floBlockchainAPI, {
|
Object.defineProperties(floBlockchainAPI, {
|
||||||
sendAmt: {
|
sendAmt: {
|
||||||
@ -120,14 +121,46 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Get balance for the given Address
|
//Get balance for the given Address
|
||||||
const getBalance = floBlockchainAPI.getBalance = function (addr) {
|
const getBalance = floBlockchainAPI.getBalance = function (addr, after = null) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
promisedAPI(`api/addr/${addr}/balance`)
|
let api = `api/addr/${addr}/balance`;
|
||||||
.then(balance => resolve(parseFloat(balance)))
|
if (after) {
|
||||||
.catch(error => reject(error));
|
if (typeof after === 'string' && /^[0-9a-z]{64}$/i.test(after))
|
||||||
|
api += '?after=' + after;
|
||||||
|
else return reject("Invalid 'after' parameter");
|
||||||
|
}
|
||||||
|
promisedAPI(api).then(result => {
|
||||||
|
if (typeof result === 'object' && result.lastItem) {
|
||||||
|
getBalance(addr, result.lastItem)
|
||||||
|
.then(r => resolve(util.toFixed(r + result.data)))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
} else resolve(result);
|
||||||
|
}).catch(error => reject(error))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getUTXOs = address => new Promise((resolve, reject) => {
|
||||||
|
promisedAPI(`api/addr/${address}/utxo`)
|
||||||
|
.then(utxo => resolve(utxo))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
})
|
||||||
|
|
||||||
|
const getUnconfirmedSpent = address => new Promise((resolve, reject) => {
|
||||||
|
readTxs(address, { mempool: "only" }).then(result => {
|
||||||
|
let unconfirmedSpent = {};
|
||||||
|
for (let tx of result.items)
|
||||||
|
if (tx.confirmations == 0)
|
||||||
|
for (let vin of tx.vin)
|
||||||
|
if (vin.addr === address) {
|
||||||
|
if (Array.isArray(unconfirmedSpent[vin.txid]))
|
||||||
|
unconfirmedSpent[vin.txid].push(vin.vout);
|
||||||
|
else
|
||||||
|
unconfirmedSpent[vin.txid] = [vin.vout];
|
||||||
|
}
|
||||||
|
resolve(unconfirmedSpent);
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
|
||||||
//create a transaction with single sender
|
//create a transaction with single sender
|
||||||
const createTx = function (senderAddr, receiverAddr, sendAmt, floData = '', strict_utxo = true) {
|
const createTx = function (senderAddr, receiverAddr, sendAmt, floData = '', strict_utxo = true) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -144,21 +177,8 @@
|
|||||||
var fee = DEFAULT.fee;
|
var fee = DEFAULT.fee;
|
||||||
if (balance < sendAmt + fee)
|
if (balance < sendAmt + fee)
|
||||||
return reject("Insufficient FLO balance!");
|
return reject("Insufficient FLO balance!");
|
||||||
//get unconfirmed tx list
|
getUnconfirmedSpent(senderAddr).then(unconfirmedSpent => {
|
||||||
promisedAPI(`api/addr/${senderAddr}`).then(result => {
|
getUTXOs(senderAddr).then(utxos => {
|
||||||
readTxs(senderAddr, 0, result.unconfirmedTxApperances).then(result => {
|
|
||||||
let unconfirmedSpent = {};
|
|
||||||
for (let tx of result.items)
|
|
||||||
if (tx.confirmations == 0)
|
|
||||||
for (let vin of tx.vin)
|
|
||||||
if (vin.addr === senderAddr) {
|
|
||||||
if (Array.isArray(unconfirmedSpent[vin.txid]))
|
|
||||||
unconfirmedSpent[vin.txid].push(vin.vout);
|
|
||||||
else
|
|
||||||
unconfirmedSpent[vin.txid] = [vin.vout];
|
|
||||||
}
|
|
||||||
//get utxos list
|
|
||||||
promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => {
|
|
||||||
//form/construct the transaction data
|
//form/construct the transaction data
|
||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
var utxoAmt = 0.0;
|
var utxoAmt = 0.0;
|
||||||
@ -185,7 +205,6 @@
|
|||||||
}).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))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +257,7 @@
|
|||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
var utxoAmt = 0.0;
|
var utxoAmt = 0.0;
|
||||||
var fee = DEFAULT.fee;
|
var fee = DEFAULT.fee;
|
||||||
promisedAPI(`api/addr/${floID}/utxo`).then(utxos => {
|
getUTXOs(floID).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) {
|
||||||
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
trx.addinput(utxos[i].txid, utxos[i].vout, utxos[i].scriptPubKey);
|
||||||
@ -261,11 +280,11 @@
|
|||||||
* @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 = [DEFAULT.receiverID], preserveRatio = true) {
|
floBlockchainAPI.writeDataMultiple = function (senderPrivKeys, data, receivers = [DEFAULT.receiverID], options = {}) {
|
||||||
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 (options.preserveRatio === false) {
|
||||||
let tmp = {};
|
let tmp = {};
|
||||||
let amount = (DEFAULT.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);
|
||||||
@ -275,7 +294,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 = DEFAULT.sendAmt;
|
let amount = options.sendAmt || DEFAULT.sendAmt;
|
||||||
receivers.forEach(floID => tmp[floID] = amount);
|
receivers.forEach(floID => tmp[floID] = amount);
|
||||||
receivers = tmp
|
receivers = tmp
|
||||||
}
|
}
|
||||||
@ -405,7 +424,7 @@
|
|||||||
//Get the UTXOs of the senders
|
//Get the UTXOs of the senders
|
||||||
let promises = [];
|
let promises = [];
|
||||||
for (let floID in senders)
|
for (let floID in senders)
|
||||||
promises.push(promisedAPI(`api/addr/${floID}/utxo`));
|
promises.push(getUTXOs(floID));
|
||||||
Promise.all(promises).then(results => {
|
Promise.all(promises).then(results => {
|
||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
for (let floID in senders) {
|
for (let floID in senders) {
|
||||||
@ -479,21 +498,8 @@
|
|||||||
var fee = DEFAULT.fee;
|
var fee = DEFAULT.fee;
|
||||||
if (balance < sendAmt + fee)
|
if (balance < sendAmt + fee)
|
||||||
return reject("Insufficient FLO balance!");
|
return reject("Insufficient FLO balance!");
|
||||||
//get unconfirmed tx list
|
getUnconfirmedSpent(senderAddr).then(unconfirmedSpent => {
|
||||||
promisedAPI(`api/addr/${senderAddr}`).then(result => {
|
getUTXOs(senderAddr).then(utxos => {
|
||||||
readTxs(senderAddr, 0, result.unconfirmedTxApperances).then(result => {
|
|
||||||
let unconfirmedSpent = {};
|
|
||||||
for (let tx of result.items)
|
|
||||||
if (tx.confirmations == 0)
|
|
||||||
for (let vin of tx.vin)
|
|
||||||
if (vin.addr === senderAddr) {
|
|
||||||
if (Array.isArray(unconfirmedSpent[vin.txid]))
|
|
||||||
unconfirmedSpent[vin.txid].push(vin.vout);
|
|
||||||
else
|
|
||||||
unconfirmedSpent[vin.txid] = [vin.vout];
|
|
||||||
}
|
|
||||||
//get utxos list
|
|
||||||
promisedAPI(`api/addr/${senderAddr}/utxo`).then(utxos => {
|
|
||||||
//form/construct the transaction data
|
//form/construct the transaction data
|
||||||
var trx = bitjs.transaction();
|
var trx = bitjs.transaction();
|
||||||
var utxoAmt = 0.0;
|
var utxoAmt = 0.0;
|
||||||
@ -521,7 +527,6 @@
|
|||||||
}).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))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +662,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getTxOutput = (txid, i) => new Promise((resolve, reject) => {
|
const getTxOutput = (txid, i) => new Promise((resolve, reject) => {
|
||||||
fetch_api(`api/tx/${txid}`)
|
promisedAPI(`api/tx/${txid}`)
|
||||||
.then(result => resolve(result.vout[i]))
|
.then(result => resolve(result.vout[i]))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
});
|
});
|
||||||
@ -740,30 +745,57 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isUndefined = val => typeof val === 'undefined';
|
||||||
|
|
||||||
//Read Txs of Address between from and to
|
//Read Txs of Address between from and to
|
||||||
const readTxs = floBlockchainAPI.readTxs = function (addr, from, to) {
|
const readTxs = floBlockchainAPI.readTxs = function (addr, options = {}) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=${from}&to=${to}`)
|
let api = `api/addrs/${addr}/txs`;
|
||||||
|
//API options
|
||||||
|
let api_options = [];
|
||||||
|
if (!isUndefined(options.after))
|
||||||
|
api_options.push(`after=${options.after}`);
|
||||||
|
else {
|
||||||
|
if (!isUndefined(options.from))
|
||||||
|
api_options.push(`from=${options.from}`);
|
||||||
|
if (!isUndefined(options.to))
|
||||||
|
api_options.push(`to=${options.to}`);
|
||||||
|
}
|
||||||
|
if (!isUndefined(options.mempool))
|
||||||
|
api_options.push(`mempool=${options.mempool}`)
|
||||||
|
if (api_options.length)
|
||||||
|
api += "?" + api_options.join('&');
|
||||||
|
promisedAPI(api)
|
||||||
.then(response => resolve(response))
|
.then(response => resolve(response))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read All Txs of Address (newest first)
|
//Read All Txs of Address (newest first)
|
||||||
floBlockchainAPI.readAllTxs = function (addr) {
|
const readAllTxs = floBlockchainAPI.readAllTxs = function (addr, options) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => {
|
readTxs(addr, options).then(response => {
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=0&to=${response.totalItems}0`)
|
if (response.incomplete) {
|
||||||
.then(response => resolve(response.items))
|
let next_options = Object.assign({}, options);
|
||||||
.catch(error => reject(error));
|
next_options.after = response.lastItem;
|
||||||
|
readAllTxs(addr, next_options).then(r => {
|
||||||
|
r.items = r.items.concat(response.items); //latest tx are 1st in array
|
||||||
|
resolve(r);
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
|
} else
|
||||||
|
resolve({
|
||||||
|
lastKey: response.lastItem || options.after,
|
||||||
|
items: response.items
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Read flo Data from txs of given Address
|
/*Read flo Data from txs of given Address
|
||||||
options can be used to filter data
|
options can be used to filter data
|
||||||
limit : maximum number of filtered data (default = 1000, negative = no limit)
|
after : query after the given txid
|
||||||
ignoreOld : ignore old txs (default = 0)
|
mempool : query mempool tx or not (options same as readAllTx, DEFAULT=false: ignore unconfirmed tx)
|
||||||
|
ignoreOld : ignore old txs (deprecated: support for backward compatibility only, cannot be used with 'after')
|
||||||
sentOnly : filters only sent data
|
sentOnly : filters only sent data
|
||||||
receivedOnly: filters only received data
|
receivedOnly: filters only received data
|
||||||
pattern : filters data that with JSON pattern
|
pattern : filters data that with JSON pattern
|
||||||
@ -773,98 +805,73 @@
|
|||||||
receiver : flo-id(s) of receiver
|
receiver : flo-id(s) of receiver
|
||||||
*/
|
*/
|
||||||
floBlockchainAPI.readData = function (addr, options = {}) {
|
floBlockchainAPI.readData = function (addr, options = {}) {
|
||||||
options.limit = options.limit || 0;
|
return new Promise((resolve, reject) => {
|
||||||
options.ignoreOld = options.ignoreOld || 0;
|
|
||||||
|
//fetch options
|
||||||
|
let fetch_options = {};
|
||||||
|
fetch_options.mempool = isUndefined(options.mempool) ? 'false' : options.mempool; //DEFAULT: ignore unconfirmed tx
|
||||||
|
if (!isUndefined(options.after)) {
|
||||||
|
if (!isUndefined(options.ignoreOld)) //Backward support
|
||||||
|
return reject("Invalid options: cannot use after and ignoreOld in same query");
|
||||||
|
else
|
||||||
|
fetch_options.after = options.after;
|
||||||
|
}
|
||||||
|
readAllTxs(addr, fetch_options).then(response => {
|
||||||
|
|
||||||
|
if (Number.isInteger(options.ignoreOld)) //backward support, cannot be used with options.after
|
||||||
|
response.items.splice(-options.ignoreOld); //negative to count from end of the array
|
||||||
|
|
||||||
if (typeof options.senders === "string") options.senders = [options.senders];
|
if (typeof options.senders === "string") options.senders = [options.senders];
|
||||||
if (typeof options.receivers === "string") options.receivers = [options.receivers];
|
if (typeof options.receivers === "string") options.receivers = [options.receivers];
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => {
|
//filter the txs based on options
|
||||||
var newItems = response.totalItems - options.ignoreOld;
|
const filteredData = response.items.filter(tx => {
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems * 2}`).then(response => {
|
|
||||||
if (options.limit <= 0)
|
if (!tx.confirmations) //unconfirmed transactions: this should not happen as we send mempool=false in API query
|
||||||
options.limit = response.items.length;
|
return false;
|
||||||
var filteredData = [];
|
|
||||||
let numToRead = response.totalItems - options.ignoreOld,
|
if (options.sentOnly && !tx.vin.some(vin => vin.addr === addr))
|
||||||
unconfirmedCount = 0;
|
return false;
|
||||||
for (let i = 0; i < numToRead && filteredData.length < options.limit; i++) {
|
else if (Array.isArray(options.senders) && !tx.vin.some(vin => options.senders.includes(vin.addr)))
|
||||||
if (!response.items[i].confirmations) { //unconfirmed transactions
|
return false;
|
||||||
unconfirmedCount++;
|
|
||||||
if (numToRead < response.items[i].length)
|
if (options.receivedOnly && !tx.vout.some(vout => vout.scriptPubKey.addresses[0] === addr))
|
||||||
numToRead++;
|
return false;
|
||||||
continue;
|
else if (Array.isArray(options.receivers) && !tx.vout.some(vout => options.receivers.includes(vout.scriptPubKey.addresses[0])))
|
||||||
}
|
return false;
|
||||||
|
|
||||||
if (options.pattern) {
|
if (options.pattern) {
|
||||||
try {
|
try {
|
||||||
let jsonContent = JSON.parse(response.items[i].floData);
|
let jsonContent = JSON.parse(tx.floData);
|
||||||
if (!Object.keys(jsonContent).includes(options.pattern))
|
if (!Object.keys(jsonContent).includes(options.pattern))
|
||||||
continue;
|
return false;
|
||||||
} catch (error) {
|
} catch {
|
||||||
continue;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.sentOnly) {
|
|
||||||
let flag = false;
|
|
||||||
for (let vin of response.items[i].vin)
|
|
||||||
if (vin.addr === addr) {
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!flag) continue;
|
|
||||||
}
|
|
||||||
if (Array.isArray(options.senders)) {
|
|
||||||
let flag = false;
|
|
||||||
for (let vin of response.items[i].vin)
|
|
||||||
if (options.senders.includes(vin.addr)) {
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!flag) continue;
|
|
||||||
}
|
|
||||||
if (options.receivedOnly) {
|
|
||||||
let flag = false;
|
|
||||||
for (let vout of response.items[i].vout)
|
|
||||||
if (vout.scriptPubKey.addresses[0] === addr) {
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!flag) continue;
|
|
||||||
}
|
|
||||||
if (Array.isArray(options.receivers)) {
|
|
||||||
let flag = false;
|
|
||||||
for (let vout of response.items[i].vout)
|
|
||||||
if (options.receivers.includes(vout.scriptPubKey.addresses[0])) {
|
|
||||||
flag = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!flag) continue;
|
|
||||||
}
|
|
||||||
if (options.filter && !options.filter(response.items[i].floData))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (options.tx) {
|
|
||||||
let d = {}
|
|
||||||
d.txid = response.items[i].txid;
|
|
||||||
d.time = response.items[i].time;
|
|
||||||
d.blockheight = response.items[i].blockheight;
|
|
||||||
d.senders = new Set(response.items[i].vin.map(v => v.addr));
|
|
||||||
d.receivers = new Set(response.items[i].vout.map(v => v.scriptPubKey.addresses[0]));
|
|
||||||
d.data = response.items[i].floData;
|
|
||||||
filteredData.push(d);
|
|
||||||
} else
|
|
||||||
filteredData.push(response.items[i].floData);
|
|
||||||
}
|
|
||||||
resolve({
|
|
||||||
totalTxs: response.totalItems - unconfirmedCount,
|
|
||||||
data: filteredData
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
}).catch(error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (options.filter && !options.filter(tx.floData))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}).map(tx => options.tx ? {
|
||||||
|
txid: tx.txid,
|
||||||
|
time: tx.time,
|
||||||
|
blockheight: tx.blockheight,
|
||||||
|
senders: new Set(tx.vin.map(v => v.addr)),
|
||||||
|
receivers: new Set(tx.vout.map(v => v.scriptPubKey.addresses[0])),
|
||||||
|
data: tx.floData
|
||||||
|
} : tx.floData);
|
||||||
|
|
||||||
|
const result = { lastKey: response.lastKey };
|
||||||
|
if (options.tx)
|
||||||
|
result.items = filteredData;
|
||||||
|
else
|
||||||
|
result.data = filteredData
|
||||||
|
resolve(result);
|
||||||
|
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
})('object' === typeof module ? module.exports : window.floBlockchainAPI = {});
|
})('object' === typeof module ? module.exports : window.floBlockchainAPI = {});
|
||||||
30
floCrypto.js
30
floCrypto.js
@ -1,4 +1,4 @@
|
|||||||
(function (EXPORTS) { //floCrypto v2.3.5a
|
(function (EXPORTS) { //floCrypto v2.3.6a
|
||||||
/* FLO Crypto Operators */
|
/* FLO Crypto Operators */
|
||||||
'use strict';
|
'use strict';
|
||||||
const floCrypto = EXPORTS;
|
const floCrypto = EXPORTS;
|
||||||
@ -152,6 +152,19 @@
|
|||||||
newID: {
|
newID: {
|
||||||
get: () => generateNewID()
|
get: () => generateNewID()
|
||||||
},
|
},
|
||||||
|
hashID: {
|
||||||
|
value: (str) => {
|
||||||
|
let bytes = ripemd160(Crypto.SHA256(str, { asBytes: true }), { asBytes: true });
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
},
|
||||||
tmpID: {
|
tmpID: {
|
||||||
get: () => {
|
get: () => {
|
||||||
let bytes = Crypto.util.randomBytes(20);
|
let bytes = Crypto.util.randomBytes(20);
|
||||||
@ -323,6 +336,21 @@
|
|||||||
return bitjs.Base58.encode(raw.bytes.concat(hash.slice(0, 4)));
|
return bitjs.Base58.encode(raw.bytes.concat(hash.slice(0, 4)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Convert raw address bytes to floID
|
||||||
|
floCrypto.rawToFloID = function (raw_bytes) {
|
||||||
|
if (typeof raw_bytes === 'string')
|
||||||
|
raw_bytes = Crypto.util.hexToBytes(raw_bytes);
|
||||||
|
if (raw_bytes.length != 20)
|
||||||
|
return null;
|
||||||
|
raw_bytes.unshift(bitjs.pub);
|
||||||
|
let hash = Crypto.SHA256(Crypto.SHA256(raw_bytes, {
|
||||||
|
asBytes: true
|
||||||
|
}), {
|
||||||
|
asBytes: true
|
||||||
|
});
|
||||||
|
return bitjs.Base58.encode(raw_bytes.concat(hash.slice(0, 4)));
|
||||||
|
}
|
||||||
|
|
||||||
//Convert the given multisig address (any blockchain) to equivalent multisig floID
|
//Convert the given multisig address (any blockchain) to equivalent multisig floID
|
||||||
floCrypto.toMultisigFloID = function (address, options = null) {
|
floCrypto.toMultisigFloID = function (address, options = null) {
|
||||||
if (!address)
|
if (!address)
|
||||||
|
|||||||
32
floDapps.js
32
floDapps.js
@ -1,4 +1,4 @@
|
|||||||
(function (EXPORTS) { //floDapps v2.3.3
|
(function (EXPORTS) { //floDapps v2.3.4
|
||||||
/* General functions for FLO Dapps*/
|
/* General functions for FLO Dapps*/
|
||||||
'use strict';
|
'use strict';
|
||||||
const floDapps = EXPORTS;
|
const floDapps = EXPORTS;
|
||||||
@ -229,10 +229,31 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const startUpOptions = {
|
||||||
|
cloud: true,
|
||||||
|
app_config: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
floDapps.startUpOptions = {
|
||||||
|
set app_config(val) {
|
||||||
|
if (val === true || val === false)
|
||||||
|
startUpOptions.app_config = val;
|
||||||
|
},
|
||||||
|
get app_config() { return startUpOptions.app_config },
|
||||||
|
|
||||||
|
set cloud(val) {
|
||||||
|
if (val === true || val === false)
|
||||||
|
startUpOptions.cloud = val;
|
||||||
|
},
|
||||||
|
get cloud() { return startUpOptions.cloud },
|
||||||
|
}
|
||||||
|
|
||||||
const startUpFunctions = [];
|
const startUpFunctions = [];
|
||||||
|
|
||||||
startUpFunctions.push(function readSupernodeListFromAPI() {
|
startUpFunctions.push(function readSupernodeListFromAPI() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!startUpOptions.cloud)
|
||||||
|
return resolve("No cloud for this app");
|
||||||
compactIDB.readData("lastTx", floCloudAPI.SNStorageID, DEFAULT.root).then(lastTx => {
|
compactIDB.readData("lastTx", floCloudAPI.SNStorageID, DEFAULT.root).then(lastTx => {
|
||||||
floBlockchainAPI.readData(floCloudAPI.SNStorageID, {
|
floBlockchainAPI.readData(floCloudAPI.SNStorageID, {
|
||||||
ignoreOld: lastTx,
|
ignoreOld: lastTx,
|
||||||
@ -265,6 +286,8 @@
|
|||||||
|
|
||||||
startUpFunctions.push(function readAppConfigFromAPI() {
|
startUpFunctions.push(function readAppConfigFromAPI() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!startUpOptions.app_config)
|
||||||
|
return resolve("No configs for this app");
|
||||||
compactIDB.readData("lastTx", `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root).then(lastTx => {
|
compactIDB.readData("lastTx", `${DEFAULT.application}|${DEFAULT.adminID}`, DEFAULT.root).then(lastTx => {
|
||||||
floBlockchainAPI.readData(DEFAULT.adminID, {
|
floBlockchainAPI.readData(DEFAULT.adminID, {
|
||||||
ignoreOld: lastTx,
|
ignoreOld: lastTx,
|
||||||
@ -306,6 +329,8 @@
|
|||||||
|
|
||||||
startUpFunctions.push(function loadDataFromAppIDB() {
|
startUpFunctions.push(function loadDataFromAppIDB() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!startUpOptions.cloud)
|
||||||
|
return resolve("No cloud for this app");
|
||||||
var loadData = ["appObjects", "generalData", "lastVC"]
|
var loadData = ["appObjects", "generalData", "lastVC"]
|
||||||
var promises = []
|
var promises = []
|
||||||
for (var i = 0; i < loadData.length; i++)
|
for (var i = 0; i < loadData.length; i++)
|
||||||
@ -417,6 +442,7 @@
|
|||||||
try {
|
try {
|
||||||
user_public = floCrypto.getPubKeyHex(privKey);
|
user_public = floCrypto.getPubKeyHex(privKey);
|
||||||
user_id = floCrypto.getAddress(privKey);
|
user_id = floCrypto.getAddress(privKey);
|
||||||
|
if (startUpOptions.cloud)
|
||||||
floCloudAPI.user(user_id, privKey); //Set user for floCloudAPI
|
floCloudAPI.user(user_id, privKey); //Set user for floCloudAPI
|
||||||
user_priv_wrap = () => checkIfPinRequired(key);
|
user_priv_wrap = () => checkIfPinRequired(key);
|
||||||
let n = floCrypto.randInt(12, 20);
|
let n = floCrypto.randInt(12, 20);
|
||||||
@ -580,6 +606,8 @@
|
|||||||
|
|
||||||
floDapps.manageAppConfig = function (adminPrivKey, addList, rmList, settings) {
|
floDapps.manageAppConfig = function (adminPrivKey, addList, rmList, settings) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!startUpOptions.app_config)
|
||||||
|
return reject("No configs for this app");
|
||||||
if (!Array.isArray(addList) || !addList.length) addList = undefined;
|
if (!Array.isArray(addList) || !addList.length) addList = undefined;
|
||||||
if (!Array.isArray(rmList) || !rmList.length) rmList = undefined;
|
if (!Array.isArray(rmList) || !rmList.length) rmList = undefined;
|
||||||
if (!settings || typeof settings !== "object" || !Object.keys(settings).length) settings = undefined;
|
if (!settings || typeof settings !== "object" || !Object.keys(settings).length) settings = undefined;
|
||||||
@ -604,6 +632,8 @@
|
|||||||
|
|
||||||
floDapps.manageAppTrustedIDs = function (adminPrivKey, addList, rmList) {
|
floDapps.manageAppTrustedIDs = function (adminPrivKey, addList, rmList) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!startUpOptions.app_config)
|
||||||
|
return reject("No configs for this app");
|
||||||
if (!Array.isArray(addList) || !addList.length) addList = undefined;
|
if (!Array.isArray(addList) || !addList.length) addList = undefined;
|
||||||
if (!Array.isArray(rmList) || !rmList.length) rmList = undefined;
|
if (!Array.isArray(rmList) || !rmList.length) rmList = undefined;
|
||||||
if (!addList && !rmList)
|
if (!addList && !rmList)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user