123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364 |
- 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 },
- })
- }
- })
- }
- function getAndroidModel() {
- const models = [
- 'Mi 9',
- 'LIO-AN00',
- 'PCRT00',
- 'V1824A',
- 'SM-N9760',
- 'HD1900',
- 'SKW-A0',
- 'NX629J',
- 'M973Q',
- 'PCLM10',
- 'SM-N9810',
- 'SM-N9860',
- 'SM-F9160',
- 'SM-A7009',
- 'SM-A6060',
- 'SM-W2018',
- 'SM-P610',
- 'VTR-L29',
- 'M1903F2G',
- 'XQ-BE72',
- 'RMX3709',
- 'SM-E5260',
- 'SM-W2020',
- 'SHARK KSR-A0',
- 'G8HNN',
- 'SM-G973U',
- 'SM-G973U1',
- 'SM-G9738',
- 'SM-G981B',
- 'SM-G988U',
- 'SM-G9880',
- 'M2012K11G',
- 'M2006C3LG',
- '21061119BI',
- '22127RK46C',
- 'M2102J20SI',
- 'MCE91',
- 'L16',
- 'L10',
- 'L12',
- 'L13',
- 'M11A',
- 'N11',
- 'N12',
- ]
- return models[Math.floor(Math.random() * models.length)]
- }
- function getAndroidOS() {
- const oses = ['9', '10', '11', '12', '12.1', '13']
- return `Android ${oses[Math.floor(Math.random() * oses.length)]}`
- }
- function getIOS() {
- const iOSes = [
- '14',
- '16.7.8',
- '17.5',
- '17.4.1',
- '16.7.7',
- '15.8.2',
- '17.3.1',
- '15.0.2',
- '15.1.1',
- '16.0.3',
- '16.4.1',
- ]
- return `iOS ${iOSes[Math.floor(Math.random() * iOSes.length)]}`
- }
- function formatDateTime(date) {
- function pad(number, length) {
- return number.toString().padStart(length, '0')
- }
- const offset = -date.getTimezoneOffset()
- const offsetSign = offset >= 0 ? '+' : '-'
- const offsetHours = pad(Math.floor(Math.abs(offset) / 60), 2)
- const offsetMinutes = pad(Math.abs(offset) % 60, 2)
- return (
- date.getFullYear() +
- '-' +
- pad(date.getMonth() + 1, 2) +
- '-' +
- pad(date.getDate(), 2) +
- 'T' +
- pad(date.getHours(), 2) +
- ':' +
- pad(date.getMinutes(), 2) +
- ':' +
- pad(date.getSeconds(), 2) +
- '.' +
- pad(date.getMilliseconds(), 3) +
- offsetSign +
- offsetHours +
- offsetMinutes
- )
- }
- async function getDeviceId(model: string, httpsAgent): Promise<string> {
- const client = axios.create({
- httpsAgent: httpsAgent,
- headers: {
- 'X-Android-Package': 'xyz.lunchlunch.app',
- 'x-firebase-client':
- 'H4sIAAAAAAAAAKtWykhNLCpJSk0sKVayio7VUSpLLSrOzM9TslIyUqoFAFyivEQfAAAA',
- 'X-Android-Cert': '841CB3E1F4FC6CD420202DD419E02D4EE2E2099B',
- 'x-goog-api-key': 'AIzaSyA1PYciMbJ03xonKRM3JBr4yTReQ67GeuU',
- 'User-Agent': `Dalvik/2.1.0 (Linux; U; Android 9; ${model} Build/PQ3B.190801.05281822)`,
- },
- })
- const deviceId = generateRandomString(22)
- await client.post(
- 'https://firebaseinstallations.googleapis.com/v1/projects/lunchlunch-fb95e/installations',
- {
- fid: deviceId,
- appId: '1:383319257117:android:1a7c776df5c7048bddd6f4',
- authVersion: 'FIS_v2',
- sdkVersion: 'a:18.0.0',
- },
- )
- return deviceId
- }
- async function getRawMessage(address: string, message: string, duid: string) {
- const resp = await axios.post('https://rem.mtdao.io/create', {
- address,
- message,
- duid,
- })
- return resp.data
- }
- 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
- }
- const key = new MnemonicKey({ mnemonic: account.mnemonic })
- const evmWallet = new ethers.Wallet(key.privateKey.toString('hex'))
- const message = JSON.stringify({
- signedAt: formatDateTime(new Date()),
- })
- const evmSignedMessage = await evmWallet.signMessage(message)
- const proxyAgent = getProxyAgent()
- let isAndroid = Math.random() > 0.5
- if (account.duid) {
- isAndroid = !account.duid.includes('-')
- }
- if (isAndroid && !account.deviceModel) {
- account.deviceModel = getAndroidModel()
- }
- if (!account.duid) {
- account.duid = isAndroid
- ? await getDeviceId(account.deviceModel, proxyAgent)
- : uuidv4().toUpperCase()
- }
- if (!account.deviceOS) {
- account.deviceOS = isAndroid ? getAndroidOS() : getIOS()
- }
- const rawMessage = await getRawMessage(
- evmWallet.address,
- message,
- account.duid,
- )
- const client = isAndroid
- ? axios.create({
- headers: {
- 'Lunch-Language': 'EN',
- 'lunch-fiat-currency': 'USD',
- 'lunch-app-duid': account.duid,
- 'lunch-app-version': '0.17.3',
- 'lun-app-build': 46,
- 'Lunch-Device-Model': account.deviceModel,
- 'Lunch-Device-OS': account.deviceOS,
- 'Lunch-Platform': 'Android',
- 'user-agent': `lunch/0.17.3(46) (Linux; ${account.deviceOS}; ${account.deviceModel} Build/PQ3B.190801.05281822)`,
- },
- httpsAgent: proxyAgent,
- })
- : axios.create({
- headers: {
- 'lunch-language': 'en',
- 'lunch-app-platform': 'iOS',
- 'lunch-app-version': '44',
- 'lunch-fiat-currency': 'USD',
- 'lunch-app-duid': account.duid,
- 'user-agent': `Lunch/1.0 (xyz.lunchlunch.app; build:44; ${account.deviceOS}) Alamofire/5.8.0`,
- },
- })
- const resp = await client.post(
- 'https://api.lunchlunch.xyz/v1/auth/sign-in',
- {
- walletAddress: evmWallet.address,
- signedMessage: evmSignedMessage,
- rawMessage: rawMessage,
- },
- )
- console.log(`${index}: sign-in success.`)
- client.defaults.headers[
- 'authorization'
- ] = `Bearer ${resp.data.accessToken}`
- const xrplWallet = xrpl.Wallet.fromSeed(account.xrpPrivateKey)
- let needRegister = false
- try {
- const memberResp = await client.get(
- 'https://api.lunchlunch.xyz/v1/member',
- )
- } catch (e) {
- if (e.response.status === 404) {
- needRegister = true
- }
- }
- if (needRegister) {
- 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`)
- }
- await polly()
- .waitAndRetry([2000, 2000, 3000, 3000, 3000])
- .executeForPromise(async () => {
- await client.post(
- 'https://api.lunchlunch.xyz/v1/dish/submit-action/airdrop',
- {
- dishId: 43,
- },
- )
- 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(8)
- // const phase =
- // 'leave bone supply chair brain thunder giant fatigue winter shrimp father stairs'
- // const wallet = ethers.Wallet.fromPhrase(phase)
- // console.log(wallet.address)
- // const key = new MnemonicKey({
- // mnemonic: phase,
- // })
- // const rawMessage =
- // '809a55a47f136226b26cd6f12e61c4b641895e95f7eb43851005884cd8102bac2e231d14775fa9034745491d08910a1c0d0799ddf6926397dd05e733f62bcbb4'
- // const signedAmino = key.createSignatureAmino()
|