-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathauto-faucet.js
More file actions
309 lines (273 loc) · 12.6 KB
/
auto-faucet.js
File metadata and controls
309 lines (273 loc) · 12.6 KB
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
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
const fs = require('fs')
const { Wallet, LCDClient, MnemonicKey } = require('@initia/initia.js')
const Worker = require('tiny-worker');
const {solveChallenge, solveChallengeWorkers} = require('altcha-lib')
const { default: axios } = require('axios');
const { join } = require('path')
require('dotenv').config({ path: join(__dirname, '../..', '.env') });
const { log } = require('../../utils/common.js')
const ethers = require('ethers')
const fakeUa = require('fake-useragent');
const { HttpsProxyAgent } = require('https-proxy-agent');
const {wallets} = require('../../wallets/initia.js')
const IP_PROXY = process.env.IP_PROXY
const lcd = new LCDClient('https://lcd.initiation-1.initia.xyz/')
let agent = new HttpsProxyAgent('http://ipfuqv0e:DC32IceOAF0HMmQp_session-bTYSwBxz@209.38.175.3:31112');
let accounts = []
wallets.forEach(k => {
accounts.push(k.address)
})
const MAX_RETRIES = 1; // 最大重试次数
const MAX_PROXY_CHECK_ATTEMPTS = 3;
let agents = `ipfuqv0e:DC32IceOAF0HMmQp_session-yXDUJGqo@209.38.175.3:31112
ipfuqv0e:DC32IceOAF0HMmQp_session-445lAYfy@209.38.175.3:31112
ipfuqv0e:DC32IceOAF0HMmQp_session-JxDTTfj8@209.38.175.3:31112`
let splited_agents = agents.split("\n")
const websiteKey = '04d28d90-d5b9-4a90-94e5-a12c595bd4e2';
const faucetUrl = 'https://bartio.faucet.berachain.com/';
const headers = {
'authority': 'faucet-api.initiation-1.initia.xyz',
'accept': 'application/json, text/plain,*/*',
'accept-language': 'zh-CN,zh;q=0.9',
'cache-control': 'no-cache',
'content-type': 'text/plain;charset=UTF-8',
'origin': 'https://faucet.testnet.initia.xyz',
'pragma': 'no-cache',
'referer': 'https://faucet.testnet.initia.xyz/',
'user-agent': fakeUa(),
};
const clientKey = process.env.YES_CAPTCHA_API_KEY;
// 创建验证码任务
async function createTask(websiteUrl, websiteKey, taskType, pageAction) {
const url = 'https://api.yescaptcha.com/createTask';
const params = {
"clientKey": clientKey,
"task": {
"websiteURL": websiteUrl,
"websiteKey": websiteKey,
"pageAction": pageAction,
"type": taskType
},
// "softID": 'YOUR CLIENT KEY'
}
return await sendRequest(url, {method: 'post', data: params})
}
// 获取验证码结果
async function getTaskResult(taskId) {
const url = 'https://api.yescaptcha.com/getTaskResult';
const params = {
clientKey: clientKey,
taskId: taskId
}
const response_data = await sendRequest(url, {method: 'post', data: params})
const sleep = (minutes) => {
const milliseconds = minutes * 60 * 1000;
return new Promise(resolve => setTimeout(resolve, milliseconds));
};
await sleep(0.2);
if (response_data.status === 'ready') {
return response_data;
} else if (response_data.status === 'processing') {
return await getTaskResult(taskId);
}
}
async function recaptcha(pageAction) {
const { taskId } = await createTask(websiteUrl, websiteKey, 'HCaptchaTaskProxyless');
let result = await getTaskResult(taskId);
// 如果result为空,等待6秒后再次请求
let retried = 0
if (!result) {
while(retried < 10) {
result = await getTaskResult(taskId);
}
}
// 如果再次为空,抛出错误
if (!result) {
throw new Error(`${pageAction} 人机验证失败`);
}
const { gRecaptchaResponse } = result.solution;
return gRecaptchaResponse
}
let claimed_at = {}
main()
async function main() {
console.log(`start.`)
let proxyVerified = false; // 代理验证标志
let proxyAttempts = 0; // 代理检查尝试次数
while (!proxyVerified && proxyAttempts < MAX_PROXY_CHECK_ATTEMPTS) {
console.log('测试代理IP是否正常');
try {
const response = await sendRequest('https://myip.ipip.net', {
method: 'get',
httpAgent: agent,
httpsAgent: agent
});
console.log('验证成功, IP信息: ', response);
proxyVerified = true; // 代理验证成功
} catch (error) {
proxyAttempts++;
console.log('代理失效,等待1分钟后重新验证');
await sleep(60); // 等待1分钟
}
}
while (true) {
try {
for (let i = 0; i < accounts.length; i++) {
try {
agent = new HttpsProxyAgent(`http://${splited_agents[i]}`);
let address = accounts[i]
console.log(`[${i+1}] handing ${address}`);
const balances = await lcd.bank.balance(address)
console.log(`balances`, balances[0]._coins)
if(balances.length > 0 && parseInt(balances[0]._coins.uinit.amount) > 20* 10**6) {
console.log(`addrees ${address} 已领取: ${balances[0]._coins.uinit.amount}`);
continue
}
let attempts = 0;
while (attempts < MAX_RETRIES) {
try {
// console.log(await result.promise)
// console.log(`finished.`)
// return
let recaptchaToken = ''
while (true) {
try {
recaptchaToken = await recaptcha('');
break
} catch (e) {
log(`人机验证失败: ${e}`)
await sleep(3000)
}
}
console.log(recaptchaToken)
// https://faucet-api.initiation-1.initia.xyz/create_challenge
// log(recaptchaToken)
// headers['authorization'] = `Bearer ${recaptchaToken}`;
let resAltcha = await axios('https://faucet-api.initiation-1.initia.xyz/create_challenge', {
headers: headers,
httpsAgent: agent,
httpAgent: agent,
})
console.log(resAltcha.data)
let result = await solveChallengeWorkers(
function() {
let worker = new Worker(function() {
const {solveChallenge} = require('altcha-lib')
let controller = undefined;
onmessage = async (message) => {
const { type, payload } = message.data;
if (type === 'abort') {
controller?.abort();
controller = undefined;
}
else if (type === 'work') {
console.log(payload)
const { alg, challenge, max, salt, start } = payload || {};
const result = solveChallenge(challenge, salt, alg, max, start);
controller = result.controller;
result.promise.then((solution) => {
console.log(`solution:`, solution)
self.postMessage(solution ? { ...solution, worker: true } : solution);
});
}
};
})
return worker
}, // Worker script URL or path
8, // Spawn 8 workers
resAltcha.data.challenge,
resAltcha.data.salt,
resAltcha.data.algorithm, resAltcha.data.maxnumber
)
console.log(result)
const url = `https://bartio.faucet.berachain.com/`;
const data = {
address: address,
denom: 'TKNBERA',
altcha_payload: btoa(JSON.stringify({
algorithm: resAltcha.data.algorithm,
challenge: resAltcha.data.challenge,
number: result.number,
salt: resAltcha.data.salt,
signature: resAltcha.data.signature,
took: result.took
})),
h_captcha: recaptchaToken,
};
const urlConfig = {
headers: headers,
httpsAgent: agent,
httpAgent: agent,
};
const response = await axios.post(url, data, urlConfig);
const amount = response.data.amount;
console.log(`领取成功✅ ${address}`, amount);
// console.log('领取成功✅,地址:', address);
// claimed_at[address] = new Date().valueOf()
attempts = MAX_RETRIES;
} catch (error) {
log(`error`, error)
if(error.response && error.response.data.msg) {
console.error(`领取失败❌,地址:${address}: ${error.response.data.msg}`);
}
attempts++;
if(attempts < MAX_RETRIES) {
console.log(`地址${address}正在重试第 ${attempts} 次...`);
await sleep(5);
} else {
claimed_at[address] = new Date().valueOf()
}
// if (error.response && error.response.data.msg === 'Faucet is overloading, please try again') {
// } else {
// console.error(`领取失败❌,地址:${address}: ${error.response.data.msg}`);
// break; // 如果是非重试误,退出循环
// }
}
}
// 暂停一段时间
const pauseTime = getRandomInt(200, 1000)
console.log(`任务完,线程暂停${pauseTime}毫秒`);
await sleep(pauseTime);
} catch (e) {
log(`error. ${e}`)
}
}
log(`完成一轮, 休息一会`);
await sleep(8 * 60 * 1000)
} catch (e) {
log(`error.`, e)
}
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function sendRequest(url, urlConfig, timeout = 10000) {
const source = axios.CancelToken.source();
const timer = setTimeout(() => {
source.cancel(`Request timed out after ${timeout} ms`);
}, timeout);
const newConfig = {
...urlConfig,
url: url,
timeout: timeout,
cancelToken: source.token,
method: urlConfig.method || 'get',
onDownloadProgress: () => clearTimeout(timer),
};
try {
const response = await axios(newConfig);
if(response && response.data) {
return response.data;
} else {
throw 'request error'
}
} catch (error) {
log(error, error)
throw error;
}
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
const CLAIM_INTERVAL = 8 * 60 * 60 * 1000; // 8小时