import fs = require('fs'); import {database as db,settings} from './database' import prompt from 'prompts'; import logger from "./logger" import * as telegram from 'telegram'; import { LogLevel } from 'telegram/extensions/Logger'; import { AccountInterface } from './interfaces/databaseInterface'; import { sleep } from 'telegram/Helpers'; import findFreePorts from 'find-free-ports'; import { waitNewMessages, startNewTorDocker, getIP,getMessagesByEntity} from './utils'; import {connect, disconnect, tor} from "node-tor-control"; import Miner from '@ulixee/miner'; import Hero from '@ulixee/hero'; import {portsInterface, usedIPInterface} from "./interfaces/otherInterfaces" import { do_sites_task, vertification } from './automatization'; import ExecuteJsPlugin from '@ulixee/execute-js-plugin'; import _ from 'lodash'; const addAccounts: ()=>Promise=async ()=>{ let apiId: number=0 let apiHash: string= ''; let accounts=await db.getUsers(); if (accounts.length!=0){ const usePrevData=await prompt({ type: 'confirm', name: 'confirmed', message: 'Use apiId and apiHash from last added account?' }); if (usePrevData.confirmed==true){ apiId=accounts[accounts.length-1].apiID; apiHash=accounts[accounts.length-1].apiHash; } } if (apiId==0 && apiHash==''){ const api=await prompt([ { type:'number', name:'apiId', message:'ApiId?' }, { type:'text', name:'apiHash', message:'ApiHash?' } ]); apiId=Number(api.apiId); apiHash=api.apiHash; } let jsonFiles: prompt.Choice[]=[]; fs.readdirSync("./").forEach((file)=>{ if (file.search('.json')!=-1 && file!='db.json' && file!='settings.json'){ jsonFiles.push( { title: file, description:'json file', value:file, } ); } }); const walletsFile=(await prompt({ type: 'select', name: 'file', message: 'Choose wallets json file', choices: jsonFiles })).file await db.findWallet(walletsFile); mainLoop: while (true){ accounts=await db.getUsers(); const answers=await prompt([ { type:'text', name:'number', message:'Phone number?' }, { type:'text', name:'password', message:'2FA Password?' } ]); for (const account of accounts){ if (account.phoneNumber==answers.number){ logger.warn('You already added this number'); continue mainLoop; } } const session=new telegram.sessions.StringSession(''); const client=new telegram.TelegramClient(session,apiId,apiHash,{deviceModel:'Samsung SM-G980',connectionRetries: 5,systemVersion: '10'}); client.setLogLevel(LogLevel.ERROR); await client.start({ phoneNumber: async ()=>answers.number.replace(/ /g, ""), password: async ()=>answers.password.replace(/ /g, ""), phoneCode: async () => (await prompt({ type:'number', name:'code', message:'Enter recieved code' })).code.toString(), onError: (err) => { logger.error(`Error due singning into telegram account\n${err}`); throw err }, }); if ((await client.isUserAuthorized())==true){ const account: telegram.Api.User | telegram.Api.InputPeerUser=(await client.getMe(false)); if (account instanceof telegram.Api.User ){ await db.addUser({ password: answers.password, phoneNumber: answers.number, apiHash: apiHash, telegramID: Number(account.id), apiID: apiId, stringSession: String(client.session.save()), refferal: await db.findRefferal(settings.maxRefferals) },walletsFile) } else { logger.error("Wrong type of account?"); } } else { logger.error('Client not authorized'); } if ((await prompt({ type: 'confirm', name: 'continue', message: 'continue?' })).continue!=true){ return; } } } const farm: ()=>Promise=async ()=>{ let usedIP:usedIPInterface[]=[] const proccesGroup=async (workersGroups:AccountInterface[],ports: portsInterface)=>{ const container=await startNewTorDocker(ports.http,ports.socks,ports.control); for (const worker of workersGroups){ logger.debug(`Current worker:${worker.phoneNumber}\nBalance:${worker.balance}`); while (usedIP.filter((value:usedIPInterface)=>{ if (_.isEqual(worker,value.worker)){ if (value.usedIps.indexOf(value.current)!=-1 || value.current==''){ return true } } else { const _ip=usedIP.filter((value)=>{return _.isEqual(worker,value.worker)}); if (value.usedIps.indexOf(_ip[0].current)!=-1 || value.current==_ip[0].current){ return true } } }).length!=0){ const torConnection = await connect({ host: '127.0.0.1', port:ports.control, password: 'qwerty', }); await tor.signalNewNYM(torConnection); usedIP.filter((value)=>{return _.isEqual(worker,value.worker)})[0].current=(await getIP(ports.http))!; } usedIP.filter((value)=>{return _.isEqual(worker,value.worker)})[0].usedIps.push(usedIP.filter((value)=>{return _.isEqual(worker,value.worker)})[0].current) const fingerprint=worker.browserFingerprint let hero: Omit; while (true){ try { hero = new Hero({ userProfile:{ deviceProfile: { deviceMemory:fingerprint.navigator.deviceMemory, } }, name:`${worker.telegramID}`, connectionToCore: { host:`ws://127.0.0.1:${ports.minerPort}` }, disableDevtools: true, // to bypass hk site showChrome:true, // to debug userAgent:fingerprint.navigator.userAgent, viewport:fingerprint.screen, locale:fingerprint.navigator.language, upstreamProxyUrl:`socks5://127.0.0.1:${ports.socks}`, }); hero.use(ExecuteJsPlugin); break; } catch (err){ logger.warn(`Some error due openning Hero. Trying again...\n${err}`); continue } } const client=new telegram.TelegramClient( new telegram.sessions.StringSession(worker.stringSession), worker.apiID, worker.apiHash, {deviceModel:'Samsung SM-G980',connectionRetries: 5,systemVersion: '10'} ); client.setLogLevel(LogLevel.ERROR); await client.connect(); if ((await client.checkAuthorization())==false){ logger.error(`Account ${worker.phoneNumber} is not authorizated`); continue } else { logger.debug(`Successfully connected to account ${worker.phoneNumber}`); // https://gram.js.org/beta/modules/Api.channels.html // https://gram.js.org/beta/classes/Api.messages.DeleteChat.html const botEntity=await client.getEntity(settings.telegramLinks.botLink) as telegram.Api.User; for (const chat of settings.telegramLinks.groupsToJoin){ try{ await client.invoke(new telegram.Api.channels.GetParticipant({channel:chat,participant:'me'})); } catch(err){ if (err.code==400){ await client.invoke(new telegram.Api.channels.JoinChannel({channel:chat})); } else{ logger.error(`${worker.phoneNumber} | Unknown error due GetParticipant`) throw err; } } } if ((await getMessagesByEntity(client,botEntity,botEntity)).length==0){ let id: number=-1; if (worker.refferal!==null){ id=(await client.sendMessage(botEntity,{message:`/start ${worker.refferal}`})).id; logger.debug(`${worker.phoneNumber} | First start of ${botEntity.username} via refferal link of ${worker.refferal}`); }else { id=(await client.sendMessage(botEntity,{message:`/start`})).id; logger.debug(`${worker.phoneNumber} | First start of ${botEntity.username}`); } await waitNewMessages(client,worker,botEntity,id) } logger.info(`${worker.phoneNumber} | Sending earn message...`); const requestTasksMessage=await client.sendMessage(botEntity,{message:settings.botButtons.earn}); await waitNewMessages(client,worker,botEntity,requestTasksMessage.id) let tasksSelector:telegram.Api.Message=(await client.getMessages(botEntity,{ minId:requestTasksMessage.id, // search: settings.botMessages.tasksSelector, }))[0]; if (tasksSelector.message.includes(settings.botMessages.verification)==true){ logger.warn(`Account ${worker.phoneNumber} is unvertificated`) const url: string=tasksSelector.buttons![0][0].url!; await vertification(client,worker,hero,url,botEntity,tasksSelector.id); const requestTasksMessage=await client.sendMessage(botEntity,{message:settings.botButtons.earn}); await waitNewMessages(client,worker,botEntity,requestTasksMessage.id) tasksSelector=(await client.getMessages(botEntity,{ minId:requestTasksMessage.id, // search: settings.botMessages.tasksSelector, }))[0]; } await do_sites_task(client,worker,hero,botEntity,tasksSelector); await hero.close(); } } container.kill(); } const workers=await db.getUsers(); let workersGroups: Array=[]; for (const worker of workers){ usedIP.push({ worker: worker, usedIps: [], current: '', }) } for (let i=0;i!=workers.length+1;i+=settings.pararels){ const _workers=workers.slice(i,i+settings.pararels); if (_workers.length!=0){ workersGroups.push(_workers); } else { break; } } if (workersGroups.length!=Math.ceil(workers.length/settings.pararels)){ logger.warn(`There is strange thing with workersGroups\n${workersGroups.length} ${Math.ceil(workers.length/settings.pararels)}`); } let pararels: Promise[] =[]; let _ports=await findFreePorts(workers.length*3+1); const miner = new Miner(); await miner.listen({port: _ports[_ports.length-1]}); for (let i=0;i!=workersGroups.length;i++){ pararels.push(proccesGroup(workersGroups[i],{ http: _ports[i*3], socks: _ports[i*3+1], control:_ports[i*3+2], minerPort: await miner.port })); } await Promise.all(pararels); await miner.close(); } // menu (async ()=> { mainLoop: while (true){ const answer=await prompt({ type: 'select', name: 'menu', message: 'Choose action', choices: [ ((await db.getUsers()).length>0) ? { title: 'Start',description: 'Starting farm', value: 'start' } : { title: 'Start',description: 'Add accounts first...', value: 'start' ,disabled: true}, { title: 'Add accounts', description: 'Adds accounts', value: 'addAccounts' }, { title: 'Check balances', value: 'checkBalances', disabled: true }, { title: 'Withdraw', value: 'withdraw', disabled: true }, { title: 'Exit',description: 'You realy dont know what it mean?'} ] }) switch (answer.menu) { case 'addAccounts': await addAccounts(); break; case 'start': while (true){ try{ await farm(); } catch (err){ logger.error(`Unknown error\n${err}`) break; } } break; default: logger.info('Bye bye'); break mainLoop; } } })();