floBlockchainAPI v2.5.1: updated readData
- uses readAllTxs to chain query the txs from flosight
- keeping ignoreOld option to support backward compatibility, but resolved value no longer have totalTxs.
- new option 'after': fetch after the given txid
- new option 'mempool': query mempool tx or not (options same as readAllTx, DEFAULT=false: ignore unconfirmed tx)
- the resolved value have the following structure based on options.tx
true: {lastKey, items}
false (DEFAULT}: {lastKey, data}
- Optimized the query and filter process
This commit is contained in:
parent
a296a5c986
commit
e37e808a98
@ -1,4 +1,4 @@
|
|||||||
(function (EXPORTS) { //floBlockchainAPI v2.5.0
|
(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;
|
||||||
@ -793,8 +793,9 @@
|
|||||||
|
|
||||||
/*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
|
||||||
@ -804,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;
|
|
||||||
options.ignoreOld = options.ignoreOld || 0;
|
|
||||||
if (typeof options.senders === "string") options.senders = [options.senders];
|
|
||||||
if (typeof options.receivers === "string") options.receivers = [options.receivers];
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=0&to=1`).then(response => {
|
|
||||||
var newItems = response.totalItems - options.ignoreOld;
|
|
||||||
promisedAPI(`api/addrs/${addr}/txs?from=0&to=${newItems * 2}`).then(response => {
|
|
||||||
if (options.limit <= 0)
|
|
||||||
options.limit = response.items.length;
|
|
||||||
var filteredData = [];
|
|
||||||
let numToRead = response.totalItems - options.ignoreOld,
|
|
||||||
unconfirmedCount = 0;
|
|
||||||
for (let i = 0; i < numToRead && filteredData.length < options.limit; i++) {
|
|
||||||
if (!response.items[i].confirmations) { //unconfirmed transactions
|
|
||||||
unconfirmedCount++;
|
|
||||||
if (numToRead < response.items[i].length)
|
|
||||||
numToRead++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (options.pattern) {
|
|
||||||
try {
|
|
||||||
let jsonContent = JSON.parse(response.items[i].floData);
|
|
||||||
if (!Object.keys(jsonContent).includes(options.pattern))
|
|
||||||
continue;
|
|
||||||
} catch (error) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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) {
|
//fetch options
|
||||||
let d = {}
|
let fetch_options = {};
|
||||||
d.txid = response.items[i].txid;
|
fetch_options.mempool = isUndefined(options.mempool) ? 'false' : options.mempool; //DEFAULT: ignore unconfirmed tx
|
||||||
d.time = response.items[i].time;
|
if (!isUndefined(options.after)) {
|
||||||
d.blockheight = response.items[i].blockheight;
|
if (!isUndefined(options.ignoreOld)) //Backward support
|
||||||
d.senders = new Set(response.items[i].vin.map(v => v.addr));
|
return reject("Invalid options: cannot use after and ignoreOld in same query");
|
||||||
d.receivers = new Set(response.items[i].vout.map(v => v.scriptPubKey.addresses[0]));
|
else
|
||||||
d.data = response.items[i].floData;
|
fetch_options.after = options.after;
|
||||||
filteredData.push(d);
|
}
|
||||||
} else
|
readAllTxs(addr, fetch_options).then(response => {
|
||||||
filteredData.push(response.items[i].floData);
|
|
||||||
|
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.receivers === "string") options.receivers = [options.receivers];
|
||||||
|
|
||||||
|
//filter the txs based on options
|
||||||
|
const filteredData = response.items.filter(tx => {
|
||||||
|
|
||||||
|
if (!tx.confirmations) //unconfirmed transactions: this should not happen as we send mempool=false in API query
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (options.sentOnly && !tx.vin.some(vin => vin.addr === addr))
|
||||||
|
return false;
|
||||||
|
else if (Array.isArray(options.senders) && !tx.vin.some(vin => options.senders.includes(vin.addr)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (options.receivedOnly && !tx.vout.some(vout => vout.scriptPubKey.addresses[0] === addr))
|
||||||
|
return false;
|
||||||
|
else if (Array.isArray(options.receivers) && !tx.vout.some(vout => options.receivers.includes(vout.scriptPubKey.addresses[0])))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (options.pattern) {
|
||||||
|
try {
|
||||||
|
let jsonContent = JSON.parse(tx.floData);
|
||||||
|
if (!Object.keys(jsonContent).includes(options.pattern))
|
||||||
|
return false;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resolve({
|
|
||||||
totalTxs: response.totalItems - unconfirmedCount,
|
if (options.filter && !options.filter(tx.floData))
|
||||||
data: filteredData
|
return false;
|
||||||
});
|
|
||||||
}).catch(error => {
|
return true;
|
||||||
reject(error);
|
}).map(tx => options.tx ? {
|
||||||
});
|
txid: tx.txid,
|
||||||
}).catch(error => {
|
time: tx.time,
|
||||||
reject(error);
|
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 = {});
|
||||||
Loading…
Reference in New Issue
Block a user