@qso-soft/shared
Version:
Shared library for QSO-soft
131 lines • 5.64 kB
JavaScript
import crypto from 'crypto';
import axios from 'axios';
import { AMOUNT_IS_TOO_LOW_ERROR, UNABLE_GET_WITHDRAW_FEE_ERROR, BINANCE_API_URL, BINANCE_PUBLIC_API_URL, } from '../../constants';
import { getAxiosConfig, getClientByNetwork, getExpectedBalance, getProxyAgent, getRandomNumber, getTopUpOptions, sleep, transactionWorker, } from '../../helpers';
import { BINANCE_NETWORK_MAP } from './constants';
export const executeBinanceWithdraw = async (params) => {
const { wallet, binanceWithdrawNetwork, tokenToWithdraw, minAndMaxAmount, minNativeBalance, logger, expectedBalance, amount, minAmount, } = params;
return makeBinanceWithdraw({
wallet,
binanceWithdrawNetwork,
tokenToWithdraw,
minAndMaxAmount,
minNativeBalance,
logger,
expectedBalance,
amount,
minAmount,
});
};
export const makeBinanceWithdraw = async ({ binanceWithdrawNetwork, wallet, expectedBalance, logger, minNativeBalance, minAndMaxAmount, tokenToWithdraw, minAmount, withdrawSleep, hideExtraLogs = false, }) => {
const logTemplate = {
action: 'execWithdraw',
status: 'in progress',
};
const { currentExpectedBalance, isTopUpByExpectedBalance } = getExpectedBalance(expectedBalance);
let binanceProxyAgent;
if (QsoGlobal.settings.useProxy) {
binanceProxyAgent = await getProxyAgent({
proxy: QsoGlobal.BINANCE.proxy,
proxy_type: 'HTTP',
}, logger);
}
const client = getClientByNetwork(binanceWithdrawNetwork, wallet.privKey, logger);
const walletAddress = wallet.walletAddress;
const fee = await getFee(binanceWithdrawNetwork, tokenToWithdraw, binanceProxyAgent?.proxyAgent);
if (!fee) {
return {
status: 'error',
message: `${UNABLE_GET_WITHDRAW_FEE_ERROR}: network=${binanceWithdrawNetwork}, token=${tokenToWithdraw}`,
};
}
const { currentAmount, shouldTopUp, isDone, successMessage, prevNativeBalance } = await getTopUpOptions({
client,
currentExpectedBalance,
isTopUpByExpectedBalance,
minNativeBalance,
minAndMaxAmount,
tokenToWithdraw,
fee,
network: binanceWithdrawNetwork,
});
if (!currentAmount && isDone) {
return {
status: 'passed',
message: successMessage,
};
}
if (currentAmount && currentAmount < (minAmount || 0)) {
return {
status: 'error',
message: AMOUNT_IS_TOO_LOW_ERROR,
};
}
if (shouldTopUp) {
const correctNetwork = binanceWithdrawNetwork === 'polygon' ? 'matic' : binanceWithdrawNetwork;
const currentDate = Date.now();
const queryString = `timestamp=${currentDate}&coin=${tokenToWithdraw}&network=${correctNetwork}&address=${walletAddress}&amount=${currentAmount}`;
const signature = crypto
.createHmac('sha256', QsoGlobal.BINANCE.secretKeys.secret)
.update(queryString)
.digest('hex');
const queryParams = `?${queryString}&signature=${signature}`;
const config = await getAxiosConfig({
proxyAgent: binanceProxyAgent?.proxyAgent,
headers: {
'X-MBX-APIKEY': QsoGlobal.BINANCE.secretKeys.apiKey,
},
});
logger.info(`Withdrawing ${currentAmount} ${tokenToWithdraw} in ${correctNetwork}`, logTemplate);
const { data } = await axios.post(`${BINANCE_API_URL}/capital/withdraw/apply${queryParams}`, {
coin: tokenToWithdraw,
network: correctNetwork,
address: walletAddress,
amount: currentAmount,
}, config);
logger.success(`${currentAmount} ${tokenToWithdraw} were send. We are waiting for the withdrawal from Binance, relax...`, {
...logTemplate,
status: 'succeeded',
});
let currentNativeBalance = await client.getNativeBalance();
while (!(currentNativeBalance.int > prevNativeBalance)) {
const currentSleep = withdrawSleep ? getRandomNumber(withdrawSleep) : 20;
await sleep(currentSleep);
currentNativeBalance = await client.getNativeBalance();
if (!hideExtraLogs) {
logger.info('Tokens are still on the way to your wallet...', logTemplate);
}
}
if (data.id) {
return {
status: 'success',
message: `Your wallet was successfully topped up from Binance. Current balance is [${currentNativeBalance.int} ${tokenToWithdraw}]`,
};
}
}
return {
status: 'error',
};
};
const getFee = async (withdrawNetwork, withDrawToken, proxyAgent) => {
const config = await getAxiosConfig({
proxyAgent,
});
const { data: feesData } = await axios.get(`${BINANCE_PUBLIC_API_URL}/capital/getNetworkCoinAll`, config);
const data = feesData?.data;
const currentTokenData = data?.find(({ coin }) => coin === withDrawToken);
if (!currentTokenData) {
return;
}
const currentNetwork = currentTokenData.networkList.find(({ network }) => network === BINANCE_NETWORK_MAP[withdrawNetwork]);
if (!currentNetwork) {
return;
}
return +currentNetwork.withdrawFee;
};
export const execBinanceWithdraw = async (params) => transactionWorker({
...params,
startLogMessage: `Execute make Binance withdraw of ${params.tokenToWithdraw} from ${params.binanceWithdrawNetwork}...`,
transactionCallback: executeBinanceWithdraw,
});
//# sourceMappingURL=make-binance-withdraw.js.map