-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.js
282 lines (237 loc) · 11.1 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
import { coday, estimate, claim, start, info, infoSpin, doSpin, init } from './scripts.js';
import { logger } from './logger.js';
import fs from 'fs/promises';
import { banner } from './banner.js';
let headers = {
'Content-Type': 'application/json',
};
async function readTokensAndIds() {
try {
const tokenData = await fs.readFile('token.txt', 'utf-8');
const tokens = tokenData
.split('\n')
.map(line => line.trim())
.filter(line => line && line.includes('|'));
const idsData = await fs.readFile('unique_id.txt', 'utf-8');
const uniqueIds = idsData
.split('\n')
.map(line => line.trim())
.filter(line => line);
let proxies = [];
try {
const proxyData = await fs.readFile('proxy.txt', 'utf-8');
proxies = proxyData.split('\n').filter(line => line.trim());
} catch (err) {
logger("File proxy.txt not found, Running without proxy", 'warn');
}
if (proxies.length === 0) {
proxies = null;
}
if (tokens.length !== uniqueIds.length) {
logger("Mismatch between the number of tokens and unique ID lines.", "error");
return [];
}
const accounts = tokens.map((line, index) => {
const [access_token, refresh_token] = line.split('|').map(token => token.trim());
const ids = uniqueIds[index].includes('|')
? uniqueIds[index].split('|').map(id => id.trim())
: [uniqueIds[index].trim()];
return { access_token, refresh_token, unique_ids: ids, proxy: proxies ? proxies[index % proxies.length] : null };
});
return accounts;
} catch (err) {
logger("Failed to read token or unique ID file:", "error", err.message);
return [];
}
}
const asyncLock = {};
const tokenLocks = new Set();
async function lockAndWrite(file, content) {
while (asyncLock[file]) {
await new Promise(resolve => setTimeout(resolve, 50));
}
asyncLock[file] = true;
try {
await fs.writeFile(file, content, 'utf-8');
} finally {
asyncLock[file] = false;
}
}
async function refreshToken(refresh_token, accountIndex) {
if (tokenLocks.has(accountIndex)) {
logger(`Account ${accountIndex + 1} is already refreshing. Waiting...`, "info");
while (tokenLocks.has(accountIndex)) {
await new Promise(resolve => setTimeout(resolve, 50));
}
return null;
}
tokenLocks.add(accountIndex);
try {
logger(`Refreshing access token for Account ${accountIndex + 1}...`, "info");
const payloadData = { refresh_token };
const response = await coday("https://api.meshchain.ai/meshmain/auth/refresh-token", 'POST', headers, payloadData);
if (response && response.access_token) {
const tokenLines = (await fs.readFile('token.txt', 'utf-8'))
.split('\n')
.map(line => line.trim())
.filter(Boolean);
tokenLines[accountIndex] = `${response.access_token}|${response.refresh_token}`.trim();
await lockAndWrite('token.txt', tokenLines.join('\n') + '\n');
logger(`Account ${accountIndex + 1} token refreshed successfully`, "success");
return response.access_token;
}
logger(`Account ${accountIndex + 1} failed to refresh token`, "error");
console.log(response);
return null;
} catch (err) {
logger(`Error refreshing token for Account ${accountIndex + 1}: ${err.message}`, "error");
return null;
} finally {
tokenLocks.delete(accountIndex);
}
}
// Main process for a single account
async function processAccount({ access_token, refresh_token, unique_ids, proxy }, accountIndex) {
headers = {
...headers,
Authorization: `Bearer ${access_token}`,
};
for (const unique_id of unique_ids) {
try {
const profile = await info(unique_id, headers, proxy);
if (profile && profile.error) {
const { status, data } = profile;
if (status === 401) {
const message = data?.message || 'Unknown error';
logger(`Account ${accountIndex + 1} | ${unique_id}: Unauthorized (Error Code: ${data?.code}), ${message}`, "warn");
if (data.code === '40100002') {
logger(`Account ${accountIndex + 1} | ${unique_id}: JWT token expired, attempting to refresh...`, "warn");
const newAccessToken = await refreshToken(refresh_token, accountIndex);
if (!newAccessToken) return;
headers.Authorization = `Bearer ${newAccessToken}`;
return;
}
} else {
logger(`Account ${accountIndex + 1} | ${unique_id}: Error fetching profile (Code: ${data?.code}), ${data?.message}`, "error");
}
}
else if (profile) {
const is_linked = profile.is_linked || false;
if (!is_linked) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Node not linked, attempting to link node...`, "warn");
try {
await init(headers, unique_id, proxy);
logger(`Account ${accountIndex + 1} | ${unique_id}: Node linked successfully.`, "success");
} catch (err) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Failed to link node: ${err.message}`, "error");
}
}
const { name, total_reward } = profile;
logger(`Account ${accountIndex + 1} | ${unique_id}: ${name} | Balance: ${total_reward}`, "success");
} else {
logger(`Account ${accountIndex + 1} | ${unique_id}: Profile data is invalid or missing.`, "error");
}
} catch (err) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Error fetching profile: ${err.message}`, "error");
}
const filled = await estimate(unique_id, headers, proxy);
if (!filled) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Failed to fetch estimate.`, "error");
continue;
} else if (filled.error) {
const errorMessage = filled.data ? filled.data.message : 'Unknown error';
logger(`Account ${accountIndex + 1} | ${unique_id}: ${errorMessage}`, "error");
if (filled.data && filled.data.status === 400) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Trying to restart mining again due to status 400.`, "info");
await start(unique_id, headers);
} else if (filled.data && filled.data.status === 401) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Unauthorized. Attempting to refresh token...`, "warn");
const newAccessToken = await refreshToken(refresh_token, accountIndex);
if (!newAccessToken) return;
headers.Authorization = `Bearer ${newAccessToken}`;
return;
}
}
if (filled.filled && filled.claimable) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Attempting to claim reward...`, "info");
const reward = await claim(unique_id, headers, proxy);
if (reward) {
logger(`Account ${accountIndex + 1} | ${unique_id}: Claim successful! New Balance: ${reward}`, "success");
await start(unique_id, headers);
logger(`Account ${accountIndex + 1} | ${unique_id}: Started mining again.`, "info");
} else {
logger(`Account ${accountIndex + 1} | ${unique_id}: Failed to claim reward. Ensure your BNB balance is enough.`, "error");
}
} else {
logger(`Account ${accountIndex + 1} | ${unique_id}: Mining already started. Mine value: ${filled.value}`, "info");
}
}
};
async function spins() {
logger('Checking Current Round Spins Information...');
const accounts = await readTokensAndIds();
if (accounts.length === 0) {
logger("No accounts to process.", "error");
return;
}
logger(`Processing Checking ${accounts.length} accounts...`, "info");
for (let index = 0; index < accounts.length; index++) {
const account = accounts[index];
headers = {
...headers,
Authorization: `Bearer ${account.access_token}`,
};
try {
const spinsData = await infoSpin(headers, account.proxy);
if (spinsData) {
const timeNow = Math.floor(Date.now() / 1000);
const { spinStartTime, spinEndTime, maxSpinPerUser, userCurrentSpin } = spinsData;
const timesNow = {
timeNow: new Date(timeNow * 1000).toLocaleString(),
spinEndTime: new Date(spinEndTime * 1000).toLocaleString(),
spinStartTime: new Date(spinStartTime * 1000).toLocaleString(),
};
if (timeNow > spinStartTime && timeNow < spinEndTime && userCurrentSpin < maxSpinPerUser) {
logger(`Account ${index + 1}: Let's do Spinning...`);
const spinResult = await doSpin(headers, account.proxy);
console.log(`Spins result for Account ${index + 1}:`, spinResult);
} else {
logger(`Account ${index + 1}: The current round has already ended, or you have reached the maximum allowed spins.`, 'warn');
logger(`Current time: ${timesNow.timeNow} | Next Round Spin Time: ${timesNow.spinStartTime}`, 'warn');
}
}
logger(`Account ${index + 1} Check completed successfully, proxy: ${account.proxy}`, "info");
} catch (error) {
logger(`Error processing account ${index + 1}: ${error.message}`, "error");
}
}
}
async function main() {
logger(banner, "debug");
setInterval(spins, 15 * 60 * 1000); // 15 minutes interval for spins
while (true) {
const accounts = await readTokensAndIds();
if (accounts.length === 0) {
logger("No accounts to process.", "error");
return;
}
logger(`Processing ${accounts.length} accounts...`, "info");
for (let index = 0; index < accounts.length; index++) {
const account = accounts[index];
try {
await processAccount(account, index);
logger(`Account ${index + 1} processed successfully, proxy: ${account.proxy}`, "info");
} catch (error) {
logger(`Error processing account ${index + 1}: ${error.message}`, "error");
}
}
logger("All accounts processed. Waiting 10 minute for the next run.", "info");
await new Promise(resolve => setTimeout(resolve, 10 * 60 * 1000)); // 10 minutes interval
}
}
process.on('SIGINT', () => {
logger('Process terminated by user.', 'warn');
process.exit(0);
});
// let Start
main();