chore: server code formatting

This commit is contained in:
Rafael Taranto 2025-05-12 15:35:00 +01:00
parent aedabcbdee
commit 68517170e2
234 changed files with 9824 additions and 6195 deletions

View file

@ -10,12 +10,19 @@ const FIAT = ['EUR']
const DEFAULT_FIAT_MARKET = 'EUR'
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey', 'currencyMarket']
const loadConfig = (account) => {
const loadConfig = account => {
const mapper = {
'privateKey': 'secret'
privateKey: 'secret',
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(account)
return { ...mapped, timeout: 3000 }
}
module.exports = { loadConfig, DEFAULT_FIAT_MARKET, REQUIRED_CONFIG_FIELDS, CRYPTO, FIAT, ORDER_TYPE }
module.exports = {
loadConfig,
DEFAULT_FIAT_MARKET,
REQUIRED_CONFIG_FIELDS,
CRYPTO,
FIAT,
ORDER_TYPE,
}

View file

@ -10,12 +10,19 @@ const FIAT = ['USD']
const DEFAULT_FIAT_MARKET = 'USD'
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey', 'currencyMarket']
const loadConfig = (account) => {
const loadConfig = account => {
const mapper = {
'privateKey': 'secret'
privateKey: 'secret',
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(account)
return { ...mapped, timeout: 3000 }
}
module.exports = { loadConfig, DEFAULT_FIAT_MARKET, REQUIRED_CONFIG_FIELDS, CRYPTO, FIAT, ORDER_TYPE }
module.exports = {
loadConfig,
DEFAULT_FIAT_MARKET,
REQUIRED_CONFIG_FIELDS,
CRYPTO,
FIAT,
ORDER_TYPE,
}

View file

@ -11,12 +11,20 @@ const DEFAULT_FIAT_MARKET = 'EUR'
const AMOUNT_PRECISION = 8
const REQUIRED_CONFIG_FIELDS = ['key', 'secret']
const loadConfig = (account) => {
const loadConfig = account => {
const mapper = {
'key': 'apiKey',
key: 'apiKey',
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(account)
return { ...mapped, timeout: 3000 }
}
module.exports = { loadConfig, REQUIRED_CONFIG_FIELDS, DEFAULT_FIAT_MARKET, CRYPTO, FIAT, ORDER_TYPE, AMOUNT_PRECISION }
module.exports = {
loadConfig,
REQUIRED_CONFIG_FIELDS,
DEFAULT_FIAT_MARKET,
CRYPTO,
FIAT,
ORDER_TYPE,
AMOUNT_PRECISION,
}

View file

@ -1,23 +1,31 @@
const { COINS } = require('@lamassu/coins')
const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts')
const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, ETH, LTC, BCH, USDT, LN, USDC } = COINS
const CRYPTO = [BTC, ETH, LTC, BCH, USDT, LN, USDC]
const FIAT = ['USD', 'EUR']
const DEFAULT_FIAT_MARKET = 'EUR'
const AMOUNT_PRECISION = 8
const REQUIRED_CONFIG_FIELDS = ['key', 'secret', 'clientId', 'currencyMarket']
const loadConfig = (account) => {
const mapper = {
'key': 'apiKey',
'clientId': 'uid'
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
return { ...mapped, timeout: 3000 }
}
module.exports = { loadConfig, DEFAULT_FIAT_MARKET, REQUIRED_CONFIG_FIELDS, CRYPTO, FIAT, ORDER_TYPE, AMOUNT_PRECISION }
const { COINS } = require('@lamassu/coins')
const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts')
const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, ETH, LTC, BCH, USDT, LN, USDC } = COINS
const CRYPTO = [BTC, ETH, LTC, BCH, USDT, LN, USDC]
const FIAT = ['USD', 'EUR']
const DEFAULT_FIAT_MARKET = 'EUR'
const AMOUNT_PRECISION = 8
const REQUIRED_CONFIG_FIELDS = ['key', 'secret', 'clientId', 'currencyMarket']
const loadConfig = account => {
const mapper = {
key: 'apiKey',
clientId: 'uid',
}
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(account)
return { ...mapped, timeout: 3000 }
}
module.exports = {
loadConfig,
DEFAULT_FIAT_MARKET,
REQUIRED_CONFIG_FIELDS,
CRYPTO,
FIAT,
ORDER_TYPE,
AMOUNT_PRECISION,
}

View file

@ -1,92 +1,129 @@
const { utils: coinUtils } = require('@lamassu/coins')
const _ = require('lodash/fp')
const ccxt = require('ccxt')
const mem = require('mem')
const { buildMarket, ALL, isConfigValid } = require('../common/ccxt')
const { ORDER_TYPES } = require('./consts')
const logger = require('../../logger')
const { currencies } = require('../../new-admin/config')
const T = require('../../time')
const DEFAULT_PRICE_PRECISION = 2
const DEFAULT_AMOUNT_PRECISION = 8
function trade (side, account, tradeEntry, exchangeName) {
const { cryptoAtoms, fiatCode, cryptoCode: _cryptoCode, tradeId } = tradeEntry
try {
const cryptoCode = coinUtils.getEquivalentCode(_cryptoCode)
const exchangeConfig = ALL[exchangeName]
if (!exchangeConfig) throw Error('Exchange configuration not found')
const { USER_REF, loadOptions, loadConfig = _.noop, REQUIRED_CONFIG_FIELDS, ORDER_TYPE, AMOUNT_PRECISION } = exchangeConfig
if (!isConfigValid(account, REQUIRED_CONFIG_FIELDS)) throw Error('Invalid config')
const selectedFiatMarket = account.currencyMarket
const symbol = buildMarket(selectedFiatMarket, cryptoCode, exchangeName)
const precision = _.defaultTo(DEFAULT_AMOUNT_PRECISION, AMOUNT_PRECISION)
const amount = coinUtils.toUnit(cryptoAtoms, cryptoCode).toFixed(precision)
const accountOptions = _.isFunction(loadOptions) ? loadOptions(account) : {}
const withCustomKey = USER_REF ? { [USER_REF]: tradeId } : {}
const options = _.assign(accountOptions, withCustomKey)
const exchange = new ccxt[exchangeName](loadConfig(account))
if (ORDER_TYPE === ORDER_TYPES.MARKET) {
return exchange.createOrder(symbol, ORDER_TYPES.MARKET, side, amount, null, options)
}
return exchange.fetchOrderBook(symbol)
.then(orderBook => {
const price = calculatePrice(side, amount, orderBook).toFixed(DEFAULT_PRICE_PRECISION)
return exchange.createOrder(symbol, ORDER_TYPES.LIMIT, side, amount, price, options)
})
} catch (e) {
return Promise.reject(e)
}
}
function calculatePrice (side, amount, orderBook) {
const book = side === 'buy' ? 'asks' : 'bids'
let collected = 0.0
for (const entry of orderBook[book]) {
collected += parseFloat(entry[1])
if (collected >= amount) return parseFloat(entry[0])
}
throw new Error('Insufficient market depth')
}
function _getMarkets (exchangeName, availableCryptos) {
const prunedCryptos = _.compose(_.uniq, _.map(coinUtils.getEquivalentCode))(availableCryptos)
try {
const exchange = new ccxt[exchangeName]()
const cryptosToQuoteAgainst = ['USDT']
const currencyCodes = _.concat(_.map(it => it.code, currencies), cryptosToQuoteAgainst)
return exchange.fetchMarkets()
.then(_.filter(it => (it.type === 'spot' || it.spot)))
.then(res =>
_.reduce((acc, value) => {
if (_.includes(value.base, prunedCryptos) && _.includes(value.quote, currencyCodes)) {
if (value.quote === value.base) return acc
if (_.isNil(acc[value.quote])) {
return { ...acc, [value.quote]: [value.base] }
}
acc[value.quote].push(value.base)
}
return acc
}, {}, res)
)
} catch (e) {
logger.debug(`No CCXT exchange found for ${exchangeName}`)
}
}
const getMarkets = mem(_getMarkets, {
maxAge: T.week,
cacheKey: (exchangeName, availableCryptos) => exchangeName
})
module.exports = { trade, getMarkets }
const { utils: coinUtils } = require('@lamassu/coins')
const _ = require('lodash/fp')
const ccxt = require('ccxt')
const mem = require('mem')
const { buildMarket, ALL, isConfigValid } = require('../common/ccxt')
const { ORDER_TYPES } = require('./consts')
const logger = require('../../logger')
const { currencies } = require('../../new-admin/config')
const T = require('../../time')
const DEFAULT_PRICE_PRECISION = 2
const DEFAULT_AMOUNT_PRECISION = 8
function trade(side, account, tradeEntry, exchangeName) {
const { cryptoAtoms, cryptoCode: _cryptoCode, tradeId } = tradeEntry
try {
const cryptoCode = coinUtils.getEquivalentCode(_cryptoCode)
const exchangeConfig = ALL[exchangeName]
if (!exchangeConfig) throw Error('Exchange configuration not found')
const {
USER_REF,
loadOptions,
loadConfig = _.noop,
REQUIRED_CONFIG_FIELDS,
ORDER_TYPE,
AMOUNT_PRECISION,
} = exchangeConfig
if (!isConfigValid(account, REQUIRED_CONFIG_FIELDS))
throw Error('Invalid config')
const selectedFiatMarket = account.currencyMarket
const symbol = buildMarket(selectedFiatMarket, cryptoCode, exchangeName)
const precision = _.defaultTo(DEFAULT_AMOUNT_PRECISION, AMOUNT_PRECISION)
const amount = coinUtils.toUnit(cryptoAtoms, cryptoCode).toFixed(precision)
const accountOptions = _.isFunction(loadOptions) ? loadOptions(account) : {}
const withCustomKey = USER_REF ? { [USER_REF]: tradeId } : {}
const options = _.assign(accountOptions, withCustomKey)
const exchange = new ccxt[exchangeName](loadConfig(account))
if (ORDER_TYPE === ORDER_TYPES.MARKET) {
return exchange.createOrder(
symbol,
ORDER_TYPES.MARKET,
side,
amount,
null,
options,
)
}
return exchange.fetchOrderBook(symbol).then(orderBook => {
const price = calculatePrice(side, amount, orderBook).toFixed(
DEFAULT_PRICE_PRECISION,
)
return exchange.createOrder(
symbol,
ORDER_TYPES.LIMIT,
side,
amount,
price,
options,
)
})
} catch (e) {
return Promise.reject(e)
}
}
function calculatePrice(side, amount, orderBook) {
const book = side === 'buy' ? 'asks' : 'bids'
let collected = 0.0
for (const entry of orderBook[book]) {
collected += parseFloat(entry[1])
if (collected >= amount) return parseFloat(entry[0])
}
throw new Error('Insufficient market depth')
}
function _getMarkets(exchangeName, availableCryptos) {
const prunedCryptos = _.compose(
_.uniq,
_.map(coinUtils.getEquivalentCode),
)(availableCryptos)
try {
const exchange = new ccxt[exchangeName]()
const cryptosToQuoteAgainst = ['USDT']
const currencyCodes = _.concat(
_.map(it => it.code, currencies),
cryptosToQuoteAgainst,
)
return exchange
.fetchMarkets()
.then(_.filter(it => it.type === 'spot' || it.spot))
.then(res =>
_.reduce(
(acc, value) => {
if (
_.includes(value.base, prunedCryptos) &&
_.includes(value.quote, currencyCodes)
) {
if (value.quote === value.base) return acc
if (_.isNil(acc[value.quote])) {
return { ...acc, [value.quote]: [value.base] }
}
acc[value.quote].push(value.base)
}
return acc
},
{},
res,
),
)
} catch (e) {
logger.debug(`No CCXT exchange found for ${exchangeName}. ${e}`)
}
}
const getMarkets = mem(_getMarkets, {
maxAge: T.week,
cacheKey: exchangeName => exchangeName,
})
module.exports = { trade, getMarkets }

View file

@ -10,12 +10,19 @@ const FIAT = ['USD', 'EUR']
const DEFAULT_FIAT_MARKET = 'EUR'
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey', 'currencyMarket']
const loadConfig = (account) => {
const loadConfig = account => {
const mapper = {
'privateKey': 'secret'
privateKey: 'secret',
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(account)
return { ...mapped, timeout: 3000 }
}
module.exports = { loadConfig, DEFAULT_FIAT_MARKET, REQUIRED_CONFIG_FIELDS, CRYPTO, FIAT, ORDER_TYPE }
module.exports = {
loadConfig,
DEFAULT_FIAT_MARKET,
REQUIRED_CONFIG_FIELDS,
CRYPTO,
FIAT,
ORDER_TYPE,
}

View file

@ -1,7 +1,6 @@
const ORDER_TYPES = {
MARKET: 'market',
LIMIT: 'limit'
}
module.exports = { ORDER_TYPES }
const ORDER_TYPES = {
MARKET: 'market',
LIMIT: 'limit',
}
module.exports = { ORDER_TYPES }

View file

@ -1,25 +1,42 @@
const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts')
const { COINS } = require('@lamassu/coins')
const ORDER_TYPE = ORDER_TYPES.LIMIT
const { BTC, ETH, USDT, LN } = COINS
const CRYPTO = [BTC, ETH, USDT, LN]
const FIAT = ['USD']
const DEFAULT_FIAT_MARKET = 'USD'
const AMOUNT_PRECISION = 4
const REQUIRED_CONFIG_FIELDS = ['clientKey', 'clientSecret', 'userId', 'walletId', 'currencyMarket']
const loadConfig = (account) => {
const mapper = {
'clientKey': 'apiKey',
'clientSecret': 'secret',
'userId': 'uid'
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(_.omit(['walletId'], account))
return { ...mapped, timeout: 3000 }
}
const loadOptions = ({ walletId }) => ({ walletId })
module.exports = { loadOptions, loadConfig, DEFAULT_FIAT_MARKET, REQUIRED_CONFIG_FIELDS, CRYPTO, FIAT, ORDER_TYPE, AMOUNT_PRECISION }
const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts')
const { COINS } = require('@lamassu/coins')
const ORDER_TYPE = ORDER_TYPES.LIMIT
const { BTC, ETH, USDT, LN } = COINS
const CRYPTO = [BTC, ETH, USDT, LN]
const FIAT = ['USD']
const DEFAULT_FIAT_MARKET = 'USD'
const AMOUNT_PRECISION = 4
const REQUIRED_CONFIG_FIELDS = [
'clientKey',
'clientSecret',
'userId',
'walletId',
'currencyMarket',
]
const loadConfig = account => {
const mapper = {
clientKey: 'apiKey',
clientSecret: 'secret',
userId: 'uid',
}
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(
_.omit(['walletId'], account),
)
return { ...mapped, timeout: 3000 }
}
const loadOptions = ({ walletId }) => ({ walletId })
module.exports = {
loadOptions,
loadConfig,
DEFAULT_FIAT_MARKET,
REQUIRED_CONFIG_FIELDS,
CRYPTO,
FIAT,
ORDER_TYPE,
AMOUNT_PRECISION,
}

View file

@ -1,30 +1,56 @@
const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts')
const { COINS } = require('@lamassu/coins')
const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, BCH, DASH, ETH, LTC, ZEC, XMR, USDT, TRX, USDT_TRON, LN, USDC } = COINS
const CRYPTO = [BTC, ETH, LTC, DASH, ZEC, BCH, XMR, USDT, TRX, USDT_TRON, LN, USDC]
const FIAT = ['USD', 'EUR']
const DEFAULT_FIAT_MARKET = 'EUR'
const AMOUNT_PRECISION = 6
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey', 'currencyMarket']
const USER_REF = 'userref'
const loadConfig = (account) => {
const mapper = {
'privateKey': 'secret'
}
const mapped = _.mapKeys(key => mapper[key] ? mapper[key] : key)(account)
return {
...mapped,
timeout: 3000,
nonce: function () { return this.microseconds() }
}
}
const loadOptions = () => ({ expiretm: '+60' })
module.exports = { USER_REF, loadOptions, loadConfig, DEFAULT_FIAT_MARKET, REQUIRED_CONFIG_FIELDS, CRYPTO, FIAT, ORDER_TYPE, AMOUNT_PRECISION }
const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts')
const { COINS } = require('@lamassu/coins')
const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, BCH, DASH, ETH, LTC, ZEC, XMR, USDT, TRX, USDT_TRON, LN, USDC } =
COINS
const CRYPTO = [
BTC,
ETH,
LTC,
DASH,
ZEC,
BCH,
XMR,
USDT,
TRX,
USDT_TRON,
LN,
USDC,
]
const FIAT = ['USD', 'EUR']
const DEFAULT_FIAT_MARKET = 'EUR'
const AMOUNT_PRECISION = 6
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey', 'currencyMarket']
const USER_REF = 'userref'
const loadConfig = account => {
const mapper = {
privateKey: 'secret',
}
const mapped = _.mapKeys(key => (mapper[key] ? mapper[key] : key))(account)
return {
...mapped,
timeout: 3000,
nonce: function () {
return this.microseconds()
},
}
}
const loadOptions = () => ({ expiretm: '+60' })
module.exports = {
USER_REF,
loadOptions,
loadConfig,
DEFAULT_FIAT_MARKET,
REQUIRED_CONFIG_FIELDS,
CRYPTO,
FIAT,
ORDER_TYPE,
AMOUNT_PRECISION,
}

View file

@ -1,14 +1,24 @@
module.exports = {
buy,
sell
sell,
}
function buy (cryptoAtoms, fiatCode, cryptoCode) {
console.log('[mock] buying %s %s for %s', cryptoAtoms.toString(), cryptoCode, fiatCode)
function buy(cryptoAtoms, fiatCode, cryptoCode) {
console.log(
'[mock] buying %s %s for %s',
cryptoAtoms.toString(),
cryptoCode,
fiatCode,
)
return Promise.resolve()
}
function sell (cryptoAtoms, fiatCode, cryptoCode) {
console.log('[mock] selling %s %s for %s', cryptoAtoms.toString(), cryptoCode, fiatCode)
function sell(cryptoAtoms, fiatCode, cryptoCode) {
console.log(
'[mock] selling %s %s for %s',
cryptoAtoms.toString(),
cryptoCode,
fiatCode,
)
return Promise.resolve()
}