Error codes

- Added error codes for floExchangeAPI
This commit is contained in:
sairajzero 2022-05-12 01:40:31 +05:30
parent 0baa6925dc
commit a77f7d77d6
4 changed files with 175 additions and 115 deletions

View File

@ -468,7 +468,7 @@
return new Promise((resolve, reject) => {
let curPos = fetch_api.curPos || 0;
if (curPos >= nodeList.length)
return reject(ExchangeError(ExchangeError.NODES_OFFLINE_CODE, 'No Node online! Try again later'));
return reject(ExchangeError(ExchangeError.NODES_OFFLINE_CODE, 'No Node online! Try again later', errorCode.NODES_OFFLINE));
let url = "https://" + nodeURL[nodeList[curPos]];
(options ? fetch(url + api, options) : fetch(url + api))
.then(result => resolve(result)).catch(error => {
@ -482,17 +482,62 @@
})
}
function ExchangeError(status, message) {
if (message === ExchangeError.INVALID_SERVER_MSG)
location.reload();
else if (this instanceof ExchangeError) {
this.message = message;
this.status = status;
} else
return new ExchangeError(status, message);
const errorCode = exchangeAPI.errorCode = {
INCORRECT_SERVER: '000',
//INVALID INPUTS: 0XX
INVALID_REQUEST_FORMAT: '001',
ACCESS_DENIED: '002',
INVALID_FLO_ID: '011',
INVALID_LOGIN_CODE: '012',
INVALID_PRIVATE_KEY: '013',
INVALID_PUBLIC_KEY: '014',
INVALID_SIGNATURE: '015',
EXPIRED_SIGNATURE: '016',
DUPLICATE_SIGNATURE: '017',
SESSION_INVALID: '018',
SESSION_EXPIRED: '019',
INVALID_TOKEN_NAME: '021',
INVALID_NUMBER: '022',
INVALID_TYPE: '023',
INVALID_TX_ID: '024',
INVALID_TAG: '025',
MISSING_PARAMETER: '099',
//INCORRECT DATA: 1XX
NOT_FOUND: '101',
NOT_OWNER: '102',
DUPLICATE_ENTRY: '103',
//INSUFFICIENT: 2XX
INSUFFICIENT_BALANCE: '201',
INSUFFICIENT_SELLCHIP: '203',
GREATER_SELLCHIP_BASE: '204',
//OTHERS
NODES_OFFLINE: '404',
INTERNAL_ERROR: '500'
};
const parseErrorCode = exchangeAPI.parseErrorCode = function(message) {
let code = message.match(/^E\d{3}:/g);
if (!code || !code.length)
return null;
else
return code[0].substring(1, 4);
}
function ExchangeError(status, message, code = null) {
if (parseErrorCode(message) === errorCode.INCORRECT_SERVER)
location.reload();
else if (this instanceof ExchangeError) {
this.code = code || parseErrorCode(message);
this.message = message.replace(/^E\d{3}:/g, '').trim();
this.status = status;
} else
return new ExchangeError(status, message, code);
}
ExchangeError.INVALID_SERVER_MSG = "INCORRECT_SERVER_ERROR";
ExchangeError.BAD_REQUEST_CODE = 400;
ExchangeError.BAD_RESPONSE_CODE = 500;
ExchangeError.NODES_OFFLINE_CODE = 404;
@ -594,7 +639,7 @@
exchangeAPI.getBalance = function(floID = null, token = null) {
return new Promise((resolve, reject) => {
if (!floID && !token)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Need atleast one argument"));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Need atleast one argument", errorCode.MISSING_PARAMETER));
let queryStr = (floID ? "floID=" + floID : "") +
(floID && token ? "&" : "") +
(token ? "token=" + token : "");
@ -609,7 +654,7 @@
exchangeAPI.getTx = function(txid) {
return new Promise((resolve, reject) => {
if (!txid)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, 'txid required'));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, 'txid required', errorCode.MISSING_PARAMETER));
fetch_api('/get-transaction?txid=' + txid)
.then(result => responseParse(result)
.then(result => resolve(result))
@ -639,7 +684,7 @@
exchangeAPI.signUp = function (privKey, code, hash) {
return new Promise((resolve, reject) => {
if (!code || !hash)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Login Code missing"));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Login Code missing", errorCode.MISSING_PARAMETER));
let request = {
pubKey: floCrypto.getPubKeyHex(privKey),
floID: floCrypto.getFloID(privKey),
@ -671,7 +716,7 @@
exchangeAPI.login = function(privKey, proxyKey, code, hash) {
return new Promise((resolve, reject) => {
if (!code || !hash)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Login Code missing"));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Login Code missing", errorCode.MISSING_PARAMETER));
let request = {
proxyKey: proxyKey,
floID: floCrypto.getFloID(privKey),
@ -681,7 +726,7 @@
hash: hash
};
if (!privKey || !request.floID)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private key"));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private key", errorCode.INVALID_PRIVATE_KEY));
request.sign = signRequest({
type: "login",
random: code,
@ -733,9 +778,9 @@
exchangeAPI.buy = function(asset, quantity, max_price, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= 0)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid quantity (${quantity})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid quantity (${quantity})`, errorCode.INVALID_NUMBER));
else if (typeof max_price !== "number" || max_price <= 0)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid max_price (${max_price})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid max_price (${max_price})`, errorCode.INVALID_NUMBER));
let request = {
floID: floID,
asset: asset,
@ -771,9 +816,9 @@
exchangeAPI.sell = function(asset, quantity, min_price, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= 0)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid quantity (${quantity})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid quantity (${quantity})`, errorCode.INVALID_NUMBER));
else if (typeof min_price !== "number" || min_price <= 0)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid min_price (${min_price})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid min_price (${min_price})`, errorCode.INVALID_NUMBER));
let request = {
floID: floID,
asset: asset,
@ -809,7 +854,7 @@
exchangeAPI.cancelOrder = function(type, id, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (type !== "buy" && type !== "sell")
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid type (${type}): type should be sell (or) buy`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid type (${type}): type should be sell (or) buy`, errorCode.INVALID_TYPE));
let request = {
floID: floID,
orderType: type,
@ -843,7 +888,7 @@
exchangeAPI.transferToken = function(receiver, token, floID, proxySecret) {
return new Promise((resolve, reject) => {
if (typeof receiver !== 'object' || receiver === null)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid receiver: parameter is not an object"));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid receiver: parameter is not an object", errorCode.INVALID_FLO_ID));
let invalidIDs = [],
invalidAmt = [];
for (let f in receiver) {
@ -853,9 +898,9 @@
invalidAmt.push(receiver[f])
}
if (invalidIDs.length)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid receiver (${invalidIDs})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid receiver (${invalidIDs})`, errorCode.INVALID_FLO_ID));
else if (invalidAmt.length)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid amount (${invalidAmt})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid amount (${invalidAmt})`, errorCode.INVALID_NUMBER));
let request = {
floID: floID,
token: token,
@ -888,7 +933,9 @@
exchangeAPI.depositFLO = function(quantity, floID, sinkID, privKey, proxySecret = null) {
return new Promise((resolve, reject) => {
if (typeof quantity !== "number" || quantity <= floGlobals.fee)
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid quantity (${quantity})`));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, `Invalid quantity (${quantity})`, errorCode.INVALID_NUMBER));
else if (!floCrypto.verifyPrivKey(privKey, floID))
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
floBlockchainAPI.sendTx(floID, sinkID, quantity, privKey, '(deposit in market)').then(txid => {
let request = {
floID: floID,
@ -950,7 +997,7 @@
exchangeAPI.depositToken = function(token, quantity, floID, sinkID, privKey, proxySecret = null) {
return new Promise((resolve, reject) => {
if (!floCrypto.verifyPrivKey(privKey, floID))
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key"));
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
floTokenAPI.sendToken(privKey, quantity, sinkID, '(deposit in market)', token).then(txid => {
let request = {
floID: floID,

View File

@ -5,7 +5,6 @@ module.exports = {
request: {
SIGN_EXPIRE_TIME: 5 * 60 * 1000, //5 mins
MAX_SESSION_TIMEOUT: 30 * 24 * 60 * 60 * 1000, //30 days
INVALID_SERVER_MSG: "INCORRECT_SERVER_ERROR" //Should be reflected in public backend script
},
market: {
PERIOD_INTERVAL: 5 * 60 * 1000, //5 min,

View File

@ -11,6 +11,8 @@ const {
TRANSFER_HASH_PREFIX
} = require('./_constants')["market"];
const eCode = require('../docs/scripts/floExchangeAPI').errorCode;
const updateBalance = coupling.updateBalance;
var DB, assetList; //container for database and allowed assets
@ -36,7 +38,7 @@ function logout(floID) {
function getRateHistory(asset, duration) {
return new Promise((resolve, reject) => {
if (!asset || !assetList.includes(asset))
reject(INVALID(`Invalid asset(${asset})`));
reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid asset(${asset})`));
else
coupling.price.getHistory(asset, duration)
.then(result => resolve(result))
@ -47,11 +49,11 @@ function getRateHistory(asset, duration) {
function getBalance(floID, token) {
return new Promise((resolve, reject) => {
if (floID && !floCrypto.validateAddr(floID))
reject(INVALID(`Invalid floID(${floID})`));
reject(INVALID(eCode.INVALID_FLO_ID, `Invalid floID(${floID})`));
else if (token && token !== floGlobals.currency && !assetList.includes(token))
reject(INVALID(`Invalid token(${token})`));
reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid token(${token})`));
else if (!floID && !token)
reject(INVALID('Missing parameters: requires atleast one (floID, token)'));
reject(INVALID(eCode.MISSING_PARAMETER, 'Missing parameters: requires atleast one (floID, token)'));
else {
var promise;
if (floID && token)
@ -114,9 +116,9 @@ const getAssetBalance = (floID, asset) => new Promise((resolve, reject) => {
getAssetBalance.check = (floID, asset, amount) => new Promise((resolve, reject) => {
getAssetBalance(floID, asset).then(balance => {
if (balance.total < amount)
reject(INVALID(`Insufficient ${asset}`));
reject(INVALID(eCode.INSUFFICIENT_BALANCE, `Insufficient ${asset}`));
else if (balance.net < amount)
reject(INVALID(`Insufficient ${asset} (Some are locked in orders)`));
reject(INVALID(eCode.INSUFFICIENT_BALANCE, `Insufficient ${asset} (Some are locked in orders)`));
else
resolve(true);
}).catch(error => reject(error))
@ -125,13 +127,13 @@ getAssetBalance.check = (floID, asset, amount) => new Promise((resolve, reject)
function addSellOrder(floID, asset, quantity, min_price) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
return reject(INVALID(eCode.INVALID_FLO_ID, `Invalid floID (${floID})`));
else if (typeof quantity !== "number" || quantity <= 0)
return reject(INVALID(`Invalid quantity (${quantity})`));
return reject(INVALID(eCode.INVALID_NUMBER, `Invalid quantity (${quantity})`));
else if (typeof min_price !== "number" || min_price <= 0)
return reject(INVALID(`Invalid min_price (${min_price})`));
return reject(INVALID(eCode.INVALID_NUMBER, `Invalid min_price (${min_price})`));
else if (!assetList.includes(asset))
return reject(INVALID(`Invalid asset (${asset})`));
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid asset (${asset})`));
getAssetBalance.check(floID, asset, quantity).then(_ => {
checkSellRequirement(floID, asset, quantity, min_price).then(_ => {
DB.query("INSERT INTO SellOrder(floID, asset, quantity, minPrice) VALUES (?, ?, ?, ?)", [floID, asset, quantity, min_price]).then(result => {
@ -151,7 +153,7 @@ const checkSellRequirement = (floID, asset, quantity, min_price) => new Promise(
let total = result[0][0].total_chips,
locked = result[1][0].locked;
if (total < locked + quantity)
reject(INVALID(`Insufficient sell-chips for ${asset}`));
reject(INVALID(eCode.INSUFFICIENT_SELLCHIP, `Insufficient sell-chips for ${asset}`));
else Promise.all([
DB.query("SELECT IFNULL(SUM(quantity), 0) AS total_chips FROM SellChips WHERE floID=? AND asset=? AND base<=?", [floID, asset, min_price]),
DB.query("SELECT IFNULL(SUM(quantity), 0) AS locked FROM SellOrder WHERE floID=? AND asset=? AND minPrice<=?", [floID, asset, min_price])
@ -164,7 +166,7 @@ const checkSellRequirement = (floID, asset, quantity, min_price) => new Promise(
if (l_locked > l_total)
rem -= l_locked - l_total;
if (rem < quantity)
reject(INVALID(`Cannot sell below purchased price`));
reject(INVALID(eCode.GREATER_SELLCHIP_BASE, `Cannot sell below purchased price`));
else
resolve(true);
}).catch(error => reject(error))
@ -174,13 +176,13 @@ const checkSellRequirement = (floID, asset, quantity, min_price) => new Promise(
function addBuyOrder(floID, asset, quantity, max_price) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
return reject(INVALID(eCode.INVALID_FLO_ID, `Invalid floID (${floID})`));
else if (typeof quantity !== "number" || quantity <= 0)
return reject(INVALID(`Invalid quantity (${quantity})`));
return reject(INVALID(eCode.INVALID_NUMBER, `Invalid quantity (${quantity})`));
else if (typeof max_price !== "number" || max_price <= 0)
return reject(INVALID(`Invalid max_price (${max_price})`));
return reject(INVALID(eCode.INVALID_NUMBER, `Invalid max_price (${max_price})`));
else if (!assetList.includes(asset))
return reject(INVALID(`Invalid asset (${asset})`));
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `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('Buy Order placed successfully');
@ -193,19 +195,19 @@ function addBuyOrder(floID, asset, quantity, max_price) {
function cancelOrder(type, id, floID) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
return reject(INVALID(eCode.INVALID_FLO_ID, `Invalid floID (${floID})`));
let tableName;
if (type === "buy")
tableName = "BuyOrder";
else if (type === "sell")
tableName = "SellOrder";
else
return reject(INVALID("Invalid Order type! Order type must be buy (or) sell"));
return reject(INVALID(eCode.INVALID_TYPE, "Invalid Order type! Order type must be buy (or) sell"));
DB.query(`SELECT floID, asset FROM ${tableName} WHERE id=?`, [id]).then(result => {
if (result.length < 1)
return reject(INVALID("Order not found!"));
return reject(INVALID(eCode.NOT_FOUND, "Order not found!"));
else if (result[0].floID !== floID)
return reject(INVALID("Order doesnt belong to the current user"));
return reject(INVALID(eCode.NOT_OWNER, "Order doesnt belong to the current user"));
let asset = result[0].asset;
//Delete the order
DB.query(`DELETE FROM ${tableName} WHERE id=?`, [id]).then(result => {
@ -262,7 +264,7 @@ function getTransactionDetails(txid) {
tableName = 'TradeTransactions';
type = 'trade';
} else
return reject(INVALID("Invalid TransactionID"));
return reject(INVALID(eCode.INVALID_TX_ID, "Invalid TransactionID"));
DB.query(`SELECT * FROM ${tableName} WHERE txid=?`, [txid]).then(result => {
if (result.length) {
let details = result[0];
@ -271,7 +273,7 @@ function getTransactionDetails(txid) {
details.receiver = JSON.parse(details.receiver);
resolve(details);
} else
reject(INVALID("Transaction not found"));
reject(INVALID(eCode.NOT_FOUND, "Transaction not found"));
}).catch(error => reject(error))
})
}
@ -279,9 +281,9 @@ function getTransactionDetails(txid) {
function transferToken(sender, receivers, token) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(sender))
reject(INVALID(`Invalid sender (${sender})`));
reject(INVALID(eCode.INVALID_FLO_ID, `Invalid sender (${sender})`));
else if (token !== floGlobals.currency && !assetList.includes(token))
reject(INVALID(`Invalid token (${token})`));
reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid token (${token})`));
else {
let invalidIDs = [],
totalAmount = 0;
@ -291,7 +293,7 @@ function transferToken(sender, receivers, token) {
else
totalAmount += receivers[floID];
if (invalidIDs.length)
reject(INVALID(`Invalid receiver (${invalidIDs})`));
reject(INVALID(eCode.INVALID_FLO_ID, `Invalid receiver (${invalidIDs})`));
else getAssetBalance.check(sender, token, totalAmount).then(_ => {
let txQueries = [];
txQueries.push(updateBalance.consume(sender, token, totalAmount));
@ -328,11 +330,11 @@ function depositFLO(floID, txid) {
if (result.length) {
switch (result[0].status) {
case "PENDING":
return reject(INVALID("Transaction already in process"));
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already in process"));
case "REJECTED":
return reject(INVALID("Transaction already rejected"));
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already rejected"));
case "SUCCESS":
return reject(INVALID("Transaction already used to add coins"));
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already used to add coins"));
}
} else
DB.query("INSERT INTO InputFLO(txid, floID, status) VALUES (?, ?, ?)", [txid, floID, "PENDING"])
@ -417,9 +419,9 @@ confirmDepositFLO.addSellChipsIfLaunchSeller = function(floID, quantity) {
function withdrawFLO(floID, amount) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
return reject(INVALID(eCode.INVALID_FLO_ID, `Invalid floID (${floID})`));
else if (typeof amount !== "number" || amount <= 0)
return reject(INVALID(`Invalid amount (${amount})`));
return reject(INVALID(eCode.INVALID_NUMBER, `Invalid amount (${amount})`));
getAssetBalance.check(floID, "FLO", amount).then(_ => {
let txQueries = [];
txQueries.push(updateBalance.consume(floID, "FLO", amount));
@ -477,11 +479,11 @@ function depositToken(floID, txid) {
if (result.length) {
switch (result[0].status) {
case "PENDING":
return reject(INVALID("Transaction already in process"));
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already in process"));
case "REJECTED":
return reject(INVALID("Transaction already rejected"));
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already rejected"));
case "SUCCESS":
return reject(INVALID("Transaction already used to add tokens"));
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already used to add tokens"));
}
} else
DB.query("INSERT INTO InputToken(txid, floID, status) VALUES (?, ?, ?)", [txid, floID, "PENDING"])
@ -550,11 +552,11 @@ confirmDepositToken.checkTx = function(sender, txid) {
function withdrawToken(floID, token, amount) {
return new Promise((resolve, reject) => {
if (!floCrypto.validateAddr(floID))
return reject(INVALID(`Invalid floID (${floID})`));
return reject(INVALID(eCode.INVALID_FLO_ID, `Invalid floID (${floID})`));
else if (typeof amount !== "number" || amount <= 0)
return reject(INVALID(`Invalid amount (${amount})`));
return reject(INVALID(eCode.INVALID_NUMBER, `Invalid amount (${amount})`));
else if ((!assetList.includes(token) && token !== floGlobals.currency) || token === "FLO")
return reject(INVALID("Invalid Token"));
return reject(INVALID(eCode.INVALID_TOKEN_NAME, "Invalid Token"));
//Check for FLO balance (transaction fee)
let required_flo = floGlobals.sendAmt + floGlobals.fee;
getAssetBalance.check(floID, "FLO", required_flo).then(_ => {
@ -614,9 +616,9 @@ function addTag(floID, tag) {
.then(result => resolve(`Added ${floID} to ${tag}`))
.catch(error => {
if (error.code === "ER_DUP_ENTRY")
reject(INVALID(`${floID} already in ${tag}`));
reject(INVALID(eCode.DUPLICATE_ENTRY, `${floID} already in ${tag}`));
else if (error.code === "ER_NO_REFERENCED_ROW")
reject(INVALID(`Invalid Tag`));
reject(INVALID(eCode.INVALID_TAG, `Invalid Tag`));
else
reject(error);
});
@ -645,9 +647,9 @@ function addDistributor(floID, asset) {
.then(result => resolve(`Added ${asset} distributor: ${floID}`))
.catch(error => {
if (error.code === "ER_DUP_ENTRY")
reject(INVALID(`${floID} is already ${asset} disributor`));
reject(INVALID(eCode.DUPLICATE_ENTRY, `${floID} is already ${asset} disributor`));
else if (error.code === "ER_NO_REFERENCED_ROW")
reject(INVALID(`Invalid Asset`));
reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid Asset`));
else
reject(error);
});

View File

@ -4,18 +4,24 @@ const market = require("./market");
const {
SIGN_EXPIRE_TIME,
MAX_SESSION_TIMEOUT,
INVALID_SERVER_MSG
MAX_SESSION_TIMEOUT
} = require("./_constants")["request"];
const eCode = require('../docs/scripts/floExchangeAPI').errorCode;
var DB, trustedIDs, secret; //container for database
global.INVALID = function(message) {
global.INVALID = function(ecode, message) {
if (!(this instanceof INVALID))
return new INVALID(message);
return new INVALID(ecode, message);
this.message = message;
this.ecode = ecode;
}
INVALID.e_code = 400;
INVALID.prototype.toString = function() {
return "E" + this.ecode + ": " + this.message;
}
INVALID.str = (ecode, message) => INVALID(ecode, message).toString();
global.INTERNAL = function INTERNAL(message) {
if (!(this instanceof INTERNAL))
@ -23,31 +29,37 @@ global.INTERNAL = function INTERNAL(message) {
this.message = message;
}
INTERNAL.e_code = 500;
INTERNAL.prototype.toString = function() {
return "E" + eCode.INTERNAL_ERROR + ": " + this.message;
}
INTERNAL.str = (ecode, message) => INTERNAL(ecode, message).toString();
const INCORRECT_SERVER_ERROR = INVALID(eCode.INCORRECT_SERVER, "Incorrect server");
var serving;
function validateRequest(request, sign, floID, pubKey) {
return new Promise((resolve, reject) => {
if (!serving)
reject(INVALID(INVALID_SERVER_MSG));
reject(INCORRECT_SERVER_ERROR);
else if (!request.timestamp)
reject(INVALID("Timestamp parameter missing"));
reject(INVALID(eCode.MISSING_PARAMETER, "Timestamp parameter missing"));
else if (Date.now() - SIGN_EXPIRE_TIME > request.timestamp)
reject(INVALID("Signature Expired"));
reject(INVALID(eCode.EXPIRED_SIGNATURE, "Signature Expired"));
else if (!floCrypto.validateAddr(floID))
reject(INVALID("Invalid floID"));
reject(INVALID(eCode.INVALID_FLO_ID, "Invalid floID"));
else if (typeof request !== "object")
reject(INVALID("Request is not an object"));
reject(INVALID(eCode.INVALID_REQUEST_FORMAT, "Request is not an object"));
else validateRequest.getSignKey(floID, pubKey).then(signKey => {
let req_str = Object.keys(request).sort().map(r => r + ":" + request[r]).join("|");
try {
if (!floCrypto.verifySign(req_str, sign, signKey))
reject(INVALID("Invalid request signature! Re-login if this error occurs frequently"));
reject(INVALID(eCode.INVALID_SIGNATURE, "Invalid request signature"));
else validateRequest.checkIfSignUsed(sign)
.then(result => resolve(req_str))
.catch(error => reject(error))
} catch {
reject(INVALID("Corrupted sign/key"));
reject(INVALID(eCode.INVALID_SIGNATURE, "Corrupted sign/key"));
}
}).catch(error => reject(error));
});
@ -57,22 +69,22 @@ validateRequest.getSignKey = (floID, pubKey) => new Promise((resolve, reject) =>
if (!pubKey)
DB.query("SELECT session_time, proxyKey FROM UserSession WHERE floID=?", [floID]).then(result => {
if (result.length < 1)
reject(INVALID("Session not active"));
reject(INVALID(eCode.SESSION_INVALID, "Session not active"));
else if (result[0].session_time + MAX_SESSION_TIMEOUT < Date.now())
reject(INVALID("Session Expired! Re-login required"));
reject(INVALID(eCode.SESSION_EXPIRED, "Session Expired! Re-login required"));
else
resolve(result[0].proxyKey);
}).catch(error => reject(error));
else if (floCrypto.getFloID(pubKey) === floID)
resolve(pubKey);
else
reject(INVALID("Invalid pubKey"));
reject(INVALID(eCode.INVALID_PUBLIC_KEY, "Invalid pubKey"));
});
validateRequest.checkIfSignUsed = sign => new Promise((resolve, reject) => {
DB.query("SELECT id FROM RequestLog WHERE sign=?", [sign]).then(result => {
if (result.length)
reject(INVALID("Duplicate signature"));
reject(INVALID(eCode.DUPLICATE_SIGNATURE, "Duplicate signature"));
else
resolve(true);
}).catch(error => reject(error))
@ -91,18 +103,18 @@ function processRequest(res, rText, validateObj, sign, floID, pubKey, marketFn)
res.send(result);
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
res.status(INVALID.e_code).send(error.toString());
else {
console.error(error);
res.status(INTERNAL.e_code).send(rText + " failed! Try again later!");
res.status(INTERNAL.e_code).send(INTERNAL.str(rText + " failed! Try again later!"));
}
})
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
res.status(INVALID.e_code).send(error.toString());
else {
console.error(error);
res.status(INTERNAL.e_code).send("Request processing failed! Try again later!");
res.status(INTERNAL.e_code).send(INTERNAL.str("Request processing failed! Try again later!"));
}
})
}
@ -123,10 +135,10 @@ function Account(req, res) {
});
}).catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
res.status(INVALID.e_code).send(error.toString());
else {
console.error(error);
res.status(INTERNAL.e_code).send("Request processing failed! Try again later!");
res.status(INTERNAL.e_code).send(INTERNAL.str("Request processing failed! Try again later!"));
}
});
}
@ -134,9 +146,9 @@ function Account(req, res) {
function Login(req, res) {
let data = req.body;
if (!data.code || data.hash != Crypto.SHA1(data.code + secret))
res.status(INVALID.e_code).send("Invalid Code");
res.status(INVALID.e_code).send(INVALID.str(eCode.INVALID_LOGIN_CODE, "Invalid Code"));
else if (!data.pubKey)
res.status(INVALID.e_code).send("Public key missing");
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
else
processRequest(res, "Login", {
type: "login",
@ -256,7 +268,7 @@ function WithdrawToken(req, res) {
function AddUserTag(req, res) {
let data = req.body;
if (!trustedIDs.includes(data.floID))
res.status(INVALID.e_code).send("Access Denied");
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
else processRequest(res, "Add user-tag", {
type: "add_tag",
user: data.user,
@ -270,7 +282,7 @@ function AddUserTag(req, res) {
function RemoveUserTag(req, res) {
let data = req.body;
if (!trustedIDs.includes(data.floID))
res.status(INVALID.e_code).send("Access Denied");
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
else processRequest(res, "Remove user-tag", {
type: "remove_tag",
user: data.user,
@ -284,7 +296,7 @@ function RemoveUserTag(req, res) {
function AddDistributor(req, res) {
let data = req.body;
if (!trustedIDs.includes(data.floID))
res.status(INVALID.e_code).send("Access Denied");
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
else processRequest(res, "Add distributor", {
type: "add_distributor",
distributor: data.distributor,
@ -298,7 +310,7 @@ function AddDistributor(req, res) {
function RemoveDistributor(req, res) {
let data = req.body;
if (!trustedIDs.includes(data.floID))
res.status(INVALID.e_code).send("Access Denied");
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
else processRequest(res, "Remove distributor", {
type: "remove_distributor",
distributor: data.distributor,
@ -313,7 +325,7 @@ function RemoveDistributor(req, res) {
function GetLoginCode(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let randID = floCrypto.randString(8, true) + Math.round(Date.now() / 1000);
let hash = Crypto.SHA1(randID + secret);
@ -326,11 +338,11 @@ function GetLoginCode(req, res) {
function ListSellOrders(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let asset = req.query.asset;
if (asset && !market.assetList.includes(asset))
res.status(INVALID.e_code).send("Invalid asset parameter");
res.status(INVALID.e_code).send(INVALID.str(eCode.INVALID_TOKEN_NAME, "Invalid asset parameter"));
else
DB.query("SELECT SellOrder.floID, SellOrder.asset, SellOrder.minPrice, SellOrder.quantity, SellOrder.time_placed FROM SellOrder" +
" INNER JOIN UserBalance ON UserBalance.floID = SellOrder.floID AND UserBalance.token = SellOrder.asset" +
@ -345,7 +357,7 @@ function ListSellOrders(req, res) {
.then(result => res.send(result))
.catch(error => {
console.error(error);
res.status(INTERNAL.e_code).send("Try again later!")
res.status(INTERNAL.e_code).send(INTERNAL.str("Try again later!"));
});
}
@ -353,11 +365,11 @@ function ListSellOrders(req, res) {
function ListBuyOrders(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let asset = req.query.asset;
if (asset && !market.assetList.includes(asset))
res.status(INVALID.e_code).send("Invalid asset parameter");
res.status(INVALID.e_code).send(INVALID.str(eCode.INVALID_TOKEN_NAME, "Invalid asset parameter"));
else
DB.query("SELECT BuyOrder.floID, BuyOrder.asset, BuyOrder.maxPrice, BuyOrder.quantity, BuyOrder.time_placed FROM BuyOrder" +
" INNER JOIN UserBalance ON UserBalance.floID = BuyOrder.floID AND UserBalance.token = ?" +
@ -371,18 +383,18 @@ function ListBuyOrders(req, res) {
.then(result => res.send(result))
.catch(error => {
console.error(error);
res.status(INTERNAL.e_code).send("Try again later!")
res.status(INTERNAL.e_code).send(INTERNAL.str("Try again later!"));
});
}
}
function ListTradeTransactions(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let asset = req.query.asset;
if (asset && !market.assetList.includes(asset))
res.status(INVALID.e_code).send("Invalid asset parameter");
res.status(INVALID.e_code).send(INVALID.str(eCode.INVALID_TOKEN_NAME, "Invalid asset parameter"));
else
DB.query("SELECT * FROM TradeTransactions" +
(asset ? " WHERE asset = ?" : "") +
@ -390,14 +402,14 @@ function ListTradeTransactions(req, res) {
.then(result => res.send(result))
.catch(error => {
console.error(error);
res.status(INTERNAL.e_code).send("Try again later!")
res.status(INTERNAL.e_code).send(INTERNAL.str("Try again later!"));
});
}
}
function GetRates(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let asset = req.query.asset,
rates = market.rates,
@ -410,7 +422,7 @@ function GetRates(req, res) {
countDown: countDown[asset]
});
else
res.status(INVALID.e_code).send("Invalid asset parameter");
res.status(INVALID.e_code).send(INVALID.str(eCode.INVALID_TOKEN_NAME, "Invalid asset parameter"));
} else
res.send({
rates,
@ -421,7 +433,7 @@ function GetRates(req, res) {
function GetRateHistory(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let asset = req.query.asset,
duration = req.query.duration || "";
@ -429,10 +441,10 @@ function GetRateHistory(req, res) {
.then(result => res.send(result))
.catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
res.status(INVALID.e_code).send(error.toString());
else {
console.error(error);
res.status(INTERNAL.e_code).send("Unable to process! Try again later!");
res.status(INTERNAL.e_code).send(INTERNAL.str("Unable to process! Try again later!"));
}
});
}
@ -440,19 +452,19 @@ function GetRateHistory(req, res) {
function GetTransaction(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let txid = req.query.txid;
if (!txid)
res.status(INVALID.e_code).send("txid (transactionID) parameter missing");
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "txid (transactionID) parameter missing"));
else market.getTransactionDetails(txid)
.then(result => res.send(result))
.catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
res.status(INVALID.e_code).send(error.toString());
else {
console.error(error);
res.status(INTERNAL.e_code).send("Unable to process! Try again later!");
res.status(INTERNAL.e_code).send(INTERNAL.str("Unable to process! Try again later!"));
}
});
}
@ -460,7 +472,7 @@ function GetTransaction(req, res) {
function GetBalance(req, res) {
if (!serving)
res.status(INVALID.e_code).send(INVALID_SERVER_MSG);
res.status(INVALID.e_code).send(INCORRECT_SERVER_ERROR.toString());
else {
let floID = req.query.floID || req.query.addr,
token = req.query.token || req.query.asset;
@ -468,10 +480,10 @@ function GetBalance(req, res) {
.then(result => res.send(result))
.catch(error => {
if (error instanceof INVALID)
res.status(INVALID.e_code).send(error.message);
res.status(INVALID.e_code).send(error.toString());
else {
console.error(error);
res.status(INTERNAL.e_code).send("Unable to process! Try again later!");
res.status(INTERNAL.e_code).send(INTERNAL.str("Unable to process! Try again later!"));
}
});
}