import { forEachAsync, generateRandomString, getAxiosClient, getProxyAgent, } from '../utils' import { getAltchaPayload, getRecaptcha, solveHCaptcha } from './captcha' import { DBClient } from '../singletons' import { Status } from '../models/Status' import polly from 'polly-js' import { MnemonicKey } from '@initia/initia.js' import { ethers } from 'ethers' import { v4 as uuidv4 } from 'uuid' import axios from 'axios' import xrpl from 'xrpl' export async function faucetAccount(address: string) { const client = getAxiosClient(true) const altcha = await getAltchaPayload(client) const hCaptcha = await solveHCaptcha(address) try { const res = await client.post( `https://faucet-api.initiation-1.initia.xyz/claim`, { address: address, altcha_payload: altcha, denom: 'uinit', h_captcha: hCaptcha, }, ) console.log(JSON.stringify(res.data)) } catch (e) { console.log(e) throw e } } async function startFaucet(concurrency, index) { const accountsRaw = await DBClient.instance.account.findMany({ where: { status: Status.Inited, }, }) const accounts = accountsRaw.filter(account => account.id % 10 === index) await forEachAsync(accounts, concurrency, async (account, index) => { console.log(`${index}/${accounts.length}: processing ${account.address}`) try { await faucetAccount(account.address) await DBClient.instance.account.update({ where: { id: account.id }, data: { status: Status.Fauceted }, }) } catch (e) { console.log(e) await DBClient.instance.account.update({ where: { id: account.id }, data: { status: Status.FaucetFailed, message: e.message }, }) } }) } async function faucetLunch(concurrency: number = 8) { const now = new Date() const accounts = await DBClient.instance.account.findMany({ where: { lastRun: { lt: new Date(now.getTime() - 24 * 60 * 60 * 1000), }, status: 0, }, orderBy: { id: 'desc', }, }) await forEachAsync(accounts, concurrency, async (account, index) => { console.log(`${index}/${accounts.length}: processing ${account.address}`) try { if (!account.gmail) account.gmail = `${generateRandomString(8)}@gmail.com` if (!account.xrpPrivateKey) account.xrpPrivateKey = xrpl.Wallet.generate().seed if (!account.duid) account.duid = uuidv4().toUpperCase() await polly() .waitAndRetry(2) .executeForPromise(async () => { const key = new MnemonicKey({ mnemonic: account.mnemonic }) const evmWallet = new ethers.Wallet(key.privateKey.toString('hex')) const message = JSON.stringify({ signedAt: new Date().toISOString() }) const client = axios.create({ headers: { 'user-agent': 'Lunch/1.0 (xyz.lunchlunch.app; build:41; iOS 17.4.1) Alamofire/5.8.0', 'lunch-app-version': 41, 'lunch-fiat-currency': 'USD', 'lunch-app-duid': account.duid, }, httpsAgent: getProxyAgent(), }) const resp = await client.post( 'https://api.lunchlunch.xyz/v1/auth/sign-in', { walletAddress: evmWallet.address, signedMessage: await evmWallet.signMessage(message), rawMessage: message, }, ) console.log(`${index}: sign-in success.`) client.defaults.headers[ 'authorization' ] = `Bearer ${resp.data.accessToken}` const xrplWallet = xrpl.Wallet.fromSeed(account.xrpPrivateKey) const register = await client.post( 'https://api.lunchlunch.xyz/v1/member/register', { evmWalletAddress: evmWallet.address, initiaWalletAddress: key.accAddress, isImportedWallet: true, firstInitiaWalletAddress: key.accAddress, email: account.gmail, xrplWalletAddress: xrplWallet.address, }, ) console.log(`${index}: register done`) const airdropResp = await client.post( 'https://api.lunchlunch.xyz/v1/dish/submit-action/airdrop', { dishId: 42, }, ) console.log(`${index}: airdrop done`) }) await DBClient.instance.account.update({ where: { id: account.id }, data: { status: Status.Fauceted, lastRun: new Date(), xrpPrivateKey: account.xrpPrivateKey, gmail: account.gmail, duid: account.duid, }, }) } catch (e) { console.log(e) await DBClient.instance.account.update({ where: { id: account.id }, data: { status: Status.FaucetFailed, message: e.message, lastRun: new Date(), xrpPrivateKey: account.xrpPrivateKey, gmail: account.gmail, duid: account.duid, }, }) } }) } await faucetLunch(50)