Last active
January 19, 2020 12:42
-
-
Save dumebi/291bda845eda79866723d225af66bc86 to your computer and use it in GitHub Desktop.
Functions for a Token Exchange
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const HttpStatus = require('http-status-codes'); | |
const TokenModel = require('../models/token'); | |
const UserModel = require('../models/user'); | |
const UserTokenModel = require('../models/user-token'); | |
const OHLVCModel = require('../models/ohlvc'); | |
const TransactionModel = require('../models/transaction'); | |
const { | |
paramsNotValid, generateTransactionReference, handleError, handleSuccess | |
} = require('../utils/utils'); | |
const { | |
createToken, | |
getTokenBalance, | |
getToken, | |
getTokenContract, | |
getBuyOrderBook, | |
getSellOrderBook, | |
sellToken, | |
buyToken, | |
cancelOrder, | |
transferToken | |
} = require('../libraries/blockchainLib.js'); | |
const publisher = require('../utils/rabbitmq'); | |
const TokenController = { | |
/** | |
* Initialize token | |
* @description initialize a token | |
* @return {object} token | |
*/ | |
async init(req, res) { | |
try { | |
const token = await TokenModel.findOne({ $or: [{ name: req.body.name }, { symbol: req.body.symbol }] }); | |
if (token) { | |
return handleError(res, HttpStatus.BAD_REQUEST, 'Token already exists', null) | |
} | |
const reference = generateTransactionReference(7) | |
const newtoken = { | |
symbol: `${req.body.symbol}`, | |
id: reference, | |
name: `${req.body.name}`, | |
supply: parseInt(req.body.supply, 10), | |
rate: parseInt(req.body.rate, 10), | |
currency: 'BA', | |
creator: req.jwtUser.address | |
} | |
const result = await createToken(newtoken); | |
console.log('user address: %o', req.jwtUser.address) | |
if (!result.tx) return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'Error creating token in blockchain', null) | |
// Get token contract | |
const address = await getTokenContract(req.body.symbol); | |
console.log(address) | |
let mongoToken = new TokenModel({ | |
reference, | |
name: req.body.name, | |
image: req.body.image, | |
symbol: req.body.symbol, | |
price: Number(req.body.rate), | |
supply: Number(req.body.supply), | |
contract: address, | |
creator: req.jwtUser._id, | |
}) | |
mongoToken = await mongoToken.save(); | |
mongoToken = await mongoToken.populate('creator').execPopulate() | |
await Promise.all([ | |
TokenController.updateTokenTransactionDetails(req, mongoToken), | |
TransactionModel.create({ | |
user: req.jwtUser._id, | |
token: token._id, | |
type: TransactionModel.Type.CREATE, | |
status: TransactionModel.Status.COMPLETED | |
}) | |
]) | |
return handleSuccess(res, HttpStatus.OK, mongoToken, 'Token created successfully'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured creating token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* OHLVC | |
* @description get OHLVC details of a token | |
* @return {object} token | |
*/ | |
async ohlvc(req, res) { | |
try { | |
const ohlvc = await OHLVCModel.find({ token: req.params.id }); | |
return handleSuccess(res, HttpStatus.OK, ohlvc, 'ohlvc details gotten successfully'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting OHLVC, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Get token | |
* @description Get a token on the BA platform | |
* @return {object} token | |
*/ | |
async one(req, res) { | |
try { | |
const token = await TokenModel.findById(req.params.id, { min: 0, max: 0 }); | |
if (token) { | |
return handleSuccess(res, HttpStatus.OK, token, 'Token gotten successfully'); | |
} | |
return handleError(res, HttpStatus.NOT_FOUND, 'Token not found', null) | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Get token by symbol | |
* @description Get a token on the BA platform | |
* @return {object} token | |
*/ | |
async token_by_symbol(req, res) { | |
try { | |
// console.log('The sent symbol: ', `${req.params.symbol}`); | |
const token = await getToken(req.params.symbol); | |
if (token) { | |
return handleSuccess(res, HttpStatus.OK, token, 'Token gotten successfully'); | |
} | |
return handleError(res, HttpStatus.NOT_FOUND, 'Token not found', null) | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Get token balance by symbol | |
* @description Get user token balance on the BA platform | |
* @return {object} token | |
*/ | |
async token_balance(req, res) { | |
try { | |
const balance = await getTokenBalance(req.params.symbol, req.jwtUser.address); | |
return handleSuccess(res, HttpStatus.OK, balance, 'Token gotten successfully'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Get tokens | |
* @description Get all tokens on the BA platform | |
* @return {Array(Object)} tokens | |
*/ | |
async all(req, res) { | |
try { | |
const tokens = await TokenModel.find().populate('creator'); | |
if (tokens) { | |
return handleSuccess(res, HttpStatus.OK, tokens, 'tokens gotten successfully'); | |
} | |
return res.status(HttpStatus.NOT_FOUND).json({ status: 'success', message: 'Token has not been initialized' }); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Get tokens | |
* @description Get all tokens on the BA platform | |
* @return {Array(Object)} tokens | |
*/ | |
async top(req, res) { | |
try { | |
const tokens = await TokenModel.find({}).sort({ vol: -1, price: -1 }); | |
if (tokens) { | |
return handleSuccess(res, HttpStatus.OK, tokens, 'tokens gotten successfully'); | |
} | |
return res.status(HttpStatus.NOT_FOUND).json({ status: 'success', message: 'Token has not been initialized' }); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Get user tokens | |
* @description Get user tokens on the BA platform | |
* @return {Array(Object)} tokens | |
*/ | |
async user(req, res) { | |
try { | |
const user_tokens = await TokenModel.find({ creator: req.jwtUser._id }).populate('token').populate('creator'); | |
let balances = user_tokens.map(user_token => getTokenBalance(user_token.symbol, req.jwtUser.address)) | |
balances = Promise.all(balances) | |
user_tokens.balances = balances | |
return handleSuccess(res, HttpStatus.OK, user_tokens, 'User tokens gotten successfully') | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token, please contact an administrator', error) | |
} | |
}, | |
/** | |
* ORDER BOOK - BID ORDERS | |
* @description Get Buy Order book for token | |
* @return {object} buy book | |
*/ | |
async buyOrderBook(req, res) { | |
try { | |
const token = await TokenModel.findById(req.params.id); | |
// console.log('This is the token', token); | |
if (token) { | |
const buybook = await getBuyOrderBook(token.symbol); | |
console.log('This is the orderbook', buybook); | |
console.log('This is the type of', token.symbol); | |
return handleSuccess(res, HttpStatus.OK, buybook, 'Token buy book gotten successfully'); | |
} | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token buy-book, please contact an administrator', error) | |
} | |
}, | |
/** | |
* ORDER BOOK - ASK ORDERS | |
* @description Get Sell Order book for token | |
* @return {object} sell book | |
*/ | |
async sellOrderBook(req, res) { | |
try { | |
const token = await TokenModel.findById(req.params.id); | |
if (token) { | |
const sellbook = await getSellOrderBook(token.symbol) | |
return handleSuccess(res, HttpStatus.OK, sellbook, 'Token sell book gotten successfully'); | |
} | |
return handleError(res, HttpStatus.NOT_FOUND, 'Token not found', null) | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting token sell-book, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Buy Token | |
* @description Buy a token | |
* @param {string} token Token ID | |
*/ | |
async buy(req, res) { | |
try { | |
const user = req.jwtUser | |
const token = await TokenModel.findById(req.params.id); | |
if (!token) return handleError(res, HttpStatus.NOT_FOUND, 'Token not found', null) | |
const price = Number(req.body.price); | |
const amount = Number(req.body.amount); | |
const bought = await buyToken(token.symbol, price, amount, user.address); | |
await Promise.all([ | |
TokenController.updateTokenTransactionDetails(req, token), | |
TokenModel.findByIdAndUpdate(token._id, { | |
price, vol: token.vol + amount, high: Math.max(token.high, price), min: Math.min(token.low, price) | |
}, { new: true }), | |
TransactionModel.create({ | |
user: req.jwtUser._id, | |
token: token._id, | |
type: TransactionModel.Type.BUY, | |
status: TransactionModel.Status.PENDING | |
}) | |
]); | |
return handleSuccess(res, HttpStatus.OK, bought, 'Your buy order has been processed'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured processing your buy order, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Sell Token | |
* @description Sell a token | |
* @param {string} token Token ID | |
*/ | |
async sell(req, res) { | |
try { | |
const user = req.jwtUser | |
const token = await TokenModel.findById(req.params.id); | |
if (!token) return handleError(res, HttpStatus.NOT_FOUND, 'Token not found', null) | |
const price = Number(req.body.price); | |
const amount = Number(req.body.amount); | |
console.log(price, amount) | |
const sold = await sellToken(token.symbol, price, amount, user.address); | |
console.log(sold.logs) | |
await Promise.all([ | |
TokenController.updateTokenTransactionDetails(req, token), | |
TokenModel.findByIdAndUpdate(token._id, { | |
price, vol: token.vol + amount, high: Math.max(token.high, price), min: Math.min(token.low, price) | |
}, { new: true }), | |
TransactionModel.create({ | |
user: req.jwtUser._id, | |
token: token._id, | |
type: TransactionModel.Type.SELL, | |
status: TransactionModel.Status.PENDING | |
}) | |
]); | |
return handleSuccess(res, HttpStatus.OK, sold, 'Your sell order has been processed'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured processing your sell order, please contact an administrator', error) | |
} | |
}, | |
/** | |
* Cancel Offer | |
* @description Cancel a buy or sell offer | |
* @param {string} id Offer ID | |
*/ | |
async cancel(req, res) { | |
try { | |
const user = req.jwtUser | |
const token = await TokenModel.findById(req.params.id); | |
if (!token) return handleError(res, HttpStatus.NOT_FOUND, 'Token not found', null) | |
const price = req.body.price; | |
const key = req.body.key; | |
const type = req.body.type === 'sell' | |
const canceled = await cancelOrder(token.symbol, type, price, key, user.address); | |
console.log('canceled: o%', canceled) | |
return handleSuccess(res, HttpStatus.OK, null, 'Your cancel order is being processed'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured processing your sell order, please contact an administrator', error) | |
} | |
}, | |
/** | |
* User Transactions | |
* @description Get all transactions made by a user on the platform | |
* @param {string} id Token ID | |
*/ | |
async user_transactions(req, res) { | |
try { | |
const pageQuery = parseInt(req.query.page, 10) || 1; | |
const options = { | |
page: pageQuery, | |
populate: ['user', 'token', 'wallet'], | |
sort: '-createdAt', | |
limit: req.query.limit || 20, | |
collation: { | |
locale: 'en' | |
} | |
}; | |
const transactions = await TransactionModel.paginate({ user: req.jwtUser._id }, options); | |
const data = { | |
page: transactions.page, | |
pages: transactions.totalPages, | |
count: transactions.totalDocs, | |
transactions: transactions.docs | |
}; | |
// const transactions = await TransactionModel.find({ user: req.jwtUser._id }).populate('token').populate('wallet').sort('-createdAt'); | |
return handleSuccess(res, HttpStatus.OK, data, 'User transactions gotten successfully'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting user transactions, please contact an administrator', error) | |
} | |
}, | |
/** | |
* All Transactions | |
* @description Get all transactions made on the platform | |
*/ | |
async transactions(req, res) { | |
try { | |
const pageQuery = parseInt(req.query.page, 10) || 1; | |
const options = { | |
page: pageQuery, | |
populate: ['user', 'token', 'wallet'], | |
sort: '-createdAt', | |
limit: req.query.limit || 20, | |
collation: { | |
locale: 'en' | |
} | |
}; | |
const transactions = await TransactionModel.paginate({}, options); | |
const data = { | |
page: transactions.page, | |
pages: transactions.totalPages, | |
count: transactions.totalDocs, | |
transactions: transactions.docs | |
}; | |
// const transactions = await TransactionModel.find().populate('user').populate('token').populate('wallet').sort('-createdAt'); | |
return handleSuccess(res, HttpStatus.OK, data, 'Transactions gotten successfully'); | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting all transactions, please contact an administrator', error) | |
} | |
}, | |
async updateTokenTransactionDetails(req, token) { | |
const [user_token] = await Promise.all([ | |
UserTokenModel.find({ user: req.jwtUser._id, token: token._id }) | |
]); | |
if (!user_token) { | |
const _user_token = new UserTokenModel({ | |
user: req.jwtUser._id, | |
token: token._id | |
}) | |
await _user_token.save() | |
} | |
}, | |
async transferTokens(req, res) { | |
try { | |
const symbol = req.body.symbol; | |
const amount = req.body.amount; | |
const from = req.body.from; | |
const to = req.body.to; | |
console.log('token ba balance before transfer: ', await getTokenBalance('BA', to)); | |
const result = await transferToken(symbol, amount, to, from); | |
console.log('token ba balance after transfer: ', await getTokenBalance('BA', to)); | |
console.log(result); | |
return result | |
} catch (error) { | |
return handleError(res, HttpStatus.INTERNAL_SERVER_ERROR, 'An error occured getting while transferring tokens', error) | |
} | |
} | |
}; | |
module.exports = TokenController; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment