Skip to content

Commit

Permalink
Merge pull request #3121 from hollaex/testnet
Browse files Browse the repository at this point in the history
Testnet
  • Loading branch information
abeikverdi authored Dec 6, 2024
2 parents baf1cde + 4ee87ce commit d64a7ba
Show file tree
Hide file tree
Showing 27 changed files with 856 additions and 137 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ templates/kubernetes/config/*
.DS_Store

.token
backups
backups
.vscode/settings.json
web/public/.vscode/settings.json
2 changes: 1 addition & 1 deletion server/api/controllers/order.js
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const orderExecute = (req, res) => {
}
};

toolsLib.order.executeUserOrder(user_id, opts, token)
toolsLib.order.executeUserOrder(user_id, opts, token, req)
.then((result) => {
const { symbol, side, size, price } = result;
executeHedging(symbol, side, size, price);
Expand Down
2 changes: 1 addition & 1 deletion server/api/swagger/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const definition = {
swagger: '2.0',
info: {
title: 'HollaEx Kit',
version: '2.13.2'
version: '2.13.3'
},
host: 'api.hollaex.com',
basePath: '/v2',
Expand Down
2 changes: 1 addition & 1 deletion server/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "2.13.2",
"version": "2.13.3",
"private": false,
"description": "HollaEx Kit",
"keywords": [
Expand Down
2 changes: 0 additions & 2 deletions server/tools/dbs/checkConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ Status.findOne()
balance_history_config: existingKitConfigurations.balance_history_config || {},
p2p_config: existingKitConfigurations.p2p_config || {},
fiat_fees: existingKitConfigurations.fiat_fees || {},
balance_history_config: existingKitConfigurations.balance_history_config || {},
selectable_native_currencies: existingKitConfigurations?.selectable_native_currencies || [existingKitConfigurations.native_currency || process.env.NATIVE_CURRENCY || 'usdt'],
auto_trade_config: existingKitConfigurations.auto_trade_config || {},
};
Expand Down Expand Up @@ -97,7 +96,6 @@ Status.findOne()
};

const constants = { ...status.constants, url: API_HOST, domain: DOMAIN };
console.log('hi', constants);

return status.update(
{ kit, secrets, constants },
Expand Down
127 changes: 87 additions & 40 deletions server/utils/hollaex-tools-lib/tools/order.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ const createUserOrderByKitId = (userKitId, symbol, side, size, type, price = 0,
});
};

const executeUserOrder = async (user_id, opts, token) => {
const executeUserOrder = async (user_id, opts, token, req) => {
const storedToken = await client.getAsync(token);
if (!storedToken) {
throw new Error(TOKEN_EXPIRED);
}
const { symbol, price, side, size, type, chain } = JSON.parse(storedToken);
if (chain) { return executeUserChainTrade(user_id, token) };
if (chain) { return executeUserChainTrade(user_id, token, opts, req) };

if (size < 0) {
throw new Error(INVALID_SIZE);
Expand Down Expand Up @@ -347,10 +347,10 @@ const getUserQuickTrade = async (spending_currency, spending_amount, receiving_a
else {
let symbol = spending_amount ? `${spending_currency}-${receiving_currency}` : `${receiving_currency}-${spending_currency}`;
let size = spending_amount || receiving_amount;
let result = await getUserChainTradeQuote(bearerToken, symbol, size, ip);
let result = await getUserChainTradeQuote(bearerToken, symbol, size, ip, opts, req);

if (spending_amount == null && result?.quote_amount) {
const spendingAmount = await getUserChainTradeQuote(bearerToken, `${spending_currency}-${receiving_currency}`, result.quote_amount, ip);
const spendingAmount = await getUserChainTradeQuote(bearerToken, `${spending_currency}-${receiving_currency}`, result.quote_amount, ip, opts, req);
result.token = spendingAmount?.token;
}
if (result?.quote_amount) {
Expand Down Expand Up @@ -1339,7 +1339,43 @@ const findConversionRate = (startCurrency, endCurrency, rates, visited = new Set
visited.delete(startCurrency);
return shortestPath;
}
const getUserChainTradeQuote = async (bearerToken, symbol, size = 1, ip, id = null, network_id = null) => {
const findTradeAmount = (trades, initialFunds) => {
const availableFunds = { ...initialFunds };
const results = [];

for (const trade of trades) {
const [baseCurrency, quoteCurrency] = trade.symbol.split('-');
const { side, size, price } = trade;

let spendingCurrency, spendingAmount, receivingCurrency, receivingAmount;

if (side === 'sell') {
spendingCurrency = baseCurrency;
spendingAmount = size
receivingCurrency = quoteCurrency;
receivingAmount = size * price;
} else if (side === 'buy') {
spendingCurrency = quoteCurrency;
spendingAmount = availableFunds[quoteCurrency] || 0;
receivingCurrency = baseCurrency;
receivingAmount = spendingAmount / price;
}

availableFunds[spendingCurrency] = (availableFunds[spendingCurrency] || 0) - spendingAmount;
availableFunds[receivingCurrency] = (availableFunds[receivingCurrency] || 0) + receivingAmount;

results.push({
trade,
spending_currency: spendingCurrency,
spending_amount: spendingAmount,
receiving_currency: receivingCurrency,
receiving_amount: receivingAmount
});
}

return results;
}
const getUserChainTradeQuote = async (bearerToken, symbol, size = 1, ip, opts, req = null, id = null, network_id = null) => {
if (
!getKitConfig().chain_trade_config ||
!getKitConfig().chain_trade_config.active
Expand Down Expand Up @@ -1369,29 +1405,40 @@ const getUserChainTradeQuote = async (bearerToken, symbol, size = 1, ip, id = nu
const quickTrades = getQuickTrades();

let data = null;
const tickers = await getTickers();
let prices = {};
if (user_id) {
data = await client.getAsync(`${user_id}-${symbol}-rates`);
prices = data ? JSON.parse(data) : {};
}

//Find all the available prices with their types on the exchange.
//Find Trade Paths
if(!data) {
for (const rate of quickTrades) {
for (const rate of quickTrades) {
prices[rate.symbol] = { type: rate.type, price: NaN, active: rate.active };
}
const result = findConversionRate(from, to, prices, new Set(), size);
let index = 0;
for(const rate of result?.trades) {
if(!rate.active) { index++; continue};

try {
if (rate.type === 'pro' && rate.active) {
prices[rate.symbol] = { type: rate.type, price: tickers[rate.symbol].open };
} else {
const assets = rate.symbol.split('-');
const quotePrice = await getUserQuickTrade(assets[0], 1, null, assets[1], bearerToken, ip, { additionalHeaders: null }, { headers: { 'api-key': null } }, { user_id: id, network_id });
prices[rate.symbol] = { type: rate.type, price: quotePrice.receiving_amount, token: quotePrice?.token || null }
}

const trades = findTradeAmount(result.trades, { [from]: size });

const quotePrice = await getUserQuickTrade(trades[index].spending_currency, trades[index].spending_amount, trades[index].receiving_amount, trades[index].receiving_currency, bearerToken, ip, opts, req, { user_id: id, network_id });

const calculatedPrice = rate.side === 'sell' ? quotePrice.receiving_amount / quotePrice.spending_amount : quotePrice.spending_amount / quotePrice.receiving_amount;
result.trades[index].price = calculatedPrice;
prices[rate.symbol] = { type: rate.type, price: calculatedPrice, token: quotePrice?.token || null}

index++;
} catch (error) {
continue;
throw new Error(error.message + ` symbol: ${rate.symbol}`)
}
}

}

let hasNetworkBroker = Object.values(prices || {}).find(price => price.type === 'network');
if (!hasNetworkBroker)
await client.setexAsync(`${user_id}-${symbol}-rates`, 25, JSON.stringify(prices));
Expand All @@ -1408,20 +1455,6 @@ const getUserChainTradeQuote = async (bearerToken, symbol, size = 1, ip, id = nu
}

if (result?.totalRate && user_id) {
try {
for(const trade of result?.trades) {
// This is for getting the right token for network brokers, because we obtained the size for the trade so we need to get a new token with the updated size
if (trade.type === 'network') {
const assets = trade.symbol.split('-');
const quotePrice = await getUserQuickTrade(assets[0], 1, null, assets[1], bearerToken, ip, { additionalHeaders: null }, { headers: { 'api-key': null } }, { user_id: id, network_id });
trade.token = quotePrice?.token || null;
}
}

} catch (error) {
throw new Error('Rate not found!');
}

result.symbol = symbol;
result.size = size;
result.price = result?.totalRate / size;
Expand All @@ -1441,7 +1474,7 @@ const getUserChainTradeQuote = async (bearerToken, symbol, size = 1, ip, id = nu
return { token, quote_amount: result?.totalRate };
}

const executeUserChainTrade = async (user_id, userToken) => {
const executeUserChainTrade = async (user_id, userToken, opts, req) => {
if (
!getKitConfig().chain_trade_config ||
!getKitConfig().chain_trade_config.active
Expand Down Expand Up @@ -1476,14 +1509,14 @@ const executeUserChainTrade = async (user_id, userToken) => {
let lastRate;

if (tradeInfo.quote_asset !== currency) {
const initialRate = await getUserChainTradeQuote(null, `${tradeInfo.base_asset}-${currency}`, tradeInfo.size, null, sourceUser.id, sourceUser.network_id);
const initialRate = await getUserChainTradeQuote(null, `${tradeInfo.base_asset}-${currency}`, tradeInfo.size, null, opts, req, sourceUser.id, sourceUser.network_id);
if (!initialRate?.token) {
throw new Error('Rate not found!');
};

lastRate = await getUserChainTradeQuote(null, `${currency}-${tradeInfo.quote_asset}`, JSON.parse(await client.getAsync(initialRate.token)).totalRate, null, sourceUser.id, sourceUser.network_id);
lastRate = await getUserChainTradeQuote(null, `${currency}-${tradeInfo.quote_asset}`, JSON.parse(await client.getAsync(initialRate.token)).totalRate, null, opts, req, sourceUser.id, sourceUser.network_id);
} else {
lastRate = await getUserChainTradeQuote(null, `${tradeInfo.base_asset}-${currency}`, tradeInfo.size, null, sourceUser.id, sourceUser.network_id);
lastRate = await getUserChainTradeQuote(null, `${tradeInfo.base_asset}-${currency}`, tradeInfo.size, null, opts, req, sourceUser.id, sourceUser.network_id);
}

if (!lastRate?.token) {
Expand All @@ -1493,7 +1526,7 @@ const executeUserChainTrade = async (user_id, userToken) => {
const token = JSON.parse(await client.getAsync(lastRate.token));
let successfulTrades = [];
try {
successfulTrades = await executeTrades(token, sourceUser);
successfulTrades = await executeTrades(token, sourceUser, opts);
} catch (error) {
throw new Error(error.message);
}
Expand Down Expand Up @@ -1550,13 +1583,13 @@ const executeUserChainTrade = async (user_id, userToken) => {
}
try {
// get the currency amount back for the middle man account
const { token } = await getUserChainTradeQuote(null, `${tradeInfo.base_asset}-${currency}`, tradeInfo.size, null, sourceUser.id, sourceUser.network_id);
const { token } = await getUserChainTradeQuote(null, `${tradeInfo.base_asset}-${currency}`, tradeInfo.size, null, opts, req, sourceUser.id, sourceUser.network_id);
if (!token) {
throw new Error('Rate not found!');
};

const sourceTradeInfo = JSON.parse(await client.getAsync(token));
await executeTrades(sourceTradeInfo, sourceUser);
await executeTrades(sourceTradeInfo, sourceUser, opts);

} catch (error) {
const admin = await getUserByKitId(1);
Expand All @@ -1574,7 +1607,7 @@ const executeUserChainTrade = async (user_id, userToken) => {
return result;
}

const executeTrades = async (tradeInfo, sourceUser) => {
const executeTrades = async (tradeInfo, sourceUser, opts) => {
const successfulTrades = [];

for (const trade of tradeInfo?.trades) {
Expand Down Expand Up @@ -1636,12 +1669,26 @@ const executeTrades = async (tradeInfo, sourceUser) => {
else if (type === 'network') {
const tierUser = getKitTier(sourceUser.verification_level);
const fee = tierUser.fees.taker[symbol];
res = await getNodeLib().executeQuote(trade?.token, sourceUser.network_id, fee);
const coins = trade.symbol.split('-');
let spending_currency = trade.side === 'sell' ? coins[0] : coins[1];
let receiving_currency = trade.side === 'sell' ? coins[1] : coins[0];
let spending_amount = trade.side === 'sell' ? size : new BigNumber(price).multipliedBy(size).toNumber();

const priceValues = await getNodeLib().getQuote(
sourceUser.network_id,
spending_currency,
spending_amount,
receiving_currency,
null,
opts
);

res = await getNodeLib().executeQuote(priceValues?.token, sourceUser.network_id, fee);
}

successfulTrades.push(res);
} catch (error) {
throw new Error(`Error occured during trade executions. Error: ${error.message} Failed trade ${trade.symbol}, successful trades: ${successfulTrades.map(trade => trade.symbol).join(', ')}`);
throw new Error(`There has been a failure processing your request please try again`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.13.2
2.13.3
2 changes: 1 addition & 1 deletion web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hollaex-kit",
"version": "2.13.2",
"version": "2.13.3",
"private": true,
"dependencies": {
"@ant-design/compatible": "1.0.5",
Expand Down
9 changes: 9 additions & 0 deletions web/src/components/AppBar/_AppBar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -527,6 +527,15 @@ $app-menu-width: calc(100vw - 40rem);
.app-bar-search-icon {
padding: 2%;
font-size: 16px;
opacity: 0.6;
svg {
transform: scale(1.3);
}
}

.app-bar-search-icon:hover {
cursor: pointer;
opacity: 1;
}
}
.capitalize {
Expand Down
10 changes: 8 additions & 2 deletions web/src/components/Notification/NewOrder.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,19 @@ const generateRows = ({ order, pairData }) => {
stringId: `TYPE,CHECK_ORDER_TYPE,TYPES_VALUES.${type},SIDES_VALUES.${side}`,
label: STRINGS['TYPE'],
value: (
<div className="text-capitalize">
<span
className={
side === 'buy'
? 'text-capitalize market-buy-side'
: ' text-capitalize market-sell-side'
}
>
{STRINGS.formatString(
STRINGS['CHECK_ORDER_TYPE'],
STRINGS[`TYPES_VALUES.${type}`],
STRINGS[`SIDES_VALUES.${side}`]
)}
</div>
</span>
),
});

Expand Down
14 changes: 14 additions & 0 deletions web/src/components/Notification/_Notification.scss
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,20 @@ $logout--size-difference: 3rem;
fill: $colors-main-black;
}
}

.market-buy-side,
.market-sell-side {
background-color: $buy;
padding: 0% 5%;
color: $buy-bids-text;
border-radius: 5px;
margin-right: 2%;
}

.market-sell-side {
background-color: $sell !important;
color: $sell-bids-text !important;
}
}
.notification-wrapper {
color: $dark-font-sub-text-color;
Expand Down
2 changes: 2 additions & 0 deletions web/src/config/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,8 @@
"LOGOUT_ERROR_INACTIVE": "You have been logged out because you have been inactive",
"ORDER_ENTRY_BUTTON": "{0} {1}",
"ORDER_ENTRY_ADVANCED": "Advanced",
"ORDER_ENTRY_SHOW_ADVANCE": "Show Advanced",
"ORDER_ENTRY_HIDE_ADVANCE": "Hide Advacned",
"QUICK_TRADE_OUT_OF_LIMITS": "Order size is out of the limits",
"QUICK_TRADE_TOKEN_USED": "Token has been used",
"QUICK_TRADE_QUOTE_EXPIRED_FIRST_LINE": "Price quote has expired.",
Expand Down
Loading

0 comments on commit d64a7ba

Please sign in to comment.