├── .gitignore ├── index.js ├── Dockerfile ├── .dockerignore ├── docker-compose.yaml ├── package.json ├── LICENSE ├── src ├── display.js ├── api.js └── tasks.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | package-lock.json 4 | bearers.json 5 | ori.js -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const { handleTasks } = require('./src/tasks'); 2 | const fs = require('fs'); 3 | 4 | const BEARERS = JSON.parse(fs.readFileSync('bearers.json', 'utf-8')); 5 | 6 | handleTasks(BEARERS); 7 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:20.12-alpine3.19 2 | 3 | WORKDIR /usr/src/app 4 | 5 | COPY package*.json ./ 6 | 7 | RUN npm install 8 | 9 | # Copy rest code 10 | COPY . . 11 | 12 | # Run the application with argument 2 13 | CMD ["npm", "start", "--", "2"] 14 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Node modules 2 | node_modules 3 | 4 | # Logs 5 | *.log 6 | 7 | # Environment files 8 | .env 9 | 10 | # Build output 11 | dist 12 | build 13 | 14 | # Test files and folders 15 | test 16 | tests 17 | coverage 18 | 19 | # Temporary files 20 | *.tmp 21 | *.swp 22 | 23 | # Git files 24 | .git 25 | .gitignore 26 | 27 | # Docker files 28 | Dockerfile 29 | .dockerignore 30 | 31 | # IDE files 32 | .vscode 33 | .idea 34 | 35 | # OS generated files 36 | .DS_Store 37 | Thumbs.db 38 | -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | # Deprecated since new version of Docker-compose 2 | # version: '3' 3 | 4 | services: 5 | app: 6 | build: . 7 | container_name: Fintopio-bot 8 | volumes: 9 | - .:/usr/src/app 10 | 11 | command: ["npm", "start", "--", "2"] 12 | 13 | # Resource constraints 14 | deploy: 15 | resources: 16 | limits: 17 | # Limit CPU usage to a maximum of 0.25 cores (25% of a CPU core). 18 | cpus: '0.25' 19 | 20 | # Limit memory usage to a maximum of 100MB. 21 | memory: 100M -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fintopio-airdrop-bot", 3 | "version": "1.0.0", 4 | "description": "An automation bot to complete tasks, check in daily, and farm on Fintopio for airdrop rewards.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "node index.js" 9 | }, 10 | "keywords": [ 11 | "fintopio", 12 | "airdrop", 13 | "bot", 14 | "automation", 15 | "check-in", 16 | "farming", 17 | "tasks", 18 | "telegram" 19 | ], 20 | "author": "", 21 | "license": "MIT", 22 | "dependencies": { 23 | "axios": "^1.7.7", 24 | "cli-table3": "^0.6.5", 25 | "colors": "^1.4.0", 26 | "moment": "^2.30.1", 27 | "readline-sync": "^1.4.10" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2024 Dante4rt 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/display.js: -------------------------------------------------------------------------------- 1 | require('colors'); 2 | const readlineSync = require('readline-sync'); 3 | const Table = require('cli-table3'); 4 | 5 | function displayHeader() { 6 | process.stdout.write('\x1Bc'); 7 | console.log('========================================'.cyan); 8 | console.log('= 🚀 Fintopio Airdrop Bot 🚀 ='.cyan); 9 | console.log('= Created by HappyCuanAirdrop ='.cyan); 10 | console.log('= https://t.me/HappyCuanAirdrop ='.cyan); 11 | console.log('========================================'.cyan); 12 | console.log(); 13 | } 14 | 15 | function displayOptions() { 16 | return readlineSync.question( 17 | '\nChoose an option:\n1. 🚀 Auto complete all tasks\n2. 🪐 Auto click asteroid\n3. 📅 Auto daily check-in\n4. 🌱 Auto farming\n5. ❌ Exit\n\nEnter 1, 2, 3, 4, or 5: ' 18 | ); 19 | } 20 | 21 | async function createTable(BEARERS, fetchReferralData) { 22 | const table = new Table({ 23 | head: ['Number', 'Balance', 'Referral(s)', 'Level', 'Rank'], 24 | colWidths: [10, 15, 15, 10, 10], 25 | }); 26 | 27 | let counter = 1; 28 | 29 | for (const BEARER of BEARERS) { 30 | const user = await fetchReferralData(BEARER); 31 | table.push([ 32 | counter, 33 | user.balance, 34 | `${user.activations.used}/${user.activations.total}`, 35 | user.level.name, 36 | user.leaderboard.position, 37 | ]); 38 | counter++; 39 | } 40 | 41 | return table.toString(); 42 | } 43 | 44 | module.exports = { 45 | displayHeader, 46 | displayOptions, 47 | createTable, 48 | }; 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Fintopio Airdrop Bot 2 | 3 | This is an automated bot to help you complete tasks, check in daily, and participate in farming on the Fintopio platform. The bot interacts with Fintopio's API to automate your tasks and save time! 4 | 5 | ## Features 6 | 7 | - ✅ Auto complete all tasks 8 | - 💎 Auto click asteroid (diamond) 9 | - 📅 Auto daily check-in 10 | - 🌱 Auto farming 11 | 12 | ## Installation 13 | 14 | 1. Clone the repository: 15 | 16 | ```bash 17 | git clone https://github.com/dante4rt/fintopio-airdrop-bot.git 18 | cd fintopio-airdrop-bot 19 | ``` 20 | 21 | 2. Install dependencies: 22 | 23 | ```bash 24 | npm install 25 | ``` 26 | 27 | 3. Create a `bearers.json` file in the project root directory. This file will contain the tokens used to authenticate with the Fintopio API. 28 | 29 | ### Format of `bearers.json` 30 | 31 | The `bearers.json` file should be an array of strings, each string being a bearer token for one account: 32 | 33 | ```json 34 | [ 35 | "your_bearer_token_1", 36 | "your_bearer_token_2", 37 | "your_bearer_token_3" 38 | ] 39 | ``` 40 | 41 | ### How to get your Bearer Token 42 | 43 | 1. Open the Fintopio Telegram Bot: [JOIN HERE](https://fintop.io/2uM1qMLs5F) 44 | 2. Right-click anywhere in the bot and select **Inspect** to open the browser's developer tools. 45 | 3. Navigate to the **Console** tab. 46 | 4. Paste the following code in the console: 47 | 48 | ```javascript 49 | console.log(localStorage.getItem(Object.keys(localStorage).find(k => k.startsWith('authToken_')))); 50 | ``` 51 | 52 | 5. The console will print your bearer token. Copy this token and paste it into the `bearers.json` file. 53 | 54 | ## Running the Bot 55 | 56 | After setting up the `bearers.json` file, you can run the bot with the following command: 57 | 58 | ```bash 59 | npm start 60 | ``` 61 | 62 | Follow the instructions in the terminal to select your desired action. 63 | 64 | ## Contributing 65 | 66 | Feel free to submit issues or create pull requests to improve the bot. 67 | 68 | ## Donations 69 | 70 | If you would like to support the development of this project, you can make a donation using the following addresses: 71 | 72 | - **Solana**: `GLQMG8j23ookY8Af1uLUg4CQzuQYhXcx56rkpZkyiJvP` 73 | - **EVM**: `0x960EDa0D16f4D70df60629117ad6e5F1E13B8F44` 74 | - **BTC**: `bc1p9za9ctgwwvc7amdng8gvrjpwhnhnwaxzj3nfv07szqwrsrudfh6qvvxrj8` 75 | 76 | ## License 77 | 78 | This project is licensed under the MIT License. 79 | -------------------------------------------------------------------------------- /src/api.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios'); 2 | const BASE_URL = 'https://fintopio-tg.fintopio.com/api/'; 3 | 4 | async function fetchReferralData(token) { 5 | try { 6 | const { data } = await axios({ 7 | url: BASE_URL + 'referrals/data', 8 | method: 'GET', 9 | headers: { 10 | Authorization: `Bearer ${token}`, 11 | }, 12 | }); 13 | 14 | return data; 15 | } catch (error) { 16 | console.log( 17 | `❌ Error fetching referral data: ${error.response.data.message}`.red 18 | ); 19 | } 20 | } 21 | 22 | async function fetchTasks(token) { 23 | try { 24 | const { data } = await axios({ 25 | url: BASE_URL + 'hold/tasks', 26 | method: 'GET', 27 | headers: { 28 | Authorization: `Bearer ${token}`, 29 | }, 30 | }); 31 | 32 | return data; 33 | } catch (error) { 34 | console.log(`❌ Error fetching tasks: ${error.response.data.message}`.red); 35 | } 36 | } 37 | 38 | async function startTask(token, id) { 39 | try { 40 | const { data } = await axios({ 41 | url: BASE_URL + `hold/tasks/${id}/start`, 42 | method: 'POST', 43 | headers: { 44 | Authorization: `Bearer ${token}`, 45 | }, 46 | data: {}, 47 | }); 48 | 49 | return data; 50 | } catch (error) { 51 | if ( 52 | error.response.data.message.includes('update task') || 53 | error.response.data.message.includes('not found') 54 | ) { 55 | console.log( 56 | `⚠️ Task with ID "${id}" failed to start, please do it manually!`.red 57 | ); 58 | } else { 59 | console.log(`❌ Error starting task: ${error.response.data.message}`.red); 60 | } 61 | } 62 | } 63 | 64 | async function claimTask(token, id) { 65 | try { 66 | const { data } = await axios({ 67 | url: BASE_URL + `hold/tasks/${id}/claim`, 68 | method: 'POST', 69 | headers: { 70 | Authorization: `Bearer ${token}`, 71 | }, 72 | data: {}, 73 | }); 74 | 75 | return data; 76 | } catch (error) { 77 | if ( 78 | error.response.data.message.includes('update task') || 79 | error.response.data.message.includes('not found') 80 | ) { 81 | console.log( 82 | `⚠️ Task with ID "${id}" failed to claim, please do it manually!`.red 83 | ); 84 | } else { 85 | console.log(`❌ Error claiming task: ${error.response.data.message}`.red); 86 | } 87 | } 88 | } 89 | 90 | async function dailyCheckin(token) { 91 | try { 92 | const { data } = await axios({ 93 | url: BASE_URL + 'daily-checkins', 94 | method: 'POST', 95 | headers: { 96 | Authorization: `Bearer ${token}`, 97 | }, 98 | data: {}, 99 | }); 100 | 101 | return data; 102 | } catch (error) { 103 | console.log(`❌ Error during daily check-in: ${error}`); 104 | } 105 | } 106 | 107 | async function startFarming(token) { 108 | try { 109 | const { data } = await axios({ 110 | url: BASE_URL + 'farming/farm', 111 | method: 'POST', 112 | headers: { 113 | Authorization: `Bearer ${token}`, 114 | }, 115 | data: {}, 116 | }); 117 | 118 | return data; 119 | } catch (error) { 120 | if (error.response.data.message.includes('already started')) { 121 | console.log(`⚠️ Farming already started, try again later!`.red); 122 | } else { 123 | console.log(`❌ Error starting farming: ${error}`); 124 | } 125 | } 126 | } 127 | 128 | async function claimFarming(token) { 129 | const { data } = await axios({ 130 | url: BASE_URL + 'farming/claim', 131 | method: 'POST', 132 | headers: { 133 | Authorization: `Bearer ${token}`, 134 | }, 135 | data: {}, 136 | }); 137 | 138 | return data; 139 | } 140 | 141 | async function fetchDiamond(token) { 142 | try { 143 | const { data } = await axios({ 144 | url: BASE_URL + 'clicker/diamond/state', 145 | method: 'GET', 146 | headers: { 147 | Authorization: `Bearer ${token}`, 148 | }, 149 | }); 150 | 151 | return data; 152 | } catch (error) { 153 | console.log( 154 | `❌ Error fetching diamond: ${error.response.data.message}`.red 155 | ); 156 | } 157 | } 158 | 159 | async function claimDiamond(token, id) { 160 | try { 161 | const { data } = await axios({ 162 | url: BASE_URL + 'clicker/diamond/complete', 163 | method: 'POST', 164 | headers: { 165 | Authorization: `Bearer ${token}`, 166 | }, 167 | data: { 168 | diamondNumber: id, 169 | }, 170 | }); 171 | 172 | return data; 173 | } catch (error) { 174 | throw error; 175 | } 176 | } 177 | 178 | module.exports = { 179 | fetchReferralData, 180 | fetchTasks, 181 | startTask, 182 | claimTask, 183 | dailyCheckin, 184 | startFarming, 185 | claimFarming, 186 | fetchDiamond, 187 | claimDiamond, 188 | }; 189 | -------------------------------------------------------------------------------- /src/tasks.js: -------------------------------------------------------------------------------- 1 | const readlineSync = require('readline-sync'); 2 | const { 3 | fetchReferralData, 4 | claimFarming, 5 | startFarming, 6 | fetchTasks, 7 | startTask, 8 | claimTask, 9 | dailyCheckin, 10 | fetchDiamond, 11 | claimDiamond, 12 | } = require('./api'); 13 | const { displayHeader, createTable } = require('./display'); 14 | const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); 15 | const moment = require('moment'); 16 | 17 | async function automaticFlow(BEARERS) { 18 | while (true) { 19 | try { 20 | console.log('📅 Auto daily check-in...'.yellow); 21 | await handleDailyCheckin(BEARERS); 22 | 23 | console.log('\n💎 Auto cracking diamond...'.yellow); 24 | await handleDiamond(BEARERS); 25 | 26 | console.log('\n🌱 Auto farming...'.yellow); 27 | await handleFarming(BEARERS); 28 | } catch (error) { 29 | console.log(`❌ Error in automatic flow: ${error.message}`.red); 30 | } 31 | 32 | console.log('\n⏳ Waiting 30 minutes before the next run...'.yellow); 33 | console.log( 34 | "📢 While waiting, don't forget to subscribe to https://t.me/HappyCuanAirdrop for the latest and best airdrops and bots!\n" 35 | .cyan 36 | ); 37 | await delay(30 * 60 * 1000); 38 | } 39 | } 40 | 41 | async function oneTimeFlow(BEARERS) { 42 | try { 43 | const options = readlineSync.question(` 44 | Choose an option: 45 | 1. 🚀 Auto complete all tasks 46 | 2. 🪐 Auto click asteroid 47 | 3. 📅 Auto daily check-in 48 | 4. 🌱 Auto farming 49 | 5. ❌ Exit 50 | 51 | Enter 1, 2, 3, 4, or 5: `); 52 | 53 | if (options === '5') { 54 | console.log('👋 Exiting the bot. See you next time!'.cyan); 55 | console.log('Subscribe: https://t.me/HappyCuanAirdrop.'.green); 56 | process.exit(0); 57 | } 58 | 59 | if (options === '1') { 60 | await handleAllTasks(BEARERS); 61 | } else if (options === '2') { 62 | await handleDiamond(BEARERS); 63 | } else if (options === '3') { 64 | await handleDailyCheckin(BEARERS); 65 | } else if (options === '4') { 66 | await handleFarming(BEARERS); 67 | } else { 68 | console.log('Invalid option!'.red); 69 | } 70 | } catch (error) { 71 | console.log(`❌ Error: ${error.message}`.red); 72 | } 73 | } 74 | 75 | async function handleAllTasks(BEARERS) { 76 | for (const [index, BEARER] of BEARERS.entries()) { 77 | const tasks = await fetchTasks(BEARER); 78 | 79 | if (tasks) { 80 | console.log(`#️⃣ ${index + 1} Account:`); 81 | 82 | for (const item of tasks.tasks) { 83 | if (item.status === 'available') { 84 | console.log(`🚀 Starting '${item.slug}' task...`.yellow); 85 | 86 | const startedTask = await startTask(BEARER, item.id); 87 | 88 | if (startedTask.status === 'verifying') { 89 | console.log(`✔️ Task "${item.slug}" started!`.green); 90 | 91 | console.log(`🛠 Claiming ${item.slug} task...`.yellow); 92 | const claimedTask = await claimTask(BEARER, item.id); 93 | 94 | await delay(1000); 95 | 96 | if (claimedTask) { 97 | console.log( 98 | `✔️ Task "${item.slug}" claimed! Congrats! 🎉 `.green 99 | ); 100 | } 101 | } 102 | } else { 103 | console.log(`🛠 Claiming ${item.slug} task...`.yellow); 104 | 105 | const claimedTask = await claimTask(BEARER, item.id); 106 | await delay(1000); 107 | 108 | if (claimedTask) { 109 | console.log(`✔️ Task "${item.slug}" claimed! Congrats! 🎉 `.green); 110 | } 111 | } 112 | } 113 | } 114 | } 115 | } 116 | 117 | async function handleDiamond(BEARERS) { 118 | for (const [index, BEARER] of BEARERS.entries()) { 119 | console.log(`#️⃣ ${index + 1} Account:`); 120 | 121 | try { 122 | const getDiamondo = await fetchDiamond(BEARER); 123 | 124 | if (getDiamondo.state === 'unavailable') { 125 | console.log( 126 | `❌ Your diamond is not available, please try again on ${moment( 127 | getDiamondo.timings.nextAt 128 | ).format('MMMM Do YYYY, h:mm:ss a')}`.red 129 | ); 130 | } else { 131 | console.log(`Please wait, we will crack the diamond...`.yellow); 132 | await delay(1000); 133 | await claimDiamond(BEARER, getDiamondo.diamondNumber); 134 | 135 | console.log( 136 | `Diamond has been cracked! You get ${getDiamondo.settings.totalReward} 💎` 137 | .green 138 | ); 139 | } 140 | } catch (error) { 141 | console.log( 142 | `❌ Error cracking diamond: ${ 143 | error.response?.data ? error.response.data.message : error.message 144 | }`.red 145 | ); 146 | } 147 | await delay(500); 148 | } 149 | } 150 | 151 | async function handleDailyCheckin(BEARERS) { 152 | for (const [index, BEARER] of BEARERS.entries()) { 153 | console.log(`#️⃣ ${index + 1} Account:`); 154 | 155 | const checkinData = await dailyCheckin(BEARER); 156 | 157 | if (checkinData.dailyReward) { 158 | console.log(`✔️ Daily check-in successful!`.green); 159 | } else { 160 | console.log( 161 | `📅 You've already done the daily check-in. Try again tomorrow!`.red 162 | ); 163 | } 164 | 165 | console.log(`📅 Total daily check-ins: ${checkinData.totalDays}`.green); 166 | console.log(`💰 Daily reward: ${checkinData.dailyReward}`.green); 167 | console.log(`💵 Balance after check-in: ${checkinData.balance}`.green); 168 | } 169 | } 170 | 171 | async function handleFarming(BEARERS) { 172 | for (const [index, BEARER] of BEARERS.entries()) { 173 | console.log(`#️⃣ ${index + 1} Account:`); 174 | 175 | try { 176 | const farm = await claimFarming(BEARER); 177 | 178 | if (farm) { 179 | console.log(`🌱 Farming started!`.green); 180 | console.log( 181 | `🌱 Start time: ${moment(farm.timings.start).format( 182 | 'MMMM Do YYYY, h:mm:ss a' 183 | )}`.green 184 | ); 185 | console.log( 186 | `🌾 End time: ${moment(farm.timings.finish).format( 187 | 'MMMM Do YYYY, h:mm:ss a' 188 | )}`.green 189 | ); 190 | } 191 | } catch (error) { 192 | if (error.response?.data?.message.includes('not finished yet')) { 193 | console.log( 194 | `⚠️ Farming not finished yet, attempting to start new farming...` 195 | .yellow 196 | ); 197 | 198 | const reFarm = await startFarming(BEARER); 199 | 200 | if (reFarm) { 201 | console.log(`🌱 Re-farming started!`.green); 202 | console.log( 203 | `🌱 Start time: ${moment(reFarm.timings.start).format( 204 | 'MMMM Do YYYY, h:mm:ss a' 205 | )}`.green 206 | ); 207 | console.log( 208 | `🌾 End time: ${moment(reFarm.timings.finish).format( 209 | 'MMMM Do YYYY, h:mm:ss a' 210 | )}`.green 211 | ); 212 | } 213 | } else { 214 | console.log( 215 | `❌ Error handling farming: ${ 216 | error.response?.data?.message || error.message 217 | }`.red 218 | ); 219 | } 220 | } 221 | } 222 | } 223 | 224 | async function handleTasks(BEARERS) { 225 | displayHeader(); 226 | console.log(`🚀 Fetching data, please wait...\n`.yellow); 227 | 228 | const table = await createTable(BEARERS, fetchReferralData); 229 | console.log(table); 230 | 231 | const mode = process.argv[2] || readlineSync.question( 232 | 'Do you want to run the bot one-time (1) or continuously (2)?\n\nEnter 1 or 2: ' 233 | ); 234 | 235 | if (mode === '1') { 236 | await oneTimeFlow(BEARERS); 237 | } else if (mode === '2') { 238 | console.log('Starting automatic flow...'.cyan); 239 | await automaticFlow(BEARERS); 240 | } else { 241 | console.log('Invalid option!'.red); 242 | } 243 | } 244 | 245 | module.exports = { 246 | handleTasks, 247 | }; 248 | --------------------------------------------------------------------------------