Adding transfer token feature

Transfer tokens
- Added transferToken: Users can directly transfer tokens (including FLO) to other registered users.
- Updated schema changes for the above requirement.
- Trade transactions and transfer transactions will generate a txid (using SHA256).

Other changes
- changed all signing type to lowercase
This commit is contained in:
sairajzero 2022-03-12 02:25:31 +05:30
parent 136ba68b42
commit 0520791696
10 changed files with 241 additions and 86 deletions

View File

@ -171,7 +171,21 @@ CREATE TABLE PriceHistory (
FOREIGN KEY (asset) REFERENCES AssetList(asset)
);
CREATE TABLE TransactionHistory (
CREATE TABLE TransferTransactions (
id INT NOT NULL AUTO_INCREMENT,
sender CHAR(34) NOT NULL,
receiver CHAR(34) NOT NULL,
token VARCHAR(64) NOT NULL,
amount FLOAT NOT NULL,
tx_time DATETIME DEFAULT CURRENT_TIMESTAMP,
txid VARCHAR(66) NOT NULL,
KEY(id),
PRIMARY KEY(txid),
FOREIGN KEY (sender) REFERENCES Users(floID),
FOREIGN KEY (receiver) REFERENCES Users(floID)
);
CREATE TABLE TradeTransactions (
id INT NOT NULL AUTO_INCREMENT,
seller CHAR(34) NOT NULL,
buyer CHAR(34) NOT NULL,
@ -179,13 +193,15 @@ CREATE TABLE TransactionHistory (
quantity FLOAT NOT NULL,
unitValue DECIMAL(10, 2) NOT NULL,
tx_time DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(id),
txid VARCHAR(66) NOT NULL,
KEY(id),
PRIMARY KEY(txid),
FOREIGN KEY (buyer) REFERENCES Users(floID),
FOREIGN KEY (seller) REFERENCES Users(floID),
FOREIGN KEY (asset) REFERENCES AssetList(asset)
);
CREATE TABLE AuditTransaction(
CREATE TABLE AuditTrade(
id INT NOT NULL AUTO_INCREMENT,
rec_time DATETIME DEFAULT CURRENT_TIMESTAMP,
unit_price FLOAT NOT NULL,
@ -324,16 +340,23 @@ FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('PriceHistory', NEW.id) ON
CREATE TRIGGER PriceHistory_D AFTER DELETE ON PriceHistory
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('PriceHistory', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
CREATE TRIGGER AuditTransaction_I AFTER INSERT ON AuditTransaction
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('AuditTransaction', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER AuditTransaction_U AFTER UPDATE ON AuditTransaction
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('AuditTransaction', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER AuditTransaction_D AFTER DELETE ON AuditTransaction
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('AuditTransaction', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
CREATE TRIGGER AuditTransaction_I AFTER INSERT ON AuditTrade
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('AuditTrade', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER AuditTransaction_U AFTER UPDATE ON AuditTrade
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('AuditTrade', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER AuditTransaction_D AFTER DELETE ON AuditTrade
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('AuditTrade', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
CREATE TRIGGER TransactionHistory_I AFTER INSERT ON TransactionHistory
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TransactionHistory', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER TransactionHistory_U AFTER UPDATE ON TransactionHistory
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TransactionHistory', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER TransactionHistory_D AFTER DELETE ON TransactionHistory
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TransactionHistory', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
CREATE TRIGGER TransactionHistory_I AFTER INSERT ON TradeTransactions
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TradeTransactions', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER TransactionHistory_U AFTER UPDATE ON TradeTransactions
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TradeTransactions', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER TransactionHistory_D AFTER DELETE ON TradeTransactions
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TradeTransactions', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;
CREATE TRIGGER TransferTransactions_I AFTER INSERT ON TransferTransactions
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TransferTransactions', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER TransferTransactions_U AFTER UPDATE ON TransferTransactions
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TransferTransactions', NEW.id) ON DUPLICATE KEY UPDATE mode=TRUE, timestamp=DEFAULT;
CREATE TRIGGER TransferTransactions_D AFTER DELETE ON TransferTransactions
FOR EACH ROW INSERT INTO _backup (t_name, id) VALUES ('TransferTransactions', OLD.id) ON DUPLICATE KEY UPDATE mode=NULL, timestamp=DEFAULT;

View File

@ -1,6 +1,6 @@
/* Node data */
TRUNCATE _backup;
TRUNCATE AuditTransaction;
TRUNCATE AuditTrade;
TRUNCATE BuyOrder;
TRUNCATE Cash;
TRUNCATE InputFLO;
@ -12,7 +12,8 @@ TRUNCATE RequestLog;
TRUNCATE SellOrder;
TRUNCATE UserSession;
TRUNCATE UserTag;
TRUNCATE TransactionHistory;
TRUNCATE TransferTransactions;
TRUNCATE TradeTransactions;
TRUNCATE Vault;
DELETE FROM Users;

View File

@ -371,6 +371,41 @@ function cancelOrder(type, id, floID, proxySecret) {
})
}
function transferToken(receiver, token, amount, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(receiver))
return reject(INVALID(`Invalid receiver (${receiver})`));
else if (typeof amount !== "number" || amount <= 0)
return reject(`Invalid amount (${amount})`);
let request = {
floID: floID,
token: token,
receiver: receiver,
amount: amount,
timestamp: Date.now()
};
request.sign = signRequest({
type: "transfer_token",
receiver: receiver,
token: token,
amount: amount,
timestamp: request.timestamp
}, proxySecret);
console.debug(request);
exchangeAPI('/transfer-token', {
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(request)
}).then(result => responseParse(result, false)
.then(result => resolve(result))
.catch(error => reject(error)))
.catch(error => reject(error))
})
}
function depositFLO(quantity, floID, sinkID, privKey, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= floGlobals.fee)
@ -382,7 +417,7 @@ function depositFLO(quantity, floID, sinkID, privKey, proxySecret) {
timestamp: Date.now()
};
request.sign = signRequest({
type: "deposit_FLO",
type: "deposit_flo",
txid: txid,
timestamp: request.timestamp
}, proxySecret);
@ -410,7 +445,7 @@ function withdrawFLO(quantity, floID, proxySecret) {
timestamp: Date.now()
};
request.sign = signRequest({
type: "withdraw_FLO",
type: "withdraw_flo",
amount: quantity,
timestamp: request.timestamp
}, proxySecret);
@ -440,7 +475,7 @@ function depositToken(token, quantity, floID, sinkID, privKey, proxySecret) {
timestamp: Date.now()
};
request.sign = signRequest({
type: "deposit_Token",
type: "deposit_token",
txid: txid,
timestamp: request.timestamp
}, proxySecret);
@ -469,7 +504,7 @@ function withdrawToken(token, quantity, floID, proxySecret) {
timestamp: Date.now()
};
request.sign = signRequest({
type: "withdraw_Token",
type: "withdraw_token",
token: token,
amount: quantity,
timestamp: request.timestamp
@ -498,7 +533,7 @@ function addUserTag(tag_user, tag, floID, proxySecret) {
timestamp: Date.now()
};
request.sign = signRequest({
command: "add_Tag",
type: "add_tag",
user: tag_user,
tag: tag,
timestamp: request.timestamp
@ -527,7 +562,7 @@ function removeUserTag(tag_user, tag, floID, proxySecret) {
timestamp: Date.now()
};
request.sign = signRequest({
command: "remove_Tag",
type: "remove_tag",
user: tag_user,
tag: tag,
timestamp: request.timestamp

View File

@ -8,7 +8,9 @@ module.exports = {
INVALID_SERVER_MSG: "INCORRECT_SERVER_ERROR" //Should be reflected in public backend script
},
market: {
MINIMUM_BUY_REQUIREMENT: 0
MINIMUM_BUY_REQUIREMENT: 0,
TRADE_HASH_PREFIX: "z1",
TRANSFER_HASH_PREFIX: "z0"
},
price: {
MIN_TIME: 1 * 60 * 60 * 1000, // 1 hr

View File

@ -68,6 +68,9 @@ module.exports = function App(secret, DB) {
//cancel sell or buy order
app.post('/cancel', Request.CancelOrder);
//transfer amount to another user
app.post('/transfer-token', Request.TransferToken);
//list sell or buy order
app.get('/list-sellorders', Request.ListSellOrders);
app.get('/list-buyorders', Request.ListBuyOrders);
@ -86,7 +89,6 @@ module.exports = function App(secret, DB) {
app.post('/withdraw-token', Request.WithdrawToken);
//Manage user tags (Access to trusted IDs only)
app.post('/add-tag', Request.addUserTag);
app.post('/remove-tag', Request.removeUserTag);

View File

@ -3,10 +3,15 @@
const group = require("./group");
const price = require("./price");
const {
TRADE_HASH_PREFIX
} = require("./_constants")["market"];
var DB; //container for database
function startCouplingForAsset(asset) {
price.getRates(asset).then(cur_rate => {
cur_rate = cur_rate.toFixed(3);
group.getBestPairs(asset, cur_rate)
.then(bestPairQueue => processCoupling(bestPairQueue))
.catch(error => console.error("initiateCoupling", error))
@ -112,7 +117,12 @@ function updateBalance(seller_best, buyer_best, txQueries, asset, cur_price, qua
//Add coins to Buyer
txQueries.push(["INSERT INTO Vault(floID, asset, base, quantity) VALUES (?, ?, ?, ?)", [buyer_best.floID, asset, cur_price, quantity]])
//Record transaction
txQueries.push(["INSERT INTO TransactionHistory (seller, buyer, asset, quantity, unitValue) VALUES (?, ?, ?, ?, ?)", [seller_best.floID, buyer_best.floID, asset, quantity, cur_price]]);
let time = Date.now();
let hash = TRADE_HASH_PREFIX + Crypto.SHA256([time, seller_best.floID, buyer_best.floID, asset, quantity, cur_price].join("|"));
txQueries.push([
"INSERT INTO TradeTransactions (seller, buyer, asset, quantity, unitValue, tx_time, txid) VALUES (?, ?, ?, ?, ?, ?, ?)",
[seller_best.floID, buyer_best.floID, asset, quantity, cur_price, global.convertDateToString(time), hash]
]);
}
function beginAudit(sellerID, buyerID, asset, unit_price, quantity) {
@ -125,7 +135,7 @@ function beginAudit(sellerID, buyerID, asset, unit_price, quantity) {
function endAudit(sellerID, buyerID, asset, old_bal, unit_price, quantity) {
auditBalance(sellerID, buyerID, asset).then(new_bal => {
DB.query("INSERT INTO AuditTransaction (asset, quantity, unit_price, total_cost," +
DB.query("INSERT INTO AuditTrade (asset, quantity, unit_price, total_cost," +
" sellerID, seller_old_cash, seller_old_asset, seller_new_cash, seller_new_asset," +
" buyerID, buyer_old_cash, buyer_old_asset, buyer_new_cash, buyer_new_asset)" +
" Value (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [

View File

@ -86,6 +86,7 @@ function Database(user, password, dbname, host = 'localhost') {
user: user,
password: password,
database: dbname,
//dateStrings : true,
timezone: 'UTC'
});
db.connect.then(conn => {

View File

@ -3,11 +3,21 @@
const coupling = require('./coupling');
const {
MINIMUM_BUY_REQUIREMENT
MINIMUM_BUY_REQUIREMENT,
TRANSFER_HASH_PREFIX
} = require('./_constants')["market"];
var DB, assetList; //container for database and allowed assets
const checkIfUserRegistered = floID => new Promise((resolve, reject) => {
DB.query("SELECT id FROM Users WHERE floID=?", [floID]).then(result => {
if (result.length)
resolve(result[0].id);
else
reject(INVALID(`User ${floID} not registered`));
}).catch(error => reject(error));
});
const getAssetBalance = (floID, asset) => new Promise((resolve, reject) => {
let promises = (asset === floGlobals.currency) ? [
DB.query("SELECT balance FROM Cash WHERE floID=?", [floID]),
@ -32,7 +42,7 @@ getAssetBalance.check = (floID, asset, amount) => new Promise((resolve, reject)
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
@ -60,8 +70,8 @@ const consumeAsset = (floID, asset, amount, txQueries = []) => new Promise((reso
function addSellOrder(floID, asset, quantity, min_price) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
return reject(INVALID("Invalid FLO ID"));
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
else if (typeof quantity !== "number" || quantity <= 0)
return reject(INVALID(`Invalid quantity (${quantity})`));
else if (typeof min_price !== "number" || min_price <= 0)
@ -71,7 +81,7 @@ function addSellOrder(floID, asset, quantity, min_price) {
getAssetBalance.check(floID, asset, quantity).then(_ => {
checkSellRequirement(floID, asset).then(_ => {
DB.query("INSERT INTO SellOrder(floID, asset, quantity, minPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, min_price])
.then(result => resolve("Added SellOrder to DB"))
.then(result => resolve('Sell Order placed successfully'))
.catch(error => reject(error));
}).catch(error => reject(error))
}).catch(error => reject(error));
@ -83,7 +93,7 @@ const checkSellRequirement = (floID, asset) => new Promise((resolve, reject) =>
if (result.length)
return resolve(true);
//TODO: Should seller need to buy same type of asset before selling?
DB.query("SELECT SUM(quantity) AS brought FROM TransactionHistory WHERE buyer=? AND asset=?", [floID, asset]).then(result => {
DB.query("SELECT SUM(quantity) AS brought FROM TradeTransactions WHERE buyer=? AND asset=?", [floID, asset]).then(result => {
if (result[0].brought >= MINIMUM_BUY_REQUIREMENT)
resolve(true);
else
@ -94,8 +104,8 @@ const checkSellRequirement = (floID, asset) => new Promise((resolve, reject) =>
function addBuyOrder(floID, asset, quantity, max_price) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
return reject(INVALID("Invalid FLO ID"));
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
else if (typeof quantity !== "number" || quantity <= 0)
return reject(INVALID(`Invalid quantity (${quantity})`));
else if (typeof max_price !== "number" || max_price <= 0)
@ -104,7 +114,7 @@ function addBuyOrder(floID, asset, quantity, max_price) {
return reject(INVALID(`Invalid asset (${asset})`));
getAssetBalance.check(floID, floGlobals.currency, quantity * max_price).then(_ => {
DB.query("INSERT INTO BuyOrder(floID, asset, quantity, maxPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, max_price])
.then(result => resolve("Added BuyOrder to DB"))
.then(result => resolve('Buy Order placed successfully'))
.catch(error => reject(error));
}).catch(error => reject(error));
});
@ -112,8 +122,8 @@ function addBuyOrder(floID, asset, quantity, max_price) {
function cancelOrder(type, id, floID) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
return reject(INVALID("Invalid FLO ID"));
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
let tableName;
if (type === "buy")
tableName = "BuyOrder";
@ -166,7 +176,7 @@ function getAccountDetails(floID) {
break;
}
});
DB.query("SELECT * FROM TransactionHistory WHERE seller=? OR buyer=?", [floID, floID])
DB.query("SELECT * FROM TradeTransactions WHERE seller=? OR buyer=?", [floID, floID])
.then(result => response.transactions = result)
.catch(error => console.error(error))
.finally(_ => resolve(response));
@ -174,6 +184,38 @@ function getAccountDetails(floID) {
});
}
function transferToken(sender, receiver, token, amount) {
return new Promise((resolve, reject) => {
if (floCrypto.validateAddr(sender))
return reject(INVALID(`Invalid sender (${sender})`));
else if (floCrypto.validateAddr(receiver))
return reject(INVALID(`Invalid receiver (${receiver})`));
else if (typeof amount !== "number" || amount <= 0)
return reject(INVALID(`Invalid amount (${amount})`));
else if (token !== floGlobals.currency && !assetList.includes(token))
return reject(INVALID(`Invalid token (${token})`));
getAssetBalance.check(senderID, token, amount).then(_ => {
checkIfUserRegistered(receiver).then(_ => {
consumeAsset(sender, token, amount).then(txQueries => {
if (token === floGlobals.currency)
txQueries.push(["UPDATE Cash SET balance=balance+? WHERE floID=?", [amount, receiver]]);
else
txQueries.push(["INSERT INTO Vault(floID, quantity) VALUES (?, ?)", [receiver, amount]]);
let time = Date.now();
let hash = TRANSFER_HASH_PREFIX + Crypto.SHA256([time, sender, receiver, token, amount].join("|"));
txQueries.push([
"INSERT INTO TransferTransactions (sender, receiver, token, amount, tx_time, txid)",
[sender, receiver, token, amount, global.convertDateToString(time), hash]
]);
DB.transaction(txQueries)
.then(result => resolve(hash))
.catch(error => reject(error))
}).catch(error => reject(error))
}).catch(error => reject(error))
}).catch(error => reject(error))
})
}
function depositFLO(floID, txid) {
return new Promise((resolve, reject) => {
DB.query("SELECT status FROM InputFLO WHERE txid=? AND floID=?", [txid, floID]).then(result => {
@ -238,8 +280,8 @@ confirmDepositFLO.checkTx = function(sender, txid) {
function withdrawFLO(floID, amount) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
return reject(INVALID("Invalid FLO ID"));
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
else if (typeof amount !== "number" || amount <= 0)
return reject(INVALID(`Invalid amount (${amount})`));
getAssetBalance.check(floID, "FLO", amount).then(_ => {
@ -372,8 +414,8 @@ confirmDepositToken.checkTx = function(sender, txid) {
function withdrawToken(floID, token, amount) {
return new Promise((resolve, reject) => {
if (!floID || !floCrypto.validateAddr(floID))
return reject(INVALID("Invalid FLO ID"));
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
else if (typeof amount !== "number" || amount <= 0)
return reject(INVALID(`Invalid amount (${amount})`));
else if ((!assetList.includes(token) && token !== floGlobals.currency) || token === "FLO")
@ -454,6 +496,7 @@ module.exports = {
addSellOrder,
cancelOrder,
getAccountDetails,
transferToken,
depositFLO,
withdrawFLO,
depositToken,

View File

@ -165,10 +165,9 @@ function PlaceSellOrder(req, res) {
min_price: data.min_price,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
market.addSellOrder(data.floID, data.asset, data.quantity, data.min_price)
.then(result => {
market.addSellOrder(data.floID, data.asset, data.quantity, data.min_price).then(result => {
storeRequest(data.floID, req_str, data.sign);
res.send('Sell Order placed successfully');
res.send(result);
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
@ -196,10 +195,9 @@ function PlaceBuyOrder(req, res) {
max_price: data.max_price,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
market.addBuyOrder(data.floID, data.asset, data.quantity, data.max_price)
.then(result => {
market.addBuyOrder(data.floID, data.asset, data.quantity, data.max_price).then(result => {
storeRequest(data.floID, req_str, data.sign);
res.send('Buy Order placed successfully');
res.send(result);
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
@ -226,8 +224,7 @@ function CancelOrder(req, res) {
id: data.orderID,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
market.cancelOrder(data.orderType, data.orderID, data.floID)
.then(result => {
market.cancelOrder(data.orderType, data.orderID, data.floID).then(result => {
storeRequest(data.floID, req_str, data.sign);
res.send(result);
}).catch(error => {
@ -248,6 +245,36 @@ function CancelOrder(req, res) {
});
}
function TransferToken(req, res) {
let data = req.body;
validateRequestFromFloID({
type: "transfer_token",
receiver: data.receiver,
token: data.token,
amount: data.amount,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
market.transferToken(data.floID, data.receiver, data.token, data.amount).then(result => {
storeRequest(data.floID, req_str, data.sign);
res.send(result);
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
else {
console.error(error);
res.status(INTERNAL.e_code).send("Token Transfer failed! Try again later!");
}
});
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
else {
console.error(error);
res.status(INTERNAL.e_code).send("Request processing failed! Try again later!");
}
});
}
function ListSellOrders(req, res) {
//TODO: Limit size (best)
DB.query("SELECT * FROM SellOrder ORDER BY time_placed")
@ -264,7 +291,7 @@ function ListBuyOrders(req, res) {
function ListTransactions(req, res) {
//TODO: Limit size (recent)
DB.query("SELECT * FROM TransactionHistory ORDER BY tx_time DESC")
DB.query("SELECT * FROM TradeTransactions ORDER BY tx_time DESC")
.then(result => res.send(result))
.catch(error => res.status(INTERNAL.e_code).send("Try again later!"));
}
@ -301,7 +328,7 @@ function Account(req, res) {
function DepositFLO(req, res) {
let data = req.body;
validateRequestFromFloID({
type: "deposit_FLO",
type: "deposit_flo",
txid: data.txid,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
@ -329,7 +356,7 @@ function DepositFLO(req, res) {
function WithdrawFLO(req, res) {
let data = req.body;
validateRequestFromFloID({
type: "withdraw_FLO",
type: "withdraw_flo",
amount: data.amount,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
@ -357,7 +384,7 @@ function WithdrawFLO(req, res) {
function DepositToken(req, res) {
let data = req.body;
validateRequestFromFloID({
type: "deposit_Token",
type: "deposit_token",
txid: data.txid,
timestamp: data.timestamp
}, data.sign, data.floID).then(req_str => {
@ -385,7 +412,7 @@ function DepositToken(req, res) {
function WithdrawToken(req, res) {
let data = req.body;
validateRequestFromFloID({
type: "withdraw_Token",
type: "withdraw_token",
token: data.token,
amount: data.amount,
timestamp: data.timestamp
@ -416,7 +443,7 @@ function addUserTag(req, res) {
if (!trustedIDs.includes(data.floID))
return res.status(INVALID.e_code).send("Access Denied");
validateRequestFromFloID({
command: "add_Tag",
type: "add_tag",
user: data.user,
tag: data.tag,
timestamp: data.timestamp
@ -448,7 +475,7 @@ function removeUserTag(req, res) {
return res.status(INVALID.e_code).send("Access Denied");
else
validateRequestFromFloID({
command: "remove_Tag",
type: "remove_tag",
user: data.user,
tag: data.tag,
timestamp: data.timestamp
@ -482,6 +509,7 @@ module.exports = {
PlaceBuyOrder,
PlaceSellOrder,
CancelOrder,
TransferToken,
ListSellOrders,
ListBuyOrders,
ListTransactions,

View File

@ -2,6 +2,16 @@
//fetch for node js (used in floBlockchainAPI.js)
global.fetch = require("node-fetch");
global.convertDateToString = function(timestamp) {
let date = new Date(timestamp);
return date.getFullYear() + '-' +
('00' + (date.getMonth() + 1)).slice(-2) + '-' +
('00' + date.getDate()).slice(-2) + ' ' +
('00' + date.getHours()).slice(-2) + ':' +
('00' + date.getMinutes()).slice(-2) + ':' +
('00' + date.getSeconds()).slice(-2);
}
//Set browser paramaters from param.json (or param-default.json)
var param;
try {