Multiple asset support
2 types of property: 1. Cash - main/central currency used for trading 2. Asset - (FLO/tokens) Can be brought or sold in the exchange market . - Allow multiple tokens to act as asset in addition to FLO. - Changes required for the above in deposits, withdraws, placing orders - some code optimization in market.js - Updated SQL schema
This commit is contained in:
parent
512dc3bcbc
commit
67c31d79a9
@ -28,7 +28,7 @@ FOREIGN KEY (floID) REFERENCES Users(floID)
|
|||||||
CREATE TABLE Cash (
|
CREATE TABLE Cash (
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
floID CHAR(34) NOT NULL UNIQUE,
|
floID CHAR(34) NOT NULL UNIQUE,
|
||||||
rupeeBalance DECIMAL(12, 2) DEFAULT 0.00,
|
balance DECIMAL(12, 2) DEFAULT 0.00,
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
FOREIGN KEY (floID) REFERENCES Users(floID)
|
FOREIGN KEY (floID) REFERENCES Users(floID)
|
||||||
);
|
);
|
||||||
@ -37,6 +37,7 @@ CREATE TABLE Vault (
|
|||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
floID CHAR(34) NOT NULL,
|
floID CHAR(34) NOT NULL,
|
||||||
locktime DATETIME DEFAULT CURRENT_TIMESTAMP,
|
locktime DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
asset VARCHAR(64) NOT NULL,
|
||||||
base DECIMAL(10, 2),
|
base DECIMAL(10, 2),
|
||||||
quantity FLOAT NOT NULL,
|
quantity FLOAT NOT NULL,
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
@ -93,20 +94,22 @@ PRIMARY KEY(id),
|
|||||||
FOREIGN KEY (floID) REFERENCES Users(floID)
|
FOREIGN KEY (floID) REFERENCES Users(floID)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE inputRupee (
|
CREATE TABLE inputToken (
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
txid VARCHAR(128) NOT NULL,
|
txid VARCHAR(128) NOT NULL,
|
||||||
floID CHAR(34) NOT NULL,
|
floID CHAR(34) NOT NULL,
|
||||||
|
token VARCHAR(64),
|
||||||
amount FLOAT,
|
amount FLOAT,
|
||||||
status VARCHAR(50) NOT NULL,
|
status VARCHAR(50) NOT NULL,
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
FOREIGN KEY (floID) REFERENCES Users(floID)
|
FOREIGN KEY (floID) REFERENCES Users(floID)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE outputRupee (
|
CREATE TABLE outputToken (
|
||||||
id INT NOT NULL AUTO_INCREMENT,
|
id INT NOT NULL AUTO_INCREMENT,
|
||||||
txid VARCHAR(128),
|
txid VARCHAR(128),
|
||||||
floID CHAR(34) NOT NULL,
|
floID CHAR(34) NOT NULL,
|
||||||
|
token VARCHAR(64),
|
||||||
amount FLOAT NOT NULL,
|
amount FLOAT NOT NULL,
|
||||||
status VARCHAR(50) NOT NULL,
|
status VARCHAR(50) NOT NULL,
|
||||||
PRIMARY KEY(id),
|
PRIMARY KEY(id),
|
||||||
@ -159,16 +162,17 @@ rec_time DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|||||||
unit_price FLOAT NOT NULL,
|
unit_price FLOAT NOT NULL,
|
||||||
quantity FLOAT NOT NULL,
|
quantity FLOAT NOT NULL,
|
||||||
total_cost FLOAT NOT NULL,
|
total_cost FLOAT NOT NULL,
|
||||||
|
asset VARCHAR(64) NOT NULL,
|
||||||
sellerID CHAR(34) NOT NULL,
|
sellerID CHAR(34) NOT NULL,
|
||||||
FLO_seller_old FLOAT NOT NULL,
|
seller_old_asset FLOAT NOT NULL,
|
||||||
FLO_seller_new FLOAT NOT NULL,
|
seller_new_asset FLOAT NOT NULL,
|
||||||
Rupee_seller_old FLOAT NOT NULL,
|
seller_old_cash FLOAT NOT NULL,
|
||||||
Rupee_seller_new FLOAT NOT NULL,
|
seller_new_cash FLOAT NOT NULL,
|
||||||
buyerID CHAR(34) NOT NULL,
|
buyerID CHAR(34) NOT NULL,
|
||||||
FLO_buyer_old FLOAT NOT NULL,
|
buyer_old_asset FLOAT NOT NULL,
|
||||||
FLO_buyer_new FLOAT NOT NULL,
|
buyer_new_asset FLOAT NOT NULL,
|
||||||
Rupee_buyer_old FLOAT NOT NULL,
|
buyer_old_cash FLOAT NOT NULL,
|
||||||
Rupee_buyer_new FLOAT NOT NULL,
|
buyer_new_cash FLOAT NOT NULL,
|
||||||
FOREIGN KEY (sellerID) REFERENCES Users(floID),
|
FOREIGN KEY (sellerID) REFERENCES Users(floID),
|
||||||
FOREIGN KEY (buyerID) REFERENCES Users(floID)
|
FOREIGN KEY (buyerID) REFERENCES Users(floID)
|
||||||
);
|
);
|
||||||
@ -239,19 +243,19 @@ FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputFLO', NEW.id) ON DU
|
|||||||
CREATE TRIGGER outputFLO_D AFTER DELETE ON outputFLO
|
CREATE TRIGGER outputFLO_D AFTER DELETE ON outputFLO
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputFLO', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputFLO', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
|
||||||
|
|
||||||
CREATE TRIGGER inputRupee_I AFTER INSERT ON inputRupee
|
CREATE TRIGGER inputToken_I AFTER INSERT ON inputToken
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('inputRupee', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('inputToken', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
||||||
CREATE TRIGGER inputRupee_U AFTER UPDATE ON inputRupee
|
CREATE TRIGGER inputToken_U AFTER UPDATE ON inputToken
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('inputRupee', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('inputToken', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
||||||
CREATE TRIGGER inputRupee_D AFTER DELETE ON inputRupee
|
CREATE TRIGGER inputToken_D AFTER DELETE ON inputToken
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('inputRupee', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('inputToken', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
|
||||||
|
|
||||||
CREATE TRIGGER outputRupee_I AFTER INSERT ON outputRupee
|
CREATE TRIGGER outputToken_I AFTER INSERT ON outputToken
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputRupee', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputToken', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
||||||
CREATE TRIGGER outputRupee_U AFTER UPDATE ON outputRupee
|
CREATE TRIGGER outputToken_U AFTER UPDATE ON outputToken
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputRupee', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputToken', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
||||||
CREATE TRIGGER outputRupee_D AFTER DELETE ON outputRupee
|
CREATE TRIGGER outputToken_D AFTER DELETE ON outputToken
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputRupee', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('outputToken', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
|
||||||
|
|
||||||
CREATE TRIGGER Tags_I AFTER INSERT ON Tags
|
CREATE TRIGGER Tags_I AFTER INSERT ON Tags
|
||||||
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('Tags', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('Tags', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
|
||||||
|
|||||||
@ -4,9 +4,9 @@ TRUNCATE auditTransaction;
|
|||||||
TRUNCATE BuyOrder;
|
TRUNCATE BuyOrder;
|
||||||
TRUNCATE Cash;
|
TRUNCATE Cash;
|
||||||
TRUNCATE inputFLO;
|
TRUNCATE inputFLO;
|
||||||
TRUNCATE inputRupee;
|
TRUNCATE inputToken;
|
||||||
TRUNCATE outputFLO;
|
TRUNCATE outputFLO;
|
||||||
TRUNCATE outputRupee;
|
TRUNCATE outputToken;
|
||||||
TRUNCATE priceHistory;
|
TRUNCATE priceHistory;
|
||||||
TRUNCATE Request_Log;
|
TRUNCATE Request_Log;
|
||||||
TRUNCATE SellOrder;
|
TRUNCATE SellOrder;
|
||||||
|
|||||||
@ -13,7 +13,7 @@ const floGlobals = {
|
|||||||
sendAmt: 0.001,
|
sendAmt: 0.001,
|
||||||
fee: 0.0005,
|
fee: 0.0005,
|
||||||
tokenURL: "https://ranchimallflo.duckdns.org/",
|
tokenURL: "https://ranchimallflo.duckdns.org/",
|
||||||
token: "rupee"
|
currency: "rupee"
|
||||||
};
|
};
|
||||||
|
|
||||||
(typeof global !== "undefined" ? global : window).cryptocoin = floGlobals.blockchain;
|
(typeof global !== "undefined" ? global : window).cryptocoin = floGlobals.blockchain;
|
||||||
|
|||||||
@ -80,8 +80,8 @@ module.exports = function App(secret, DB) {
|
|||||||
//withdraw and deposit request
|
//withdraw and deposit request
|
||||||
app.post('/deposit-flo', Request.DepositFLO);
|
app.post('/deposit-flo', Request.DepositFLO);
|
||||||
app.post('/withdraw-flo', Request.WithdrawFLO);
|
app.post('/withdraw-flo', Request.WithdrawFLO);
|
||||||
app.post('/deposit-rupee', Request.DepositRupee);
|
app.post('/deposit-token', Request.DepositToken);
|
||||||
app.post('/withdraw-rupee', Request.WithdrawRupee);
|
app.post('/withdraw-token', Request.WithdrawToken);
|
||||||
|
|
||||||
//Manage user tags (Access to trusted IDs only)
|
//Manage user tags (Access to trusted IDs only)
|
||||||
|
|
||||||
|
|||||||
323
src/market.js
323
src/market.js
@ -3,9 +3,59 @@
|
|||||||
const coupling = require('./coupling');
|
const coupling = require('./coupling');
|
||||||
const MINIMUM_BUY_REQUIREMENT = 0.1;
|
const MINIMUM_BUY_REQUIREMENT = 0.1;
|
||||||
|
|
||||||
var DB; //container for database
|
var DB, allowedAssets; //container for database and allowed assets
|
||||||
|
|
||||||
function addSellOrder(floID, quantity, min_price) {
|
const getAssetBalance = (floID, asset) => new Promise((resolve, reject) => {
|
||||||
|
let promises = (asset === floGlobals.currency) ? [
|
||||||
|
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 locked FROM SellOrder WHERE floID=? AND asset=?", [floID, asset])
|
||||||
|
];
|
||||||
|
Promise.all(promises).then(result => resolve({
|
||||||
|
total: result[0][0].balance,
|
||||||
|
locked: result[1][0].locked,
|
||||||
|
net: result[0][0].balance - result[1][0].locked
|
||||||
|
})).catch(error => reject(error))
|
||||||
|
});
|
||||||
|
|
||||||
|
getAssetBalance.check = (floID, asset, amount) => new Promise((resolve, reject) => {
|
||||||
|
getAssetBalance(floID, asset).then(balance => {
|
||||||
|
if (balance.total < amount)
|
||||||
|
reject(INVALID(`Insufficient ${asset}`));
|
||||||
|
else if (balance.net < amount)
|
||||||
|
reject(INVALID(`Insufficient ${asset} (Some are locked in orders)`));
|
||||||
|
else
|
||||||
|
resolve(true);
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
|
||||||
|
const consumeAsset = (floID, asset, amount, txQueries = []) => new Promise((resolve, reject) => {
|
||||||
|
//If asset/token is currency update Cash else consume from Vault
|
||||||
|
if (asset === floGlobals.currency) {
|
||||||
|
txQueries.push(["UPDATE Cash SET balance=balance-? WHERE floID=?", [amount, floID]]);
|
||||||
|
return resolve(txQueries);
|
||||||
|
} else
|
||||||
|
DB.query("SELECT id, quantity FROM Vault WHERE floID=? AND asset=? ORDER BY locktime", [floID, asset]).then(coins => {
|
||||||
|
let rem = amount;
|
||||||
|
for (let i = 0; i < coins.length && rem > 0; i++) {
|
||||||
|
if (rem < coins[i].quantity) {
|
||||||
|
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, coins[i].id]]);
|
||||||
|
rem = 0;
|
||||||
|
} else {
|
||||||
|
txQueries.push(["DELETE FROM Vault WHERE id=?", [coins[i].id]]);
|
||||||
|
rem -= result[i].quantity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rem > 0) //should not happen AS the total and net is checked already
|
||||||
|
reject(INVALID("Insufficient Asset"));
|
||||||
|
else
|
||||||
|
resolve(txQueries);
|
||||||
|
}).catch(error => reject(error));
|
||||||
|
});
|
||||||
|
|
||||||
|
function addSellOrder(floID, asset, quantity, min_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floID || !floCrypto.validateAddr(floID))
|
if (!floID || !floCrypto.validateAddr(floID))
|
||||||
return reject(INVALID("Invalid FLO ID"));
|
return reject(INVALID("Invalid FLO ID"));
|
||||||
@ -13,41 +63,33 @@ function addSellOrder(floID, quantity, min_price) {
|
|||||||
return reject(INVALID(`Invalid quantity (${quantity})`));
|
return reject(INVALID(`Invalid quantity (${quantity})`));
|
||||||
else if (typeof min_price !== "number" || min_price <= 0)
|
else if (typeof min_price !== "number" || min_price <= 0)
|
||||||
return reject(INVALID(`Invalid min_price (${min_price})`));
|
return reject(INVALID(`Invalid min_price (${min_price})`));
|
||||||
checkSellRequirement(floID).then(_ => {
|
else if (!allowedAssets.includes(asset))
|
||||||
DB.query("SELECT SUM(quantity) AS total FROM Vault WHERE floID=?", [floID]).then(result => {
|
return reject(INVALID(`Invalid asset (${asset})`));
|
||||||
let total = result.pop()["total"] || 0;
|
getAssetBalance.check(floID, asset, quantity).then(_ => {
|
||||||
if (total < quantity)
|
checkSellRequirement(floID).then(_ => {
|
||||||
return reject(INVALID("Insufficient FLO"));
|
DB.query("INSERT INTO SellOrder(floID, quantity, minPrice) VALUES (?, ?, ?)", [floID, quantity, min_price])
|
||||||
DB.query("SELECT SUM(quantity) AS locked FROM SellOrder WHERE floID=?", [floID]).then(result => {
|
.then(result => resolve("Added SellOrder to DB"))
|
||||||
let locked = result.pop()["locked"] || 0;
|
.catch(error => reject(error));
|
||||||
let available = total - locked;
|
}).catch(error => reject(error))
|
||||||
if (available < quantity)
|
|
||||||
return reject(INVALID("Insufficient FLO (Some FLO are locked in another sell order)"));
|
|
||||||
DB.query("INSERT INTO SellOrder(floID, quantity, minPrice) VALUES (?, ?, ?)", [floID, quantity, min_price])
|
|
||||||
.then(result => resolve("Added SellOrder to DB"))
|
|
||||||
.catch(error => reject(error));
|
|
||||||
}).catch(error => reject(error));
|
|
||||||
}).catch(error => reject(error));
|
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkSellRequirement(floID) {
|
const checkSellRequirement = floID => new Promise((resolve, reject) => {
|
||||||
return new Promise((resolve, reject) => {
|
DB.query("SELECT * FROM Tags WHERE floID=? AND tag=?", [floID, "MINER"]).then(result => {
|
||||||
DB.query("SELECT * FROM Tags WHERE floID=? AND tag=?", [floID, "MINER"]).then(result => {
|
if (result.length)
|
||||||
if (result.length)
|
return resolve(true);
|
||||||
return resolve(true);
|
//TODO: Should seller need to buy same type of asset before selling?
|
||||||
DB.query("SELECT SUM(quantity) AS brought FROM Transactions WHERE buyer=?", [floID]).then(result => {
|
DB.query("SELECT SUM(quantity) AS brought FROM Transactions WHERE buyer=?", [floID]).then(result => {
|
||||||
if (result[0].brought >= MINIMUM_BUY_REQUIREMENT)
|
if (result[0].brought >= MINIMUM_BUY_REQUIREMENT)
|
||||||
resolve(true);
|
resolve(true);
|
||||||
else
|
else
|
||||||
reject(INVALID(`Sellers required to buy atleast ${MINIMUM_BUY_REQUIREMENT} FLO before placing a sell order unless they are a Miner`));
|
reject(INVALID(`Sellers required to buy atleast ${MINIMUM_BUY_REQUIREMENT} FLO before placing a sell order unless they are a Miner`));
|
||||||
}).catch(error => reject(error))
|
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
}).catch(error => reject(error))
|
||||||
}
|
});
|
||||||
|
|
||||||
function addBuyOrder(floID, quantity, max_price) {
|
function addBuyOrder(floID, asset, quantity, max_price) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floID || !floCrypto.validateAddr(floID))
|
if (!floID || !floCrypto.validateAddr(floID))
|
||||||
return reject(INVALID("Invalid FLO ID"));
|
return reject(INVALID("Invalid FLO ID"));
|
||||||
@ -55,21 +97,12 @@ function addBuyOrder(floID, quantity, max_price) {
|
|||||||
return reject(INVALID(`Invalid quantity (${quantity})`));
|
return reject(INVALID(`Invalid quantity (${quantity})`));
|
||||||
else if (typeof max_price !== "number" || max_price <= 0)
|
else if (typeof max_price !== "number" || max_price <= 0)
|
||||||
return reject(INVALID(`Invalid max_price (${max_price})`));
|
return reject(INVALID(`Invalid max_price (${max_price})`));
|
||||||
DB.query("SELECT rupeeBalance FROM Cash WHERE floID=?", [floID]).then(result => {
|
else if (!allowedAssets.includes(asset))
|
||||||
if (result.length < 1)
|
return reject(INVALID(`Invalid asset (${asset})`));
|
||||||
return reject(INVALID("FLO ID not registered"));
|
getAssetBalance.check(floID, asset, quantity).then(_ => {
|
||||||
let total = result.pop()["rupeeBalance"];
|
DB.query("INSERT INTO BuyOrder(floID, quantity, maxPrice) VALUES (?, ?, ?)", [floID, quantity, max_price])
|
||||||
if (total < quantity * max_price)
|
.then(result => resolve("Added BuyOrder to DB"))
|
||||||
return reject(INVALID("Insufficient Rupee balance"));
|
.catch(error => reject(error));
|
||||||
DB.query("SELECT SUM(maxPrice * quantity) AS locked FROM BuyOrder WHERE floID=?", [floID]).then(result => {
|
|
||||||
let locked = result.pop()["locked"] || 0;
|
|
||||||
let available = total - locked;
|
|
||||||
if (available < quantity * max_price)
|
|
||||||
return reject(INVALID("Insufficient Rupee balance (Some rupee tokens are locked in another buy order)"));
|
|
||||||
DB.query("INSERT INTO BuyOrder(floID, quantity, maxPrice) VALUES (?, ?, ?)", [floID, quantity, max_price])
|
|
||||||
.then(result => resolve("Added BuyOrder to DB"))
|
|
||||||
.catch(error => reject(error));
|
|
||||||
}).catch(error => reject(error));
|
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -101,11 +134,11 @@ function cancelOrder(type, id, floID) {
|
|||||||
function getAccountDetails(floID) {
|
function getAccountDetails(floID) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let select = [];
|
let select = [];
|
||||||
select.push(["rupeeBalance", "Cash"]);
|
select.push(["balance", "Cash"]);
|
||||||
select.push(["base, quantity", "Vault"]);
|
select.push(["asset, AVG(base) AS avg_base, SUM(quantity) AS quantity", "Vault", "GROUP BY asset"]);
|
||||||
select.push(["id, quantity, minPrice, time_placed", "SellOrder"]);
|
select.push(["id, asset, quantity, minPrice, time_placed", "SellOrder"]);
|
||||||
select.push(["id, quantity, maxPrice, time_placed", "BuyOrder"]);
|
select.push(["id, asset, quantity, maxPrice, time_placed", "BuyOrder"]);
|
||||||
let promises = select.map(a => DB.query("SELECT " + a[0] + " FROM " + a[1] + " WHERE floID=?", [floID]));
|
let promises = select.map(a => DB.query(`SELECT ${a[0]} FROM ${a[1]} WHERE floID=? ${a[2] || ""}`, [floID]));
|
||||||
Promise.allSettled(promises).then(results => {
|
Promise.allSettled(promises).then(results => {
|
||||||
let response = {
|
let response = {
|
||||||
floID: floID,
|
floID: floID,
|
||||||
@ -117,10 +150,10 @@ function getAccountDetails(floID) {
|
|||||||
else
|
else
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0:
|
case 0:
|
||||||
response.rupee_total = a.value[0].rupeeBalance;
|
response.cash = a.value[0].balance;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
response.coins = a.value;
|
response.vault = a.value;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
response.sellOrders = a.value;
|
response.sellOrders = a.value;
|
||||||
@ -166,7 +199,7 @@ function confirmDepositFLO() {
|
|||||||
txQueries.push(["INSERT INTO Vault(floID, quantity) VALUES (?, ?)", [req.floID, amount]]);
|
txQueries.push(["INSERT INTO Vault(floID, quantity) VALUES (?, ?)", [req.floID, amount]]);
|
||||||
txQueries.push(["UPDATE inputFLO SET status=?, amount=? WHERE id=?", ["SUCCESS", amount, req.id]]);
|
txQueries.push(["UPDATE inputFLO SET status=?, amount=? WHERE id=?", ["SUCCESS", amount, req.id]]);
|
||||||
DB.transaction(txQueries)
|
DB.transaction(txQueries)
|
||||||
.then(result => console.debug("FLO deposited for ", req.floID))
|
.then(result => console.debug("FLO deposited:", req.floID, amount))
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error))
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -206,45 +239,23 @@ function withdrawFLO(floID, amount) {
|
|||||||
return reject(INVALID("Invalid FLO ID"));
|
return reject(INVALID("Invalid FLO ID"));
|
||||||
else if (typeof amount !== "number" || amount <= 0)
|
else if (typeof amount !== "number" || amount <= 0)
|
||||||
return reject(INVALID(`Invalid amount (${amount})`));
|
return reject(INVALID(`Invalid amount (${amount})`));
|
||||||
DB.query("SELECT SUM(quantity) AS total FROM Vault WHERE floID=?", [floID]).then(result => {
|
getAssetBalance.check(floID, "FLO", amount).then(_ => {
|
||||||
let total = result.pop()["total"] || 0;
|
consumeAsset(floID, "FLO", amount).then(txQueries => {
|
||||||
if (total < amount)
|
DB.transaction(txQueries).then(result => {
|
||||||
return reject(INVALID("Insufficient FLO"));
|
//Send FLO to user via blockchain API
|
||||||
DB.query("SELECT SUM(quantity) AS locked FROM SellOrder WHERE floID=?", [floID]).then(result => {
|
floBlockchainAPI.sendTx(global.myFloID, floID, amount, global.myPrivKey, 'Withdraw FLO Coins from Market').then(txid => {
|
||||||
let locked = result.pop()["locked"] || 0;
|
if (!txid)
|
||||||
let available = total - locked;
|
throw Error("Transaction not successful");
|
||||||
if (available < amount)
|
//Transaction was successful, Add in DB
|
||||||
return reject(INVALID("Insufficient FLO (Some FLO are locked in sell orders)"));
|
DB.query("INSERT INTO outputFLO (floID, amount, txid, status) VALUES (?, ?, ?, ?)", [floID, amount, txid, "WAITING_CONFIRMATION"])
|
||||||
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY locktime", [floID]).then(coins => {
|
.then(_ => null).catch(error => console.error(error))
|
||||||
let rem = amount,
|
.finally(_ => resolve("Withdrawal was successful"));
|
||||||
txQueries = [];
|
}).catch(error => {
|
||||||
for (let i = 0; i < coins.length && rem > 0; i++) {
|
console.debug(error);
|
||||||
if (rem < coins[i].quantity) {
|
DB.query("INSERT INTO outputFLO (floID, amount, status) VALUES (?, ?, ?)", [floID, amount, "PENDING"])
|
||||||
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, coins[i].id]]);
|
.then(_ => null).catch(error => console.error(error))
|
||||||
rem = 0;
|
.finally(_ => resolve("Withdrawal request is in process"));
|
||||||
} else {
|
});
|
||||||
txQueries.push(["DELETE FROM Vault WHERE id=?", [coins[i].id]]);
|
|
||||||
rem -= coins[i].quantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rem > 0) //should not happen AS the total and net is checked already
|
|
||||||
return reject(INVALID("Insufficient FLO"));
|
|
||||||
DB.transaction(txQueries).then(result => {
|
|
||||||
//Send FLO to user via blockchain API
|
|
||||||
floBlockchainAPI.sendTx(global.myFloID, floID, amount, global.myPrivKey, 'Withdraw FLO Coins from Market').then(txid => {
|
|
||||||
if (!txid)
|
|
||||||
throw Error("Transaction not successful");
|
|
||||||
//Transaction was successful, Add in DB
|
|
||||||
DB.query("INSERT INTO outputFLO (floID, amount, txid, status) VALUES (?, ?, ?, ?)", [floID, amount, txid, "WAITING_CONFIRMATION"])
|
|
||||||
.then(_ => null).catch(error => console.error(error))
|
|
||||||
.finally(_ => resolve("Withdrawal was successful"));
|
|
||||||
}).catch(error => {
|
|
||||||
console.debug(error);
|
|
||||||
DB.query("INSERT INTO outputFLO (floID, amount, status) VALUES (?, ?, ?)", [floID, amount, "PENDING"])
|
|
||||||
.then(_ => null).catch(error => console.error(error))
|
|
||||||
.finally(_ => resolve("Withdrawal request is in process"));
|
|
||||||
});
|
|
||||||
}).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));
|
||||||
@ -266,22 +277,22 @@ function retryWithdrawalFLO() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function confirmWithdrawalFLO() {
|
function confirmWithdrawalFLO() {
|
||||||
DB.query("SELECT id, floID, txid FROM outputFLO WHERE status=?", ["WAITING_CONFIRMATION"]).then(results => {
|
DB.query("SELECT id, floID, amount, txid FROM outputFLO WHERE status=?", ["WAITING_CONFIRMATION"]).then(results => {
|
||||||
results.forEach(req => {
|
results.forEach(req => {
|
||||||
floBlockchainAPI.getTx(req.txid).then(tx => {
|
floBlockchainAPI.getTx(req.txid).then(tx => {
|
||||||
if (!tx.blockheight || !tx.confirmations) //Still not confirmed
|
if (!tx.blockheight || !tx.confirmations) //Still not confirmed
|
||||||
return;
|
return;
|
||||||
DB.query("UPDATE outputFLO SET status=? WHERE id=?", ["SUCCESS", req.id])
|
DB.query("UPDATE outputFLO SET status=? WHERE id=?", ["SUCCESS", req.id])
|
||||||
.then(result => console.debug("FLO withdrawed for ", req.floID))
|
.then(result => console.debug("FLO withdrawed:", req.floID, req.amount))
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error))
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
})
|
})
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
function depositRupee(floID, txid) {
|
function depositToken(floID, txid) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
DB.query("SELECT status FROM inputRupee WHERE txid=? AND floID=?", [txid, floID]).then(result => {
|
DB.query("SELECT status FROM inputToken WHERE txid=? AND floID=?", [txid, floID]).then(result => {
|
||||||
if (result.length) {
|
if (result.length) {
|
||||||
switch (result[0].status) {
|
switch (result[0].status) {
|
||||||
case "PENDING":
|
case "PENDING":
|
||||||
@ -292,53 +303,58 @@ function depositRupee(floID, txid) {
|
|||||||
return reject(INVALID("Transaction already used to add tokens"));
|
return reject(INVALID("Transaction already used to add tokens"));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
DB.query("INSERT INTO inputRupee(txid, floID, status) VALUES (?, ?, ?)", [txid, floID, "PENDING"])
|
DB.query("INSERT INTO inputToken(txid, floID, status) VALUES (?, ?, ?)", [txid, floID, "PENDING"])
|
||||||
.then(result => resolve("Deposit request in process"))
|
.then(result => resolve("Deposit request in process"))
|
||||||
.catch(error => reject(error));
|
.catch(error => reject(error));
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmDepositRupee() {
|
function confirmDepositToken() {
|
||||||
DB.query("SELECT id, floID, txid FROM inputRupee WHERE status=?", ["PENDING"]).then(results => {
|
DB.query("SELECT id, floID, txid FROM inputToken WHERE status=?", ["PENDING"]).then(results => {
|
||||||
results.forEach(req => {
|
results.forEach(req => {
|
||||||
confirmDepositRupee.checkTx(req.floID, req.txid).then(amounts => {
|
confirmDepositToken.checkTx(req.floID, req.txid).then(amounts => {
|
||||||
DB.query("SELECT id FROM inputFLO where floID=? AND txid=?", [req.floID, req.txid]).then(result => {
|
DB.query("SELECT id FROM inputFLO where floID=? AND txid=?", [req.floID, req.txid]).then(result => {
|
||||||
let txQueries = [],
|
let txQueries = [],
|
||||||
amount_rupee = amounts[0];
|
token_name = amounts[0],
|
||||||
|
amount_token = amounts[1];
|
||||||
//Add the FLO balance if necessary
|
//Add the FLO balance if necessary
|
||||||
if (!result.length) {
|
if (!result.length) {
|
||||||
let amount_flo = amounts[1];
|
let amount_flo = amounts[2];
|
||||||
txQueries.push(["INSERT INTO Vault(floID, quantity) VALUES (?, ?)", [req.floID, amount_flo]]);
|
txQueries.push(["INSERT INTO Vault(floID, asset, quantity) VALUES (?, ?, ?)", [req.floID, "FLO", amount_flo]]);
|
||||||
txQueries.push(["INSERT INTO inputFLO(txid, floID, amount, status) VALUES (?, ?, ?, ?)", [req.txid, req.floID, amount_flo, "SUCCESS"]]);
|
txQueries.push(["INSERT INTO inputFLO(txid, floID, amount, status) VALUES (?, ?, ?, ?)", [req.txid, req.floID, amount_flo, "SUCCESS"]]);
|
||||||
}
|
}
|
||||||
txQueries.push(["UPDATE inputRupee SET status=? WHERE id=?", ["SUCCESS", req.id]]);
|
txQueries.push(["UPDATE inputToken SET status=?, token=?, amount=? WHERE id=?", ["SUCCESS", token_name, amount_token, req.id]]);
|
||||||
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance+? WHERE floID=?", [amount_rupee, req.floID]]);
|
if (token_name === floGlobals.currency)
|
||||||
|
txQueries.push(["UPDATE Cash SET balance=balance+? WHERE floID=?", [amount_token, req.floID]]);
|
||||||
|
else
|
||||||
|
txQueries.push(["INSERT INTO Vault(floID, asset, quantity) VALUES (?, ?, ?)", [req.floID, token_name, amount_token]]);
|
||||||
DB.transaction(txQueries)
|
DB.transaction(txQueries)
|
||||||
.then(result => console.debug("Rupee deposited for ", req.floID))
|
.then(result => console.debug("Token deposited:", req.floID, token_name, amount_token))
|
||||||
.catch(error => console.error(error));
|
.catch(error => console.error(error));
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (error[0])
|
if (error[0])
|
||||||
DB.query("UPDATE inputRupee SET status=? WHERE id=?", ["REJECTED", req.id])
|
DB.query("UPDATE inputToken SET status=? WHERE id=?", ["REJECTED", req.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}).catch(error => console.error(error))
|
}).catch(error => console.error(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmDepositRupee.checkTx = function(sender, txid) {
|
confirmDepositToken.checkTx = function(sender, txid) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const receiver = global.myFloID; //receiver should be market's floID (ie, adminID)
|
const receiver = global.sinkID; //receiver should be market's floID (ie, sinkID)
|
||||||
tokenAPI.getTx(txid).then(tx => {
|
tokenAPI.getTx(txid).then(tx => {
|
||||||
if (tx.parsedFloData.type !== "transfer")
|
if (tx.parsedFloData.type !== "transfer")
|
||||||
return reject([true, "Transaction type not 'transfer'"]);
|
return reject([true, "Transaction type not 'transfer'"]);
|
||||||
else if (tx.parsedFloData.transferType !== "token")
|
else if (tx.parsedFloData.transferType !== "token")
|
||||||
return reject([true, "Transaction transfer is not 'token'"]);
|
return reject([true, "Transaction transfer is not 'token'"]);
|
||||||
else if (tx.parsedFloData.tokenIdentification !== "rupee")
|
var token_name = tx.parsedFloData.tokenIdentification,
|
||||||
return reject([true, "Transaction token is not 'rupee'"]);
|
amount_token = tx.parsedFloData.tokenAmount;
|
||||||
var amount_rupee = tx.parsedFloData.tokenAmount;
|
if (!allowedAssets.includes(token_name) || token_name === "FLO")
|
||||||
|
return reject([true, "Token not authorised"]);
|
||||||
let vin_sender = tx.transactionDetails.vin.filter(v => v.addr === sender)
|
let vin_sender = tx.transactionDetails.vin.filter(v => v.addr === sender)
|
||||||
if (!vin_sender.length)
|
if (!vin_sender.length)
|
||||||
return reject([true, "Transaction not sent by the sender"]);
|
return reject([true, "Transaction not sent by the sender"]);
|
||||||
@ -346,60 +362,36 @@ confirmDepositRupee.checkTx = function(sender, txid) {
|
|||||||
if (amount_flo == 0)
|
if (amount_flo == 0)
|
||||||
return reject([true, "Transaction receiver is not market ID"]);
|
return reject([true, "Transaction receiver is not market ID"]);
|
||||||
else
|
else
|
||||||
resolve([amount_rupee, amount_flo]);
|
resolve([token_name, amount_token, amount_flo]);
|
||||||
}).catch(error => reject([false, error]))
|
}).catch(error => reject([false, error]))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function withdrawRupee(floID, amount) {
|
function withdrawToken(floID, token, amount) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floID || !floCrypto.validateAddr(floID))
|
if (!floID || !floCrypto.validateAddr(floID))
|
||||||
return reject(INVALID("Invalid FLO ID"));
|
return reject(INVALID("Invalid FLO ID"));
|
||||||
else if (typeof amount !== "number" || amount <= 0)
|
else if (typeof amount !== "number" || amount <= 0)
|
||||||
return reject(INVALID(`Invalid amount (${amount})`));
|
return reject(INVALID(`Invalid amount (${amount})`));
|
||||||
DB.query("SELECT SUM(quantity) AS total FROM Vault WHERE floID=?", [floID]).then(result => {
|
else if (!allowedAssets.includes(token) || token === "FLO")
|
||||||
let required_flo = floGlobals.sendAmt + floGlobals.fee,
|
return reject(INVALID("Invalid Token"));
|
||||||
total = result.pop()["total"] || 0;
|
//Check for FLO balance (transaction fee)
|
||||||
if (total < required_flo)
|
const required_flo = floGlobals.sendAmt + floGlobals.fee;
|
||||||
return reject(INVALID(`Insufficient FLO! Required ${required_flo} FLO to withdraw tokens`));
|
getAssetBalance.check(floID, "FLO", required_flo).then(_ => {
|
||||||
DB.query("SELECT SUM(quantity) AS locked FROM SellOrder WHERE floID=?", [floID]).then(result => {
|
getAssetBalance.check(floID, token, amount).then(_ => {
|
||||||
let locked = result.pop()["locked"] || 0;
|
consumeAsset(floID, "FLO", required_flo).then(txQueries => {
|
||||||
let available = total - locked;
|
consumeAsset(floID, token, amount, txQueries).then(txQueries => {
|
||||||
if (available < required_flo)
|
|
||||||
return reject(INVALID(`Insufficient FLO (Some FLO are locked in sell orders)! Required ${required_flo} FLO to withdraw tokens`));
|
|
||||||
DB.query("SELECT rupeeBalance FROM Cash WHERE floID=?", [floID]).then(result => {
|
|
||||||
if (result.length < 1)
|
|
||||||
return reject(INVALID(`FLO_ID: ${floID} not registered`));
|
|
||||||
if (result[0].rupeeBalance < amount)
|
|
||||||
return reject(INVALID('Insufficient Rupee balance'));
|
|
||||||
DB.query("SELECT id, quantity, base FROM Vault WHERE floID=? ORDER BY locktime", [floID]).then(coins => {
|
|
||||||
let rem = required_flo,
|
|
||||||
txQueries = [];
|
|
||||||
for (let i = 0; i < coins.length && rem > 0; i++) {
|
|
||||||
if (rem < coins[i].quantity) {
|
|
||||||
txQueries.push(["UPDATE Vault SET quantity=quantity-? WHERE id=?", [rem, coins[i].id]]);
|
|
||||||
rem = 0;
|
|
||||||
} else {
|
|
||||||
txQueries.push(["DELETE FROM Vault WHERE id=?", [coins[i].id]]);
|
|
||||||
rem -= result[i].quantity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (rem > 0) //should not happen AS the total and net is checked already
|
|
||||||
return reject(INVALID("Insufficient FLO"));
|
|
||||||
txQueries.push(["UPDATE Cash SET rupeeBalance=rupeeBalance-? WHERE floID=?", [amount, floID]]);
|
|
||||||
|
|
||||||
DB.transaction(txQueries).then(result => {
|
DB.transaction(txQueries).then(result => {
|
||||||
//Send FLO to user via blockchain API
|
//Send FLO to user via blockchain API
|
||||||
tokenAPI.sendToken(global.myPrivKey, amount, '(withdrawal from market)', floID).then(txid => {
|
tokenAPI.sendToken(global.myPrivKey, amount, '(withdrawal from market)', floID, token).then(txid => {
|
||||||
if (!txid)
|
if (!txid) throw Error("Transaction not successful");
|
||||||
throw Error("Transaction not successful");
|
|
||||||
//Transaction was successful, Add in DB
|
//Transaction was successful, Add in DB
|
||||||
DB.query("INSERT INTO outputRupee (floID, amount, txid, status) VALUES (?, ?, ?, ?)", [floID, amount, txid, "WAITING_CONFIRMATION"])
|
DB.query("INSERT INTO outputToken (floID, token, amount, txid, status) VALUES (?, ?, ?, ?, ?)", [floID, token, amount, txid, "WAITING_CONFIRMATION"])
|
||||||
.then(_ => null).catch(error => console.error(error))
|
.then(_ => null).catch(error => console.error(error))
|
||||||
.finally(_ => resolve("Withdrawal was successful"));
|
.finally(_ => resolve("Withdrawal was successful"));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.debug(error);
|
console.debug(error);
|
||||||
DB.query("INSERT INTO outputRupee (floID, amount, status) VALUES (?, ?, ?)", [floID, amount, "PENDING"])
|
DB.query("INSERT INTO outputToken (floID, token, amount, status) VALUES (?, ?, ?, ?)", [floID, token, amount, "PENDING"])
|
||||||
.then(_ => null).catch(error => console.error(error))
|
.then(_ => null).catch(error => console.error(error))
|
||||||
.finally(_ => resolve("Withdrawal request is in process"));
|
.finally(_ => resolve("Withdrawal request is in process"));
|
||||||
});
|
});
|
||||||
@ -411,26 +403,26 @@ function withdrawRupee(floID, amount) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function retryWithdrawalRupee() {
|
function retryWithdrawalToken() {
|
||||||
DB.query("SELECT id, floID, amount FROM outputRupee WHERE status=?", ["PENDING"]).then(results => {
|
DB.query("SELECT id, floID, token, amount FROM outputToken WHERE status=?", ["PENDING"]).then(results => {
|
||||||
results.forEach(req => {
|
results.forEach(req => {
|
||||||
tokenAPI.sendToken(global.myPrivKey, req.amount, '(withdrawal from market)', req.floID).then(txid => {
|
tokenAPI.sendToken(global.myPrivKey, req.amount, '(withdrawal from market)', req.floID, req.token).then(txid => {
|
||||||
if (!txid)
|
if (!txid)
|
||||||
throw Error("Transaction not successful");
|
throw Error("Transaction not successful");
|
||||||
//Transaction was successful, Add in DB
|
//Transaction was successful, Add in DB
|
||||||
DB.query("UPDATE outputRupee SET status=?, txid=? WHERE id=?", ["WAITING_CONFIRMATION", txid, req.id])
|
DB.query("UPDATE outputToken SET status=?, txid=? WHERE id=?", ["WAITING_CONFIRMATION", txid, req.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
});
|
});
|
||||||
}).catch(error => reject(error));
|
}).catch(error => reject(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmWithdrawalRupee() {
|
function confirmWithdrawalToken() {
|
||||||
DB.query("SELECT id, floID, amount, txid FROM outputRupee WHERE status=?", ["WAITING_CONFIRMATION"]).then(results => {
|
DB.query("SELECT id, floID, token, amount, txid FROM outputToken WHERE status=?", ["WAITING_CONFIRMATION"]).then(results => {
|
||||||
results.forEach(req => {
|
results.forEach(req => {
|
||||||
tokenAPI.getTx(req.txid).then(tx => {
|
tokenAPI.getTx(req.txid).then(tx => {
|
||||||
DB.query("UPDATE outputRupee SET status=? WHERE id=?", ["SUCCESS", req.id])
|
DB.query("UPDATE outputToken SET status=? WHERE id=?", ["SUCCESS", req.id])
|
||||||
.then(result => console.debug("Rupee withdrawed for ", req.floID))
|
.then(result => console.debug("Token withdrawed:", req.floID, req.token, req.amount))
|
||||||
.catch(error => console.error(error));
|
.catch(error => console.error(error));
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
})
|
})
|
||||||
@ -444,11 +436,11 @@ function periodicProcess() {
|
|||||||
|
|
||||||
function blockchainReCheck() {
|
function blockchainReCheck() {
|
||||||
confirmDepositFLO();
|
confirmDepositFLO();
|
||||||
confirmDepositRupee();
|
confirmDepositToken();
|
||||||
retryWithdrawalFLO();
|
retryWithdrawalFLO();
|
||||||
retryWithdrawalRupee();
|
retryWithdrawalToken();
|
||||||
confirmWithdrawalFLO();
|
confirmWithdrawalFLO();
|
||||||
confirmWithdrawalRupee();
|
confirmWithdrawalToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
@ -461,12 +453,15 @@ module.exports = {
|
|||||||
getAccountDetails,
|
getAccountDetails,
|
||||||
depositFLO,
|
depositFLO,
|
||||||
withdrawFLO,
|
withdrawFLO,
|
||||||
depositRupee,
|
depositToken,
|
||||||
withdrawRupee,
|
withdrawToken,
|
||||||
periodicProcess,
|
periodicProcess,
|
||||||
group: coupling.group,
|
group: coupling.group,
|
||||||
set DB(db) {
|
set DB(db) {
|
||||||
DB = db;
|
DB = db;
|
||||||
coupling.DB = db;
|
coupling.DB = db;
|
||||||
|
},
|
||||||
|
set allowedAssets(assets) {
|
||||||
|
allowedAssets = assets;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -159,11 +159,12 @@ function PlaceSellOrder(req, res) {
|
|||||||
let data = req.body;
|
let data = req.body;
|
||||||
validateRequestFromFloID({
|
validateRequestFromFloID({
|
||||||
type: "sell_order",
|
type: "sell_order",
|
||||||
|
asset: data.asset,
|
||||||
quantity: data.quantity,
|
quantity: data.quantity,
|
||||||
min_price: data.min_price,
|
min_price: data.min_price,
|
||||||
timestamp: data.timestamp
|
timestamp: data.timestamp
|
||||||
}, data.sign, data.floID).then(req_str => {
|
}, data.sign, data.floID).then(req_str => {
|
||||||
market.addSellOrder(data.floID, data.quantity, data.min_price)
|
market.addSellOrder(data.floID, data.asset, data.quantity, data.min_price)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
storeRequest(data.floID, req_str, data.sign);
|
storeRequest(data.floID, req_str, data.sign);
|
||||||
res.send('Sell Order placed successfully');
|
res.send('Sell Order placed successfully');
|
||||||
@ -189,11 +190,12 @@ function PlaceBuyOrder(req, res) {
|
|||||||
let data = req.body;
|
let data = req.body;
|
||||||
validateRequestFromFloID({
|
validateRequestFromFloID({
|
||||||
type: "buy_order",
|
type: "buy_order",
|
||||||
|
asset: data.asset,
|
||||||
quantity: data.quantity,
|
quantity: data.quantity,
|
||||||
max_price: data.max_price,
|
max_price: data.max_price,
|
||||||
timestamp: data.timestamp
|
timestamp: data.timestamp
|
||||||
}, data.sign, data.floID).then(req_str => {
|
}, data.sign, data.floID).then(req_str => {
|
||||||
market.addBuyOrder(data.floID, data.quantity, data.max_price)
|
market.addBuyOrder(data.floID, data.asset, data.quantity, data.max_price)
|
||||||
.then(result => {
|
.then(result => {
|
||||||
storeRequest(data.floID, req_str, data.sign);
|
storeRequest(data.floID, req_str, data.sign);
|
||||||
res.send('Buy Order placed successfully');
|
res.send('Buy Order placed successfully');
|
||||||
@ -351,14 +353,14 @@ function WithdrawFLO(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function DepositRupee(req, res) {
|
function DepositToken(req, res) {
|
||||||
let data = req.body;
|
let data = req.body;
|
||||||
validateRequestFromFloID({
|
validateRequestFromFloID({
|
||||||
type: "deposit_Rupee",
|
type: "deposit_Token",
|
||||||
txid: data.txid,
|
txid: data.txid,
|
||||||
timestamp: data.timestamp
|
timestamp: data.timestamp
|
||||||
}, data.sign, data.floID).then(req_str => {
|
}, data.sign, data.floID).then(req_str => {
|
||||||
market.depositRupee(data.floID, data.txid).then(result => {
|
market.depositToken(data.floID, data.txid).then(result => {
|
||||||
storeRequest(data.floID, req_str, data.sign);
|
storeRequest(data.floID, req_str, data.sign);
|
||||||
res.send(result);
|
res.send(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -379,14 +381,15 @@ function DepositRupee(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function WithdrawRupee(req, res) {
|
function WithdrawToken(req, res) {
|
||||||
let data = req.body;
|
let data = req.body;
|
||||||
validateRequestFromFloID({
|
validateRequestFromFloID({
|
||||||
type: "withdraw_Rupee",
|
type: "withdraw_Token",
|
||||||
|
token: data.token,
|
||||||
amount: data.amount,
|
amount: data.amount,
|
||||||
timestamp: data.timestamp
|
timestamp: data.timestamp
|
||||||
}, data.sign, data.floID).then(req_str => {
|
}, data.sign, data.floID).then(req_str => {
|
||||||
market.withdrawRupee(data.floID, data.amount).then(result => {
|
market.withdrawToken(data.floID, data.token, data.amount).then(result => {
|
||||||
storeRequest(data.floID, req_str, data.sign);
|
storeRequest(data.floID, req_str, data.sign);
|
||||||
res.send(result);
|
res.send(result);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
@ -485,8 +488,8 @@ module.exports = {
|
|||||||
Account,
|
Account,
|
||||||
DepositFLO,
|
DepositFLO,
|
||||||
WithdrawFLO,
|
WithdrawFLO,
|
||||||
DepositRupee,
|
DepositToken,
|
||||||
WithdrawRupee,
|
WithdrawToken,
|
||||||
periodicProcess: market.periodicProcess,
|
periodicProcess: market.periodicProcess,
|
||||||
addUserTag,
|
addUserTag,
|
||||||
removeUserTag,
|
removeUserTag,
|
||||||
|
|||||||
@ -14,7 +14,7 @@
|
|||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getBalance: function(floID, token = floGlobals.token) {
|
getBalance: function(floID, token = floGlobals.currency) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.fetch_api(`api/v1.0/getFloAddressBalance?token=${token}&floAddress=${floID}`)
|
this.fetch_api(`api/v1.0/getFloAddressBalance?token=${token}&floAddress=${floID}`)
|
||||||
.then(result => resolve(result.balance || 0))
|
.then(result => resolve(result.balance || 0))
|
||||||
@ -35,7 +35,7 @@
|
|||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
sendToken: function(privKey, amount, message = "", receiverID = floGlobals.adminID, token = floGlobals.token) {
|
sendToken: function(privKey, amount, message = "", receiverID = floGlobals.adminID, token = floGlobals.currency) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let senderID = floCrypto.getFloID(privKey);
|
let senderID = floCrypto.getFloID(privKey);
|
||||||
if (typeof amount !== "number" || amount <= 0)
|
if (typeof amount !== "number" || amount <= 0)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user