Convert fund management
- Added Withdrawal of convert fund - Convert fund is moved to a different table (ConvertFund) - Added APIs for withdraw fund - Changed add-convert-fund to deposit-convert-fund - Fixed minor bugs
This commit is contained in:
parent
970b4547cb
commit
0381c44733
@ -1314,7 +1314,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeAPI.addConvertFundCurrency = function (amount, floID, sinkID, privKey) {
|
exchangeAPI.depositConvertFundCurrency = function (amount, floID, sinkID, privKey) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.verifyPrivKey(privKey, floID))
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
|
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
|
||||||
@ -1328,14 +1328,14 @@
|
|||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
};
|
};
|
||||||
request.sign = signRequest({
|
request.sign = signRequest({
|
||||||
type: "add_convert_currency_fund",
|
type: "deposit_convert_currency_fund",
|
||||||
coin: request.coin,
|
coin: request.coin,
|
||||||
txid: txid,
|
txid: txid,
|
||||||
timestamp: request.timestamp
|
timestamp: request.timestamp
|
||||||
}, privKey);
|
}, privKey);
|
||||||
console.debug(request);
|
console.debug(request);
|
||||||
|
|
||||||
fetch_api('/add-convert-currency-fund', {
|
fetch_api('/deposit-convert-currency-fund', {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -1350,7 +1350,7 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
exchangeAPI.addConvertFundBTC = function (quantity, floID, sinkID, privKey) {
|
exchangeAPI.depositConvertFundBTC = function (quantity, floID, sinkID, privKey) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.verifyPrivKey(privKey, floID))
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
|
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
|
||||||
@ -1366,14 +1366,14 @@
|
|||||||
timestamp: Date.now()
|
timestamp: Date.now()
|
||||||
};
|
};
|
||||||
request.sign = signRequest({
|
request.sign = signRequest({
|
||||||
type: "add_convert_coin_fund",
|
type: "deposit_convert_coin_fund",
|
||||||
coin: request.coin,
|
coin: request.coin,
|
||||||
txid: data.txid,
|
txid: data.txid,
|
||||||
timestamp: request.timestamp
|
timestamp: request.timestamp
|
||||||
}, proxySecret || privKey);
|
}, proxySecret || privKey);
|
||||||
console.debug(request);
|
console.debug(request);
|
||||||
|
|
||||||
fetch_api('/add-convert-coin-fund', {
|
fetch_api('/deposit-convert-coin-fund', {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
@ -1388,6 +1388,74 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exchangeAPI.withdrawConvertFundCurrency = function (amount, floID, privKey) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
|
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
|
||||||
|
if (floID !== floGlobals.adminID)
|
||||||
|
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Access Denied", errorCode.ACCESS_DENIED));
|
||||||
|
let request = {
|
||||||
|
floID: floID,
|
||||||
|
amount: amount,
|
||||||
|
coin: "BTC",
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
request.sign = signRequest({
|
||||||
|
type: "withdraw_convert_currency_fund",
|
||||||
|
coin: request.coin,
|
||||||
|
amount: amount,
|
||||||
|
timestamp: request.timestamp
|
||||||
|
}, privKey);
|
||||||
|
console.debug(request);
|
||||||
|
|
||||||
|
fetch_api('/withdraw-convert-currency-fund', {
|
||||||
|
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))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
exchangeAPI.withdrawConvertFundCurrency = function (quantity, floID, privKey) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
|
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Invalid Private Key", errorCode.INVALID_PRIVATE_KEY));
|
||||||
|
if (floID !== floGlobals.adminID)
|
||||||
|
return reject(ExchangeError(ExchangeError.BAD_REQUEST_CODE, "Access Denied", errorCode.ACCESS_DENIED));
|
||||||
|
let request = {
|
||||||
|
floID: floID,
|
||||||
|
quantity: quantity,
|
||||||
|
coin: "BTC",
|
||||||
|
timestamp: Date.now()
|
||||||
|
};
|
||||||
|
request.sign = signRequest({
|
||||||
|
type: "withdraw_convert_coin_fund",
|
||||||
|
coin: request.coin,
|
||||||
|
quantity: quantity,
|
||||||
|
timestamp: request.timestamp
|
||||||
|
}, privKey);
|
||||||
|
console.debug(request);
|
||||||
|
|
||||||
|
fetch_api('/withdraw-convert-coin-fund', {
|
||||||
|
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))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
exchangeAPI.closeBlockchainBond = function (bond_id, floID, privKey) {
|
exchangeAPI.closeBlockchainBond = function (bond_id, floID, privKey) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!floCrypto.verifyPrivKey(privKey, floID))
|
if (!floCrypto.verifyPrivKey(privKey, floID))
|
||||||
|
|||||||
@ -88,8 +88,10 @@ module.exports = function App(secret, DB) {
|
|||||||
//convert from or to coin
|
//convert from or to coin
|
||||||
app.post('/convert-to', Request.ConvertTo);
|
app.post('/convert-to', Request.ConvertTo);
|
||||||
app.post('/convert-from', Request.ConvertFrom);
|
app.post('/convert-from', Request.ConvertFrom);
|
||||||
app.post('/add-convert-coin-fund', Request.AddConvertCoinFund);
|
app.post('/deposit-convert-coin-fund', Request.DepositConvertCoinFund);
|
||||||
app.post('/add-convert-currency-fund', Request.AddConvertCurrencyFund);
|
app.post('/deposit-convert-currency-fund', Request.DepositConvertCurrencyFund);
|
||||||
|
app.post('/withdraw-convert-coin-fund', Request.WithdrawConvertCoinFund);
|
||||||
|
app.post('/withdraw-convert-currency-fund', Request.WithdrawConvertCurrencyFund);
|
||||||
|
|
||||||
//close blockchain-bond
|
//close blockchain-bond
|
||||||
app.post('/close-blockchain-bonds', Request.CloseBlockchainBond);
|
app.post('/close-blockchain-bonds', Request.CloseBlockchainBond);
|
||||||
|
|||||||
@ -222,7 +222,7 @@ verifyTx.BTC = function (sender, txid) {
|
|||||||
function verifyConvert() {
|
function verifyConvert() {
|
||||||
DB.query("SELECT id, floID, mode, in_txid, amount, quantity FROM DirectConvert WHERE status=? AND coin=?", ["PENDING", "BTC"]).then(results => {
|
DB.query("SELECT id, floID, mode, in_txid, amount, quantity FROM DirectConvert WHERE status=? AND coin=?", ["PENDING", "BTC"]).then(results => {
|
||||||
results.forEach(r => {
|
results.forEach(r => {
|
||||||
if (mode == _sql.CONVERT_MODE_GET) {
|
if (r.mode == _sql.CONVERT_MODE_GET) {
|
||||||
verifyTx.token(r.floID, r.in_txid, true).then(({ amount }) => {
|
verifyTx.token(r.floID, r.in_txid, true).then(({ amount }) => {
|
||||||
if (r.amount !== amount)
|
if (r.amount !== amount)
|
||||||
throw ([true, "Transaction amount mismatched in blockchain"]);
|
throw ([true, "Transaction amount mismatched in blockchain"]);
|
||||||
@ -235,7 +235,7 @@ function verifyConvert() {
|
|||||||
DB.query("UPDATE DirectConvert SET status=? WHERE id=?", ["REJECTED", r.id])
|
DB.query("UPDATE DirectConvert SET status=? WHERE id=?", ["REJECTED", r.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
});
|
});
|
||||||
} else if (mode == _sql.CONVERT_MODE_PUT) {
|
} else if (r.mode == _sql.CONVERT_MODE_PUT) {
|
||||||
verifyTx.BTC(r.floID, r.in_txid).then(quantity => {
|
verifyTx.BTC(r.floID, r.in_txid).then(quantity => {
|
||||||
if (r.quantity !== quantity)
|
if (r.quantity !== quantity)
|
||||||
throw ([true, "Transaction quantity mismatched in blockchain"]);
|
throw ([true, "Transaction quantity mismatched in blockchain"]);
|
||||||
@ -256,9 +256,9 @@ function verifyConvert() {
|
|||||||
function retryConvert() {
|
function retryConvert() {
|
||||||
DB.query("SELECT id, floID, mode, amount, quantity FROM DirectConvert WHERE status=? AND coin=?", ["PROCESSING", "BTC"]).then(results => {
|
DB.query("SELECT id, floID, mode, amount, quantity FROM DirectConvert WHERE status=? AND coin=?", ["PROCESSING", "BTC"]).then(results => {
|
||||||
results.forEach(r => {
|
results.forEach(r => {
|
||||||
if (mode == _sql.CONVERT_MODE_GET)
|
if (r.mode == _sql.CONVERT_MODE_GET)
|
||||||
blockchain.convertToCoin.retry(r.floID, "BTC", r.quantity, r.id);
|
blockchain.convertToCoin.retry(r.floID, "BTC", r.quantity, r.id);
|
||||||
else if (mode == _sql.CONVERT_MODE_PUT)
|
else if (r.mode == _sql.CONVERT_MODE_PUT)
|
||||||
blockchain.convertFromCoin.retry(r.floID, r.amount, r.id)
|
blockchain.convertFromCoin.retry(r.floID, r.amount, r.id)
|
||||||
})
|
})
|
||||||
}).catch(error => console.error(error))
|
}).catch(error => console.error(error))
|
||||||
@ -267,7 +267,7 @@ function retryConvert() {
|
|||||||
function confirmConvert() {
|
function confirmConvert() {
|
||||||
DB.query("SELECT id, floID, mode, amount, quantity, out_txid FROM DirectConvert WHERE status=? AND coin=?", ["WAITING_CONFIRMATION", "BTC"]).then(results => {
|
DB.query("SELECT id, floID, mode, amount, quantity, out_txid FROM DirectConvert WHERE status=? AND coin=?", ["WAITING_CONFIRMATION", "BTC"]).then(results => {
|
||||||
results.forEach(r => {
|
results.forEach(r => {
|
||||||
if (mode == _sql.CONVERT_MODE_GET)
|
if (r.mode == _sql.CONVERT_MODE_GET)
|
||||||
btcOperator.getTx(r.out_txid).then(tx => {
|
btcOperator.getTx(r.out_txid).then(tx => {
|
||||||
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||||
return;
|
return;
|
||||||
@ -275,7 +275,7 @@ function confirmConvert() {
|
|||||||
.then(result => console.debug(`${r.floID} converted ${amount} to ${r.quantity} BTC`))
|
.then(result => console.debug(`${r.floID} converted ${amount} to ${r.quantity} BTC`))
|
||||||
.catch(error => console.error(error))
|
.catch(error => console.error(error))
|
||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
else if (mode == _sql.CONVERT_MODE_PUT)
|
else if (r.mode == _sql.CONVERT_MODE_PUT)
|
||||||
floTokenAPI.getTx(r.out_txid).then(tx => {
|
floTokenAPI.getTx(r.out_txid).then(tx => {
|
||||||
if (!tx.transactionDetails.blockheight || !tx.transactionDetails.confirmations) //Still not confirmed
|
if (!tx.transactionDetails.blockheight || !tx.transactionDetails.confirmations) //Still not confirmed
|
||||||
return;
|
return;
|
||||||
@ -287,27 +287,27 @@ function confirmConvert() {
|
|||||||
}).catch(error => console.error(error));
|
}).catch(error => console.error(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
function convert_depositFund() {
|
function verifyConvertFundDeposit() {
|
||||||
DB.query("SELECT id, floID, mode, in_txid FROM DirectConvert WHERE status=? AND coin=?", ["DEPOSIT_PENDING", "BTC"]).then(results => {
|
DB.query("SELECT id, floID, mode, txid FROM ConvertFund WHERE status=? AND coin=?", ["PROCESSING", "BTC"]).then(results => {
|
||||||
results.forEach(r => {
|
results.forEach(r => {
|
||||||
if (mode == _sql.CONVERT_MODE_GET) {
|
if (r.mode == _sql.CONVERT_MODE_GET) { //deposit currency
|
||||||
verifyTx.token(r.floID, r.in_txid, true).then(({ amount }) => {
|
verifyTx.token(r.floID, r.txid, true).then(({ amount }) => {
|
||||||
DB.query("UPDATE DirectConvert SET status=?, amount=? WHERE id=?", ["DEPOSIT_SUCCESS", amount, r.id])
|
DB.query("UPDATE ConvertFund SET status=?, amount=? WHERE id=?", ["SUCCESS", amount, r.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (error[0])
|
if (error[0])
|
||||||
DB.query("UPDATE DirectConvert SET status=? WHERE id=?", ["REJECTED", r.id])
|
DB.query("UPDATE ConvertFund SET status=? WHERE id=?", ["REJECTED", r.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
});
|
});
|
||||||
} else if (mode == _sql.CONVERT_MODE_PUT) {
|
} else if (r.mode == _sql.CONVERT_MODE_PUT) {//deposit coin
|
||||||
verifyTx.BTC(r.floID, r.in_txid).then(quantity => {
|
verifyTx.BTC(r.floID, r.txid).then(quantity => {
|
||||||
DB.query("UPDATE DirectConvert SET status=?, quantity=? WHERE id=?", ["DEPOSIT_SUCCESS", quantity, r.id])
|
DB.query("UPDATE ConvertFund SET status=?, quantity=? WHERE id=?", ["SUCCESS", quantity, r.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
if (error[0])
|
if (error[0])
|
||||||
DB.query("UPDATE DirectConvert SET status=? WHERE id=?", ["REJECTED", r.id])
|
DB.query("UPDATE ConvertFund SET status=? WHERE id=?", ["REJECTED", r.id])
|
||||||
.then(_ => null).catch(error => console.error(error));
|
.then(_ => null).catch(error => console.error(error));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -315,6 +315,41 @@ function convert_depositFund() {
|
|||||||
}).catch(error => console.error(error))
|
}).catch(error => console.error(error))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function retryConvertFundWithdraw() {
|
||||||
|
DB.query("SELECT id, mode, coin, quantity, amount FROM ConvertFund WHERE status=? AND coin=?", ["PENDING", "BTC"]).then(results => {
|
||||||
|
results.forEach(r => {
|
||||||
|
if (r.mode == _sql.CONVERT_MODE_GET) //withdraw coin
|
||||||
|
blockchain.convertFundWithdraw.retry(r.coin, r.quantity, r.id);
|
||||||
|
else if (r.mode == _sql.CONVERT_MODE_PUT) //withdraw currency
|
||||||
|
blockchain.convertFundWithdraw.retry(floGlobals.currency, r.amount, r.id);
|
||||||
|
})
|
||||||
|
}).catch(error => console.error(error))
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmConvertFundWithdraw() {
|
||||||
|
DB.query("SELECT * FROM ConvertFund WHERE status=? AND coin=?", ["WAITING_CONFIRMATION", "BTC"]).then(results => {
|
||||||
|
results.forEach(r => {
|
||||||
|
if (r.mode == _sql.CONVERT_MODE_GET) { //withdraw coin
|
||||||
|
btcOperator.getTx(r.txid).then(tx => {
|
||||||
|
if (!tx.blockhash || !tx.confirmations) //Still not confirmed
|
||||||
|
return;
|
||||||
|
DB.query("UPDATE ConvertFund SET status=? WHERE id=?", ["SUCCESS", r.id])
|
||||||
|
.then(result => console.debug(`Withdraw-fund ${r.quantity} ${r.coin} successful`))
|
||||||
|
.catch(error => console.error(error))
|
||||||
|
}).catch(error => console.error(error));
|
||||||
|
} else if (r.mode == _sql.CONVERT_MODE_PUT) {//withdraw currency
|
||||||
|
floTokenAPI.getTx(r.txid).then(tx => {
|
||||||
|
if (!tx.transactionDetails.blockheight || !tx.transactionDetails.confirmations) //Still not confirmed
|
||||||
|
return;
|
||||||
|
DB.query("UPDATE ConvertFund SET status=? WHERE id=?", ["SUCCESS", r.id])
|
||||||
|
.then(result => console.debug(`Withdraw-fund ${r.amount} ${floGlobals.currency} successful`))
|
||||||
|
.catch(error => console.error(error));
|
||||||
|
}).catch(error => console.error(error));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(error => console.error(error))
|
||||||
|
}
|
||||||
|
|
||||||
function verifyRefund() {
|
function verifyRefund() {
|
||||||
DB.query("SELECT id, floID, in_txid FROM RefundTransact WHERE status=?", ["PENDING"]).then(results => {
|
DB.query("SELECT id, floID, in_txid FROM RefundTransact WHERE status=?", ["PENDING"]).then(results => {
|
||||||
verifyTx.token(r.floID, r.in_txid, true)
|
verifyTx.token(r.floID, r.in_txid, true)
|
||||||
@ -395,6 +430,7 @@ function confirmFundClosing() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function processAll() {
|
function processAll() {
|
||||||
|
//deposit-withdraw asset balance
|
||||||
confirmDepositFLO();
|
confirmDepositFLO();
|
||||||
confirmDepositToken();
|
confirmDepositToken();
|
||||||
retryWithdrawalCoin();
|
retryWithdrawalCoin();
|
||||||
@ -402,14 +438,20 @@ function processAll() {
|
|||||||
confirmWithdrawalFLO();
|
confirmWithdrawalFLO();
|
||||||
confirmWithdrawalBTC();
|
confirmWithdrawalBTC();
|
||||||
confirmWithdrawalToken();
|
confirmWithdrawalToken();
|
||||||
|
//convert service
|
||||||
verifyConvert();
|
verifyConvert();
|
||||||
retryConvert();
|
retryConvert();
|
||||||
confirmConvert();
|
confirmConvert();
|
||||||
convert_depositFund();
|
verifyConvertFundDeposit();
|
||||||
|
retryConvertFundWithdraw();
|
||||||
|
confirmConvertFundWithdraw();
|
||||||
|
//blockchain-bond service
|
||||||
retryBondClosing();
|
retryBondClosing();
|
||||||
confirmBondClosing();
|
confirmBondClosing();
|
||||||
|
//bob's fund service
|
||||||
retryFundClosing();
|
retryFundClosing();
|
||||||
confirmFundClosing();
|
confirmFundClosing();
|
||||||
|
//refund transactions
|
||||||
verifyRefund();
|
verifyRefund();
|
||||||
retryRefund();
|
retryRefund();
|
||||||
confirmRefund();
|
confirmRefund();
|
||||||
|
|||||||
@ -7,6 +7,7 @@ var DB; //container for database
|
|||||||
const TYPE_TOKEN = "TOKEN",
|
const TYPE_TOKEN = "TOKEN",
|
||||||
TYPE_COIN = "COIN",
|
TYPE_COIN = "COIN",
|
||||||
TYPE_CONVERT = "CONVERT",
|
TYPE_CONVERT = "CONVERT",
|
||||||
|
TYPE_CONVERT_POOL = "CONVERT_POOL",
|
||||||
TYPE_REFUND = "REFUND",
|
TYPE_REFUND = "REFUND",
|
||||||
TYPE_BOND = "BOND",
|
TYPE_BOND = "BOND",
|
||||||
TYPE_FUND = "BOB-FUND";
|
TYPE_FUND = "BOB-FUND";
|
||||||
@ -17,6 +18,7 @@ const balance_locked = {},
|
|||||||
[TYPE_COIN]: {},
|
[TYPE_COIN]: {},
|
||||||
[TYPE_TOKEN]: {},
|
[TYPE_TOKEN]: {},
|
||||||
[TYPE_CONVERT]: {},
|
[TYPE_CONVERT]: {},
|
||||||
|
[TYPE_CONVERT_POOL]: {},
|
||||||
[TYPE_REFUND]: {},
|
[TYPE_REFUND]: {},
|
||||||
[TYPE_BOND]: {},
|
[TYPE_BOND]: {},
|
||||||
[TYPE_FUND]: {}
|
[TYPE_FUND]: {}
|
||||||
@ -65,6 +67,7 @@ const WITHDRAWAL_MESSAGE = {
|
|||||||
[TYPE_COIN]: "(withdrawal from market)",
|
[TYPE_COIN]: "(withdrawal from market)",
|
||||||
[TYPE_TOKEN]: "(withdrawal from market)",
|
[TYPE_TOKEN]: "(withdrawal from market)",
|
||||||
[TYPE_CONVERT]: "(convert coin)",
|
[TYPE_CONVERT]: "(convert coin)",
|
||||||
|
[TYPE_CONVERT_POOL]: "(convert fund)",
|
||||||
[TYPE_REFUND]: "(refund from market)",
|
[TYPE_REFUND]: "(refund from market)",
|
||||||
[TYPE_BOND]: "(bond closing)",
|
[TYPE_BOND]: "(bond closing)",
|
||||||
[TYPE_FUND]: "(fund investment closing)"
|
[TYPE_FUND]: "(fund investment closing)"
|
||||||
@ -87,6 +90,7 @@ const updateSyntax = {
|
|||||||
[TYPE_COIN]: "UPDATE WithdrawCoin SET status=?, txid=? WHERE id=?",
|
[TYPE_COIN]: "UPDATE WithdrawCoin SET status=?, txid=? WHERE id=?",
|
||||||
[TYPE_TOKEN]: "UPDATE WithdrawToken SET status=?, txid=? WHERE id=?",
|
[TYPE_TOKEN]: "UPDATE WithdrawToken SET status=?, txid=? WHERE id=?",
|
||||||
[TYPE_CONVERT]: "UPDATE DirectConvert SET status=?, out_txid=? WHERE id=?",
|
[TYPE_CONVERT]: "UPDATE DirectConvert SET status=?, out_txid=? WHERE id=?",
|
||||||
|
[TYPE_CONVERT_POOL]: "UPDATE ConvertFund SET status=?, txid=? WHERE id=?",
|
||||||
[TYPE_REFUND]: "UPDATE RefundTransact SET status=?, out_txid=? WHERE id=?",
|
[TYPE_REFUND]: "UPDATE RefundTransact SET status=?, out_txid=? WHERE id=?",
|
||||||
[TYPE_BOND]: "UPDATE CloseBondTransact SET status=?, txid=? WHERE id=?",
|
[TYPE_BOND]: "UPDATE CloseBondTransact SET status=?, txid=? WHERE id=?",
|
||||||
[TYPE_FUND]: "UPDATE CloseFundTransact SET status=?, txid=? WHERE id=?"
|
[TYPE_FUND]: "UPDATE CloseFundTransact SET status=?, txid=? WHERE id=?"
|
||||||
@ -163,6 +167,12 @@ function convertFromCoin_retry(floID, currency_amount, id) {
|
|||||||
else sendAsset(floID, floGlobals.currency, currency_amount, TYPE_CONVERT, id);
|
else sendAsset(floID, floGlobals.currency, currency_amount, TYPE_CONVERT, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function convertFundWithdraw_retry(asset, amount, id) {
|
||||||
|
if (id in callbackCollection[TYPE_CONVERT_POOL])
|
||||||
|
console.debug("A callback is already pending for this Convert fund withdrawal");
|
||||||
|
else sendAsset(floGlobals.adminID, asset, amount, TYPE_CONVERT_POOL, id);
|
||||||
|
}
|
||||||
|
|
||||||
function bondTransact_retry(floID, amount, id) {
|
function bondTransact_retry(floID, amount, id) {
|
||||||
if (id in callbackCollection[TYPE_BOND])
|
if (id in callbackCollection[TYPE_BOND])
|
||||||
console.debug("A callback is already pending for this Bond closing");
|
console.debug("A callback is already pending for this Bond closing");
|
||||||
@ -213,6 +223,9 @@ module.exports = {
|
|||||||
init: convertFromCoin_init,
|
init: convertFromCoin_init,
|
||||||
retry: convertFromCoin_retry
|
retry: convertFromCoin_retry
|
||||||
},
|
},
|
||||||
|
convertFundWithdraw: {
|
||||||
|
retry: convertFundWithdraw_retry
|
||||||
|
},
|
||||||
bondTransact: {
|
bondTransact: {
|
||||||
retry: bondTransact_retry
|
retry: bondTransact_retry
|
||||||
},
|
},
|
||||||
|
|||||||
@ -326,32 +326,60 @@ function ConvertFrom(req, res) {
|
|||||||
}, () => conversion.convertFromCoin(data.floID, data.txid, data.tx_hex, data.coin, data.quantity));
|
}, () => conversion.convertFromCoin(data.floID, data.txid, data.tx_hex, data.coin, data.quantity));
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddConvertCoinFund(req, res) {
|
function DepositConvertCoinFund(req, res) {
|
||||||
let data = req.body;
|
let data = req.body;
|
||||||
if (data.floID !== floGlobals.adminID)
|
if (data.floID !== floGlobals.adminID)
|
||||||
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
||||||
else if (!data.pubKey)
|
else if (!data.pubKey)
|
||||||
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
|
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
|
||||||
else processRequest(res, data.floID, data.pubKey, data.sign, "Conversion Fund", {
|
else processRequest(res, data.floID, data.pubKey, data.sign, "Conversion Fund", {
|
||||||
type: "add_convert_coin_fund",
|
type: "deposit_convert_coin_fund",
|
||||||
coin: data.coin,
|
coin: data.coin,
|
||||||
txid: data.txid,
|
txid: data.txid,
|
||||||
timestamp: data.timestamp
|
timestamp: data.timestamp
|
||||||
}, () => conversion.addFund.coin(data.floID, data.txid, data.coin));
|
}, () => conversion.depositFund.coin(data.floID, data.txid, data.coin));
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddConvertCurrencyFund(req, res) {
|
function DepositConvertCurrencyFund(req, res) {
|
||||||
let data = req.body;
|
let data = req.body;
|
||||||
if (data.floID !== floGlobals.adminID)
|
if (data.floID !== floGlobals.adminID)
|
||||||
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
||||||
else if (!data.pubKey)
|
else if (!data.pubKey)
|
||||||
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
|
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
|
||||||
else processRequest(res, data.floID, data.pubKey, data.sign, "Conversion Fund", {
|
else processRequest(res, data.floID, data.pubKey, data.sign, "Conversion Fund", {
|
||||||
type: "add_convert_currency_fund",
|
type: "deposit_convert_currency_fund",
|
||||||
coin: data.coin,
|
coin: data.coin,
|
||||||
txid: data.txid,
|
txid: data.txid,
|
||||||
timestamp: data.timestamp
|
timestamp: data.timestamp
|
||||||
}, () => conversion.addFund.currency(data.floID, data.txid, data.coin));
|
}, () => conversion.depositFund.currency(data.floID, data.txid, data.coin));
|
||||||
|
}
|
||||||
|
|
||||||
|
function WithdrawConvertCoinFund(req, res) {
|
||||||
|
let data = req.body;
|
||||||
|
if (data.floID !== floGlobals.adminID)
|
||||||
|
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
||||||
|
else if (!data.pubKey)
|
||||||
|
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
|
||||||
|
else processRequest(res, data.floID, data.pubKey, data.sign, "Conversion Fund", {
|
||||||
|
type: "withdraw_convert_coin_fund",
|
||||||
|
coin: data.coin,
|
||||||
|
quantity: data.quantity,
|
||||||
|
timestamp: data.timestamp
|
||||||
|
}, () => conversion.withdrawFund.coin(data.floID, data.coin, data.quantity));
|
||||||
|
}
|
||||||
|
|
||||||
|
function WithdrawConvertCurrencyFund(req, res) {
|
||||||
|
let data = req.body;
|
||||||
|
if (data.floID !== floGlobals.adminID)
|
||||||
|
res.status(INVALID.e_code).send(INVALID.str(eCode.ACCESS_DENIED, "Access Denied"));
|
||||||
|
else if (!data.pubKey)
|
||||||
|
res.status(INVALID.e_code).send(INVALID.str(eCode.MISSING_PARAMETER, "Public key missing"));
|
||||||
|
else processRequest(res, data.floID, data.pubKey, data.sign, "Conversion Fund", {
|
||||||
|
type: "withdraw_convert_currency_fund",
|
||||||
|
coin: data.coin,
|
||||||
|
amount: data.amount,
|
||||||
|
timestamp: data.timestamp
|
||||||
|
}, () => conversion.withdrawFund.currency(data.floID, data.coin, data.amount));
|
||||||
}
|
}
|
||||||
|
|
||||||
function CloseBlockchainBond(req, res) {
|
function CloseBlockchainBond(req, res) {
|
||||||
@ -573,8 +601,10 @@ module.exports = {
|
|||||||
RemoveDistributor,
|
RemoveDistributor,
|
||||||
ConvertTo,
|
ConvertTo,
|
||||||
ConvertFrom,
|
ConvertFrom,
|
||||||
AddConvertCoinFund,
|
DepositConvertCoinFund,
|
||||||
AddConvertCurrencyFund,
|
DepositConvertCurrencyFund,
|
||||||
|
WithdrawConvertCoinFund,
|
||||||
|
WithdrawConvertCurrencyFund,
|
||||||
CloseBlockchainBond,
|
CloseBlockchainBond,
|
||||||
CloseBobsFund,
|
CloseBobsFund,
|
||||||
set trustedIDs(ids) {
|
set trustedIDs(ids) {
|
||||||
|
|||||||
@ -48,7 +48,11 @@ function checkPoolBalance(coin, req_value, mode) {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (!allowedConversion.includes(coin))
|
if (!allowedConversion.includes(coin))
|
||||||
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
||||||
DB.query("SELECT mode, SUM(quantity) AS coin_val, SUM(amount) AS cash_val FROM DirectConvert WHERE coin=? AND status NOT IN (?) GROUP BY mode", [coin, ["REJECTED", "REFUND"]]).then(result => {
|
let q = "SELECT mode, SUM(quantity) AS coin_val, SUM(amount) AS cash_val FROM (" +
|
||||||
|
"(SELECT amount, coin, quantity, mode, status FROM DirectConvert) UNION " +
|
||||||
|
"(SELECT amount, coin, quantity, mode, status FROM ConvertFund) " +
|
||||||
|
") WHERE coin=? AND status NOT IN (?) GROUP BY mode"
|
||||||
|
DB.query(q, [coin, ["REJECTED", "REFUND"]]).then(result => {
|
||||||
let coin_net = 0, cash_net = 0;
|
let coin_net = 0, cash_net = 0;
|
||||||
for (let r of result)
|
for (let r of result)
|
||||||
if (r.mode == _sql.CONVERT_MODE_GET) {
|
if (r.mode == _sql.CONVERT_MODE_GET) {
|
||||||
@ -130,38 +134,76 @@ function convertFromCoin(floID, txid, tx_hex, coin, quantity) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCurrencyFund(floID, txid, coin) {
|
function depositCurrencyFund(floID, txid, coin) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (floID !== floGlobals.adminID)
|
if (floID !== floGlobals.adminID)
|
||||||
return reject(INVALID(eCode.ACCESS_DENIED, 'Access Denied'));
|
return reject(INVALID(eCode.ACCESS_DENIED, 'Access Denied'));
|
||||||
else if (!allowedConversion.includes(coin))
|
else if (!allowedConversion.includes(coin))
|
||||||
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
||||||
DB.query("SELECT status FROM DirectConvert WHERE in_txid=? AND floID=? AND mode=?", [txid, floID, _sql.CONVERT_MODE_GET]).then(result => {
|
DB.query("SELECT status FROM ConvertFund WHERE txid=? AND mode=?", [txid, _sql.CONVERT_MODE_GET]).then(result => {
|
||||||
if (result.length)
|
if (result.length)
|
||||||
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already in process"));
|
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already in process"));
|
||||||
DB.query("INSERT INTO DirectConvert(floID, in_txid, mode, coin, status) VALUES (?)", [[floID, b_txid, _sql.CONVERT_MODE_GET, coin, "DEPOSIT_PENDING"]])
|
DB.query("INSERT INTO ConvertFund(txid, mode, coin, status) VALUES (?)", [[b_txid, _sql.CONVERT_MODE_GET, coin, "PROCESSING"]])
|
||||||
.then(result => resolve("Add currency fund in process"))
|
.then(result => resolve("Add currency fund in process"))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function addCoinFund(floID, txid, coin) {
|
function depositCoinFund(floID, txid, coin) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
if (floID !== floGlobals.adminID)
|
if (floID !== floGlobals.adminID)
|
||||||
return reject(INVALID(eCode.ACCESS_DENIED, 'Access Denied'));
|
return reject(INVALID(eCode.ACCESS_DENIED, 'Access Denied'));
|
||||||
else if (!allowedConversion.includes(coin))
|
else if (!allowedConversion.includes(coin))
|
||||||
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
||||||
DB.query("SELECT status FROM DirectConvert WHERE in_txid=? AND floID=? AND mode=?", [txid, floID, _sql.CONVERT_MODE_PUT]).then(result => {
|
DB.query("SELECT status FROM ConvertFund WHERE txid=? AND mode=?", [txid, _sql.CONVERT_MODE_PUT]).then(result => {
|
||||||
if (result.length)
|
if (result.length)
|
||||||
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already in process"));
|
return reject(INVALID(eCode.DUPLICATE_ENTRY, "Transaction already in process"));
|
||||||
DB.query("INSERT INTO DirectConvert(floID, in_txid, mode, coin, status) VALUES (?)", [[floID, b_txid, _sql.CONVERT_MODE_PUT, coin, "DEPOSIT_PENDING"]])
|
DB.query("INSERT INTO ConvertFund(txid, mode, coin, status) VALUES (?)", [[b_txid, _sql.CONVERT_MODE_PUT, coin, "PROCESSING"]])
|
||||||
.then(result => resolve("Add coin fund in process"))
|
.then(result => resolve("Add coin fund in process"))
|
||||||
.catch(error => reject(error))
|
.catch(error => reject(error))
|
||||||
}).catch(error => reject(error))
|
}).catch(error => reject(error))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function withdrawCurrencyFund(floID, coin, amount) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (floID !== floGlobals.adminID)
|
||||||
|
return reject(INVALID(eCode.ACCESS_DENIED, 'Access Denied'));
|
||||||
|
else if (!allowedConversion.includes(coin))
|
||||||
|
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
||||||
|
DB.query("SELECT SUM(amount) AS deposit_amount FROM ConvertFund WHERE mode=? AND status=?", [_sql.CONVERT_MODE_GET, "SUCCESS"]).then(r1 => {
|
||||||
|
DB.query("SELECT SUM(amount) AS withdraw_amount FROM ConvertFund WHERE mode=? AND status IN (?)", [_sql.CONVERT_MODE_PUT, ["SUCCESS", "PENDING", "WAITING_CONFIRMATION"]]).then(r2 => {
|
||||||
|
let available_amount = (r1[0].deposit_amount || 0) - (r2[0].withdraw_amount || 0);
|
||||||
|
if (available_amount < amount)
|
||||||
|
return reject(INVALID(eCode.INSUFFICIENT_BALANCE, "Insufficient convert-fund deposits to withdraw"));
|
||||||
|
DB.query("INSERT INTO ConvertFund(mode, coin, amount, status) VALUES (?)", [[_sql.CONVERT_MODE_PUT, coin, amount, "PENDING"]])
|
||||||
|
.then(result => resolve("Add currency fund in process"))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function withdrawCoinFund(floID, coin, quantity) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (floID !== floGlobals.adminID)
|
||||||
|
return reject(INVALID(eCode.ACCESS_DENIED, 'Access Denied'));
|
||||||
|
else if (!allowedConversion.includes(coin))
|
||||||
|
return reject(INVALID(eCode.INVALID_TOKEN_NAME, `Invalid coin (${coin})`));
|
||||||
|
DB.query("SELECT SUM(quantity) AS deposit_quantity FROM ConvertFund WHERE mode=? AND status=?", [_sql.CONVERT_MODE_PUT, "SUCCESS"]).then(r1 => {
|
||||||
|
DB.query("SELECT SUM(quantity) AS withdraw_quantity FROM ConvertFund WHERE mode=? AND status IN (?)", [_sql.CONVERT_MODE_GET, ["SUCCESS", "PENDING"]]).then(r2 => {
|
||||||
|
let available_quantity = (r1[0].deposit_quantity || 0) - (r2[0].withdraw_quantity || 0);
|
||||||
|
if (available_quantity < quantity)
|
||||||
|
return reject(INVALID(eCode.INSUFFICIENT_BALANCE, "Insufficient convert-fund deposits to withdraw"));
|
||||||
|
DB.query("INSERT INTO ConvertFund(mode, coin, quantity, status) VALUES (?)", [[_sql.CONVERT_MODE_GET, coin, quantity, "PENDING"]])
|
||||||
|
.then(result => resolve("Add currency fund in process"))
|
||||||
|
.catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
}).catch(error => reject(error))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getRate: {
|
getRate: {
|
||||||
BTC_USD,
|
BTC_USD,
|
||||||
@ -170,9 +212,13 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
convertToCoin,
|
convertToCoin,
|
||||||
convertFromCoin,
|
convertFromCoin,
|
||||||
addFund: {
|
depositFund: {
|
||||||
coin: addCoinFund,
|
coin: depositCoinFund,
|
||||||
currency: addCurrencyFund
|
currency: depositCurrencyFund
|
||||||
|
},
|
||||||
|
withdrawFund: {
|
||||||
|
coin: withdrawCoinFund,
|
||||||
|
currency: withdrawCurrencyFund
|
||||||
},
|
},
|
||||||
set DB(db) {
|
set DB(db) {
|
||||||
DB = db;
|
DB = db;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user