├── token.txt ├── README.md ├── package.json └── index.js /token.txt: -------------------------------------------------------------------------------- 1 | eyj... 2 | eyj... -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnichAutoBot-NTE 2 | Full Tutorial Join https://t.me/NTExhaust 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NT EXHAUST - UNICH AUTO MINiNG", 3 | "version": "1.0.0", 4 | "description": "BOT UNICH AUTO MINiNG", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "type": "module", 13 | "dependencies": { 14 | "axios": "^1.9.0", 15 | "blessed": "^0.1.81", 16 | "cfonts": "^3.3.0", 17 | "chalk": "^5.3.0", 18 | "https-proxy-agent": "^7.0.6", 19 | "socks-proxy-agent": "^8.0.5" 20 | } 21 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import blessed from 'blessed'; 2 | import axios from 'axios'; 3 | import chalk from 'chalk'; 4 | import fs from 'fs/promises'; 5 | import path from 'path'; 6 | import { fileURLToPath } from 'url'; 7 | import cfonts from 'cfonts'; 8 | import { SocksProxyAgent } from 'socks-proxy-agent'; 9 | import { HttpsProxyAgent } from 'https-proxy-agent'; 10 | 11 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 12 | 13 | class UnichMiner { 14 | constructor(token, proxy = null, id) { 15 | this.token = token; 16 | this.proxy = proxy; 17 | this.id = id; 18 | this.userInfo = {}; 19 | this.status = 'Idle'; 20 | this.nextMining = '-'; 21 | this.totalPoints = 0; 22 | this.countdownInterval = null; 23 | this.uiScreen = null; 24 | this.accountPane = null; 25 | this.logPane = null; 26 | this.isDisplayed = false; 27 | this.logs = []; 28 | this.email = 'N/A'; 29 | this.ipAddress = 'N/A'; 30 | } 31 | 32 | async start() { 33 | await this.fetchIpAddress(); 34 | await this.fetchUserInfo(); 35 | this.startCountdown(); 36 | } 37 | 38 | async fetchIpAddress() { 39 | try { 40 | let config = { 41 | headers: { 42 | 'user-agent': this.getRandomUserAgent(), 43 | 'accept': 'application/json, text/plain, */*', 44 | }, 45 | }; 46 | if (this.proxy) { 47 | const agent = this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url); 48 | config = { ...config, httpsAgent: agent, httpAgent: agent }; 49 | this.addLog(chalk.yellow(`Using proxy: ${this.proxy.url} (${this.proxy.type})`)); 50 | } else { 51 | this.addLog(chalk.yellow('No proxy configured')); 52 | } 53 | const response = await axios.get('https://api.ipify.org?format=json', config); 54 | this.ipAddress = response.data.ip; 55 | } catch (error) { 56 | this.ipAddress = 'Unknown'; 57 | this.addLog(chalk.red(`Failed to fetch IP: ${error.message}`)); 58 | } 59 | } 60 | 61 | async fetchUserInfo() { 62 | try { 63 | const response = await axios.get('https://api.unich.com/airdrop/user/v1/info/my-info', { 64 | headers: { 65 | 'authorization': `Bearer ${this.token}`, 66 | 'user-agent': this.getRandomUserAgent(), 67 | 'accept': 'application/json, text/plain, */*', 68 | 'accept-encoding': 'gzip, deflate, br, zstd', 69 | 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 70 | 'cache-control': 'no-cache', 71 | 'origin': 'https://unich.com', 72 | 'pragma': 'no-cache', 73 | 'priority': 'u=1, i', 74 | 'referer': 'https://unich.com/', 75 | 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Opera";v="119"', 76 | 'sec-ch-ua-mobile': '?0', 77 | 'sec-ch-ua-platform': '"Windows"', 78 | 'sec-fetch-dest': 'empty', 79 | 'sec-fetch-mode': 'cors', 80 | 'sec-fetch-site': 'same-site', 81 | }, 82 | ...(this.proxy ? { 83 | httpsAgent: this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url), 84 | httpAgent: this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url), 85 | } : {}), 86 | }); 87 | const data = response.data.data; 88 | this.userInfo = data; 89 | this.email = data.email; 90 | this.totalPoints = data.mUn || 0; 91 | this.addLog(chalk.green('User info fetched successfully')); 92 | if (data.mining.todayMining.started) { 93 | this.status = 'Mining Started'; 94 | this.nextMining = this.formatTime(data.mining.todayMining.remainingTimeInMillis); 95 | this.addLog(chalk.green('Mining is running')); 96 | } else { 97 | this.status = 'Idle'; 98 | this.nextMining = '-'; 99 | this.addLog(chalk.yellow('Mining is not running')); 100 | await this.startMining(); 101 | } 102 | } catch (error) { 103 | this.addLog(chalk.red(`Failed to fetch user info: ${error.message}`)); 104 | if (error.response && error.response.status === 401) { 105 | this.addLog(chalk.red('Invalid token: Unauthorized (401)')); 106 | this.status = 'Error'; 107 | } 108 | } 109 | this.refreshDisplay(); 110 | } 111 | 112 | async startMining() { 113 | try { 114 | await axios.post('https://api.unich.com/airdrop/user/v1/mining/start', {}, { 115 | headers: { 116 | 'authorization': `Bearer ${this.token}`, 117 | 'user-agent': this.getRandomUserAgent(), 118 | 'accept': 'application/json, text/plain, */*', 119 | 'accept-encoding': 'gzip, deflate, br, zstd', 120 | 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 121 | 'cache-control': 'no-cache', 122 | 'origin': 'https://unich.com', 123 | 'pragma': 'no-cache', 124 | 'priority': 'u=1, i', 125 | 'referer': 'https://unich.com/', 126 | 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Opera";v="119"', 127 | 'sec-ch-ua-mobile': '?0', 128 | 'sec-ch-ua-platform': '"Windows"', 129 | 'sec-fetch-dest': 'empty', 130 | 'sec-fetch-mode': 'cors', 131 | 'sec-fetch-site': 'same-site', 132 | }, 133 | ...(this.proxy ? { 134 | httpsAgent: this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url), 135 | httpAgent: this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url), 136 | } : {}), 137 | }); 138 | this.addLog(chalk.green('Mining started successfully')); 139 | await this.updateUserInfo(); 140 | } catch (error) { 141 | this.addLog(chalk.red(`Failed to start mining: ${error.message}`)); 142 | if (error.response && error.response.status === 401) { 143 | this.addLog(chalk.red('Invalid token: Unauthorized (401)')); 144 | this.status = 'Error'; 145 | } 146 | this.refreshDisplay(); 147 | } 148 | } 149 | 150 | async updateUserInfo() { 151 | try { 152 | const response = await axios.get('https://api.unich.com/airdrop/user/v1/info/my-info', { 153 | headers: { 154 | 'authorization': `Bearer ${this.token}`, 155 | 'user-agent': this.getRandomUserAgent(), 156 | 'accept': 'application/json, text/plain, */*', 157 | 'accept-encoding': 'gzip, deflate, br, zstd', 158 | 'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8', 159 | 'cache-control': 'no-cache', 160 | 'origin': 'https://unich.com', 161 | 'pragma': 'no-cache', 162 | 'priority': 'u=1, i', 163 | 'referer': 'https://unich.com/', 164 | 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Opera";v="119"', 165 | 'sec-ch-ua-mobile': '?0', 166 | 'sec-ch-ua-platform': '"Windows"', 167 | 'sec-fetch-dest': 'empty', 168 | 'sec-fetch-mode': 'cors', 169 | 'sec-fetch-site': 'same-site', 170 | }, 171 | ...(this.proxy ? { 172 | httpsAgent: this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url), 173 | httpAgent: this.proxy.type === 'socks5' ? new SocksProxyAgent(this.proxy.url) : new HttpsProxyAgent(this.proxy.url), 174 | } : {}), 175 | }); 176 | const data = response.data.data; 177 | this.userInfo = data; 178 | this.email = data.email; 179 | this.totalPoints = data.mUn || 0; 180 | if (data.mining.todayMining.started) { 181 | this.status = 'Mining Started'; 182 | this.nextMining = this.formatTime(data.mining.todayMining.remainingTimeInMillis); 183 | this.addLog(chalk.green('Mining is running')); 184 | } else { 185 | this.status = 'Idle'; 186 | this.nextMining = '-'; 187 | this.addLog(chalk.yellow('Mining is not running')); 188 | } 189 | this.refreshDisplay(); 190 | } catch (error) { 191 | this.addLog(chalk.red(`Failed to update user info: ${error.message}`)); 192 | if (error.response && error.response.status === 401) { 193 | this.addLog(chalk.red('Invalid token: Unauthorized (401)')); 194 | this.status = 'Error'; 195 | } 196 | this.refreshDisplay(); 197 | } 198 | } 199 | 200 | startCountdown() { 201 | if (this.countdownInterval) { 202 | clearInterval(this.countdownInterval); 203 | } 204 | this.countdownInterval = setInterval(() => { 205 | if (this.userInfo.mining && this.userInfo.mining.todayMining.started) { 206 | const remaining = this.userInfo.mining.todayMining.remainingTimeInMillis - 1000; 207 | if (remaining <= 0) { 208 | this.userInfo.mining.todayMining.remainingTimeInMillis = 0; 209 | this.nextMining = '-'; 210 | this.status = 'Idle'; 211 | this.addLog(chalk.yellow('Mining is not running')); 212 | setTimeout(() => this.fetchUserInfo(), 10000); 213 | } else { 214 | this.userInfo.mining.todayMining.remainingTimeInMillis = remaining; 215 | this.nextMining = this.formatTime(remaining); 216 | } 217 | this.refreshDisplay(); 218 | } 219 | }, 1000); 220 | } 221 | 222 | formatTime(millis) { 223 | const seconds = Math.floor(millis / 1000); 224 | const hours = Math.floor(seconds / 3600); 225 | const minutes = Math.floor((seconds % 3600) / 60); 226 | const secs = seconds % 60; 227 | return `${hours}h ${minutes}m ${secs}s`; 228 | } 229 | 230 | getRandomUserAgent() { 231 | const userAgents = [ 232 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 OPR/119.0.0.0 (Edition cdf)', 233 | 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36', 234 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0', 235 | 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0', 236 | ]; 237 | return userAgents[Math.floor(Math.random() * userAgents.length)]; 238 | } 239 | 240 | addLog(message) { 241 | const timestamp = new Date().toLocaleTimeString(); 242 | const logMessage = `[${timestamp}] [Account ${this.id}] ${message.replace(/\{[^}]+\}/g, '')}`; 243 | this.logs.push(logMessage); 244 | if (this.logs.length > 100) this.logs.shift(); 245 | if (this.logPane && this.isDisplayed) { 246 | this.logPane.setContent(this.logs.join('\n')); 247 | this.logPane.setScrollPerc(100); 248 | this.uiScreen.render(); 249 | } 250 | } 251 | 252 | refreshDisplay() { 253 | if (!this.isDisplayed || !this.accountPane || !this.logPane) return; 254 | const statusColor = this.status === 'Mining Started' ? 'green' : this.status === 'Error' ? 'red' : 'yellow'; 255 | const info = ` 256 | Email Address : {magenta-fg}${this.email}{/magenta-fg} 257 | Total Points : {green-fg}${this.totalPoints}{/green-fg} 258 | Status : {${statusColor}-fg}${this.status}{/} 259 | Next Mining : {yellow-fg}${this.nextMining}{/yellow-fg} 260 | IP Address : {cyan-fg}${this.ipAddress}{/cyan-fg} 261 | Proxy : {cyan-fg}${this.proxy ? `${this.proxy.url} (${this.proxy.type})` : 'None'}{/cyan-fg} 262 | `; 263 | this.accountPane.setContent(info); 264 | this.logPane.setContent(this.logs.join('\n')); 265 | this.logPane.setScrollPerc(100); 266 | this.uiScreen.render(); 267 | } 268 | 269 | static async loadTokens() { 270 | try { 271 | const filePath = path.join(__dirname, 'token.txt'); 272 | const data = await fs.readFile(filePath, 'utf8'); 273 | const tokens = data.split('\n') 274 | .map(line => line.trim()) 275 | .filter(line => line !== '') 276 | .map((token, index) => ({ id: index + 1, token })); 277 | if (!tokens.length) { 278 | console.error('[ERROR] token.txt is empty'); 279 | return []; 280 | } 281 | return tokens; 282 | } catch (error) { 283 | console.error(`[ERROR] Failed to load token.txt: ${error.message}`); 284 | return []; 285 | } 286 | } 287 | 288 | static async loadProxies() { 289 | const proxies = []; 290 | try { 291 | const filePath = path.join(__dirname, 'proxy.txt'); 292 | const data = await fs.readFile(filePath, 'utf8'); 293 | const lines = data.split('\n') 294 | .map(line => line.trim()) 295 | .filter(line => line !== ''); 296 | for (const line of lines) { 297 | const proxyRegex = /^(socks5|http|https):\/\/(?:([^:@]+):([^@]+)@)?([^:]+):(\d+)$/i; 298 | const match = line.match(proxyRegex); 299 | if (!match) { 300 | proxies.push({ error: `Invalid proxy format: ${line}. Expected 'socks5://[user:pass@]host:port' or 'http(s)://[user:pass@]host:port', skipping.` }); 301 | continue; 302 | } 303 | const [, scheme, username, password, host, port] = match; 304 | const type = scheme.toLowerCase() === 'socks5' ? 'socks5' : 'http'; 305 | const auth = username && password ? `${username}:${password}@` : ''; 306 | const url = `${scheme}://${auth}${host}:${port}`; 307 | proxies.push({ type, url }); 308 | } 309 | if (!proxies.filter(p => !p.error).length) { 310 | proxies.push({ error: 'No valid proxies found in proxy.txt. Running without proxy.' }); 311 | } 312 | return proxies; 313 | } catch (error) { 314 | proxies.push({ error: `Failed to read proxy.txt: ${error.message}. Running without proxy.` }); 315 | return proxies; 316 | } 317 | } 318 | } 319 | 320 | async function main() { 321 | const screen = blessed.screen({ 322 | smartCSR: true, 323 | title: 'Unich Auto Mining', 324 | }); 325 | 326 | const headerPane = blessed.box({ 327 | top: 0, 328 | left: 0, 329 | width: '100%', 330 | height: 7, 331 | tags: true, 332 | align: 'left', 333 | }); 334 | screen.append(headerPane); 335 | 336 | function renderBanner() { 337 | const threshold = 80; 338 | const margin = Math.max(screen.width - 80, 0); 339 | let art = ""; 340 | if (screen.width >= threshold) { 341 | art = cfonts.render('NT EXHAUST', { 342 | font: 'block', 343 | align: 'center', 344 | colors: ['cyan', 'magenta'], 345 | background: 'transparent', 346 | letterSpacing: 1, 347 | lineHeight: 1, 348 | space: true, 349 | maxLength: screen.width - margin, 350 | }).string; 351 | } else { 352 | art = cfonts.render('NT EXHAUST', { 353 | font: 'tiny', 354 | align: 'center', 355 | colors: ['cyan', 'magenta'], 356 | background: 'transparent', 357 | letterSpacing: 1, 358 | lineHeight: 1, 359 | space: true, 360 | maxLength: screen.width - margin, 361 | }).string; 362 | } 363 | headerPane.setContent(art + '\n'); 364 | headerPane.height = Math.min(8, art.split('\n').length + 2); 365 | } 366 | renderBanner(); 367 | 368 | const channelPane2 = blessed.box({ 369 | top: '28%', 370 | left: 2, 371 | width: '100%', 372 | height: 2, 373 | tags: false, 374 | align: 'center', 375 | }); 376 | channelPane2.setContent('✪ BOT UNICH AUTO MINING ✪'); 377 | screen.append(channelPane2); 378 | 379 | const infoPane = blessed.box({ 380 | bottom: 0, 381 | left: 'center', 382 | width: '100%', 383 | height: 2, 384 | tags: true, 385 | align: 'center', 386 | }); 387 | screen.append(infoPane); 388 | 389 | const dashTop = headerPane.height + channelPane2.height; 390 | const accountPane = blessed.box({ 391 | top: dashTop, 392 | left: 0, 393 | width: '50%', 394 | height: '60%', 395 | border: { type: 'line' }, 396 | label: ' User Info ', 397 | tags: true, 398 | style: { border: { fg: 'cyan' }, fg: 'white', bg: 'default' }, 399 | }); 400 | screen.append(accountPane); 401 | 402 | const logPane = blessed.log({ 403 | top: dashTop, 404 | left: '50%', 405 | width: '50%', 406 | height: '60%', 407 | border: { type: 'line' }, 408 | label: ' System Logs ', 409 | tags: true, 410 | style: { border: { fg: 'magenta' }, fg: 'white', bg: 'default' }, 411 | scrollable: true, 412 | scrollbar: { bg: 'blue', fg: 'white' }, 413 | alwaysScroll: true, 414 | mouse: true, 415 | keys: true, 416 | }); 417 | screen.append(logPane); 418 | 419 | logPane.on('keypress', (ch, key) => { 420 | if (key.name === 'up') { 421 | logPane.scroll(-1); 422 | screen.render(); 423 | } else if (key.name === 'down') { 424 | logPane.scroll(1); 425 | screen.render(); 426 | } else if (key.name === 'pageup') { 427 | logPane.scroll(-10); 428 | screen.render(); 429 | } else if (key.name === 'pagedown') { 430 | logPane.scroll(10); 431 | screen.render(); 432 | } 433 | }); 434 | 435 | logPane.on('mouse', (data) => { 436 | if (data.action === 'wheelup') { 437 | logPane.scroll(-2); 438 | screen.render(); 439 | } else if (data.action === 'wheeldown') { 440 | logPane.scroll(2); 441 | screen.render(); 442 | } 443 | }); 444 | 445 | let tokens = await UnichMiner.loadTokens(); 446 | let proxies = await UnichMiner.loadProxies(); 447 | let activeIndex = 0; 448 | let miners = []; 449 | 450 | function updateMiners() { 451 | miners.forEach(miner => { 452 | if (miner.countdownInterval) { 453 | clearInterval(miner.countdownInterval); 454 | } 455 | }); 456 | miners = tokens.map((token, idx) => { 457 | const proxyEntry = proxies[idx % proxies.length] || null; 458 | const proxy = proxyEntry && !proxyEntry.error ? { ...proxyEntry } : null; 459 | const miner = new UnichMiner(token.token, proxy, token.id); 460 | miner.uiScreen = screen; 461 | miner.accountPane = accountPane; 462 | miner.logPane = logPane; 463 | if (proxyEntry && proxyEntry.error) { 464 | miner.addLog(chalk.yellow(proxyEntry.error)); 465 | } 466 | return miner; 467 | }); 468 | 469 | if (miners.length > 0) { 470 | miners[activeIndex].isDisplayed = true; 471 | miners[activeIndex].addLog(chalk.green('Miner initialized successfully')); 472 | miners[activeIndex].refreshDisplay(); 473 | miners.forEach(miner => miner.start()); 474 | } else { 475 | logPane.setContent('No valid tokens found in token.txt.\nPress \'q\' or Ctrl+C to exit.'); 476 | accountPane.setContent(''); 477 | screen.render(); 478 | } 479 | } 480 | 481 | updateMiners(); 482 | 483 | if (!miners.length) { 484 | screen.key(['escape', 'q', 'C-c'], () => { 485 | screen.destroy(); 486 | process.exit(0); 487 | }); 488 | screen.render(); 489 | return; 490 | } 491 | 492 | infoPane.setContent(`Current Account: ${miners.length > 0 ? activeIndex + 1 : 0}/${miners.length} | Use Left/Right arrow keys to switch accounts.`); 493 | 494 | screen.key(['escape', 'q', 'C-c'], () => { 495 | miners.forEach(miner => { 496 | if (miner.countdownInterval) { 497 | clearInterval(miner.countdownInterval); 498 | } 499 | miner.addLog(chalk.yellow('Miner stopped')); 500 | }); 501 | screen.destroy(); 502 | process.exit(0); 503 | }); 504 | 505 | screen.key(['right'], () => { 506 | if (miners.length === 0) return; 507 | miners[activeIndex].isDisplayed = false; 508 | activeIndex = (activeIndex + 1) % miners.length; 509 | miners[activeIndex].isDisplayed = true; 510 | miners[activeIndex].refreshDisplay(); 511 | infoPane.setContent(`Current Account: ${activeIndex + 1}/${miners.length} | Use Left/Right arrow keys to switch accounts.`); 512 | screen.render(); 513 | }); 514 | 515 | screen.key(['left'], () => { 516 | if (miners.length === 0) return; 517 | miners[activeIndex].isDisplayed = false; 518 | activeIndex = (activeIndex - 1 + miners.length) % miners.length; 519 | miners[activeIndex].isDisplayed = true; 520 | miners[activeIndex].refreshDisplay(); 521 | infoPane.setContent(`Current Account: ${activeIndex + 1}/${miners.length} | Use Left/Right arrow keys to switch accounts.`); 522 | screen.render(); 523 | }); 524 | 525 | screen.key(['tab'], () => { 526 | logPane.focus(); 527 | screen.render(); 528 | }); 529 | 530 | screen.on('resize', () => { 531 | renderBanner(); 532 | headerPane.width = '100%'; 533 | channelPane2.top = headerPane.height; 534 | accountPane.top = dashTop; 535 | logPane.top = dashTop; 536 | screen.render(); 537 | }); 538 | 539 | screen.render(); 540 | } 541 | 542 | main().catch(error => { 543 | console.error(`[ERROR] Failed to start: ${error.message}`); 544 | const screen = blessed.screen({ smartCSR: true, title: 'Unich Miner' }); 545 | const logPane = blessed.box({ 546 | top: 'center', 547 | left: 'center', 548 | width: '80%', 549 | height: '100%', 550 | border: { type: 'line' }, 551 | label: ' System Logs ', 552 | content: `Failed to start: ${error.message}\nPlease fix the issue and restart.\nPress 'q' or Ctrl+C to exit`, 553 | style: { border: { fg: 'red' }, fg: 'blue', bg: 'default' }, 554 | }); 555 | screen.append(logPane); 556 | screen.key(['escape', 'q', 'C-c'], () => { 557 | screen.destroy(); 558 | process.exit(0); 559 | }); 560 | screen.render(); 561 | }); --------------------------------------------------------------------------------