UNPKG

@qso-soft/shared

Version:

Shared library for QSO-soft

185 lines 8.63 kB
import { AxiosError } from 'axios'; import { CRITICAL_ERRORS_MAP, NFT_HOLDING_ERROR, PASSED_ERROR_MAP, SUCCESS_MESSAGES_TO_STOP_WALLET, WARNING_ERRORS_MAP, } from '../../constants'; import { runAutoGas } from '../../managers'; import { getClientByNetwork } from '../clients'; import { waitGas } from '../gas'; import { updateSavedModulesCount } from '../modules/save-modules'; import { checkMultipleOf, createRandomProxyAgent, sleep, sleepByRange } from '../utils'; const DEFAULT_ERROR_MSG = 'Execution was not done successfully'; export const transactionWorker = async (props) => { const { startLogMessage = 'Processing transaction', wallet, logger, baseNetwork, count: countTxRange, delay, transactionCallback, projectName, moduleIndex, proxyAgent, proxyObject, } = props; if (countTxRange > 1) { logger.success(`Total number of transactions for [${logger.meta.moduleName}] module: [${countTxRange}]`, { action: 'transactionWorker', }); } const transactionsDelayRange = delay || QsoGlobal.settings.delay.betweenTransactions; let currentProxyAgent = proxyAgent; let currentProxyObject = proxyObject; const currentNetwork = props.network ? props.network : baseNetwork; const client = getClientByNetwork(currentNetwork, wallet.privKey, props.logger); let workerResponse = { status: 'success', logTemplate: {}, }; for (let txIndex = 0; txIndex < countTxRange; txIndex++) { let attempts = QsoGlobal.settings.txAttempts; const logTemplate = { txId: txIndex + 1, action: 'transactionWorker', status: 'in progress', }; workerResponse = { ...workerResponse, logTemplate, }; while (attempts > 0) { try { logger.info(startLogMessage, logTemplate); await waitGas({ logger, maxGas: props.maxGas, wallet, sleepSeconds: 30, }); const modulesWithoutAutogas = ['binance-withdraw', 'okx-withdraw']; const moduleName = props.moduleName; const shouldRunAutoGas = !modulesWithoutAutogas.includes(moduleName); if (shouldRunAutoGas) { await runAutoGas({ network: currentNetwork, client, wallet, logger, }); } const response = await transactionCallback({ ...props, proxyAgent: currentProxyAgent, proxyObject: currentProxyObject, client, }); workerResponse = { ...workerResponse, status: response.status, }; if (response.txHash && response.explorerLink) { const txScanUrl = `${response.explorerLink}/tx/${response.txHash}`; logger.success(`Check your transaction - ${txScanUrl}`, logTemplate); updateSavedModulesCount({ wallet, moduleIndex, projectName, }); } if (response.status === 'success' || response.status === 'passed') { const logMessage = response.message || 'Execution was done successfully'; logger.success(logMessage, logTemplate); updateSavedModulesCount({ wallet, moduleIndex, projectName, }); } if (response.status === 'warning' || response.status === 'critical') { return { ...workerResponse, message: response.message || DEFAULT_ERROR_MSG, }; } if (response.status === 'error') { throw new Error(response.message || DEFAULT_ERROR_MSG); } if (txIndex !== countTxRange) { await sleepByRange(transactionsDelayRange, logTemplate, logger); } break; } catch (e) { const error = e; let errorMessage = error.message; if (e instanceof AxiosError) { errorMessage = e.response?.data.msg || e.response?.data.message || errorMessage; } const successMessage = SUCCESS_MESSAGES_TO_STOP_WALLET.find((error) => errorMessage.includes(error)); const isNftHoldingError = errorMessage.includes(NFT_HOLDING_ERROR); if (errorMessage.includes('execution reverted') && !isNftHoldingError) { errorMessage = 'Unable to execute transaction for unknown reason'; } if (successMessage) { throw new Error(errorMessage); } for (const [originalMessage, customMessage] of Object.entries(CRITICAL_ERRORS_MAP)) { if (errorMessage.includes(originalMessage)) { return { ...workerResponse, status: 'critical', message: customMessage, }; } } attempts--; for (const [originalMessage, customMessage] of Object.entries(WARNING_ERRORS_MAP)) { if (errorMessage.includes(originalMessage)) { if (!props.stopWalletOnError) { updateSavedModulesCount({ wallet, moduleIndex, projectName, setZeroCount: true, }); } return { ...workerResponse, status: 'warning', message: customMessage, }; } } for (const [originalMessage, customMessage] of Object.entries(PASSED_ERROR_MAP)) { if (errorMessage.includes(originalMessage)) { updateSavedModulesCount({ wallet, moduleIndex, projectName, setZeroCount: true, }); logger.success(customMessage, { ...logTemplate, status: 'succeeded', }); return { ...workerResponse, status: 'passed', }; } } if (attempts > 0) { logger.warning(`${errorMessage}. ${attempts} attempts left`, logTemplate); await sleep(QsoGlobal.settings.delay.betweenRetries, logTemplate, logger); const attemptsToChangeProxy = QsoGlobal.settings.txAttemptsToChangeProxy; const currentRetryCount = QsoGlobal.settings.txAttempts - attempts; const shouldUpdateProxy = checkMultipleOf(attemptsToChangeProxy, currentRetryCount); if (QsoGlobal.settings.useProxy && shouldUpdateProxy) { const newProxyData = await createRandomProxyAgent(logger); if (newProxyData) { const { proxyAgent: newProxyAgent, ...newProxyObject } = newProxyData; currentProxyAgent = newProxyAgent || proxyAgent; currentProxyObject = newProxyObject || proxyObject; } } } else { logger.warning(`The attempts are over. ${attempts} attempts left`, logTemplate); return { ...workerResponse, status: 'error', message: errorMessage, }; } } } } return workerResponse; }; //# sourceMappingURL=transaction-worker.js.map