123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- import { forEachAsync, generateRandomString } from '../utils'
- 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, { AxiosInstance } from 'axios'
- import xrpl from 'xrpl'
- import { InitiaClient } from '../InitiaClient'
- import { HttpsProxyAgent } from 'https-proxy-agent'
- export 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)]
- }
- export function getAndroidOS() {
- const oses = ['9', '10', '11', '12', '12.1', '13']
- return `Android ${oses[Math.floor(Math.random() * oses.length)]}`
- }
- export 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)]}`
- }
- export 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
- )
- }
- export async function getDeviceId(
- isAndroid: boolean,
- model: string,
- httpsAgent: any,
- ): Promise<string> {
- const deviceId = generateRandomString(22)
- let client: AxiosInstance
- if (isAndroid) {
- 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; ${getAndroidOS()}; ${model} Build/PQ3B.190801.05281822)`,
- },
- })
- } else {
- }
- 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
- }
- export 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: {
- // address: 'init1muxa5dedmr2wcc9dkd4k8d54al9gsu5szyw9rd',
- lastRun: {
- lt: new Date(now.getTime() - 24 * 60 * 60 * 1000),
- },
- status: 0,
- },
- orderBy: {
- id: 'asc',
- },
- })
- await forEachAsync(accounts, concurrency, async (account, index) => {
- console.log(`${index}/${accounts.length}: processing ${account.address}`)
- account.gmail = 'cryptoky1998@gmail.com'
- account.duid = 'FBF66888-C389-4C27-B832-CB49A923CED6'
- // account.mnemonic= 'can similar vanish left sudden vocal plate acoustic humor toast observe tortoise demand cook ankle planet angle future detail scout rookie flock type top'
- 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 key = new MnemonicKey()
- // account.duid = uuidv4().toUpperCase()
- // const evmWallet = new ethers.Wallet(key.privateKey.toString('hex'))
- const evmWallet = ethers.Wallet.fromPhrase(account.mnemonic)
- // const evmWallet = ethers.Wallet.createRandom()
- const message = JSON.stringify({
- signedAt: formatDateTime(new Date()),
- })
- const evmSignedMessage = await evmWallet.signMessage(message)
- const proxyAgent = undefined
- // let isAndroid = Math.random() > 0.5
- let isAndroid = false
- if (account.duid) {
- isAndroid = !account.duid.includes('-')
- }
- if (isAndroid && !account.deviceModel) {
- account.deviceModel = getAndroidModel()
- }
- if (!account.duid) {
- account.duid = isAndroid
- ? await getDeviceId(isAndroid, 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': '45',
- 'lunch-fiat-currency': 'USD',
- 'lunch-app-duid': account.duid,
- 'user-agent': `Lunch/1.0 (xyz.lunchlunch.app; build:45; ${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}`
- // await client.delete('http://api.lunchlunch.xyz/v1/member/delete')
- // return
- 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(10)
- .executeForPromise(async info => {
- if (info.count) console.log(`${index}: retry ${info.count}`)
- try {
- await client.post(
- 'https://api.lunchlunch.xyz/v1/dish/submit-action/airdrop',
- {
- dishId: 43,
- },
- )
- console.log(`${index}: airdrop done`)
- } catch (e) {
- console.log(e.response.status, e.response?.data)
- throw e
- }
- })
- 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,
- deviceModel: account.deviceModel,
- deviceOS: account.deviceOS,
- },
- })
- } 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,
- deviceModel: account.deviceModel,
- deviceOS: account.deviceOS,
- },
- })
- }
- })
- }
- await faucetLunch(1)
- //
- // 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()
|