├── .gitignore ├── config.json.example ├── tsconfig.json ├── src ├── utils │ ├── generator.ts │ ├── logger.ts │ └── captchaServices.ts ├── index.ts └── classes │ ├── proxy.ts │ └── flow3.ts ├── package.json └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | package-lock.json 2 | dist 3 | node_modules 4 | accounts.txt 5 | proxy.txt 6 | token.txt 7 | config.json -------------------------------------------------------------------------------- /config.json.example: -------------------------------------------------------------------------------- 1 | { 2 | "captchaServices": { 3 | "captchaUsing": "private", 4 | "urlPrivate" : "url_service", 5 | "antiCaptchaApikey": [""], 6 | "captcha2Apikey": [""] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "CommonJS", 5 | "outDir": "./dist", 6 | "rootDir": "./src", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "typeRoots": ["./node_modules/@types"] 11 | }, 12 | "include": ["src/**/*"] 13 | } -------------------------------------------------------------------------------- /src/utils/generator.ts: -------------------------------------------------------------------------------- 1 | 2 | export class Generator { 3 | Password() { 4 | const firstLetter = String.fromCharCode( 5 | Math.floor(Math.random() * 26) + 65 6 | ); 7 | const otherLetters = Array.from({ length: 4 }, () => 8 | String.fromCharCode(Math.floor(Math.random() * 26) + 97) 9 | ).join(""); 10 | const numbers = Array.from({ length: 3 }, () => 11 | Math.floor(Math.random() * 10) 12 | ).join(""); 13 | return `${firstLetter}${otherLetters}@${numbers}!`; 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flow3-autoref", 3 | "version": "1.0.0", 4 | "main": "node dist/index.ts", 5 | "scripts": { 6 | "start": "node dist/index.js", 7 | "build": "tsc", 8 | "dev": "ts-node src/index.ts", 9 | "dev:watch": "nodemon --exec ts-node src/index.ts" 10 | }, 11 | "keywords": [ 12 | "flow3", 13 | "autref" 14 | ], 15 | "author": "Ahlul Mukhramin", 16 | "license": "ISC", 17 | "description": "", 18 | "devDependencies": { 19 | "@types/node": "^22.10.10", 20 | "@types/user-agents": "^1.0.4", 21 | "typescript": "^5.7.3" 22 | }, 23 | "dependencies": { 24 | "@2captcha/captcha-solver": "^1.3.0", 25 | "@faker-js/faker": "^9.7.0", 26 | "@solana/web3.js": "^1.98.0", 27 | "axios": "^1.7.9", 28 | "bs58": "^6.0.0", 29 | "chalk": "^4.1.2", 30 | "fs": "^0.0.1-security", 31 | "https-proxy-agent": "^7.0.6", 32 | "readline": "^1.3.0", 33 | "socks-proxy-agent": "^8.0.5", 34 | "tweetnacl": "^1.0.3", 35 | "user-agents": "^1.1.483" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/utils/logger.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | import * as readline from "readline"; 3 | 4 | const rl = readline.createInterface({ 5 | input: process.stdin, 6 | output: process.stdout, 7 | }); 8 | 9 | export const prompt = (question: string): Promise => { 10 | return new Promise((resolve) => { 11 | rl.question(question, (answer) => { 12 | resolve(answer); 13 | }); 14 | }); 15 | }; 16 | 17 | export function logMessage( 18 | currentNum: number | null = null, 19 | total: number | null = null, 20 | message: string = "", 21 | messageType: string = "info" 22 | ): void { 23 | const now = new Date(); 24 | const timestamp = now 25 | .toLocaleString("id-ID", { 26 | year: "numeric", 27 | month: "2-digit", 28 | day: "2-digit", 29 | hour: "2-digit", 30 | minute: "2-digit", 31 | second: "2-digit", 32 | hour12: false, 33 | }) 34 | .replace(/\./g, ":") 35 | .replace(/, /g, " "); 36 | const accountStatus = currentNum && total ? `[${currentNum}/${total}] ` : ""; 37 | 38 | const colors = { 39 | info: chalk.blueBright, 40 | success: chalk.greenBright, 41 | error: chalk.redBright, 42 | warning: chalk.yellowBright, 43 | process: chalk.cyanBright, 44 | debug: chalk.blue, 45 | }; 46 | 47 | const emojis = { 48 | info: "ℹ️", 49 | success: "✅", 50 | error: "❌", 51 | warning: "⚠️", 52 | process: "🔄", 53 | debug: "🐞", 54 | }; 55 | 56 | const logColor = colors[messageType as keyof typeof colors] || chalk.white; 57 | const emoji = emojis[messageType as keyof typeof emojis] || "❓"; 58 | 59 | let logText = logColor(`${emoji} ${message}`); 60 | 61 | console.log( 62 | `${chalk.white("[")}${chalk.dim(timestamp)}${chalk.white( 63 | "]" 64 | )} ${accountStatus}${logText}` 65 | ); 66 | } 67 | 68 | export { rl }; 69 | 70 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Flow3 Network Auto Referral 2 | 3 | This bot automates the process of creating accounts and using referral codes for the Flow3 Website 4 | 5 | ## Features 6 | 7 | - Automatically generates wallet. 8 | - Automatically generates email address and password. 9 | - Uses proxies to avoid IP bans. 10 | - Logs the created accounts. 11 | 12 | ## Requirements 13 | 14 | - Node.js v18.20.6 LTS [Download](https://nodejs.org/dist/v18.20.6/node-v18.20.6-x64.msi). 15 | - Account Flow3 [Flow3](https://dashboard.flow3.tech/?ref=UVRKPHgSp) 16 | - Captcha Services Anti Captcha / 2 Captcha Or cf-cloudflarance 17 | - Proxy (Optional). Best Proxy [Cherry Proxy](https://center.cherryproxy.com/Login/Register?invite=029ad2d3) 18 | 19 | ## Installation 20 | 21 | 1. Clone the repository: 22 | 23 | ```sh 24 | git clone https://github.com/ahlulmukh/flow3-autoref.git 25 | cd flow3-autoref 26 | ``` 27 | 28 | 2. Install the dependencies: 29 | 30 | ```sh 31 | npm install 32 | npm run build 33 | ``` 34 | 35 | 3. Create a `proxy.txt` file in the root directory and add your proxies (one per line). 36 | ``` 37 | http://user:pass@host:port 38 | http://user:pass@host:port 39 | http://user:pass@host:port 40 | ``` 41 | 4. Make config and put your apikey `cp config.json.example config.json`. `captchaUsing` can be `antiCaptcha` or `2captcha` or you can using your private captcha solved `private` [Using this for private captcha](https://github.com/ZFC-Digital/cf-clearance-scraper/) 42 | 43 | ```json 44 | { 45 | "captchaServices": { 46 | "captchaUsing": "private", 47 | "urlPrivate": "url_services_private", 48 | "antiCaptchaApikey": [""], 49 | "captcha2Apikey": [""] 50 | } 51 | } 52 | ``` 53 | 54 | ## Usage 55 | 56 | 1. Run the bot: 57 | 58 | ```sh 59 | npm run start 60 | ``` 61 | 62 | 2. Follow the prompts to enter your referral code 63 | 64 | ## Output 65 | 66 | - The created accounts will be saved in `accounts.txt`. 67 | 68 | ## Notes 69 | 70 | - Make sure to use valid proxies to avoid IP bans. 71 | 72 | ## Stay Connected 73 | 74 | - Channel Telegram : [Telegram](https://t.me/elpuqus) 75 | - Channel WhatsApp : [Whatsapp](https://whatsapp.com/channel/0029VavBRhGBqbrEF9vxal1R) 76 | - Discord : [Discord](https://discord.com/invite/uKM4UCAccY) 77 | 78 | ## Donation 79 | 80 | If you would like to support the development of this project, you can make a donation using the following addresses: 81 | 82 | - Solana: `FdHsx8He55QgRCSv6NMEpFfkjXFsXFEeWEpJpo7sUQZe` 83 | - EVM: `0x406de5ec09201002c45fdd408ab23159cd12fa3e` 84 | - BTC: `bc1prze475lgalevngrhwq6r9wyng3rl3zskyru4rn4k6j8kwzmmczmqcd7u7y` 85 | 86 | ## Disclaimer 87 | 88 | This tool is for educational purposes only. Use it at your own risk. 89 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk"; 2 | import fs from "fs"; 3 | import { Flow3Referral } from "./classes/flow3"; 4 | import { getRandomProxy, loadProxies } from "./classes/proxy"; 5 | import { logMessage, prompt, rl } from "./utils/logger"; 6 | 7 | async function main(): Promise { 8 | console.log( 9 | chalk.cyan(` 10 | ░█▀▀░█░░░█▀█░█░█░▀▀█ 11 | ░█▀▀░█░░░█░█░█▄█░░▀▄ 12 | ░▀░░░▀▀▀░▀▀▀░▀░▀░▀▀░ 13 | By : El Puqus Airdrop 14 | github.com/ahlulmukh 15 | `) 16 | ); 17 | 18 | const refCode = await prompt(chalk.yellow("Enter Referral Code: ")); 19 | const count = parseInt(await prompt(chalk.yellow("How many do you want? "))); 20 | const proxiesLoaded = loadProxies(); 21 | if (!proxiesLoaded) { 22 | console.log(chalk.yellow("No proxy available. Using default IP.")); 23 | } 24 | let successful = 0; 25 | const accountsFlow = fs.createWriteStream("accounts.txt", { flags: "a" }); 26 | const tokenAccount = fs.createWriteStream("token.txt", { flags: "a" }); 27 | 28 | try { 29 | let retryCount = 0; 30 | const maxRetries = 3; 31 | while (successful < count) { 32 | console.log(chalk.white("-".repeat(85))); 33 | const currentProxy = await getRandomProxy(successful + 1, count); 34 | const flow = new Flow3Referral(refCode, currentProxy, successful + 1, count); 35 | 36 | try { 37 | const data = await flow.singleProses(); 38 | if (data) { 39 | logMessage(successful + 1, count, `Email Address: ${data.dataAccount.email}`, "success"); 40 | accountsFlow.write(`Email Address : ${data.dataAccount.email}\n`); 41 | accountsFlow.write(`Password : ${data.dataAccount.password}\n`); 42 | accountsFlow.write(`Wallet Address : ${data.dataWallet.publicKey}\n`); 43 | accountsFlow.write(`Secret Key : ${data.dataWallet.secretKey}\n`); 44 | accountsFlow.write(`===================================================================\n`); 45 | tokenAccount.write(`${data.dataAccount.refreshToken}\n`); 46 | successful++; 47 | retryCount = 0; 48 | } 49 | } catch (error) { 50 | logMessage(successful + 1, count, `Error: ${(error as Error).message}, retrying...`, "error"); 51 | retryCount++; 52 | if (retryCount >= maxRetries) { 53 | console.log(chalk.red("Max retries reached, skipping...")); 54 | successful++; 55 | retryCount = 0; 56 | } else { 57 | await new Promise((resolve) => setTimeout(resolve, 3000)); 58 | } 59 | } 60 | } 61 | 62 | } finally { 63 | accountsFlow.end(); 64 | tokenAccount.end(); 65 | console.log(chalk.magenta("\n[*] Done!")); 66 | rl.close(); 67 | } 68 | } 69 | 70 | main().catch((err) => { 71 | console.error(chalk.red("Error occurred:"), err); 72 | process.exit(1); 73 | }); -------------------------------------------------------------------------------- /src/classes/proxy.ts: -------------------------------------------------------------------------------- 1 | import axios, { AxiosRequestConfig } from "axios"; 2 | import chalk from "chalk"; 3 | import fs from "fs"; 4 | import { HttpsProxyAgent } from "https-proxy-agent"; 5 | import { SocksProxyAgent } from "socks-proxy-agent"; 6 | import { logMessage } from "../utils/logger"; 7 | 8 | let proxyList: string[] = []; 9 | let axiosConfig: AxiosRequestConfig = {}; 10 | 11 | export function getProxyAgent(proxyUrl: string, index: number, total: number): HttpsProxyAgent | SocksProxyAgent | null { 12 | try { 13 | const isSocks = proxyUrl.toLowerCase().startsWith("socks"); 14 | if (isSocks) { 15 | return new SocksProxyAgent(proxyUrl); 16 | } 17 | return new HttpsProxyAgent( 18 | proxyUrl.startsWith("http") ? proxyUrl : `http://${proxyUrl}` 19 | ); 20 | } catch (error) { 21 | if (error instanceof Error) { 22 | logMessage( 23 | index, 24 | total, 25 | `Error creating proxy agent: ${error.message}`, 26 | "error" 27 | ); 28 | } else { 29 | logMessage( 30 | index, 31 | total, 32 | `Error creating proxy agent`, 33 | "error" 34 | ); 35 | } 36 | return null; 37 | } 38 | } 39 | 40 | export function loadProxies(): boolean { 41 | try { 42 | const proxyFile = fs.readFileSync("proxy.txt", "utf8"); 43 | proxyList = proxyFile 44 | .split("\n") 45 | .filter((line) => line.trim()) 46 | .map((proxy) => { 47 | proxy = proxy.trim(); 48 | if (!proxy.includes("://")) { 49 | return `http://${proxy}`; 50 | } 51 | return proxy; 52 | }); 53 | 54 | if (proxyList.length === 0) { 55 | throw new Error("No proxies found in proxies.txt"); 56 | } 57 | console.log( 58 | chalk.green(`✓ Loaded ${proxyList.length} proxies from proxies.txt`) 59 | ); 60 | return true; 61 | } catch (error) { 62 | if (error instanceof Error) { 63 | console.error(chalk.red(`[!] Error loading proxies: ${error.message}`)); 64 | } else { 65 | console.error(chalk.red(`[!] Error loading proxies`)); 66 | } 67 | return false; 68 | } 69 | } 70 | 71 | export async function checkIP(index: number, total: number): Promise { 72 | try { 73 | const response = await axios.get( 74 | "https://api.ipify.org?format=json", 75 | axiosConfig 76 | ); 77 | const ip = response.data.ip; 78 | logMessage(index, total, `IP Using: ${ip}`, "success"); 79 | return true; 80 | } catch (error) { 81 | if (error instanceof Error) { 82 | logMessage(index, total, `Failed to get IP: ${error.message}`, "error"); 83 | } else { 84 | logMessage(index, total, `Failed to get IP`, "error"); 85 | } 86 | return false; 87 | } 88 | } 89 | 90 | export async function getRandomProxy(index: number, total: number): Promise { 91 | if (proxyList.length === 0) { 92 | axiosConfig = {}; 93 | await checkIP(index, total); 94 | return null; 95 | } 96 | 97 | let proxyAttempt = 0; 98 | while (proxyAttempt < proxyList.length) { 99 | const proxy = proxyList[Math.floor(Math.random() * proxyList.length)]; 100 | try { 101 | const agent = getProxyAgent(proxy, index, total); 102 | if (!agent) continue; 103 | 104 | axiosConfig.httpsAgent = agent; 105 | await checkIP(index, total); 106 | return proxy; 107 | } catch (error) { 108 | proxyAttempt++; 109 | } 110 | } 111 | 112 | logMessage(index, total, "Using default IP", "warning"); 113 | axiosConfig = {}; 114 | await checkIP(index, total); 115 | return null; 116 | } -------------------------------------------------------------------------------- /src/utils/captchaServices.ts: -------------------------------------------------------------------------------- 1 | import { Solver } from "@2captcha/captcha-solver"; 2 | import axios from "axios"; 3 | import fs from "fs"; 4 | import path from "path"; 5 | import { logMessage } from "../utils/logger"; 6 | const configPath = path.resolve(__dirname, "../../config.json"); 7 | const config = JSON.parse(fs.readFileSync(configPath, "utf-8")); 8 | 9 | 10 | export class CaptchaServices { 11 | private sitekey: string; 12 | private pageUrl: string; 13 | private cfSolved: string; 14 | private antiCaptchaApiUrl: string; 15 | 16 | constructor() { 17 | this.sitekey = "0x4AAAAAABDpOwOAt5nJkp9b"; 18 | this.pageUrl = "https://app.flow3.tech/sign-up"; 19 | this.cfSolved = `${config.captchaServices.urlPrivate}/cf-clearance-scraper`; 20 | this.antiCaptchaApiUrl = "https://api.anti-captcha.com"; 21 | } 22 | 23 | async solveCaptcha(currentNum: number, total: number) { 24 | const provider = config.captchaServices.captchaUsing; 25 | if (provider === "2captcha") { 26 | return this.solveCaptcha2(currentNum, total); 27 | } else if (provider === "antiCaptcha") { 28 | return this.antiCaptcha(currentNum, total); 29 | } else if (provider === 'private') { 30 | return this.solvedPrivate(currentNum, total); 31 | } else { 32 | logMessage(null, null, "Invalid captcha provider.", "error"); 33 | return null; 34 | } 35 | } 36 | 37 | async solvedPrivate(currentNum: number, total: number) { 38 | logMessage(currentNum, total, "Trying to solved captcha cloudflare with private...", "process"); 39 | try { 40 | const response = await axios.post( 41 | this.cfSolved, 42 | { 43 | url: "https://app.flow3.tech/sign-up", 44 | siteKey: "0x4AAAAAABDpOwOAt5nJkp9b", 45 | mode: "turnstile-min", 46 | }, 47 | { 48 | headers: { 49 | "Content-Type": "application/json" 50 | } 51 | } 52 | ); 53 | 54 | if (!response.data || !response.data.token) { 55 | throw new Error("Failed to get token from Cloudflare"); 56 | } 57 | logMessage(currentNum, total, "Captcha solved successfully!", "success"); 58 | return response.data.token; 59 | } catch (error: any) { 60 | logMessage(currentNum, total, `Failed to solve captcha: ${error.message}`, "error"); 61 | return null; 62 | } 63 | } 64 | 65 | async antiCaptcha(currentNum: number, total: number) { 66 | logMessage(currentNum, total, "Trying solving captcha Turnstile with anticaptcha...", "process"); 67 | const apiKey = config.captchaServices.antiCaptchaApikey[0]; 68 | 69 | try { 70 | const createTaskResponse = await axios.post(`${this.antiCaptchaApiUrl}/createTask`, { 71 | clientKey: apiKey, 72 | task: { 73 | type: "TurnstileTaskProxyless", 74 | websiteURL: this.pageUrl, 75 | websiteKey: this.sitekey, 76 | }, 77 | softId: 0, 78 | }); 79 | 80 | const taskId = createTaskResponse.data.taskId; 81 | if (!taskId) throw new Error("Failed to get task ID"); 82 | 83 | logMessage(currentNum, total, `Task created with ID: ${taskId}`, "process"); 84 | let result = null; 85 | while (!result) { 86 | await new Promise(resolve => setTimeout(resolve, 5000)); 87 | 88 | const getResultResponse = await axios.post(`${this.antiCaptchaApiUrl}/getTaskResult`, { 89 | clientKey: apiKey, 90 | taskId: taskId, 91 | }); 92 | 93 | if (getResultResponse.data.status === "ready") { 94 | result = getResultResponse.data.solution.token; 95 | logMessage(currentNum, total, "Captcha solved successfully!", "success"); 96 | } 97 | } 98 | 99 | return result; 100 | } catch (error: any) { 101 | logMessage(currentNum, total, `AntiCaptcha failed: ${error.message}`, "error"); 102 | return null; 103 | } 104 | } 105 | 106 | async solveCaptcha2(currentNum: number, total: number) { 107 | logMessage(currentNum, total, "Trying solving captcha Turnstile with 2captcha...", "process"); 108 | const apikey = config.captchaServices.captcha2Apikey[0]; 109 | try { 110 | const res = await new Solver(apikey).cloudflareTurnstile({ 111 | pageurl: this.pageUrl, 112 | sitekey: this.sitekey, 113 | }); 114 | logMessage(currentNum, total, "Captcha solved successfully!", "success"); 115 | return res.data; 116 | } catch (error) { 117 | logMessage(currentNum, total, `2Captcha failed`, "error"); 118 | return null; 119 | } 120 | } 121 | } -------------------------------------------------------------------------------- /src/classes/flow3.ts: -------------------------------------------------------------------------------- 1 | import { faker } from "@faker-js/faker"; 2 | import { Keypair } from "@solana/web3.js"; 3 | import axios, { AxiosResponse } from "axios"; 4 | import bs58 from "bs58"; 5 | import * as nacl from "tweetnacl"; 6 | import UserAgent from "user-agents"; 7 | import { CaptchaServices } from "../utils/captchaServices"; 8 | import { Generator } from "../utils/generator"; 9 | import { logMessage } from "../utils/logger"; 10 | import { getProxyAgent } from "./proxy"; 11 | 12 | export class Flow3Referral { 13 | private refCode: string; 14 | private currentNum: number; 15 | private total: number; 16 | private proxy: string | null; 17 | private wallet: Keypair; 18 | private axios: any; 19 | private generator: Generator = new Generator(); 20 | private userAgent: string = new UserAgent().toString(); 21 | private captchaService: CaptchaServices = new CaptchaServices(); 22 | 23 | constructor(refCode: string, proxy: string | null = null, currentNum: number, total: number,) { 24 | this.refCode = refCode; 25 | this.proxy = proxy; 26 | this.currentNum = currentNum; 27 | this.total = total; 28 | this.wallet = Keypair.generate(); 29 | this.axios = axios.create({ 30 | httpsAgent: this.proxy ? getProxyAgent(this.proxy, this.currentNum, this.total) : undefined, 31 | timeout: 120000, 32 | headers: { 33 | "User-Agent": this.userAgent, 34 | }, 35 | }); 36 | } 37 | 38 | private async makeRequest(method: string, url: string, config: any = {}, retries: number = 3): Promise { 39 | for (let i = 0; i < retries; i++) { 40 | try { 41 | return await this.axios({ method, url, ...config }); 42 | } catch (error: any) { 43 | const errorData = error.response ? error.response.data : error.message; 44 | logMessage( 45 | this.currentNum, 46 | this.total, 47 | `Request failed: ${error.message}`, 48 | "error" 49 | ); 50 | logMessage( 51 | this.currentNum, 52 | this.total, 53 | `Error response data: ${JSON.stringify(errorData, null, 2)}`, 54 | "error" 55 | ); 56 | 57 | logMessage( 58 | this.currentNum, 59 | this.total, 60 | `Retrying... (${i + 1}/${retries})`, 61 | "process" 62 | ); 63 | await new Promise((resolve) => setTimeout(resolve, 12000)); 64 | } 65 | } 66 | return null; 67 | } 68 | 69 | private async getRandomDomain() { 70 | logMessage( 71 | this.currentNum, 72 | this.total, 73 | "Trying to get a random domain...", 74 | "process" 75 | ); 76 | const vowels = "aeiou"; 77 | const consonants = "bcdfghjklmnpqrstvwxyz"; 78 | const keyword = 79 | consonants[Math.floor(Math.random() * consonants.length)] + 80 | vowels[Math.floor(Math.random() * vowels.length)]; 81 | try { 82 | const response = await this.makeRequest( 83 | "GET", 84 | `https://generator.email/search.php?key=${keyword}` 85 | ); 86 | 87 | if (!response) { 88 | logMessage( 89 | this.currentNum, 90 | this.total, 91 | "No response from API", 92 | "error" 93 | ); 94 | return null; 95 | } 96 | const domains = response.data.filter((d: string) => /^[\x00-\x7F]*$/.test(d)); 97 | if (domains.length) { 98 | const selectedDomain = 99 | domains[Math.floor(Math.random() * domains.length)]; 100 | logMessage( 101 | this.currentNum, 102 | this.total, 103 | `Selected domain: ${selectedDomain}`, 104 | "success" 105 | ); 106 | return selectedDomain; 107 | } 108 | 109 | logMessage( 110 | this.currentNum, 111 | this.total, 112 | "Could not find valid domain", 113 | "error" 114 | ); 115 | return null; 116 | } catch (error: any) { 117 | logMessage( 118 | this.currentNum, 119 | this.total, 120 | `Error getting random domain: ${error.message}`, 121 | "error" 122 | ); 123 | return null; 124 | } 125 | } 126 | 127 | private async generateEmail(domain: string) { 128 | logMessage( 129 | this.currentNum, 130 | this.total, 131 | "Trying to generate email...", 132 | "process" 133 | ); 134 | 135 | const firstname = faker.person.firstName().toLowerCase(); 136 | const lastname = faker.person.lastName().toLowerCase(); 137 | const randomNums = Math.floor(Math.random() * 900 + 100).toString(); 138 | 139 | const separator = Math.random() > 0.5 ? "" : "."; 140 | const email = `${firstname}${separator}${lastname}${randomNums}@${domain}`; 141 | 142 | logMessage( 143 | this.currentNum, 144 | this.total, 145 | `Generated email: ${email}`, 146 | "success" 147 | ); 148 | return email; 149 | } 150 | 151 | private async registerAccount(email: string, password: string, captcha: string) { 152 | const headers = { 153 | "Content-Type": "application/json", 154 | origin: 'https://app.flow3.tech/', 155 | referer: 'https://app.flow3.tech/' 156 | } 157 | 158 | const payload = { 159 | email: email, 160 | password: password, 161 | captchaToken: captcha, 162 | referralCode: this.refCode, 163 | } 164 | 165 | try { 166 | const response = await this.makeRequest("POST", "https://api2.flow3.tech/api/user/register", { data: payload, headers: headers }); 167 | if (!response) { 168 | logMessage(this.currentNum, this.total, "No response from API", "error"); 169 | return null; 170 | } 171 | return response.data 172 | } catch (error: any) { 173 | logMessage(this.currentNum, this.total, `Error: ${error.message}`, "error"); 174 | return null; 175 | } 176 | } 177 | 178 | private async checkingWalletAddress(accessToken: string, wallet: string) { 179 | const headers = { 180 | Authorization: `Bearer ${accessToken}`, 181 | "Content-Type": "application/json", 182 | origin: 'https://app.flow3.tech/', 183 | referer: 'https://app.flow3.tech/' 184 | } 185 | 186 | try { 187 | const response = await this.makeRequest("GET", `https://api2.flow3.tech/api/user/check-old-wallet?walletAddress=${wallet}`, { headers: headers }); 188 | if (!response) { 189 | logMessage(this.currentNum, this.total, "No response from API", "error"); 190 | return null; 191 | } 192 | return response.data 193 | } catch (error: any) { 194 | logMessage(this.currentNum, this.total, `Error: ${error.message}`, "error"); 195 | return null; 196 | } 197 | } 198 | 199 | private async updateWalletAddress(accessToken: string, wallet: string) { 200 | const headers = { 201 | Authorization: `Bearer ${accessToken}`, 202 | "Content-Type": "application/json", 203 | origin: 'https://app.flow3.tech/', 204 | referer: 'https://app.flow3.tech/' 205 | } 206 | 207 | const payload = { 208 | walletAddress: wallet, 209 | } 210 | 211 | try { 212 | const response = await this.makeRequest("POST", 'https://api2.flow3.tech/api/user/update-wallet-address', { data: payload, headers: headers }); 213 | if (!response) { 214 | logMessage(this.currentNum, this.total, "No response from API", "error"); 215 | return null; 216 | } 217 | return response.data 218 | } catch (error: any) { 219 | logMessage(this.currentNum, this.total, `Error: ${error.message}`, "error"); 220 | return null; 221 | 222 | } 223 | } 224 | 225 | public getWallet(): { publicKey: string; secretKey: string } { 226 | return { 227 | publicKey: this.wallet.publicKey.toBase58(), 228 | secretKey: bs58.encode(this.wallet.secretKey), 229 | }; 230 | } 231 | 232 | async generateSignature(message: string) { 233 | const messageBuffer = Buffer.from(message); 234 | const signature = nacl.sign.detached(messageBuffer, this.wallet.secretKey); 235 | const encode = bs58.encode(signature); 236 | return encode; 237 | } 238 | 239 | async login() { 240 | logMessage(this.currentNum, this.total, `Trying Register Account...`, "process"); 241 | const message = `Please sign this message to connect your wallet to Flow 3 and verifying your ownership only.`; 242 | const signature = await this.generateSignature(message); 243 | const payload = { 244 | message: message, 245 | walletAddress: this.wallet.publicKey.toBase58(), 246 | signature: signature, 247 | referralCode: this.refCode, 248 | }; 249 | 250 | try { 251 | const response = await this.makeRequest("POST", "https://api.flow3.tech/api/v1/user/login", { 252 | data: payload, 253 | }); 254 | if (response?.data.statusCode === 200) { 255 | logMessage(this.currentNum, this.total, 'Register Account Success', "success"); 256 | return response.data.data.refreshToken 257 | } 258 | return null 259 | } catch (error: any) { 260 | logMessage(this.currentNum, this.total, `Login failed: ${error.message}`, "error"); 261 | return null; 262 | } 263 | } 264 | 265 | public async singleProses() { 266 | try { 267 | const domain = await this.getRandomDomain(); 268 | if (!domain) return 269 | const email = await this.generateEmail(domain); 270 | if (!email) return 271 | const password = this.generator.Password(); 272 | const captcha = await this.captchaService.solveCaptcha(this.currentNum, this.total); 273 | if (!captcha) return 274 | const registerResponse = await this.registerAccount(email, password, captcha); 275 | if (!registerResponse) return 276 | const accessToken = registerResponse.data.accessToken; 277 | const wallet = this.wallet.publicKey.toBase58(); 278 | const checkWallet = await this.checkingWalletAddress(accessToken, wallet); 279 | if (!checkWallet) return 280 | if (checkWallet.data.exist === false) { 281 | const updateWallet = await this.updateWalletAddress(accessToken, wallet); 282 | if (!updateWallet) return 283 | } 284 | return { 285 | dataAccount: { 286 | email: email, 287 | password: password, 288 | accessToken: accessToken, 289 | refreshToken: registerResponse.data.refreshToken, 290 | }, 291 | dataWallet: { 292 | publicKey: this.wallet.publicKey.toBase58(), 293 | secretKey: bs58.encode(this.wallet.secretKey), 294 | } 295 | } 296 | } catch (error: any) { 297 | logMessage(this.currentNum, this.total, `Error: ${error.message}`, "error"); 298 | return null; 299 | } 300 | } 301 | 302 | } 303 | --------------------------------------------------------------------------------