import { JsonDB, Config } from "node-json-db"; import { FingerprintGenerator } from "fingerprint-generator"; import logger from "./logger"; import * as interfacesDB from "./interfaces/databaseInterface"; import * as interfacesSettings from "./interfaces/settingsInterface"; import { arrayWithoutElementAtIndex } from "./utils"; export class Database { public readonly default: interfacesDB.DatabaseInterface = { accounts: [], }; private json: JsonDB; constructor() { this.json = new JsonDB(new Config("db.json", false, true, "/")); this.json.getData("/").then((result) => { if (Object.keys(result).length == 0) { this.json .push("/", this.default, true) .catch((err) => logger.error(`${err} due setting defaults`)) .then(() => { logger.info("Setting DB to defaults..."); }); this.save(); } }); } async findWallet( walletsFile: string ): Promise { const wallets_json = new JsonDB( new Config(walletsFile, true, true, "/") ); const wallets = await wallets_json.getData("/"); if (Object.keys(wallets).length == 0) { logger.error("File which you choose doesnt have anything"); throw new Error("File which you choose doesnt have anything"); } const accounts = await this.getUsers(); let faucetWallet: interfacesDB.faucetMailInterface | undefined = undefined; for (const _wallet in wallets) { let flag = false; if (accounts.length > 0) { for (const account of accounts) { if (account.faucetMail.mail.address == _wallet) { flag = true; break; } } } if (flag == false) { faucetWallet = { faucet: { username: wallets[_wallet].faucetpay.username, password: wallets[_wallet].faucetpay.password, }, mail: { address: _wallet, password: wallets[_wallet].mail_passphrase, }, }; break; } } return faucetWallet; } async findRefferal(maxRefferals: number): Promise { let refferal: number | null = null; const accounts = await this.getUsers(); if (accounts.length > 0) { for (const mainAccount of accounts) { let counter = 0; if (mainAccount.canBeRefferal == true) { const _accounts = arrayWithoutElementAtIndex( accounts, accounts.indexOf(mainAccount) ); for (const _account of _accounts) { if (_account.refferal == mainAccount.telegramID) { counter += 1; } } if (counter < maxRefferals) { refferal = Number(mainAccount.telegramID); } } } } return refferal; } async save() { await this.json.save(true); } async updateUser(account: interfacesDB.AccountInterface) { const index = await this.json.getIndex( "/accounts", account.phoneNumber, "phoneNumber" ); logger.debug(`Index in database is ${index} of ${account.phoneNumber}`); await this.json.push(`/accounts[${index}]`, account, true); } async addUser( account: Omit< interfacesDB.AccountInterface, | "balance" | "withdraws" | "completedGroupsTasks" | "canBeRefferal" | "browserFingerprint" | "faucetMail" >, wallets_json: string ): Promise { const fingerprintGenerator = new FingerprintGenerator(); const fingerprint = fingerprintGenerator.getFingerprint({ devices: ["desktop"], browsers: ["chrome"], }).fingerprint; const faucet: interfacesDB.faucetMailInterface | undefined = await this.findWallet(wallets_json); if (faucet === undefined) { logger.error("Add new faucet accounts"); throw new Error("Add new faucet accounts"); } else { const canBeRefferal: boolean = Math.random() < 0.5; const _account: interfacesDB.AccountInterface = { phoneNumber: account.phoneNumber, telegramID: account.telegramID, apiID: account.apiID, apiHash: account.apiHash, password: account.password, faucetMail: faucet, stringSession: account.stringSession, balance: 0.0, withdraws: [], completedGroupsTasks: [], canBeRefferal: canBeRefferal, refferal: account.refferal, browserFingerprint: fingerprint, }; await this.json.push(`/accounts[]`, _account); } await this.save(); } async getUsers(): Promise { try { return await this.json.getObject( "/accounts" ); } catch { return []; } } } export class Settings implements interfacesSettings.settingsInterface { public readonly default: interfacesSettings.settingsInterface = { logLevel: "debug", pararels: 2, mainCrypto: "TRX", minimalToWithdraw: 0.0003, maxRefferals: 3, botMessages: { verification: "To continue using this bot,", tasksSelector: "Choose an option to start earning your TRX", taskOver: "Sorry, there are no new ads available.", taskComplete: "Success, ", notInGroup: "not entered the chat", oldMessage: "forwarded is old", }, botButtons: { earn: "❇️ Earn cryptocurrency", balance: "💰 Balance", withdraw: "📤 Withdraw", }, telegramLinks: { botLink: "@hkearn_trx_bot", groupsToJoin: ["@hkearn_transactions", "@hkearn_updates"], }, bypassMode: false, sleepTime: { afterDoing: [1 * 3600, 2 * 3600], betweenSessions: [35, 70], }, shuffleAccounts: true, }; logLevel: "debug" | "info" | "error"; mainCrypto: "TRX"; minimalToWithdraw: number; maxRefferals: number; botMessages: { verification: string; tasksSelector: string; taskOver: string; taskComplete: string; notInGroup: string; oldMessage: string; }; botButtons: { earn: string; balance: string; withdraw: string }; telegramLinks: { botLink: string; groupsToJoin: string[] }; bypassMode: boolean; pararels: number; sleepTime: { afterDoing: number[]; betweenSessions: number[]; }; shuffleAccounts: boolean; private json: JsonDB; constructor() { this.json = new JsonDB(new Config("settings.json", false, true, "/")); this.json .getObject("/") .then((result) => { if (Object.keys(result).length == 0) { logger.warn("Setup config first..."); this.json .push("/", this.default, true) .catch((err) => logger.error(`${err} due setting defaults`) ) .then(() => { this.json.save(true).then(() => { throw new Error("Config doesn't setup"); }); }); } else { mainLoop: for (const setting of Object.keys(this.default)) { if ( result[setting] === undefined || typeof result[setting] != typeof this.default[setting] ) { this[setting] = this.default[setting]; logger.warn( `Setting '${setting}' corrupted or undefined. Check out it...` ); } else { if (typeof result[setting] == "object") { for (const attr of Object.keys( this.default[setting] )) { if ( Object.keys(result[setting]).indexOf( attr ) == -1 ) { this[setting] = this.default[setting]; logger.warn( `Setting '${setting}' corrupted. Check out it...` ); continue mainLoop; } } } this[setting] = result[setting]; } } logger.level = this.logLevel; } }); } } const database = new Database(); const settings = new Settings(); export { database, settings };