Blockchain-bonds and Bobs-fund balance check API
- Added API to check the balance and closing-amount needed for blockchain-bonds and bobs fund (checkBlockchainBond, checkBobsFund) in floExchangeAPI. - API resolves values in .pending: bond/fund closed by user, but not yet finished processing .ready: bond/fund ready to close by users .upcoming: bond/fund that will be out of lockin period (by given prior_time parameter) - Fixed: Bonds and Funds closing data not written to DB due to async - Fixed: floExchangeAPI not reading trusted-id list from blockchain - Added floExchangeAPI.config: getters for trustedList, assetList and tagList
This commit is contained in:
parent
28e4815636
commit
65c0d3c91f
@ -1527,6 +1527,66 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exchangeAPI.checkBlockchainBond = function (prior_time, floID, proxySecret) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let request = {
|
||||||
|
floID: floID,
|
||||||
|
prior_time,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
|
||||||
|
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
|
||||||
|
request.sign = signRequest({
|
||||||
|
type: "check_blockchain_bond",
|
||||||
|
prior_time,
|
||||||
|
timestamp: request.timestamp
|
||||||
|
}, proxySecret);
|
||||||
|
console.debug(request);
|
||||||
|
|
||||||
|
fetch_api('/check-blockchain-bond', {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(request)
|
||||||
|
}).then(result => {
|
||||||
|
responseParse(result)
|
||||||
|
.then(result => resolve(result))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
exchangeAPI.checkBobsFund = function (prior_time, floID, proxySecret) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let request = {
|
||||||
|
floID: floID,
|
||||||
|
prior_time,
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
if (floCrypto.getFloID(proxySecret) === floID) //Direct signing (without proxy)
|
||||||
|
request.pubKey = floCrypto.getPubKeyHex(proxySecret);
|
||||||
|
request.sign = signRequest({
|
||||||
|
type: "check_bobs_fund",
|
||||||
|
prior_time,
|
||||||
|
timestamp: request.timestamp
|
||||||
|
}, proxySecret);
|
||||||
|
console.debug(request);
|
||||||
|
|
||||||
|
fetch_api('/check-bobs-fund', {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify(request)
|
||||||
|
}).then(result => {
|
||||||
|
responseParse(result)
|
||||||
|
.then(result => resolve(result))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
exchangeAPI.closeBobsFundInvestment = function (fund_id, floID, privKey) {
|
exchangeAPI.closeBobsFundInvestment = function (fund_id, floID, privKey) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.verifyPrivKey(privKey, floID))
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
@ -1660,9 +1720,10 @@
|
|||||||
|
|
||||||
exchangeAPI.init = function refreshDataFromBlockchain() {
|
exchangeAPI.init = function refreshDataFromBlockchain() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let nodes, assets, tags, lastTx;
|
let nodes, trusted = new Set(), assets, tags, lastTx;
|
||||||
try {
|
try {
|
||||||
nodes = JSON.parse(localStorage.getItem('exchange-nodes'));
|
nodes = JSON.parse(localStorage.getItem('exchange-nodes'));
|
||||||
|
trusted = new Set((localStorage.getItem('exchange-trusted') || "").split(','));
|
||||||
assets = new Set((localStorage.getItem('exchange-assets') || "").split(','));
|
assets = new Set((localStorage.getItem('exchange-assets') || "").split(','));
|
||||||
tags = new Set((localStorage.getItem('exchange-tags') || "").split(','));
|
tags = new Set((localStorage.getItem('exchange-tags') || "").split(','));
|
||||||
if (typeof nodes !== 'object' || nodes === null)
|
if (typeof nodes !== 'object' || nodes === null)
|
||||||
@ -1671,6 +1732,7 @@
|
|||||||
lastTx = parseInt(localStorage.getItem('exchange-lastTx')) || 0;
|
lastTx = parseInt(localStorage.getItem('exchange-lastTx')) || 0;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
nodes = {};
|
nodes = {};
|
||||||
|
trusted = new Set();
|
||||||
assets = new Set();
|
assets = new Set();
|
||||||
tags = new Set();
|
tags = new Set();
|
||||||
lastTx = 0;
|
lastTx = 0;
|
||||||
@ -1691,6 +1753,15 @@
|
|||||||
for (let n in content.Nodes.add)
|
for (let n in content.Nodes.add)
|
||||||
nodes[n] = content.Nodes.add[n];
|
nodes[n] = content.Nodes.add[n];
|
||||||
}
|
}
|
||||||
|
//Trusted List
|
||||||
|
if (content.Trusted) {
|
||||||
|
if (content.Trusted.remove)
|
||||||
|
for (let id of content.Trusted.remove)
|
||||||
|
trusted.delete(id);
|
||||||
|
if (content.Trusted.add)
|
||||||
|
for (let id of content.Trusted.add)
|
||||||
|
trusted.add(id);
|
||||||
|
}
|
||||||
//Asset List
|
//Asset List
|
||||||
if (content.Assets) {
|
if (content.Assets) {
|
||||||
for (let a in content.Assets)
|
for (let a in content.Assets)
|
||||||
@ -1708,6 +1779,7 @@
|
|||||||
});
|
});
|
||||||
localStorage.setItem('exchange-lastTx', result.totalTxs);
|
localStorage.setItem('exchange-lastTx', result.totalTxs);
|
||||||
localStorage.setItem('exchange-nodes', JSON.stringify(nodes));
|
localStorage.setItem('exchange-nodes', JSON.stringify(nodes));
|
||||||
|
localStorage.setItem('exchange-trusted', Array.from(trusted).join(","));
|
||||||
localStorage.setItem('exchange-assets', Array.from(assets).join(","));
|
localStorage.setItem('exchange-assets', Array.from(assets).join(","));
|
||||||
localStorage.setItem('exchange-tags', Array.from(tags).join(","));
|
localStorage.setItem('exchange-tags', Array.from(tags).join(","));
|
||||||
nodeURL = nodes;
|
nodeURL = nodes;
|
||||||
@ -1718,8 +1790,21 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const config = exchangeAPI.config = {
|
||||||
|
get trustedList() {
|
||||||
|
return new Set((localStorage.getItem('exchange-trusted') || "").split(','));
|
||||||
|
},
|
||||||
|
get assetList() {
|
||||||
|
return new Set((localStorage.getItem('exchange-assets') || "").split(','));
|
||||||
|
},
|
||||||
|
get tagList() {
|
||||||
|
return new Set((localStorage.getItem('exchange-tags') || "").split(','));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exchangeAPI.clearAllLocalData = function () {
|
exchangeAPI.clearAllLocalData = function () {
|
||||||
localStorage.removeItem('exchange-nodes');
|
localStorage.removeItem('exchange-nodes');
|
||||||
|
localStorage.removeItem('exchange-trusted');
|
||||||
localStorage.removeItem('exchange-assets');
|
localStorage.removeItem('exchange-assets');
|
||||||
localStorage.removeItem('exchange-tags');
|
localStorage.removeItem('exchange-tags');
|
||||||
localStorage.removeItem('exchange-lastTx');
|
localStorage.removeItem('exchange-lastTx');
|
||||||
|
|||||||
@ -102,11 +102,15 @@ module.exports = function App(secret) {
|
|||||||
app.post('/withdraw-convert-coin-fund', Request.WithdrawConvertCoinFund);
|
app.post('/withdraw-convert-coin-fund', Request.WithdrawConvertCoinFund);
|
||||||
app.post('/withdraw-convert-currency-fund', Request.WithdrawConvertCurrencyFund);
|
app.post('/withdraw-convert-currency-fund', Request.WithdrawConvertCurrencyFund);
|
||||||
|
|
||||||
//close blockchain-bond
|
//close blockchain-bond and bobs-fund-investment
|
||||||
app.post('/close-blockchain-bonds', Request.CloseBlockchainBond);
|
app.post('/close-blockchain-bonds', Request.CloseBlockchainBond);
|
||||||
app.post('/close-bobs-fund-investment', Request.CloseBobsFund);
|
app.post('/close-bobs-fund-investment', Request.CloseBobsFund);
|
||||||
|
|
||||||
//Manage user tags (Access to trusted IDs only)
|
//check balance for blockchain-bond and bobs-fund (trusted IDs only)
|
||||||
|
app.post('/check-blockchain-bond', Request.CheckBlockchainBondBalance);
|
||||||
|
app.post('/check-bobs-fund', Request.CheckBobsFundBalance);
|
||||||
|
|
||||||
|
//Manage user tags (trusted IDs only)
|
||||||
app.post('/add-tag', Request.AddUserTag);
|
app.post('/add-tag', Request.AddUserTag);
|
||||||
app.post('/remove-tag', Request.RemoveUserTag);
|
app.post('/remove-tag', Request.RemoveUserTag);
|
||||||
app.post('/add-distributor', Request.AddDistributor);
|
app.post('/add-distributor', Request.AddDistributor);
|
||||||
|
|||||||
@ -104,10 +104,10 @@ function logRequest(floID, req_str, sign, proxy = false) {
|
|||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
function processRequest(res, floID, pubKey, sign, rText, validateObj, marketFn) {
|
function processRequest(res, floID, pubKey, sign, rText, validateObj, marketFn, log = true) {
|
||||||
validateRequest(validateObj, sign, floID, pubKey).then(req_str => {
|
validateRequest(validateObj, sign, floID, pubKey).then(req_str => {
|
||||||
marketFn().then(result => {
|
marketFn().then(result => {
|
||||||
logRequest(floID, req_str, sign, !pubKey);
|
if (log) logRequest(floID, req_str, sign, !pubKey);
|
||||||
res.send(result);
|
res.send(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
if (error instanceof INVALID)
|
if (error instanceof INVALID)
|
||||||
@ -452,6 +452,28 @@ function CloseBobsFund(req, res) {
|
|||||||
}, () => bobs_fund.closeFund(data.fund_id, data.floID, `${data.timestamp}.${data.sign}`));
|
}, () => bobs_fund.closeFund(data.fund_id, data.floID, `${data.timestamp}.${data.sign}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function CheckBlockchainBondBalance(req, res) {
|
||||||
|
let data = req.body;
|
||||||
|
if (!trustedIDs.includes(data.floID))
|
||||||
|
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
||||||
|
else processRequest(res, data.floID, data.pubKey, data.sign, "Check blockchain-bond", {
|
||||||
|
type: "check_blockchain_bond",
|
||||||
|
prior_time: data.prior_time,
|
||||||
|
timestamp: data.timestamp
|
||||||
|
}, () => blockchain_bonds.checkBondBalance(data.prior_time), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function CheckBobsFundBalance(req, res) {
|
||||||
|
let data = req.body;
|
||||||
|
if (!trustedIDs.includes(data.floID))
|
||||||
|
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
||||||
|
else processRequest(res, data.floID, data.pubKey, data.sign, "Check bobs-fund", {
|
||||||
|
type: "check_bobs_fund",
|
||||||
|
prior_time: data.prior_time,
|
||||||
|
timestamp: data.timestamp
|
||||||
|
}, () => bobs_fund.checkFundBalance(data.prior_time), false);
|
||||||
|
}
|
||||||
|
|
||||||
/* Public Requests */
|
/* Public Requests */
|
||||||
|
|
||||||
function GetLoginCode(req, res) {
|
function GetLoginCode(req, res) {
|
||||||
@ -695,6 +717,8 @@ module.exports = {
|
|||||||
WithdrawConvertCurrencyFund,
|
WithdrawConvertCurrencyFund,
|
||||||
CloseBlockchainBond,
|
CloseBlockchainBond,
|
||||||
CloseBobsFund,
|
CloseBobsFund,
|
||||||
|
CheckBlockchainBondBalance,
|
||||||
|
CheckBobsFundBalance,
|
||||||
set trustedIDs(ids) {
|
set trustedIDs(ids) {
|
||||||
trustedIDs = ids;
|
trustedIDs = ids;
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const DB = require("../database");
|
const DB = require("../database");
|
||||||
|
const { sink_chest, sink_groups } = require("../keys");
|
||||||
const eCode = require('../../docs/scripts/floExchangeAPI').errorCode;
|
const eCode = require('../../docs/scripts/floExchangeAPI').errorCode;
|
||||||
const pCode = require('../../docs/scripts/floExchangeAPI').processCode;
|
const pCode = require('../../docs/scripts/floExchangeAPI').processCode;
|
||||||
const getRate = require('./conversion').getRate;
|
const getRate = require('./conversion').getRate;
|
||||||
@ -210,7 +211,7 @@ function refreshBlockchainData(nodeList = []) {
|
|||||||
tx: true,
|
tx: true,
|
||||||
filter: d => d.startsWith(bobsFund.productStr)
|
filter: d => d.startsWith(bobsFund.productStr)
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
let promises = [];
|
let txQueries = [];
|
||||||
result.data.reverse().forEach(d => {
|
result.data.reverse().forEach(d => {
|
||||||
let fund = bobsFund.parse(d.data);
|
let fund = bobsFund.parse(d.data);
|
||||||
if (d.senders.has(bobsFund.config.adminID) && !/close:/.test(d.data)) {
|
if (d.senders.has(bobsFund.config.adminID) && !/close:/.test(d.data)) {
|
||||||
@ -220,11 +221,11 @@ function refreshBlockchainData(nodeList = []) {
|
|||||||
let values = [fund_id, fund.start_date, fund.BTC_base, fund.USD_base, fund.fee, fund.duration];
|
let values = [fund_id, fund.start_date, fund.BTC_base, fund.USD_base, fund.fee, fund.duration];
|
||||||
if (fund.tapoutInterval)
|
if (fund.tapoutInterval)
|
||||||
values.push(fund.topoutWindow, fund.tapoutInterval.join(','));
|
values.push(fund.topoutWindow, fund.tapoutInterval.join(','));
|
||||||
promises.push(DB.query(`INSERT INTO BobsFund(fund_id, begin_date, btc_base, usd_base, fee, duration ${fund.tapoutInterval ? ", tapout_window, tapout_interval" : ""}) VALUES ? ON DUPLICATE KEY UPDATE fund_id=fund_id`, [[values]]));
|
txQueries.push([`INSERT INTO BobsFund(fund_id, begin_date, btc_base, usd_base, fee, duration ${fund.tapoutInterval ? ", tapout_window, tapout_interval" : ""}) VALUE (?) ON DUPLICATE KEY UPDATE fund_id=fund_id`, [values]])
|
||||||
} else
|
} else
|
||||||
fund_id = fund_id.pop().match(/[a-z0-9]{64}/).pop();
|
fund_id = fund_id.pop().match(/[a-z0-9]{64}/).pop();
|
||||||
let investments = Object.entries(fund.investments).map(a => [fund_id, a[0], a[1].amount]);
|
let investments = Object.entries(fund.investments).map(a => [fund_id, a[0], a[1].amount]);
|
||||||
promises.push(DB.query("INSERT INTO BobsFundInvestments(fund_id, floID, amount_in) VALUES ? ON DUPLICATE KEY UPDATE floID=floID", [investments]));
|
txQueries.push(["INSERT INTO BobsFundInvestments(fund_id, floID, amount_in) VALUES ? ON DUPLICATE KEY UPDATE floID=floID", [investments]]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let fund_id = d.data.match(/close: [a-z0-9]{64}\|/);
|
let fund_id = d.data.match(/close: [a-z0-9]{64}\|/);
|
||||||
@ -232,20 +233,16 @@ function refreshBlockchainData(nodeList = []) {
|
|||||||
fund_id = fund_id.pop().match(/[a-z0-9]{64}/).pop();
|
fund_id = fund_id.pop().match(/[a-z0-9]{64}/).pop();
|
||||||
let closing_details = Object.entries(fund.investments).filter(a => typeof a[1].closed === "object" && a[1].closed.amountFinal).pop(); //only one close-fund will be there in a tx
|
let closing_details = Object.entries(fund.investments).filter(a => typeof a[1].closed === "object" && a[1].closed.amountFinal).pop(); //only one close-fund will be there in a tx
|
||||||
if (closing_details)
|
if (closing_details)
|
||||||
promises.push(DB.query("UPDATE BobsFundInvestments SET close_id=?, amount_out=? WHERE fund_id=? AND floID=?", [d.txid, closing_details[1].closed.amountFinal, fund_id, closing_details[0]]))
|
txQueries.push(["UPDATE BobsFundInvestments SET close_id=?, amount_out=? WHERE fund_id=? AND floID=?",
|
||||||
|
[d.txid, closing_details[1].closed.amountFinal, fund_id, closing_details[0]]])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Promise.allSettled(promises).then(results => {
|
txQueries.push(["INSERT INTO LastTx (floID, num) VALUE (?) ON DUPLICATE KEY UPDATE num=?",
|
||||||
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0)) {
|
[[bobsFund.config.adminID, result.totalTxs], result.totalTxs]])
|
||||||
console.debug(results.filter(r => r.status === "rejected"));
|
DB.transaction(txQueries)
|
||||||
reject("Some fund data might not have been saved in database correctly");
|
.then(_ => resolve(result.totalTxs))
|
||||||
}
|
.catch(error => reject(["Bobs-Fund refresh data failed!", error]));
|
||||||
else
|
|
||||||
DB.query("INSERT INTO LastTx (floID, num) VALUE (?) ON DUPLICATE KEY UPDATE num=?", [[bobsFund.config.adminID, result.totalTxs], result.totalTxs])
|
|
||||||
.then(_ => resolve(result.totalTxs))
|
|
||||||
.catch(error => reject(error));
|
|
||||||
})
|
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
@ -296,6 +293,59 @@ function closeFund(fund_id, floID, ref) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkFundBalance(prior_time) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
prior_time = new Date(prior_time);
|
||||||
|
let cur_date = Date.now();
|
||||||
|
if (isNaN(prior_time) || prior_time.toString() == "Invalid Date")
|
||||||
|
return reject(INVALID(eCode.INVALID_VALUE, `Invalid Date for prior_time`));
|
||||||
|
let sql_query = "SELECT bf.begin_date, bf.btc_base, bf.usd_base, bf.fee, bf.duration, fi.amount_in, cf.amount AS amount_close FROM BobsFund AS bf" +
|
||||||
|
" INNER JOIN BobsFundInvestments AS fi ON bf.fund_id = fi.fund_id" +
|
||||||
|
" LEFT JOIN CloseFundTransact AS cf ON fi.fund_id = cf.fund_id AND fi.floID = cf.floID" +
|
||||||
|
" WHERE fi.close_id IS NULL AND (cf.r_status IS NULL OR cf.r_status NOT IN (?))";
|
||||||
|
DB.query(sql_query, [[pCode.STATUS_SUCCESS, pCode.STATUS_CONFIRMATION]]).then(result => {
|
||||||
|
getRate.BTC_USD().then(btc_rate => {
|
||||||
|
getRate.USD_INR().then(usd_rate => {
|
||||||
|
let pending = { require_amount_cash: 0, n_investment: 0 },
|
||||||
|
ready = { require_amount_cash: 0, n_investment: 0 },
|
||||||
|
upcoming = { require_amount_cash: 0, n_investment: 0 }
|
||||||
|
result.forEach(i => {
|
||||||
|
if (i.amount_close) {
|
||||||
|
pending.require_amount_cash += i.amount_close;
|
||||||
|
pending.n_investment++;
|
||||||
|
} else {
|
||||||
|
let end_date = bobsFund.dateAdder(i.begin_date, i.duration);
|
||||||
|
if (end_date < prior_time) {
|
||||||
|
let net_value = bobsFund.calcNetValue(i.btc_base, btc_rate, i.usd_base, usd_rate, i.amount_in, i.fee);
|
||||||
|
if (end_date > cur_date) {
|
||||||
|
upcoming.require_amount_cash += net_value;
|
||||||
|
upcoming.n_investment++;
|
||||||
|
} else {
|
||||||
|
ready.require_amount_cash += net_value;
|
||||||
|
ready.n_investment++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
pending.require_amount_cash = global.toStandardDecimal(pending.require_amount_cash);
|
||||||
|
ready.require_amount_cash = global.toStandardDecimal(ready.require_amount_cash);
|
||||||
|
upcoming.require_amount_cash = global.toStandardDecimal(upcoming.require_amount_cash);
|
||||||
|
pending.require_amount_btc = global.toStandardDecimal(pending.require_amount_cash / (btc_rate * usd_rate));
|
||||||
|
ready.require_amount_btc = global.toStandardDecimal(ready.require_amount_cash / (btc_rate * usd_rate));
|
||||||
|
upcoming.require_amount_btc = global.toStandardDecimal(upcoming.require_amount_cash / (btc_rate * usd_rate));
|
||||||
|
Promise.allSettled(sink_chest.list(sink_groups.BOBS_FUND)
|
||||||
|
.map(id => btcOperator.getBalance(btcOperator.convert.legacy2bech(id)))).then(result => {
|
||||||
|
let balance = result.filter(r => r.status === 'fulfilled').reduce((a, bal) => a += bal, 0);
|
||||||
|
resolve({ pending, ready, upcoming, balance });
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
refresh(nodeList) {
|
refresh(nodeList) {
|
||||||
refreshBlockchainData(nodeList)
|
refreshBlockchainData(nodeList)
|
||||||
@ -303,5 +353,6 @@ module.exports = {
|
|||||||
.catch(error => console.error(error));
|
.catch(error => console.error(error));
|
||||||
},
|
},
|
||||||
util: bobsFund,
|
util: bobsFund,
|
||||||
|
checkFundBalance,
|
||||||
closeFund
|
closeFund
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const DB = require("../database");
|
const DB = require("../database");
|
||||||
|
const { sink_chest, sink_groups } = require("../keys");
|
||||||
const eCode = require('../../docs/scripts/floExchangeAPI').errorCode;
|
const eCode = require('../../docs/scripts/floExchangeAPI').errorCode;
|
||||||
const pCode = require('../../docs/scripts/floExchangeAPI').processCode;
|
const pCode = require('../../docs/scripts/floExchangeAPI').processCode;
|
||||||
const getRate = require('./conversion').getRate;
|
const getRate = require('./conversion').getRate;
|
||||||
@ -193,28 +194,24 @@ function refreshBlockchainData(nodeList = []) {
|
|||||||
tx: true,
|
tx: true,
|
||||||
filter: d => d.startsWith(blockchainBond.productStr)
|
filter: d => d.startsWith(blockchainBond.productStr)
|
||||||
}).then(result => {
|
}).then(result => {
|
||||||
let promises = [];
|
let txQueries = [];
|
||||||
result.data.reverse().forEach(d => {
|
result.data.reverse().forEach(d => {
|
||||||
let bond = d.senders.has(blockchainBond.config.adminID) ? blockchainBond.parse.main(d.data) : null;
|
let bond = d.senders.has(blockchainBond.config.adminID) ? blockchainBond.parse.main(d.data) : null;
|
||||||
if (bond && bond.amount)
|
if (bond && bond.amount)
|
||||||
promises.push(DB.query("INSERT INTO BlockchainBonds(bond_id, floID, amount_in, begin_date, btc_base, usd_base, gain_cut, min_ipa, max_period, lockin_period) VALUES ? ON DUPLICATE KEY UPDATE bond_id=bond_id",
|
txQueries.push(["INSERT INTO BlockchainBonds(bond_id, floID, amount_in, begin_date, btc_base, usd_base, gain_cut, min_ipa, max_period, lockin_period) VALUE (?) ON DUPLICATE KEY UPDATE bond_id=bond_id",
|
||||||
[[[d.txid, bond.floID, bond.amount, bond.startDate, bond.BTC_base, bond.USD_base, bond.cut, bond.minIpa, bond.maxPeriod, bond.lockinPeriod]]]));
|
[[d.txid, bond.floID, bond.amount, bond.startDate, bond.BTC_base, bond.USD_base, bond.cut, bond.minIpa, bond.maxPeriod, bond.lockinPeriod]]]);
|
||||||
else {
|
else {
|
||||||
let details = blockchainBond.parse.end(d.data);
|
let details = blockchainBond.parse.end(d.data);
|
||||||
if (details.bondID && details.amountFinal)
|
if (details.bondID && details.amountFinal)
|
||||||
promises.push(DB.query("UPDATE BlockchainBonds SET close_id=?, amount_out=? WHERE bond_id=?", [d.txid, details.amountFinal, details.bondID]));
|
txQueries.push(["UPDATE BlockchainBonds SET close_id=?, amount_out=? WHERE bond_id=?",
|
||||||
|
[d.txid, details.amountFinal, details.bondID]]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Promise.allSettled(promises).then(results => {
|
txQueries.push(["INSERT INTO LastTx (floID, num) VALUE (?) ON DUPLICATE KEY UPDATE num=?",
|
||||||
if (results.reduce((a, r) => r.status === "rejected" ? ++a : a, 0)) {
|
[[blockchainBond.config.adminID, result.totalTxs], result.totalTxs]])
|
||||||
reject("Some bond data might not have been saved in database correctly");
|
DB.transaction(txQueries)
|
||||||
console.debug(results.filter(r => r.status === "rejected"));
|
.then(_ => resolve(result.totalTxs))
|
||||||
}
|
.catch(error => reject(["Blockchain-bonds refresh data failed!", error]));
|
||||||
else
|
|
||||||
DB.query("INSERT INTO LastTx (floID, num) VALUE (?) ON DUPLICATE KEY UPDATE num=?", [[blockchainBond.config.adminID, result.totalTxs], result.totalTxs])
|
|
||||||
.then(_ => resolve(result.totalTxs))
|
|
||||||
.catch(error => reject(error));
|
|
||||||
})
|
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
@ -249,6 +246,57 @@ function closeBond(bond_id, floID, ref) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkBondBalance(prior_time) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
prior_time = new Date(prior_time);
|
||||||
|
let cur_date = Date.now();
|
||||||
|
if (isNaN(prior_time) || prior_time.toString() == "Invalid Date")
|
||||||
|
return reject(INVALID(eCode.INVALID_VALUE, `Invalid Date for prior_time`));
|
||||||
|
let sql_query = "SELECT bb.*, cb.amount AS amount_close FROM BlockchainBonds AS bb" +
|
||||||
|
" LEFT JOIN CloseBondTransact AS cb ON bb.bond_id = cb.bond_id" +
|
||||||
|
" WHERE bb.close_id IS NULL AND (cb.r_status IS NULL OR cb.r_status NOT IN (?))";
|
||||||
|
DB.query(sql_query, [[pCode.STATUS_SUCCESS, pCode.STATUS_CONFIRMATION]]).then(result => {
|
||||||
|
getRate.BTC_USD().then(btc_rate => {
|
||||||
|
getRate.USD_INR().then(usd_rate => {
|
||||||
|
let pending = { require_amount_cash: 0, n_bond: 0 },
|
||||||
|
ready = { require_amount_cash: 0, n_bond: 0 },
|
||||||
|
upcoming = { require_amount_cash: 0, n_bond: 0 }
|
||||||
|
result.forEach(bond => {
|
||||||
|
if (bond.amount_close) {
|
||||||
|
pending.require_amount_cash += bond.amount_close;
|
||||||
|
pending.n_bond++;
|
||||||
|
} else {
|
||||||
|
let end_date = blockchainBond.dateAdder(bond.begin_date, bond.lockin_period)
|
||||||
|
if (end_date < prior_time) {
|
||||||
|
let net_value = blockchainBond.calcNetValue(bond.btc_base, btc_rate, bond.begin_date, bond.min_ipa, bond.max_period, bond.gain_cut, bond.amount_in, bond.usd_base, usd_rate);
|
||||||
|
if (end_date > cur_date) {
|
||||||
|
upcoming.require_amount_cash += net_value;
|
||||||
|
upcoming.n_bond++;
|
||||||
|
} else {
|
||||||
|
ready.require_amount_cash += net_value;
|
||||||
|
ready.n_bond++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
pending.require_amount_cash = global.toStandardDecimal(pending.require_amount_cash);
|
||||||
|
ready.require_amount_cash = global.toStandardDecimal(ready.require_amount_cash);
|
||||||
|
upcoming.require_amount_cash = global.toStandardDecimal(upcoming.require_amount_cash);
|
||||||
|
pending.require_amount_btc = global.toStandardDecimal(pending.require_amount_cash / (btc_rate * usd_rate));
|
||||||
|
ready.require_amount_btc = global.toStandardDecimal(ready.require_amount_cash / (btc_rate * usd_rate));
|
||||||
|
upcoming.require_amount_btc = global.toStandardDecimal(upcoming.require_amount_cash / (btc_rate * usd_rate));
|
||||||
|
Promise.allSettled(sink_chest.list(sink_groups.BLOCKCHAIN_BONDS)
|
||||||
|
.map(id => btcOperator.getBalance(btcOperator.convert.legacy2bech(id)))).then(result => {
|
||||||
|
let balance = result.filter(r => r.status === 'fulfilled').reduce((a, bal) => a += bal, 0);
|
||||||
|
resolve({ pending, ready, upcoming, balance });
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
refresh(nodeList) {
|
refresh(nodeList) {
|
||||||
refreshBlockchainData(nodeList)
|
refreshBlockchainData(nodeList)
|
||||||
@ -256,5 +304,6 @@ module.exports = {
|
|||||||
.catch(error => console.error(error));
|
.catch(error => console.error(error));
|
||||||
},
|
},
|
||||||
util: blockchainBond,
|
util: blockchainBond,
|
||||||
|
checkBondBalance,
|
||||||
closeBond
|
closeBond
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user