crypto-bot
Version:
multi-function tools for blockchain automation
181 lines (147 loc) • 6.91 kB
JavaScript
const { ethers, BigNumber } = require("ethers");
const { Contract, Provider } = require('ethcall')
const fs = require('fs');
const cliProgress = require('cli-progress');
const colors = require('ansi-colors');
const { logger } = require('./logger');
const { cryptolib: config } = require('./../index');
const botType = config.botType
module.exports = {
splitMultiCall: function(_ArrayData, _type){
const maxToken = this.resizeMultiCallArray(_ArrayData.length, _type);
let round = 0;
const _splitArrayData = new Array();
let _splitData = new Array();
for(let i = 0 ; i < _ArrayData.length ; i++)
{
let _arrayData = new Object(_ArrayData[i]);
if(i < ((maxToken*round)+maxToken) ){
_splitData.push(_arrayData);
} else {
_splitArrayData.push(_splitData);
_splitData = new Array();
_splitData.push(_arrayData);
round++;
}
}
if(_splitData.length > 0) _splitArrayData.push(_splitData);
return _splitArrayData;
},
resizeMultiCallArray: function(_length, _type){
logger.debug(` Resize MultiCallArray has been called for ${_length} type: ${_type}`)
const MAX_MULTICALL_SIZE = (4*128);
const TOKENDATASIZE = (MAX_MULTICALL_SIZE / 4);
const TOKENDATASIZE_NOSUPPLY = (MAX_MULTICALL_SIZE / 3);
const PAIRDATASIZE = (MAX_MULTICALL_SIZE / 3);
logger.debug(` TOKENDATASIZE constant: ${TOKENDATASIZE} `);
logger.debug(` PAIRDATASIZE constant: ${PAIRDATASIZE} `);
let MAX_COUNT = MAX_MULTICALL_SIZE;
if(_type == undefined){
logger.error(` invalid type provided`);
throw(error)
return undefined;
}
if(_type == botType.MULTI_CALL_TOKEN_FULL){
MAX_COUNT = TOKENDATASIZE;
} else if(_type == botType.MULTI_CALL_TOKEN_NO_SUPPLY) {
MAX_COUNT = TOKENDATASIZE_NOSUPPLY;
} else if(_type == botType.MULTI_CALL_PAIRDATA) {
MAX_COUNT = PAIRDATASIZE;
} else if(_type == botType.MULTI_CALL_PAIRINFO) {
MAX_COUNT = MAX_MULTICALL_SIZE;
} else if(_type == botType.MULTI_CALL_ROUTER_RESERVES) {
MAX_COUNT = MAX_MULTICALL_SIZE;
} else if(_type == botType.MULTI_CALL_WALLET_BALANCE) {
MAX_COUNT = MAX_MULTICALL_SIZE;
} else {
MAX_COUNT = MAX_MULTICALL_SIZE;
}
logger.debug(` MAX_COUNT is: ${MAX_COUNT}`);
let round = 1;
let loopcount = 0;
for(let i = 0 ; i < _length ; i++)
{
if(loopcount < MAX_COUNT){
loopcount++;
} else{
round++;
loopcount = 0;
}
}
logger.debug(` MultiCallArray resize array need to be split in ${round} for type: ${_type}`);
return MAX_COUNT;
},
cryptocall: async function(_Provider, CallArray, _type) {
let rpc = _Provider
const ethcallProvider = new Provider();
const provider = new ethers.providers.JsonRpcProvider(rpc);
//const title = `(${Network.name}) - multi-call progress |`
//const bar1 = new cliProgress.SingleBar({format: title + colors.green('{bar}') + '| {percentage}% | {value}/{total} pair'}, cliProgress.Presets.shades_classic);
const _splitCallArray = this.splitMultiCall(CallArray, _type);
const CallData = new Array()
const count = CallArray.length
try{
// bar1.start(count, 0);
await ethcallProvider.init(provider);
}
catch(e){
logger.error(`Failed to initialize provider for MuliCall. ${e}`)
}
finally{
logger.verbose(`Successfull connection to MuliCall provider.`)
let data = undefined
try{
//let _countProgress = 0;
//bar1.start(count, 0);
for(let i = 0 ; i < _splitCallArray.length ; i++){
const _calldata = await ethcallProvider.all(_splitCallArray[i]);
if( !(_calldata.length == _splitCallArray[i].length) ){
logger.error(` Received data for ${_calldata.length} new token. Expected data for: ${_splitCallArray[i].length}`)
//console.log(_splitCallArray[i])
//return
}
else{
logger.info(` Received ${_calldata.length} new data object...`)
//console.log(_calldata)
let _realTimeArray = new Array();
for(let j = 0; j < _calldata.length ; j++){
const DataObject = _calldata[j]
CallData.push(_calldata[j])
_realTimeArray.push(DataObject)
}
//await this.addPairData(Network, _realTimeArray, Exchange);
logger.info(` ${_realTimeArray.length} data received.`);
}
//_countProgress = _countProgress + _calldata.length;
//bar1.update(_countProgress);
}
//bar1.update(_countProgress);
//bar1.stop();
//console.log(CallData)
return CallData
}
catch (e){
if(e.code == "BUFFER_OVERRUN") {
logger.error(`BUFFER OVERRUN error encountered. reason: ${e.reason}`)
}
if (e.code == "NUMERIC_FAULT") {
logger.error(`NUMERIC_FAULT error encountered reason: ${e.reason}`)
}
if ( (e.code == "CALL_EXCEPTION") ) {
if (e.reason == "missing revert data in call exception") {
logger.error(`Error when call multi-calling contract. Invalid ABI?: ${e.reason}`)
}
else if (e.reason == "undefined"){
logger.error(`Bug in Crypto BOT caused data not received: ${e.reason}`)
} else {
logger.error(`Unknown CALL EXCEPTION error encountered reason: ${e.reason}`)
}
} else {
logger.error(`UNKNOWN error encountered: ${e}`)
console.log(e)
}
return []
}
}
},
}