Browse Source

lunchClient

Shawn Lu 1 year ago
parent
commit
70e5ffb505
2 changed files with 153 additions and 15 deletions
  1. 14 15
      src/faucet/faucetLunch.ts
  2. 139 0
      src/lunchClient.ts

+ 14 - 15
src/faucet/faucetLunch.ts

@@ -5,12 +5,12 @@ 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 axios, { AxiosInstance } from 'axios'
 import xrpl from 'xrpl'
 import { InitiaClient } from '../InitiaClient'
+import { HttpsProxyAgent } from 'https-proxy-agent'
 
-
-function getAndroidModel() {
+export function getAndroidModel() {
   const models = [
     'Mi 9',
     'LIO-AN00',
@@ -60,12 +60,12 @@ function getAndroidModel() {
   return models[Math.floor(Math.random() * models.length)]
 }
 
-function getAndroidOS() {
+export function getAndroidOS() {
   const oses = ['9', '10', '11', '12', '12.1', '13']
   return `Android ${oses[Math.floor(Math.random() * oses.length)]}`
 }
 
-function getIOS() {
+export function getIOS() {
   const iOSes = [
     '14',
     '16.7.8',
@@ -82,7 +82,7 @@ function getIOS() {
   return `iOS ${iOSes[Math.floor(Math.random() * iOSes.length)]}`
 }
 
-function formatDateTime(date) {
+export function formatDateTime(date) {
   function pad(number, length) {
     return number.toString().padStart(length, '0')
   }
@@ -112,13 +112,13 @@ function formatDateTime(date) {
   )
 }
 
-async function getDeviceId(
+export async function getDeviceId(
   isAndroid: boolean,
   model: string,
-  httpsAgent,
+  httpsAgent: any,
 ): Promise<string> {
   const deviceId = generateRandomString(22)
-  let client
+  let client: AxiosInstance
   if (isAndroid) {
     client = axios.create({
       httpsAgent: httpsAgent,
@@ -128,7 +128,7 @@ async function getDeviceId(
           '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)`,
+        'User-Agent': `Dalvik/2.1.0 (Linux; U; ${getAndroidOS()}; ${model} Build/PQ3B.190801.05281822)`,
       },
     })
   } else {
@@ -145,7 +145,7 @@ async function getDeviceId(
   return deviceId
 }
 
-async function getRawMessage(address: string, message: string, duid: string) {
+export async function getRawMessage(address: string, message: string, duid: string) {
   const resp = await axios.post('https://rem.mtdao.io/create', {
     address,
     message,
@@ -181,8 +181,8 @@ async function faucetLunch(concurrency: number = 8) {
         account.xrpPrivateKey = xrpl.Wallet.generate().seed
       }
 
-      // const key = new MnemonicKey({ mnemonic: account.mnemonic })
-      const key = new MnemonicKey()
+      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)
@@ -327,8 +327,7 @@ async function faucetLunch(concurrency: number = 8) {
   })
 }
 
-
-// await faucetLunch(1)
+await faucetLunch(1)
 //
 // const phase =
 //   'leave bone supply chair brain thunder giant fatigue winter shrimp father stairs'

+ 139 - 0
src/lunchClient.ts

@@ -0,0 +1,139 @@
+import axios, { AxiosInstance } from 'axios'
+import { HttpsProxyAgent } from 'https-proxy-agent'
+import { generateRandomString, getProxyAgent } from './utils'
+import { DBClient } from './singletons'
+import { MnemonicKey } from '@initia/initia.js'
+import xrpl from 'xrpl'
+import { ethers } from 'ethers'
+import { v4 as uuidv4 } from 'uuid'
+import {
+  formatDateTime,
+  getAndroidModel,
+  getAndroidOS,
+  getDeviceId,
+  getIOS,
+  getRawMessage,
+} from './faucet/faucetLunch'
+import { Status } from './models/Status'
+
+export class LunchClient {
+  mnemonic: string
+  client: AxiosInstance
+  proxyAgent: HttpsProxyAgent<any>
+  key
+  constructor(mnemonic: string, useProxy: boolean = true) {
+    this.mnemonic = mnemonic
+    this.proxyAgent = useProxy ? getProxyAgent() : undefined
+    this.key = new MnemonicKey({ mnemonic: mnemonic })
+  }
+
+  async login() {
+    const account = await DBClient.instance.account.findFirst({
+      where: { address: this.key.accAddress },
+    })
+    if (!account.gmail) {
+      account.gmail = `${generateRandomString(8)}@gmail.com`
+    }
+    if (!account.xrpPrivateKey) {
+      account.xrpPrivateKey = xrpl.Wallet.generate().seed
+    }
+    const evmWallet = new ethers.Wallet(this.key.privateKey.toString('hex'))
+    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(`${account.address}: sign-in success.`)
+    // register
+    client.defaults.headers['authorization'] = `Bearer ${resp.data.accessToken}`
+    const xrplWallet = xrpl.Wallet.fromSeed(account.xrpPrivateKey)
+    let needRegister = false
+    try {
+      await client.get('https://api.lunchlunch.xyz/v1/member')
+    } catch (e) {
+      if (e.response.status === 404) {
+        needRegister = true
+      }
+    }
+    if (needRegister) {
+      await client.post('https://api.lunchlunch.xyz/v1/member/register', {
+        evmWalletAddress: evmWallet.address,
+        initiaWalletAddress: this.key.accAddress,
+        isImportedWallet: true,
+        firstInitiaWalletAddress: this.key.accAddress,
+        email: account.gmail,
+        xrplWalletAddress: xrplWallet.address,
+      })
+      console.log(`${this.key.accAddress}: register done`)
+    } else {
+      console.log(`${this.key.accAddress}: already registered`)
+    }
+    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,
+      },
+    })
+  }
+}