Bug fixes
- Fixed: SQL schema asset foreign key incorrectly referenced - Fixed: initial rate of asset not loading correctly from DB - Fixed: get-rate API returning [object Object] instead of rates - Fixed: Bug where transaction-loop happens with 0 quantity - Improved: spendAsset to use assets NULL/Non-NULL base correctly - Fixed: minor typos, syntax errors and SQL query errors User-pages: - Added: UI fields for assets in Buy/Sell orders - Updated: UI display of correct asset in listing orders and transactions - Updated: localStorage keys are prefixed 'exchange-' - Fixed: Rates and Balance amount not displayed correctly Others: - Added: temporary code for tracing output lines in set_globals.js (commented out by default)
This commit is contained in:
parent
048ab0667b
commit
ab3df761b0
@ -67,7 +67,7 @@ CREATE TABLE Vault (
|
||||
quantity FLOAT NOT NULL,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY (floID) REFERENCES Users(floID),
|
||||
FOREIGN KEY (asset) REFERENCES Users(asset)
|
||||
FOREIGN KEY (asset) REFERENCES AssetList(asset)
|
||||
);
|
||||
|
||||
CREATE TABLE UserTag (
|
||||
@ -99,7 +99,7 @@ CREATE TABLE SellOrder (
|
||||
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY (floID) REFERENCES Users(floID),
|
||||
FOREIGN KEY (asset) REFERENCES Users(asset)
|
||||
FOREIGN KEY (asset) REFERENCES AssetList(asset)
|
||||
);
|
||||
|
||||
CREATE TABLE BuyOrder (
|
||||
@ -111,7 +111,7 @@ CREATE TABLE BuyOrder (
|
||||
time_placed DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY(id),
|
||||
FOREIGN KEY (floID) REFERENCES Users(floID),
|
||||
FOREIGN KEY (asset) REFERENCES Users(asset)
|
||||
FOREIGN KEY (asset) REFERENCES AssetList(asset)
|
||||
);
|
||||
|
||||
CREATE TABLE InputFLO (
|
||||
@ -159,8 +159,10 @@ CREATE TABLE OutputToken (
|
||||
/* Transaction Data */
|
||||
|
||||
CREATE TABLE PriceHistory (
|
||||
asset VARCHAR(64) NOT NULL,
|
||||
rate FLOAT NOT NULL,
|
||||
rec_time DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
rec_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (asset) REFERENCES AssetList(asset)
|
||||
);
|
||||
|
||||
CREATE TABLE TransactionHistory (
|
||||
@ -172,7 +174,7 @@ CREATE TABLE TransactionHistory (
|
||||
tx_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (buyer) REFERENCES Users(floID),
|
||||
FOREIGN KEY (seller) REFERENCES Users(floID),
|
||||
FOREIGN KEY (asset) REFERENCES Users(asset)
|
||||
FOREIGN KEY (asset) REFERENCES AssetList(asset)
|
||||
);
|
||||
|
||||
CREATE TABLE AuditTransaction(
|
||||
@ -193,7 +195,7 @@ CREATE TABLE AuditTransaction(
|
||||
buyer_new_cash FLOAT NOT NULL,
|
||||
FOREIGN KEY (sellerID) REFERENCES Users(floID),
|
||||
FOREIGN KEY (buyerID) REFERENCES Users(floID),
|
||||
FOREIGN KEY (asset) REFERENCES Users(asset)
|
||||
FOREIGN KEY (asset) REFERENCES AssetList(asset)
|
||||
);
|
||||
|
||||
/* Backup Feature (Tables & Triggers) */
|
||||
|
||||
@ -154,7 +154,7 @@ function getTransactionList() {
|
||||
function getRates() {
|
||||
return new Promise((resolve, reject) => {
|
||||
exchangeAPI('/get-rates')
|
||||
.then(result => responseParse(result, false)
|
||||
.then(result => responseParse(result)
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error)))
|
||||
.catch(error => reject(error));
|
||||
|
||||
@ -102,6 +102,7 @@
|
||||
<strip-option value="sell">Sell</strip-option>
|
||||
</strip-select>
|
||||
</div>
|
||||
<select id="get_asset"></select>
|
||||
<sm-input id="get_price" variant="outlined" placeholder="Max price (₹)" type="number" step="0.01"
|
||||
required hiderequired animate>
|
||||
</sm-input>
|
||||
@ -976,23 +977,23 @@
|
||||
}
|
||||
const render = {
|
||||
orderCard(orderDetails = {}) {
|
||||
const { id, quantity, price, time, type } = orderDetails
|
||||
const { id, asset, quantity, price, time, type } = orderDetails
|
||||
const card = getRef('order_template').content.cloneNode(true).firstElementChild
|
||||
card.dataset.id = id
|
||||
card.dataset.type = type
|
||||
card.querySelector('.order-card__type').textContent = type
|
||||
card.querySelector('.order-card__quantity').textContent = `${quantity} FLO`
|
||||
card.querySelector('.order-card__quantity').textContent = `${quantity} ${asset}`
|
||||
card.querySelector('.order-card__price-type').textContent = type === 'buy' ? 'Max price' : 'Min price'
|
||||
card.querySelector('.order-card__price').textContent = formatAmount(price)
|
||||
card.querySelector('.order-card__time').textContent = getFormattedTime(time, true)
|
||||
return card
|
||||
},
|
||||
transactionCard(transactionDetails = {}) {
|
||||
const { buyer, seller, type, other, quantity, unitValue, time } = transactionDetails
|
||||
const { buyer, seller, type, other, asset, quantity, unitValue, time } = transactionDetails
|
||||
const card = getRef('transaction_template').content.cloneNode(true).firstElementChild
|
||||
card.dataset.type = type
|
||||
card.querySelector('.transaction-card__type').textContent = type
|
||||
card.querySelector('.transaction-card__quantity').textContent = `${quantity} FLO`
|
||||
card.querySelector('.transaction-card__quantity').textContent = `${quantity} ${asset}`
|
||||
card.querySelector('.transaction-card__price').textContent = formatAmount(unitValue)
|
||||
card.querySelector('.transaction-card__total').textContent = formatAmount(parseFloat((unitValue * quantity).toFixed(2)))
|
||||
card.querySelector('.more-info').dataset.buyer = buyer
|
||||
@ -1002,12 +1003,12 @@
|
||||
return card
|
||||
},
|
||||
marketOrderCard(orderDetails = {}) {
|
||||
const { floID, quantity, unitValue, time, type } = orderDetails
|
||||
const { floID, asset, quantity, unitValue, time, type } = orderDetails
|
||||
const card = getRef('market_order_template').content.cloneNode(true).firstElementChild
|
||||
card.dataset.type = type
|
||||
card.classList.add(`transaction-card--${type}`)
|
||||
card.querySelector('.transaction-card__type').textContent = type
|
||||
card.querySelector('.transaction-card__quantity').textContent = `${quantity} FLO`
|
||||
card.querySelector('.transaction-card__quantity').textContent = `${quantity} ${asset}`
|
||||
card.querySelector('.transaction-card__price').textContent = formatAmount(unitValue)
|
||||
card.querySelector('.transaction-card__total').textContent = formatAmount(parseFloat((unitValue * quantity).toFixed(2)))
|
||||
card.querySelector('.more-info').dataset.time = time
|
||||
@ -1017,9 +1018,9 @@
|
||||
return card
|
||||
},
|
||||
marketTransactionCard(transactionDetails = {}) {
|
||||
const { buyer, seller, quantity, unitValue, time } = transactionDetails
|
||||
const { buyer, seller, asset, quantity, unitValue, time } = transactionDetails
|
||||
const card = getRef('market_transaction_template').content.cloneNode(true).firstElementChild
|
||||
card.querySelector('.transaction-card__quantity').textContent = `${quantity} FLO`
|
||||
card.querySelector('.transaction-card__quantity').textContent = `${quantity} ${asset}`
|
||||
card.querySelector('.transaction-card__price').textContent = `₹${unitValue}`
|
||||
card.querySelector('.transaction-card__total').textContent = formatAmount(parseFloat((unitValue * quantity).toFixed(2)))
|
||||
card.querySelector('.more-info').dataset.time = time
|
||||
@ -1047,14 +1048,15 @@
|
||||
getRef('quantity_type').textContent = tradeType === 'buy' ? `Rupee` : `FLO`
|
||||
})
|
||||
async function tradeFlo() {
|
||||
const asset = getRef('get_asset').value;
|
||||
const quantity = parseFloat(getRef('get_quantity').value)
|
||||
const price = parseFloat(getRef('get_price').value)
|
||||
showProcess('trade_button_wrapper')
|
||||
try {
|
||||
if (tradeType === 'buy') {
|
||||
await buy(quantity, price, proxy.userID, await proxy.secret) //TODO: asset_name
|
||||
await buy(asset, quantity, price, proxy.userID, await proxy.secret) //TODO: asset_name
|
||||
} else {
|
||||
await sell(quantity, price, proxy.userID, await proxy.secret) //TODO: asset_name
|
||||
await sell(asset, quantity, price, proxy.userID, await proxy.secret) //TODO: asset_name
|
||||
}
|
||||
getRef('trade_button_wrapper').append(getRef('success_template').content.cloneNode(true))
|
||||
notify(`Placed ${tradeType} order`, 'success')
|
||||
@ -1422,9 +1424,10 @@
|
||||
if (ordersType === 'open') {
|
||||
const allOpenOrders = [...buyOrders, ...sellOrders].sort((a, b) => new Date(b.time_placed).getTime() - new Date(a.time_placed).getTime())
|
||||
allOpenOrders.forEach(order => {
|
||||
const { id, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
|
||||
const { id, asset, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
|
||||
const orderDetails = {
|
||||
id,
|
||||
asset,
|
||||
quantity,
|
||||
type: minPrice ? 'sell' : 'buy',
|
||||
price: minPrice || maxPrice,
|
||||
@ -1434,7 +1437,7 @@
|
||||
})
|
||||
} else {
|
||||
transactions.forEach(transaction => {
|
||||
const { quantity, unitValue, tx_time, buyer, seller } = transaction
|
||||
const {asset, quantity, unitValue, tx_time, buyer, seller } = transaction
|
||||
let type, other;
|
||||
if (seller === proxy.userID) {
|
||||
type = 'Sold';
|
||||
@ -1449,6 +1452,7 @@
|
||||
seller,
|
||||
type,
|
||||
other,
|
||||
asset,
|
||||
quantity,
|
||||
unitValue,
|
||||
time: tx_time
|
||||
@ -1470,9 +1474,10 @@
|
||||
const [buyOrders, sellOrders] = await Promise.all([getBuyList(), getSellList()])
|
||||
const allOpenOrders = [...buyOrders, ...sellOrders].sort((a, b) => new Date(b.time_placed).getTime() - new Date(a.time_placed).getTime())
|
||||
allOpenOrders.forEach(order => {
|
||||
const { floID, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
|
||||
const { floID, asset, quantity, minPrice = undefined, maxPrice = undefined, time_placed } = order
|
||||
const orderDetails = {
|
||||
floID,
|
||||
asset,
|
||||
quantity,
|
||||
type: minPrice ? 'sell' : 'buy',
|
||||
unitValue: minPrice || maxPrice,
|
||||
@ -1488,10 +1493,11 @@
|
||||
try {
|
||||
const marketTransactions = await getTransactionList()
|
||||
marketTransactions.forEach(transaction => {
|
||||
const { seller, buyer, quantity, unitValue, tx_time } = transaction
|
||||
const { seller, buyer, asset, quantity, unitValue, tx_time } = transaction
|
||||
const transactionDetails = {
|
||||
buyer,
|
||||
seller,
|
||||
asset,
|
||||
quantity,
|
||||
unitValue,
|
||||
time: tx_time
|
||||
@ -1554,14 +1560,14 @@
|
||||
notify("Password minimum length is 4", 'error');
|
||||
else {
|
||||
let tmp = Crypto.AES.encrypt(this.private, pwd);
|
||||
localStorage.setItem("proxy_secret", "?" + tmp);
|
||||
localStorage.setItem("exchange-proxy_secret", "?" + tmp);
|
||||
notify("Successfully locked with Password", 'success');
|
||||
}
|
||||
}).catch(_ => null);
|
||||
},
|
||||
clear() {
|
||||
localStorage.removeItem("proxy_secret");
|
||||
localStorage.removeItem("user_ID");
|
||||
localStorage.removeItem("exchange-proxy_secret");
|
||||
localStorage.removeItem("exchange-user_ID");
|
||||
this.user = null;
|
||||
this.private = null;
|
||||
this.public = null;
|
||||
@ -1570,19 +1576,19 @@
|
||||
return getRef("sink_id").value;
|
||||
},
|
||||
set userID(id){
|
||||
localStorage.setItem("user_ID", id);
|
||||
localStorage.setItem("exchange-user_ID", id);
|
||||
this.user = id;
|
||||
},
|
||||
get userID(){
|
||||
if(this.user)
|
||||
return this.user;
|
||||
else{
|
||||
let id = localStorage.getItem('user_ID');
|
||||
let id = localStorage.getItem('exchange-user_ID');
|
||||
return id ? this.user = id : undefined;
|
||||
}
|
||||
},
|
||||
set secret(key) {
|
||||
localStorage.setItem("proxy_secret", key);
|
||||
localStorage.setItem("exchange-proxy_secret", key);
|
||||
this.private = key;
|
||||
this.public = floCrypto.getPubKeyHex(key);
|
||||
},
|
||||
@ -1605,7 +1611,7 @@
|
||||
Reject("Unable to fetch Proxy secret");
|
||||
}
|
||||
};
|
||||
let tmp = localStorage.getItem("proxy_secret");
|
||||
let tmp = localStorage.getItem("exchange-proxy_secret");
|
||||
if (typeof tmp !== "string")
|
||||
Reject("Unable to fetch Proxy secret");
|
||||
else if (tmp.startsWith("?")) {
|
||||
@ -1629,9 +1635,17 @@
|
||||
}
|
||||
|
||||
let floExchangeRate = 0
|
||||
function updateRate() {
|
||||
function updateRate(init = false) {
|
||||
getRates().then(rates => {
|
||||
console.debug(rates);
|
||||
if(init){
|
||||
let assetList = getRef('get_asset');
|
||||
for(let asset in rates){
|
||||
let e = document.createElement('option');
|
||||
e.innerText = asset;
|
||||
assetList.appendChild(e);
|
||||
}
|
||||
}
|
||||
let flo_rate = rates["FLO"];
|
||||
floExchangeRate = parseFloat(flo_rate)
|
||||
getRef('flo_rate').textContent = formatAmount(parseFloat(flo_rate))
|
||||
@ -1654,7 +1668,7 @@
|
||||
}
|
||||
} else
|
||||
console.info("refresh");
|
||||
updateRate();
|
||||
updateRate(init);
|
||||
renderMarketOrders();
|
||||
if(proxy.userID)
|
||||
account();
|
||||
@ -1688,7 +1702,8 @@
|
||||
getRef("user_id").value = acc.floID;
|
||||
getRef("sink_id").value = acc.sinkID;
|
||||
//FLO Balance
|
||||
let flo_total = acc.coins.reduce((a, x) => a + x.quantity, 0);
|
||||
console.debug(acc.vault);
|
||||
let flo_total = acc.vault.reduce((a, x) => a + (x.asset === "FLO" ? x.quantity : 0), 0);
|
||||
let flo_locked = acc.sellOrders.reduce((a, x) => a + x.quantity, 0);
|
||||
let flo_net = flo_total - flo_locked;
|
||||
console.debug("FLO", flo_total, flo_locked, flo_net);
|
||||
@ -1696,7 +1711,7 @@
|
||||
|
||||
showBalance("flo", flo_net, flo_locked,)
|
||||
//Rupee Balance
|
||||
let rupee_total = acc.rupee_total;
|
||||
let rupee_total = acc.cash;
|
||||
let rupee_locked = acc.buyOrders.reduce((a, x) => a + x.quantity * x.maxPrice, 0);
|
||||
let rupee_net = rupee_total - rupee_locked;
|
||||
console.debug("RUPEE", rupee_total, rupee_locked, rupee_net);
|
||||
|
||||
@ -19,17 +19,21 @@ function processCoupling(bestPairQueue) {
|
||||
seller_best = pair_result.sellOrder;
|
||||
console.debug("Sell:", seller_best);
|
||||
console.debug("Buy:", buyer_best);
|
||||
spendAsset(bestPairQueue.asset, buyer_best, seller_best, pair_result.null_base).then(spend_result => {
|
||||
let tx_quantity = spend_result.quantity,
|
||||
txQueries = spend_result.txQueries,
|
||||
clear_sell = spend_result.incomplete && !spend_result.flag_baseNull; //clear_sell can be true only if an order is placed without enough ASSET
|
||||
processOrders(seller_best, buyer_best, txQueries, tx_quantity, clear_sell);
|
||||
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.asset, bestPairQueue.cur_rate, tx_quantity);
|
||||
spendAsset(bestPairQueue.asset, buyer_best, seller_best, pair_result.null_base).then(spent => {
|
||||
if (!spent.quantity) {
|
||||
//Happens when there are only Null-base assets
|
||||
bestPairQueue.next(spent.quantity, spent.incomplete);
|
||||
processCoupling(bestPairQueue);
|
||||
return;
|
||||
}
|
||||
let txQueries = spent.txQueries;
|
||||
processOrders(seller_best, buyer_best, txQueries, spent.quantity, spent.incomplete && pair_result.null_base);
|
||||
updateBalance(seller_best, buyer_best, txQueries, bestPairQueue.asset, bestPairQueue.cur_rate, spent.quantity);
|
||||
//begin audit
|
||||
beginAudit(seller_best.floID, buyer_best.floID, bestPairQueue.asset, bestPairQueue.cur_rate, tx_quantity).then(audit => {
|
||||
beginAudit(seller_best.floID, buyer_best.floID, bestPairQueue.asset, bestPairQueue.cur_rate, spent.quantity).then(audit => {
|
||||
//process txn query in SQL
|
||||
DB.transaction(txQueries).then(_ => {
|
||||
bestPairQueue.next(tx_quantity, spend_result.incomplete, spend_result.flag_baseNull);
|
||||
bestPairQueue.next(spent.quantity, spent.incomplete);
|
||||
console.log(`Transaction was successful! BuyOrder:${buyer_best.id}| SellOrder:${seller_best.id}`);
|
||||
audit.end();
|
||||
price.updateLastTime();
|
||||
@ -46,7 +50,7 @@ function processCoupling(bestPairQueue) {
|
||||
console.error(error.buy);
|
||||
noBuy = null;
|
||||
} else {
|
||||
console.log("No valid buyOrders.");
|
||||
console.log("No valid buyOrders for Asset:", bestPairQueue.asset);
|
||||
noBuy = true;
|
||||
}
|
||||
if (error.sell === undefined)
|
||||
@ -55,7 +59,7 @@ function processCoupling(bestPairQueue) {
|
||||
console.error(error.sell);
|
||||
noSell = null;
|
||||
} else {
|
||||
console.log("No valid sellOrders.");
|
||||
console.log("No valid sellOrders for Asset:", bestPairQueue.asset);
|
||||
noSell = true;
|
||||
}
|
||||
price.noOrder(bestPairQueue.asset, noBuy, noSell);
|
||||
@ -64,26 +68,22 @@ function processCoupling(bestPairQueue) {
|
||||
|
||||
function spendAsset(asset, buyOrder, sellOrder, null_base) {
|
||||
return new Promise((resolve, reject) => {
|
||||
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? AND asset=? ORDER BY base", [sellOrder.floID, asset]).then(result => {
|
||||
DB.query('SELECT id, quantity FROM Vault WHERE floID=? AND asset=? AND base IS ' +
|
||||
(null_base ? "NULL ORDER BY locktime" : "NOT NULL ORDER BY base"), [sellOrder.floID, asset]).then(result => {
|
||||
let rem = Math.min(buyOrder.quantity, sellOrder.quantity),
|
||||
txQueries = [],
|
||||
flag_baseNull = false;
|
||||
txQueries = [];
|
||||
for (let i = 0; i < result.length && rem > 0; i++)
|
||||
if (result[i].base || null_base) {
|
||||
if (rem < result[i].quantity) {
|
||||
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, result[i].id]]);
|
||||
rem = 0;
|
||||
} else {
|
||||
txQueries.push(["DELETE FROM Vault WHERE id=?", [result[i].id]]);
|
||||
rem -= result[i].quantity;
|
||||
}
|
||||
} else
|
||||
flag_baseNull = true;
|
||||
if (rem < result[i].quantity) {
|
||||
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, result[i].id]]);
|
||||
rem = 0;
|
||||
} else {
|
||||
txQueries.push(["DELETE FROM Vault WHERE id=?", [result[i].id]]);
|
||||
rem -= result[i].quantity;
|
||||
}
|
||||
resolve({
|
||||
quantity: Math.min(buyOrder.quantity, sellOrder.quantity) - rem,
|
||||
txQueries,
|
||||
incomplete: rem > 0,
|
||||
flag_baseNull
|
||||
incomplete: rem > 0
|
||||
});
|
||||
}).catch(error => reject(error));
|
||||
})
|
||||
@ -98,7 +98,7 @@ function processOrders(seller_best, buyer_best, txQueries, quantity, clear_sell)
|
||||
else
|
||||
txQueries.push(["UPDATE BuyOrder SET quantity=quantity-? WHERE id=?", [quantity, buyer_best.id]]);
|
||||
//Process Sell Order
|
||||
if (quantity == seller_best.quantity || clear_sell)
|
||||
if (quantity == seller_best.quantity || clear_sell) //clear_sell must be true iff an order is placed without enough Asset
|
||||
txQueries.push(["DELETE FROM SellOrder WHERE id=?", [seller_best.id]]);
|
||||
else
|
||||
txQueries.push(["UPDATE SellOrder SET quantity=quantity-? WHERE id=?", [quantity, seller_best.id]]);
|
||||
|
||||
12
src/group.js
12
src/group.js
@ -62,7 +62,7 @@ const bestPair = function(asset, cur_rate, tags_buy, tags_sell) {
|
||||
}).catch(error => reject(error))
|
||||
});
|
||||
|
||||
this.next = (tx_quantity, incomplete_sell, flag_sell) => {
|
||||
this.next = (tx_quantity, incomplete_sell) => {
|
||||
let buy = getBuyOrder.cache,
|
||||
sell = getSellOrder.cache;
|
||||
if (buy.cur_order && sell.cur_order) {
|
||||
@ -77,7 +77,7 @@ const bestPair = function(asset, cur_rate, tags_buy, tags_sell) {
|
||||
if (tx_quantity < sell.cur_order.quantity) {
|
||||
sell.cur_order.quantity -= tx_quantity;
|
||||
if (incomplete_sell) {
|
||||
if (!sell.mode_null && flag_sell)
|
||||
if (!sell.mode_null)
|
||||
sell.null_queue.push(sell.cur_order);
|
||||
sell.cur_order = null;
|
||||
}
|
||||
@ -134,7 +134,7 @@ const bestPair = function(asset, cur_rate, tags_buy, tags_sell) {
|
||||
.then(result => resolve(result))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error));
|
||||
} else if (!cache.mode_null) { //Lowest priority Coins (FLO Brought from other sources)
|
||||
} else if (!cache.mode_null) { //Lowest priority Assets (Brought from other sources)
|
||||
cache.orders = cache.null_queue.reverse(); //Reverse it so that we can pop the highest priority
|
||||
cache.mode_null = true;
|
||||
cache.null_queue = null;
|
||||
@ -337,9 +337,9 @@ function verifySellOrder(sellOrder, asset, cur_price, mode_null) {
|
||||
}).catch(error => reject(error));
|
||||
else if (mode_null)
|
||||
DB.query("SELECT SUM(quantity) as total FROM Vault WHERE floID=? AND asset=?", [sellOrder.floID, asset]).then(result => {
|
||||
if (result.total < sellOrder.quantity)
|
||||
console.warn(`Sell Order ${sellOrder.id} was made without enough FLO. This should not happen`);
|
||||
if (result.total > 0)
|
||||
if (result[0].total < sellOrder.quantity)
|
||||
console.warn(`Sell Order ${sellOrder.id} was made without enough Assets. This should not happen`);
|
||||
if (result[0].total > 0)
|
||||
resolve(sellOrder);
|
||||
else
|
||||
reject(false);
|
||||
|
||||
@ -132,7 +132,7 @@ loadDataFromDB.assetList = function() {
|
||||
//update dependents
|
||||
backup.assetList = assets;
|
||||
app.assetList = assets;
|
||||
resolve(nodes);
|
||||
resolve(assets);
|
||||
}).catch(error => reject(error))
|
||||
})
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ const getAssetBalance = (floID, asset) => new Promise((resolve, reject) => {
|
||||
DB.query("SELECT balance FROM Cash WHERE floID=?", [floID]),
|
||||
DB.query("SELECT SUM(quantity*maxPrice) AS locked FROM BuyOrder WHERE floID=?", [floID])
|
||||
] : [
|
||||
DB.query("SELECT SUM(quantity) AS balance FROM Vault WHERE floID=?, asset=?", [floID, asset]),
|
||||
DB.query("SELECT SUM(quantity) AS balance FROM Vault WHERE floID=? AND asset=?", [floID, asset]),
|
||||
DB.query("SELECT SUM(quantity) AS locked FROM SellOrder WHERE floID=? AND asset=?", [floID, asset])
|
||||
];
|
||||
Promise.all(promises).then(result => resolve({
|
||||
|
||||
38
src/price.js
38
src/price.js
@ -10,7 +10,7 @@ const MIN_TIME = 10 * 1000, // 1 * 60 * 60 * 1000,
|
||||
|
||||
var DB; //container for database
|
||||
|
||||
var cur_rate = {}, //container for FLO price (from API or by model)
|
||||
var currentRate = {}, //container for FLO price (from API or by model)
|
||||
lastTime = {}, //container for timestamp of the last tx
|
||||
noBuyOrder = {},
|
||||
noSellOrder = {};
|
||||
@ -23,8 +23,8 @@ function storeRate(asset, rate) {
|
||||
.then(_ => null).catch(error => console.error(error))
|
||||
}
|
||||
setInterval(() => {
|
||||
for (let asset in cur_rate)
|
||||
storeRate(asset, cur_rate[asset]);
|
||||
for (let asset in currentRate)
|
||||
storeRate(asset, currentRate[asset]);
|
||||
}, REC_HISTORY_INTERVAL)
|
||||
|
||||
function getPastRate(asset, hrs = 24) {
|
||||
@ -37,15 +37,15 @@ function getPastRate(asset, hrs = 24) {
|
||||
|
||||
function loadRate(asset) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (typeof cur_rate[asset] !== "undefined")
|
||||
return resolve(cur_rate[asset]);
|
||||
if (typeof currentRate[asset] !== "undefined")
|
||||
return resolve(currentRate[asset]);
|
||||
updateLastTime(asset);
|
||||
DB.query("SELECT rate FROM PriceHistory WHERE asset=? ORDER BY rec_time DESC LIMIT 1", [asset]).then(result => {
|
||||
if (result.length)
|
||||
resolve(cur_rate[asset] = result[0].rate);
|
||||
resolve(currentRate[asset] = result[0].rate);
|
||||
else
|
||||
DB.query("SELECT initialPrice FROM AssetList WHERE asset=?", [asset])
|
||||
.then(result => resolve(result[0].initialPrice))
|
||||
.then(result => resolve(currentRate[asset] = result[0].initialPrice))
|
||||
.catch(error => reject(error))
|
||||
}).catch(error => reject(error));
|
||||
})
|
||||
@ -95,41 +95,41 @@ fetchRates.USD_INR = function() {
|
||||
function getRates(asset) {
|
||||
return new Promise((resolve, reject) => {
|
||||
loadRate(asset).then(_ => {
|
||||
console.debug(cur_rate[asset]);
|
||||
console.debug(asset, currentRate[asset]);
|
||||
let cur_time = Date.now();
|
||||
if (cur_time - lastTime[asset] < MIN_TIME) //Minimum time to update not crossed: No update required
|
||||
resolve(cur_rate[asset]);
|
||||
resolve(currentRate[asset]);
|
||||
else if (noBuyOrder[asset] && noSellOrder[asset]) //Both are not available: No update required
|
||||
resolve(cur_rate[asset]);
|
||||
resolve(currentRate[asset]);
|
||||
else if (noBuyOrder[asset] === null || noSellOrder[asset] === null) //An error has occured during last process: No update (might cause price to crash/jump)
|
||||
resolve(cur_rate[asset]);
|
||||
resolve(currentRate[asset]);
|
||||
else
|
||||
getPastRate(asset).then(ratePast24hr => {
|
||||
if (noBuyOrder[asset]) {
|
||||
//No Buy, But Sell available: Decrease the price
|
||||
let tmp_val = cur_rate[asset] * (1 - DOWN_RATE);
|
||||
let tmp_val = currentRate[asset] * (1 - DOWN_RATE);
|
||||
if (tmp_val >= ratePast24hr * (1 - MAX_DOWN_PER_DAY)) {
|
||||
cur_rate[asset] = tmp_val;
|
||||
currentRate[asset] = tmp_val;
|
||||
updateLastTime(asset);
|
||||
} else
|
||||
console.debug("Max Price down for the day has reached");
|
||||
resolve(cur_rate[asset]);
|
||||
resolve(currentRate[asset]);
|
||||
} else if (noSellOrder[asset]) {
|
||||
//No Sell, But Buy available: Increase the price
|
||||
checkForRatedSellers().then(result => {
|
||||
if (result) {
|
||||
let tmp_val = cur_rate[asset] * (1 + UP_RATE);
|
||||
let tmp_val = currentRate[asset] * (1 + UP_RATE);
|
||||
if (tmp_val <= ratePast24hr * (1 + MAX_UP_PER_DAY)) {
|
||||
cur_rate[asset] = tmp_val;
|
||||
currentRate[asset] = tmp_val;
|
||||
updateLastTime(asset);
|
||||
} else
|
||||
console.debug("Max Price up for the day has reached");
|
||||
}
|
||||
}).catch(error => console.error(error)).finally(_ => resolve(cur_rate[asset]));
|
||||
}).catch(error => console.error(error)).finally(_ => resolve(currentRate[asset]));
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error(error);
|
||||
resolve(cur_rate[asset]);
|
||||
resolve(currentRate[asset]);
|
||||
});
|
||||
}).catch(error => reject(error));
|
||||
})
|
||||
@ -160,6 +160,6 @@ module.exports = {
|
||||
DB = db;
|
||||
},
|
||||
get currentRates() {
|
||||
return Object.assign({}, cur_rate);
|
||||
return Object.assign({}, currentRate);
|
||||
}
|
||||
}
|
||||
@ -272,7 +272,7 @@ function getRates(req, res) {
|
||||
if (!serving)
|
||||
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
|
||||
else
|
||||
res.send(`${market.rates}`);
|
||||
res.send(market.rates);
|
||||
}
|
||||
|
||||
function Account(req, res) {
|
||||
|
||||
@ -11,4 +11,13 @@ try {
|
||||
} finally {
|
||||
for (let p in param)
|
||||
global[p] = param[p];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
//Trace the debug logs in node js
|
||||
var debug = console.debug;
|
||||
console.debug = function() {
|
||||
debug.apply(console, arguments);
|
||||
console.trace();
|
||||
};
|
||||
*/
|
||||
Loading…
Reference in New Issue
Block a user