├── LICENSE ├── README.md ├── account.txt ├── index.js ├── package.json ├── proxy.txt └── src └── gpu.json /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 recitativonika 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Openledger Bot 2 | Openledger Bot is a simple tool designed to automate the node and daily reward claim interaction. 3 | 4 | ## Features 5 | - **Automated node interaction** 6 | - **Auto claim daily rewards** 7 | - **Auto claim medals** 8 | - **Proxy support** 9 | 10 | ## Prerequisites 11 | - [Node.js](https://nodejs.org/) (version 14 or higher) 12 | 13 | ## Installation 14 | 15 | 1. Clone the repository to your local machine: 16 | ```bash 17 | git clone https://github.com/recitativonika/openledger-bot.git 18 | ``` 19 | 2. Navigate to the project directory: 20 | ```bash 21 | cd openledger-bot 22 | ``` 23 | 4. Install the necessary dependencies: 24 | ```bash 25 | npm install 26 | ``` 27 | 28 | ## Usage 29 | 30 | 1. Set the `account.txt` and `proxy.txt (if you want to use proxy)` before running the script. Below how to setup this fie. 31 | 2. Modify the `account.txt` file with your account wallet info 32 | ``` 33 | wallet1 34 | wallet2 35 | ``` 36 | To get your wallet address, login and open your profile and copy your wallet on [OpenLedger dashboard](https://testnet.openledger.xyz/?referral_code=ffqrnwqlzq) 37 | ![Screenshot 202waeawea](https://github.com/user-attachments/assets/858c5b48-8e4d-4298-aaab-0e2d64e9f6d2) 38 | 39 | 40 | 3. Modify and set the `proxy.txt` file if you want to use proxy 41 | ``` 42 | ip:port 43 | username:password@ip:port 44 | http://ip:port 45 | http://username:password@ip:port 46 | ``` 47 | 4. Run the script: 48 | ```bash 49 | node index.js 50 | ``` 51 | Do not delete `data.json`, it store your websocket and account data. 52 | 53 | ## License 54 | This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details. 55 | 56 | ## Note 57 | This script only for testing purpose, using this script might violates ToS and may get your account permanently banned. 58 | 59 | Extension link : [Extension](https://chromewebstore.google.com/detail/openledger-node/ekbbplmjjgoobhdlffmgeokalelnmjjc) 60 | Dashboard Link : [Dashboard](https://testnet.openledger.xyz/?referral_code=ffqrnwqlzq) 61 | 62 | My reff code if you want to use :) : https://testnet.openledger.xyz/?referral_code=ffqrnwqlzq 63 | -------------------------------------------------------------------------------- /account.txt: -------------------------------------------------------------------------------- 1 | token1:workerID1:id1:ownerAddress1 2 | token2:workerID2:id2:ownerAddress2 3 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const WebSocket = require('ws'); 3 | const axios = require('axios'); 4 | const readline = require('readline'); 5 | const { HttpsProxyAgent } = require('https-proxy-agent'); 6 | const { v4: uuidv4 } = require('uuid'); 7 | 8 | let dataStore = {}; 9 | try { 10 | dataStore = JSON.parse(fs.readFileSync('data.json', 'utf8')); 11 | } catch (err) { 12 | console.log('No existing data store found, creating a new data.json.'); 13 | } 14 | 15 | const gpuList = JSON.parse(fs.readFileSync('src/gpu.json', 'utf8')); 16 | 17 | function getOrAssignResources(address) { 18 | if (!dataStore[address].gpu || !dataStore[address].storage) { 19 | const randomGPU = gpuList[Math.floor(Math.random() * gpuList.length)]; 20 | const randomStorage = (Math.random() * 500).toFixed(2); 21 | 22 | dataStore[address].gpu = randomGPU; 23 | dataStore[address].storage = randomStorage; 24 | 25 | try { 26 | fs.writeFileSync('data.json', JSON.stringify(dataStore, null, 2)); 27 | } catch (error) { 28 | console.error('Error writing GPU/storage to data.json:', error.message); 29 | } 30 | } 31 | } 32 | 33 | function displayHeader() { 34 | const width = process.stdout.columns; 35 | const headerLines = [ 36 | "<|============================================|>", 37 | " OpenLedger Bot ", 38 | " github.com/recitativonika ", 39 | "<|============================================|>" 40 | ]; 41 | headerLines.forEach(line => { 42 | console.log(`\x1b[36m${line.padStart((width + line.length) / 2)}\x1b[0m`); 43 | }); 44 | } 45 | 46 | let wallets = []; 47 | try { 48 | wallets = fs.readFileSync('account.txt', 'utf8') 49 | .trim() 50 | .split(/\s+/) 51 | .filter(Boolean); 52 | } catch (err) { 53 | console.error('Error reading account.txt:', err.message); 54 | process.exit(1); 55 | } 56 | 57 | let proxies = []; 58 | try { 59 | proxies = fs.readFileSync('proxy.txt', 'utf8') 60 | .trim() 61 | .split(/\s+/) 62 | .filter(Boolean); 63 | } catch (error) { 64 | console.error('Error reading proxy.txt:', error.message); 65 | } 66 | 67 | const accountIDs = {}; 68 | 69 | async function askUseProxy() { 70 | const rl = readline.createInterface({ 71 | input: process.stdin, 72 | output: process.stdout 73 | }); 74 | 75 | return new Promise((resolve) => { 76 | function ask() { 77 | rl.question('Do you want to use a proxy? (y/n): ', (answer) => { 78 | if (answer.toLowerCase() === 'y') { 79 | resolve(true); 80 | rl.close(); 81 | } else if (answer.toLowerCase() === 'n') { 82 | resolve(false); 83 | rl.close(); 84 | } else { 85 | console.log('Please answer with y or n.'); 86 | ask(); 87 | } 88 | }); 89 | } 90 | ask(); 91 | }); 92 | } 93 | 94 | async function generateTokenForAddress(address, agent, delay = 60000) { 95 | let attempt = 1; 96 | while (true) { 97 | try { 98 | const result = await axios.post( 99 | 'https://apitn.openledger.xyz/api/v1/auth/generate_token', 100 | { address }, 101 | { 102 | headers: { 'Content-Type': 'application/json' }, 103 | httpsAgent: agent 104 | } 105 | ); 106 | return result.data?.data?.token || null; 107 | } catch (error) { 108 | console.error(`Error generating token for wallet ${address}, attempt ${attempt}:`, error.message); 109 | console.log(`Retrying token generation for wallet ${address} in ${delay / 1000} seconds...`); 110 | await new Promise(resolve => setTimeout(resolve, delay)); 111 | attempt++; 112 | } 113 | } 114 | } 115 | 116 | async function getOrCreateWalletData(address, agent) { 117 | if (!dataStore[address]) { 118 | dataStore[address] = { 119 | address, 120 | workerID: Buffer.from(address).toString('base64'), 121 | id: uuidv4(), 122 | token: null, 123 | gpu: null, 124 | storage: null 125 | }; 126 | } 127 | 128 | if (!dataStore[address].token) { 129 | const token = await generateTokenForAddress(address, agent); 130 | if (!token) { 131 | console.log('Could not generate token. Will skip this wallet for now.'); 132 | return null; 133 | } 134 | dataStore[address].token = token; 135 | try { 136 | fs.writeFileSync('data.json', JSON.stringify(dataStore, null, 2)); 137 | } catch (error) { 138 | console.error('Error writing to data.json:', error.message); 139 | } 140 | } 141 | 142 | return dataStore[address]; 143 | } 144 | 145 | async function getAccountID(token, address, index, useProxy, delay = 60000) { 146 | const proxyUrl = proxies.length > 0 ? proxies[index % proxies.length] : ''; 147 | const agent = useProxy && proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; 148 | const proxyText = useProxy && proxyUrl ? proxyUrl : 'False'; 149 | 150 | let attempt = 1; 151 | while (true) { 152 | try { 153 | const response = await axios.get('https://apitn.openledger.xyz/api/v1/users/me', { 154 | headers: { 'Authorization': `Bearer ${token}` }, 155 | httpsAgent: agent 156 | }); 157 | const acctID = response.data.data.id; 158 | accountIDs[address] = acctID; 159 | console.log(`\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${acctID}\x1b[0m, Proxy: \x1b[36m${proxyText}\x1b[0m`); 160 | return; 161 | } catch (error) { 162 | console.error(`\x1b[33m[${index + 1}]\x1b[0m Error getting accountID for wallet ${address}, attempt ${attempt}:`, error.message); 163 | console.log(`\x1b[33m[${index + 1}]\x1b[0m Retrying in ${delay / 1000} seconds...`); 164 | await new Promise(resolve => setTimeout(resolve, delay)); 165 | attempt++; 166 | } 167 | } 168 | } 169 | 170 | async function getAccountDetails(token, address, index, useProxy, retries = 3, delay = 60000) { 171 | const proxyUrl = proxies.length > 0 ? proxies[index % proxies.length] : ''; 172 | const agent = useProxy && proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; 173 | const proxyText = useProxy && proxyUrl ? proxyUrl : 'False'; 174 | 175 | for (let attempt = 1; attempt <= retries; attempt++) { 176 | try { 177 | const rewardRealtimeResponse = await axios.get('https://rewardstn.openledger.xyz/api/v1/reward_realtime', { 178 | headers: { 'Authorization': `Bearer ${token}` }, 179 | httpsAgent: agent 180 | }); 181 | const rewardHistoryResponse = await axios.get('https://rewardstn.openledger.xyz/api/v1/reward_history', { 182 | headers: { 'Authorization': `Bearer ${token}` }, 183 | httpsAgent: agent 184 | }); 185 | const rewardResponse = await axios.get('https://rewardstn.openledger.xyz/api/v1/reward', { 186 | headers: { 'Authorization': `Bearer ${token}` }, 187 | httpsAgent: agent 188 | }); 189 | 190 | const totalHeartbeats = parseInt(rewardRealtimeResponse.data.data[0]?.total_heartbeats || 0, 10); 191 | const totalPointFromReward = parseFloat(rewardResponse.data.data?.totalPoint || 0); 192 | const epochName = rewardResponse.data.data?.name || ''; 193 | 194 | const total = totalHeartbeats + totalPointFromReward; 195 | 196 | console.log( 197 | `\x1b[33m[${index + 1}]\x1b[0m Wallet \x1b[36m${address}\x1b[0m, ` + 198 | `AccountID \x1b[36m${accountIDs[address]}\x1b[0m, Total Heartbeat \x1b[32m${totalHeartbeats}\x1b[0m, ` + 199 | `Total Points \x1b[32m${total.toFixed(2)}\x1b[0m (\x1b[33m${epochName}\x1b[0m), ` + 200 | `Proxy: \x1b[36m${proxyText}\x1b[0m` 201 | ); 202 | return; 203 | } catch (error) { 204 | console.error(`Error getting account details for wallet ${address}, attempt ${attempt}:`, error.message); 205 | if (attempt < retries) { 206 | console.log(`Retrying in ${delay / 1000} seconds...`); 207 | await new Promise(resolve => setTimeout(resolve, delay)); 208 | } else { 209 | console.error('All retry attempts failed for account details.'); 210 | } 211 | } 212 | } 213 | } 214 | 215 | async function checkAndClaimReward(token, address, index, useProxy, retries = 3, delay = 60000) { 216 | const proxyUrl = proxies.length > 0 ? proxies[index % proxies.length] : ''; 217 | const agent = useProxy && proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; 218 | 219 | for (let attempt = 1; attempt <= retries; attempt++) { 220 | try { 221 | const claimDetailsResponse = await axios.get('https://rewardstn.openledger.xyz/api/v1/claim_details', { 222 | headers: { 'Authorization': `Bearer ${token}` }, 223 | httpsAgent: agent 224 | }); 225 | 226 | const claimed = claimDetailsResponse.data.data?.claimed; 227 | if (!claimed) { 228 | const claimRewardResponse = await axios.get('https://rewardstn.openledger.xyz/api/v1/claim_reward', { 229 | headers: { 'Authorization': `Bearer ${token}` }, 230 | httpsAgent: agent 231 | }); 232 | 233 | if (claimRewardResponse.data.status === 'SUCCESS') { 234 | console.log( 235 | `\x1b[33m[${index + 1}]\x1b[0m Wallet \x1b[36m${address}\x1b[0m, ` + 236 | `AccountID \x1b[36m${accountIDs[address]}\x1b[0m \x1b[32mClaimed daily reward successfully!\x1b[0m` 237 | ); 238 | } 239 | } 240 | return; 241 | } catch (error) { 242 | console.error(`Error claiming reward for wallet ${address}, attempt ${attempt}:`, error.message); 243 | if (attempt < retries) { 244 | console.log(`Retrying in ${delay / 1000} seconds...`); 245 | await new Promise(resolve => setTimeout(resolve, delay)); 246 | } else { 247 | console.error('All retry attempts failed for claiming reward.'); 248 | } 249 | } 250 | } 251 | } 252 | 253 | async function checkAndClaimRewardsPeriodically(useProxy) { 254 | const promises = wallets.map(async (address, index) => { 255 | const { token } = dataStore[address] || {}; 256 | if (!token) return; 257 | await checkAndClaimReward(token, address, index, useProxy); 258 | }); 259 | await Promise.all(promises); 260 | 261 | setInterval(async () => { 262 | const promises = wallets.map(async (address, idx) => { 263 | const { token } = dataStore[address] || {}; 264 | if (!token) return; 265 | await checkAndClaimReward(token, address, idx, useProxy); 266 | }); 267 | await Promise.all(promises); 268 | }, 12 * 60 * 60 * 1000); 269 | } 270 | 271 | function connectWebSocket({ token, workerID, id, address }, index, useProxy) { 272 | const proxyUrl = proxies.length > 0 ? proxies[index % proxies.length] : ''; 273 | const agent = useProxy && proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; 274 | const wsUrl = `wss://apitn.openledger.xyz/ws/v1/orch?authToken=${token}`; 275 | const wsOptions = { 276 | agent, 277 | headers: { 278 | 'Accept-Encoding': 'gzip, deflate, br, zstd', 279 | 'Accept-Language': 'en-US,en;q=0.9,id;q=0.8', 280 | 'Cache-Control': 'no-cache', 281 | 'Connection': 'Upgrade', 282 | 'Host': 'apitn.openledger.xyz', 283 | 'Origin': 'chrome-extension://ekbbplmjjgoobhdlffmgeokalelnmjjc', 284 | 'Pragma': 'no-cache', 285 | 'Sec-WebSocket-Extensions': 'permessage-deflate; client_max_window_bits', 286 | 'Sec-WebSocket-Key': '0iJKzoEtY2vsWuXjR8ZSng==', 287 | 'Sec-WebSocket-Version': '13', 288 | 'Upgrade': 'websocket', 289 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36' 290 | } 291 | }; 292 | const proxyText = useProxy && proxyUrl ? proxyUrl : 'False'; 293 | 294 | const ws = new WebSocket(wsUrl, wsOptions); 295 | let heartbeatInterval; 296 | 297 | function sendHeartbeat() { 298 | getOrAssignResources(address); 299 | const assignedGPU = dataStore[address].gpu || ''; 300 | const assignedStorage = dataStore[address].storage || ''; 301 | const heartbeatMessage = { 302 | message: { 303 | Worker: { 304 | Identity: workerID, 305 | ownerAddress: address, 306 | type: 'LWEXT', 307 | Host: 'chrome-extension://ekbbplmjjgoobhdlffmgeokalelnmjjc' 308 | }, 309 | Capacity: { 310 | AvailableMemory: (Math.random() * 32).toFixed(2), 311 | AvailableStorage: assignedStorage, 312 | AvailableGPU: assignedGPU, 313 | AvailableModels: [] 314 | } 315 | }, 316 | msgType: 'HEARTBEAT', 317 | workerType: 'LWEXT', 318 | workerID 319 | }; 320 | console.log( 321 | `\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${accountIDs[address]}\x1b[0m: ` + 322 | `Sending heartbeat for workerID: \x1b[33m${workerID}\x1b[0m, Proxy: \x1b[36m${proxyText}\x1b[0m` 323 | ); 324 | ws.send(JSON.stringify(heartbeatMessage)); 325 | } 326 | 327 | ws.on('open', () => { 328 | console.log( 329 | `\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${accountIDs[address]}\x1b[0m: ` + 330 | `Connected to WebSocket for workerID: \x1b[33m${workerID}\x1b[0m, Proxy: \x1b[36m${proxyText}\x1b[0m` 331 | ); 332 | 333 | const registerMessage = { 334 | workerID, 335 | msgType: 'REGISTER', 336 | workerType: 'LWEXT', 337 | message: { 338 | id, 339 | type: 'REGISTER', 340 | worker: { 341 | host: 'chrome-extension://ekbbplmjjgoobhdlffmgeokalelnmjjc', 342 | identity: workerID, 343 | ownerAddress: address, 344 | type: 'LWEXT' 345 | } 346 | } 347 | }; 348 | ws.send(JSON.stringify(registerMessage)); 349 | 350 | heartbeatInterval = setInterval(sendHeartbeat, 30000); 351 | }); 352 | 353 | ws.on('message', data => { 354 | console.log( 355 | `\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${accountIDs[address]}\x1b[0m: ` + 356 | `Received for workerID \x1b[33m${workerID}\x1b[0m: ${data}, Proxy: \x1b[36m${proxyText}\x1b[0m` 357 | ); 358 | }); 359 | 360 | ws.on('error', err => { 361 | console.error(`\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${accountIDs[address]}\x1b[0m: ` + 362 | `WebSocket error for workerID \x1b[33m${workerID}\x1b[0m:`, err); 363 | }); 364 | 365 | ws.on('close', () => { 366 | console.log( 367 | `\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${accountIDs[address]}\x1b[0m: ` + 368 | `WebSocket connection closed for workerID \x1b[33m${workerID}\x1b[0m, Proxy: \x1b[36m${proxyText}\x1b[0m` 369 | ); 370 | clearInterval(heartbeatInterval); 371 | 372 | setTimeout(() => { 373 | console.log( 374 | `\x1b[33m[${index + 1}]\x1b[0m AccountID \x1b[36m${accountIDs[address]}\x1b[0m: ` + 375 | `Reconnecting WebSocket for workerID: \x1b[33m${workerID}\x1b[0m, Proxy: \x1b[36m${proxyText}\x1b[0m` 376 | ); 377 | connectWebSocket({ token, workerID, id, address }, index, useProxy); 378 | }, 30000); 379 | }); 380 | } 381 | 382 | async function claimMedals(token, address, index, useProxy) { 383 | const proxyUrl = proxies.length > 0 ? proxies[index % proxies.length] : ''; 384 | const agent = useProxy && proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; 385 | 386 | for (let tierId = 1; tierId <= 8; tierId++) { 387 | try { 388 | const response = await axios.put( 389 | 'https://rewardstn.openledger.xyz/api/v1/claim_tier', 390 | { tierId }, 391 | { 392 | headers: { 'Authorization': `Bearer ${token}` }, 393 | httpsAgent: agent 394 | } 395 | ); 396 | 397 | if (response.data.status === 'SUCCESS' && response.data.data === true) { 398 | console.log( 399 | `\x1b[33m[${index + 1}]\x1b[0m Wallet \x1b[36m${address}\x1b[0m: ` + 400 | `Successfully claimed medal for tier \x1b[32m${tierId}\x1b[0m` 401 | ); 402 | } 403 | } catch (error) { 404 | 405 | } 406 | } 407 | } 408 | 409 | async function processRequests(useProxy) { 410 | const promises = wallets.map(async (address, index) => { 411 | const proxyUrl = proxies.length > 0 ? proxies[index % proxies.length] : ''; 412 | const agent = useProxy && proxyUrl ? new HttpsProxyAgent(proxyUrl) : undefined; 413 | 414 | const record = await getOrCreateWalletData(address, agent); 415 | if (!record || !record.token) { 416 | console.log(`Skipping wallet ${address} due to missing token.`); 417 | return; 418 | } 419 | 420 | await getAccountID(record.token, address, index, useProxy); 421 | if (!accountIDs[address]) { 422 | console.log(`Wallet ${address} has no valid accountID, skipping further steps...`); 423 | return; 424 | } 425 | 426 | connectWebSocket({ 427 | token: record.token, 428 | workerID: record.workerID, 429 | id: record.id, 430 | address 431 | }, index, useProxy); 432 | 433 | await Promise.all([ 434 | claimMedals(record.token, address, index, useProxy), 435 | checkAndClaimReward(record.token, address, index, useProxy), 436 | getAccountDetails(record.token, address, index, useProxy) 437 | ]); 438 | 439 | getOrAssignResources(address); 440 | }); 441 | 442 | await Promise.all(promises); 443 | } 444 | async function claimMedalsPeriodically(useProxy) { 445 | setInterval(async () => { 446 | const promises = wallets.map(async (address, index) => { 447 | const { token } = dataStore[address] || {}; 448 | if (!token) return; 449 | await claimMedals(token, address, index, useProxy); 450 | }); 451 | await Promise.all(promises); 452 | }, 12 * 60 * 60 * 1000); 453 | } 454 | 455 | async function updateAccountDetailsPeriodically(useProxy) { 456 | setInterval(async () => { 457 | const promises = wallets.map(async (address, index) => { 458 | const { token } = dataStore[address] || {}; 459 | if (!token) return; 460 | await getAccountDetails(token, address, index, useProxy); 461 | }); 462 | await Promise.all(promises); 463 | }, 5 * 60 * 1000); 464 | } 465 | 466 | (async () => { 467 | displayHeader(); 468 | 469 | const useProxy = await askUseProxy(); 470 | 471 | if (useProxy) { 472 | if (proxies.length < wallets.length) { 473 | console.error('The number of proxies is less than the number of wallets. Please provide enough proxies.'); 474 | process.exit(1); 475 | } 476 | } 477 | 478 | await checkAndClaimRewardsPeriodically(useProxy); 479 | await processRequests(useProxy); 480 | updateAccountDetailsPeriodically(useProxy); 481 | claimMedalsPeriodically(useProxy); 482 | })(); 483 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "axios": "^1.7.9", 4 | "fs": "^0.0.1-security", 5 | "https-proxy-agent": "^7.0.6", 6 | "readline": "^1.3.0", 7 | "uuid": "^11.0.5", 8 | "ws": "^8.18.0" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /proxy.txt: -------------------------------------------------------------------------------- 1 | ip:port 2 | username:password@ip:port 3 | http://ip:port 4 | http://username:password@ip:port 5 | -------------------------------------------------------------------------------- /src/gpu.json: -------------------------------------------------------------------------------- 1 | [ 2 | "NVIDIA GTX 1050", 3 | "NVIDIA GTX 1050 Ti", 4 | "NVIDIA GTX 1060", 5 | "NVIDIA GTX 1070", 6 | "NVIDIA GTX 1070 Ti", 7 | "NVIDIA GTX 1080", 8 | "NVIDIA GTX 1080 Ti", 9 | "NVIDIA GTX 1650", 10 | "NVIDIA GTX 1650 Super", 11 | "NVIDIA GTX 1660", 12 | "NVIDIA GTX 1660 Super", 13 | "NVIDIA GTX 1660 Ti", 14 | "NVIDIA RTX 2060", 15 | "NVIDIA RTX 2060 Super", 16 | "NVIDIA RTX 2070", 17 | "NVIDIA RTX 2070 Super", 18 | "NVIDIA RTX 2080", 19 | "NVIDIA RTX 2080 Super", 20 | "NVIDIA RTX 2080 Ti", 21 | "NVIDIA RTX 3060", 22 | "NVIDIA RTX 3060 Ti", 23 | "NVIDIA RTX 3070", 24 | "NVIDIA RTX 3070 Ti", 25 | "NVIDIA RTX 3080", 26 | "NVIDIA RTX 3080 Ti", 27 | "NVIDIA RTX 3090", 28 | "NVIDIA RTX 3090 Ti", 29 | "AMD Radeon RX 460", 30 | "AMD Radeon RX 470", 31 | "AMD Radeon RX 480", 32 | "AMD Radeon RX 550", 33 | "AMD Radeon RX 560", 34 | "AMD Radeon RX 570", 35 | "AMD Radeon RX 580", 36 | "AMD Radeon RX 590", 37 | "AMD Radeon RX 5500 XT", 38 | "AMD Radeon RX 5600 XT", 39 | "AMD Radeon RX 5700", 40 | "AMD Radeon RX 5700 XT", 41 | "AMD Radeon RX 6600", 42 | "AMD Radeon RX 6600 XT", 43 | "AMD Radeon RX 6700 XT", 44 | "AMD Radeon RX 6800", 45 | "AMD Radeon RX 6800 XT", 46 | "AMD Radeon RX 6900 XT", 47 | "AMD Radeon RX 6950 XT" 48 | ] --------------------------------------------------------------------------------