├── .env ├── README.md ├── index.js └── package.json /.env: -------------------------------------------------------------------------------- 1 | RPC_URL=https://sepolia.base.org 2 | PRIVATE_KEY= -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PriorAutoBot-NTE 2 | Full Tutorial Join https://t.me/NTExhaust 3 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import blessed from "blessed"; 3 | import figlet from "figlet"; 4 | import { ethers } from "ethers"; 5 | 6 | const RPC_URL = process.env.RPC_URL; 7 | const PRIVATE_KEY = process.env.PRIVATE_KEY; 8 | const USDC_ADDRESS = "0x109694D75363A75317A8136D80f50F871E81044e"; 9 | const USDT_ADDRESS = "0x014397DaEa96CaC46DbEdcbce50A42D5e0152B2E"; 10 | const PRIOR_ADDRESS = "0xc19Ec2EEBB009b2422514C51F9118026f1cD89ba"; 11 | const routerAddress = "0x0f1DADEcc263eB79AE3e4db0d57c49a8b6178B0B"; 12 | const FAUCET_ADDRESS = "0xCa602D9E45E1Ed25105Ee43643ea936B8e2Fd6B7"; 13 | const NETWORK_NAME = "PRIOR TESTNET"; 14 | 15 | let walletInfo = { 16 | address: "", 17 | balanceETH: "0.00", 18 | balancePrior: "0.00", 19 | balanceUSDC: "0.00", 20 | balanceUSDT: "0.00", 21 | network: "Prior Testnet", 22 | status: "Initializing" 23 | }; 24 | let transactionLogs = []; 25 | let priorSwapRunning = false; 26 | let priorSwapCancelled = false; 27 | let globalWallet = null; 28 | 29 | const ERC20_ABI = [ 30 | "function balanceOf(address owner) view returns (uint256)", 31 | "function approve(address spender, uint256 amount) returns (bool)", 32 | "function allowance(address owner, address spender) view returns (uint256)", 33 | "function transfer(address to, uint256 amount) returns (bool)", 34 | "function transferFrom(address from, address to, uint256 amount) returns (bool)" 35 | ]; 36 | 37 | const routerABI = [ 38 | { 39 | "inputs": [ 40 | { "internalType": "uint256", "name": "varg0", "type": "uint256" } 41 | ], 42 | "name": "swapPriorToUSDC", 43 | "outputs": [], 44 | "stateMutability": "nonpayable", 45 | "type": "function" 46 | }, 47 | { 48 | "inputs": [ 49 | { "internalType": "uint256", "name": "varg0", "type": "uint256" } 50 | ], 51 | "name": "swapPriorToUSDT", 52 | "outputs": [], 53 | "stateMutability": "nonpayable", 54 | "type": "function" 55 | } 56 | ]; 57 | 58 | const FAUCET_ABI = [ 59 | "function claimTokens() external", 60 | "function lastClaimTime(address) view returns (uint256)", 61 | "function claimCooldown() view returns (uint256)", 62 | "function claimAmount() view returns (uint256)" 63 | ]; 64 | 65 | function getShortAddress(address) { 66 | return address.slice(0, 6) + "..." + address.slice(-4); 67 | } 68 | 69 | function addLog(message, type) { 70 | const timestamp = new Date().toLocaleTimeString(); 71 | let coloredMessage = message; 72 | if (type === "prior") { 73 | coloredMessage = `{bright-magenta-fg}${message}{/bright-magenta-fg}`; 74 | } else if (type === "system") { 75 | coloredMessage = `{bright-white-fg}${message}{/bright-white-fg}`; 76 | } else if (type === "error") { 77 | coloredMessage = `{bright-red-fg}${message}{/bright-red-fg}`; 78 | } else if (type === "success") { 79 | coloredMessage = `{bright-green-fg}${message}{/bright-green-fg}`; 80 | } else if (type === "warning") { 81 | coloredMessage = `{bright-yellow-fg}${message}{/bright-yellow-fg}`; 82 | } 83 | transactionLogs.push(`{bright-cyan-fg}[{/bright-cyan-fg} {bold}{grey-fg}${timestamp}{/grey-fg}{/bold} {bright-cyan-fg}]{/bright-cyan-fg} {bold}${coloredMessage}{/bold}`); 84 | updateLogs(); 85 | } 86 | 87 | function delay(ms) { 88 | return new Promise(resolve => setTimeout(resolve, ms)); 89 | } 90 | 91 | 92 | function getRandomDelay() { 93 | return Math.random() * (60000 - 30000) + 30000; 94 | } 95 | 96 | function getRandomNumber(min, max) { 97 | return Math.random() * (max - min) + min; 98 | } 99 | 100 | function getShortHash(hash) { 101 | return hash.slice(0, 6) + "..." + hash.slice(-4); 102 | } 103 | 104 | function updateLogs() { 105 | logsBox.setContent(transactionLogs.join("\n")); 106 | logsBox.setScrollPerc(100); 107 | safeRender(); 108 | } 109 | 110 | function clearTransactionLogs() { 111 | transactionLogs = []; 112 | updateLogs(); 113 | addLog("Transaction logs telah dihapus.", "system"); 114 | } 115 | 116 | async function waitWithCancel(delay, type) { 117 | return Promise.race([ 118 | new Promise(resolve => setTimeout(resolve, delay)), 119 | new Promise(resolve => { 120 | const interval = setInterval(() => { 121 | if (type === "prior" && priorSwapCancelled) { clearInterval(interval); resolve(); } 122 | }, 100); 123 | }) 124 | ]); 125 | } 126 | 127 | const screen = blessed.screen({ 128 | smartCSR: true, 129 | title: "Prior Swap", 130 | fullUnicode: true, 131 | mouse: true 132 | }); 133 | 134 | let renderTimeout; 135 | function safeRender() { 136 | if (renderTimeout) clearTimeout(renderTimeout); 137 | renderTimeout = setTimeout(() => { screen.render(); }, 50); 138 | } 139 | 140 | const headerBox = blessed.box({ 141 | top: 0, 142 | left: "center", 143 | width: "100%", 144 | tags: true, 145 | style: { fg: "white", bg: "default" } 146 | }); 147 | 148 | figlet.text("NT EXHAUST".toUpperCase(), { font: "ANSI Shadow", horizontalLayout: "default" }, (err, data) => { 149 | if (err) headerBox.setContent("{center}{bold}NT Exhaust{/bold}{/center}"); 150 | else headerBox.setContent(`{center}{bold}{bright-cyan-fg}${data}{/bright-cyan-fg}{/bold}{/center}`); 151 | safeRender(); 152 | }); 153 | 154 | const descriptionBox = blessed.box({ 155 | left: "center", 156 | width: "100%", 157 | content: "{center}{bold}{bright-yellow-fg} « ✮ P̳̿͟͞R̳̿͟͞I̳̿͟͞O̳̿͟͞R̳̿͟͞ A̳̿͟͞U̳̿͟͞T̳̿͟͞O̳̿͟͞ B̳̿͟͞O̳̿͟͞T̳̿͟͞ ✮ »{/bright-yellow-fg}{/bold}{/center}", 158 | tags: true, 159 | style: { fg: "white", bg: "default" } 160 | }); 161 | 162 | const logsBox = blessed.box({ 163 | label: " Transaction Logs ", 164 | left: 0, 165 | border: { type: "line" }, 166 | scrollable: true, 167 | alwaysScroll: true, 168 | mouse: true, 169 | keys: true, 170 | vi: true, 171 | tags: true, 172 | scrollbar: { ch: " ", inverse: true, style: { bg: "blue" } }, 173 | content: "", 174 | style: { border: { fg: "bright-cyan" }, bg: "default" } 175 | }); 176 | 177 | const walletBox = blessed.box({ 178 | label: " Informasi Wallet ", 179 | border: { type: "line" }, 180 | tags: true, 181 | style: { border: { fg: "magenta" }, fg: "white", bg: "default", align: "left", valign: "top" }, 182 | content: "Loading Data wallet..." 183 | }); 184 | 185 | const mainMenu = blessed.list({ 186 | label: " Menu ", 187 | left: "60%", 188 | keys: true, 189 | vi: true, 190 | mouse: true, 191 | border: { type: "line" }, 192 | style: { fg: "white", bg: "default", border: { fg: "red" }, selected: { bg: "green", fg: "black" } }, 193 | items: getMainMenuItems() 194 | }); 195 | 196 | const priorSubMenu = blessed.list({ 197 | label: " Prior Swap Sub Menu ", 198 | left: "60%", 199 | keys: true, 200 | vi: true, 201 | mouse: true, 202 | border: { type: "line" }, 203 | style: { fg: "white", bg: "default", border: { fg: "red" }, selected: { bg: "cyan", fg: "black" } }, 204 | items: getPriorMenuItems() 205 | }); 206 | priorSubMenu.hide(); 207 | 208 | const promptBox = blessed.prompt({ 209 | parent: screen, 210 | border: "line", 211 | height: 5, 212 | width: "60%", 213 | top: "center", 214 | left: "center", 215 | label: "{bright-blue-fg}Swap Prompt{/bright-blue-fg}", 216 | tags: true, 217 | keys: true, 218 | vi: true, 219 | mouse: true, 220 | style: { fg: "bright-red", bg: "default", border: { fg: "red" } } 221 | }); 222 | 223 | screen.append(headerBox); 224 | screen.append(descriptionBox); 225 | screen.append(logsBox); 226 | screen.append(walletBox); 227 | screen.append(mainMenu); 228 | screen.append(priorSubMenu); 229 | 230 | function getMainMenuItems() { 231 | let items = ["Prior Swap", "Clam Faucet", "Clear Transaction Logs", "Refresh", "Exit"]; 232 | if (priorSwapRunning) { 233 | items.unshift("Stop All Transactions"); 234 | } 235 | return items; 236 | } 237 | 238 | function getPriorMenuItems() { 239 | let items = ["Auto Swap Prior & USDC/USDT", "Clear Transaction Logs", "Back To Main Menu", "Refresh"]; 240 | if (priorSwapRunning) { 241 | items.splice(1, 0, "Stop Transaction"); 242 | } 243 | return items; 244 | } 245 | 246 | function updateWallet() { 247 | const shortAddress = walletInfo.address ? getShortAddress(walletInfo.address) : "N/A"; 248 | const prior = walletInfo.balancePrior ? Number(walletInfo.balancePrior).toFixed(2) : "0.00"; 249 | const usdc = walletInfo.balanceUSDC ? Number(walletInfo.balanceUSDC).toFixed(2) : "0.00"; 250 | const usdt = walletInfo.balanceUSDT ? Number(walletInfo.balanceUSDT).toFixed(2) : "0.00"; 251 | const eth = walletInfo.balanceETH ? Number(walletInfo.balanceETH).toFixed(4) : "0.000"; 252 | const content = `┌── Address : {bright-yellow-fg}${shortAddress}{/bright-yellow-fg} 253 | │ ├── ETH : {bright-green-fg}${eth}{/bright-green-fg} 254 | │ ├── PRIOR : {bright-green-fg}${prior}{/bright-green-fg} 255 | │ ├── USDC : {bright-green-fg}${usdc}{/bright-green-fg} 256 | │ └── USDT : {bright-green-fg}${usdt}{/bright-green-fg} 257 | └── Network : {bright-cyan-fg}${NETWORK_NAME}{/bright-cyan-fg} 258 | `; 259 | 260 | walletBox.setContent(content); 261 | safeRender(); 262 | } 263 | 264 | async function updateWalletData() { 265 | try { 266 | const provider = new ethers.JsonRpcProvider(RPC_URL); 267 | const wallet = new ethers.Wallet(PRIVATE_KEY, provider); 268 | globalWallet = wallet; 269 | walletInfo.address = wallet.address; 270 | 271 | const [ethBalance, balancePrior, balanceUSDC, balanceUSDT] = await Promise.all([ 272 | provider.getBalance(wallet.address), 273 | new ethers.Contract(PRIOR_ADDRESS, ERC20_ABI, provider).balanceOf(wallet.address), 274 | new ethers.Contract(USDC_ADDRESS, ERC20_ABI, provider).balanceOf(wallet.address), 275 | new ethers.Contract(USDT_ADDRESS, ERC20_ABI, provider).balanceOf(wallet.address) 276 | ]); 277 | 278 | walletInfo.balanceETH = ethers.formatEther(ethBalance); 279 | walletInfo.balancePrior = ethers.formatEther(balancePrior); 280 | walletInfo.balanceUSDC = ethers.formatUnits(balanceUSDC, 6); 281 | walletInfo.balanceUSDT = ethers.formatUnits(balanceUSDT, 6); 282 | 283 | updateWallet(); 284 | addLog("Saldo & Wallet Updated !!", "system"); 285 | } catch (error) { 286 | addLog("Gagal mengambil data wallet: " + error.message, "system"); 287 | } 288 | } 289 | 290 | function stopAllTransactions() { 291 | if (priorSwapRunning) { 292 | priorSwapCancelled = true; 293 | addLog("Stop All Transactions command received. Semua transaksi telah dihentikan.", "system"); 294 | } 295 | } 296 | 297 | async function autoClaimFaucet() { 298 | const provider = new ethers.JsonRpcProvider(RPC_URL); 299 | const wallet = new ethers.Wallet(PRIVATE_KEY, provider); 300 | const faucetContract = new ethers.Contract(FAUCET_ADDRESS, FAUCET_ABI, wallet); 301 | 302 | try { 303 | const lastClaim = await faucetContract.lastClaimTime(wallet.address); 304 | const cooldown = await faucetContract.claimCooldown(); 305 | const currentTime = Math.floor(Date.now() / 1000); 306 | const nextClaimTime = Number(lastClaim) + Number(cooldown); 307 | 308 | if (currentTime < nextClaimTime) { 309 | const waitTime = nextClaimTime - currentTime; 310 | const waitHours = Math.floor(waitTime / 3600); 311 | const waitMinutes = Math.floor((waitTime % 3600) / 60); 312 | addLog(`You have to wait ${waitHours} Hours ${waitMinutes} minutes before claiming again.`, "warning"); 313 | return; 314 | } 315 | addLog("Starting Claim Faucet PRIOR...", "system"); 316 | const tx = await faucetContract.claimTokens(); 317 | const txHash = tx.hash; 318 | addLog(`Transaction Sent!!. Hash: ${getShortHash(txHash)}`, "warning"); 319 | 320 | const receipt = await tx.wait(); 321 | if (receipt.status === 1) { 322 | addLog("Claim Faucet Successfully!!", "success"); 323 | await updateWalletData(); 324 | } else { 325 | addLog("Claim Faucet Failed.", "error"); 326 | } 327 | } catch (error) { 328 | addLog(`Error When Claiming: ${error.message}`, "error"); 329 | } 330 | } 331 | 332 | async function runAutoSwap() { 333 | promptBox.setFront(); 334 | promptBox.readInput("Masukkan Jumalah Swap:", "", async (err, value) => { 335 | promptBox.hide(); 336 | safeRender(); 337 | if (err || !value) { 338 | addLog("Prior Swap: Input tidak valid atau dibatalkan.", "prior"); 339 | return; 340 | } 341 | const loopCount = parseInt(value); 342 | if (isNaN(loopCount)) { 343 | addLog("Prior Swap: Input harus berupa angka.", "prior"); 344 | return; 345 | } 346 | addLog(`Prior Swap: Anda Memasukkan ${loopCount} kali auto swap.`, "prior"); 347 | if (priorSwapRunning) { 348 | addLog("Prior: Transaksi Sedang Berjalan. Silahkan stop transaksi terlebih dahulu.", "rubic"); 349 | return; 350 | } 351 | const provider = new ethers.JsonRpcProvider(RPC_URL); 352 | const wallet = new ethers.Wallet(PRIVATE_KEY, provider); 353 | globalWallet = wallet; 354 | 355 | const priorToken = new ethers.Contract(PRIOR_ADDRESS, ERC20_ABI, wallet); 356 | const usdcToken = new ethers.Contract(USDC_ADDRESS, ERC20_ABI, provider); 357 | 358 | priorSwapRunning = true; 359 | priorSwapCancelled = false; 360 | mainMenu.setItems(getMainMenuItems()); 361 | priorSubMenu.setItems(getPriorMenuItems()); 362 | priorSubMenu.show(); 363 | safeRender(); 364 | 365 | for (let i = 1; i <= loopCount; i++) { 366 | if (priorSwapCancelled) { 367 | addLog(`Prior Swap: Auto swap dihentikan pada Cycle Ke ${i}.`, "prior"); 368 | break; 369 | } 370 | 371 | const randomAmount = getRandomNumber(0.001, 0.01); 372 | const amountPrior = ethers.parseEther(randomAmount.toFixed(6)); 373 | const isUSDC = i % 2 === 1; 374 | const functionSelector = isUSDC ? "0xf3b68002" : "0x03b530a3"; 375 | const swapTarget = isUSDC ? "USDC" : "USDT"; 376 | try { 377 | const approveTx = await priorToken.approve(routerAddress, amountPrior); 378 | const txHash = approveTx.hash; 379 | addLog(`Prior: Approval Transaction dikirim. Hash: ${getShortHash(txHash)}`, "prior"); 380 | const approveReceipt = await approveTx.wait(); 381 | if (approveReceipt.status !== 1) { 382 | addLog(`Prior: Approval gagal. Melewati Cycle ini.`, "prior"); 383 | await delay(getRandomNumber(30000, 60000)); 384 | continue; 385 | } 386 | addLog(`Prior: Approval berhasil.`, "prior"); 387 | } catch (approvalError) { 388 | addLog(`Prior: Error saat approval: ${approvalError.message}`, "prior"); 389 | await delay(getRandomNumber(30000, 60000)); 390 | continue; 391 | } 392 | 393 | const paramHex = ethers.zeroPadValue(ethers.toBeHex(amountPrior), 32); 394 | const txData = functionSelector + paramHex.slice(2); 395 | try { 396 | addLog(`Prior: Melakukan swap PRIOR ➯ ${swapTarget}, Ammount ${ethers.formatEther(amountPrior)} PRIOR`, "prior"); 397 | const tx = await wallet.sendTransaction({ 398 | to: routerAddress, 399 | data: txData, 400 | gasLimit: 500000 401 | }); 402 | const txHash = tx.hash; 403 | addLog(`Prior: Transaksi dikirim. Hash: ${getShortHash(txHash)}`, "prior"); 404 | const receipt = await tx.wait(); 405 | if (receipt.status === 1) { 406 | addLog(`Prior: Swap PRIOR ➯ ${swapTarget} berhasil.`, "prior"); 407 | await updateWalletData(); 408 | addLog(`Prior: Swap Ke ${i} Selesai.`, "prior"); 409 | } else { 410 | addLog(`Prior: Swap PRIOR ➯ ${swapTarget} gagal.`, "prior"); 411 | } 412 | } catch (txError) { 413 | addLog(`Prior Swap: Error saat mengirim transaksi swap: ${txError.message}`, "prior"); 414 | } 415 | 416 | if (i < loopCount) { 417 | const delay = getRandomDelay(); 418 | const minutes = Math.floor(delay / 60000); 419 | const seconds = Math.floor((delay % 60000) / 1000); 420 | addLog(`Prior: Menunggu ${minutes} menit ${seconds} detik sebelum transaksi berikutnya`, "prior"); 421 | await waitWithCancel(delay, "prior"); 422 | if (priorSwapCancelled) { 423 | addLog("Prior: Auto swap Dihentikan saat waktu tunggu.", "prior"); 424 | break; 425 | } 426 | } 427 | } 428 | priorSwapRunning = false; 429 | mainMenu.setItems(getMainMenuItems()); 430 | priorSubMenu.setItems(getPriorMenuItems()); 431 | safeRender(); 432 | addLog("Prior Swap: Auto swap selesai.", "prior"); 433 | }); 434 | } 435 | 436 | 437 | function adjustLayout() { 438 | const screenHeight = screen.height; 439 | const screenWidth = screen.width; 440 | const headerHeight = Math.max(8, Math.floor(screenHeight * 0.15)); 441 | headerBox.top = 0; 442 | headerBox.height = headerHeight; 443 | headerBox.width = "100%"; 444 | descriptionBox.top = "25%"; 445 | descriptionBox.height = Math.floor(screenHeight * 0.05); 446 | logsBox.top = headerHeight + descriptionBox.height; 447 | logsBox.left = 0; 448 | logsBox.width = Math.floor(screenWidth * 0.6); 449 | logsBox.height = screenHeight - (headerHeight + descriptionBox.height); 450 | walletBox.top = headerHeight + descriptionBox.height; 451 | walletBox.left = Math.floor(screenWidth * 0.6); 452 | walletBox.width = Math.floor(screenWidth * 0.4); 453 | walletBox.height = Math.floor(screenHeight * 0.35); 454 | mainMenu.top = headerHeight + descriptionBox.height + walletBox.height; 455 | mainMenu.left = Math.floor(screenWidth * 0.6); 456 | mainMenu.width = Math.floor(screenWidth * 0.4); 457 | mainMenu.height = screenHeight - (headerHeight + descriptionBox.height + walletBox.height); 458 | priorSubMenu.top = mainMenu.top; 459 | priorSubMenu.left = mainMenu.left; 460 | priorSubMenu.width = mainMenu.width; 461 | priorSubMenu.height = mainMenu.height; 462 | safeRender(); 463 | } 464 | 465 | screen.on("resize", adjustLayout); 466 | adjustLayout(); 467 | 468 | mainMenu.on("select", (item) => { 469 | const selected = item.getText(); 470 | if (selected === "Stop All Transactions") { 471 | stopAllTransactions(); 472 | mainMenu.setItems(getMainMenuItems()); 473 | mainMenu.focus(); 474 | safeRender(); 475 | } else if (selected === "Prior Swap") { 476 | priorSubMenu.show(); 477 | priorSubMenu.focus(); 478 | safeRender(); 479 | } else if (selected === "Clam Faucet") { 480 | autoClaimFaucet(); 481 | } else if (selected === "Clear Transaction Logs") { 482 | clearTransactionLogs(); 483 | } else if (selected === "Refresh") { 484 | updateWalletData(); 485 | updateLogs(); 486 | safeRender(); 487 | addLog("Refreshed", "system"); 488 | } else if (selected === "Exit") { 489 | process.exit(0); 490 | } 491 | }); 492 | 493 | priorSubMenu.on("select", (item) => { 494 | const selected = item.getText(); 495 | if (selected === "Auto Swap Prior & USDC/USDT") { 496 | runAutoSwap(); 497 | } else if (selected === "Stop Transaction") { 498 | if (priorSwapRunning) { 499 | priorSwapCancelled = true; 500 | addLog("Prior Swap: Perintah Stop Transaction diterima.", "prior"); 501 | } else { 502 | addLog("Prior Swap: Tidak ada transaksi yang berjalan.", "prior"); 503 | } 504 | } else if (selected === "Clear Transaction Logs") { 505 | clearTransactionLogs(); 506 | } else if (selected === "Back To Main Menu") { 507 | priorSubMenu.hide(); 508 | mainMenu.show(); 509 | mainMenu.focus(); 510 | safeRender(); 511 | } else if (selected === "Refresh") { 512 | updateWalletData(); 513 | updateLogs(); 514 | safeRender(); 515 | addLog("Refreshed", "system"); 516 | } 517 | }); 518 | 519 | screen.key(["escape", "q", "C-c"], () => process.exit(0)); 520 | screen.key(["C-up"], () => { logsBox.scroll(-1); safeRender(); }); 521 | screen.key(["C-down"], () => { logsBox.scroll(1); safeRender(); }); 522 | 523 | safeRender(); 524 | mainMenu.focus(); 525 | updateLogs(); 526 | updateWalletData(); 527 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "NT Exhaust - Prior Auto Bot", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "start": "node index.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "blessed": "^0.1.81", 15 | "dotenv": "^16.4.7", 16 | "ethers": "^6.13.5", 17 | "figlet": "^1.8.0" 18 | } 19 | } --------------------------------------------------------------------------------