LunchClient.ts 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import axios, { AxiosInstance } from 'axios'
  2. import { HttpsProxyAgent } from 'https-proxy-agent'
  3. import { generateRandomString, getProxyAgent } from './utils'
  4. import { DBClient } from './singletons'
  5. import { MnemonicKey } from '@initia/initia.js'
  6. import xrpl from 'xrpl'
  7. import { ethers } from 'ethers'
  8. import { v4 as uuidv4 } from 'uuid'
  9. import {
  10. formatDateTime,
  11. getAndroidModel,
  12. getAndroidOS,
  13. getDeviceId,
  14. getIOS,
  15. getRawMessage,
  16. } from './faucet/faucetLunch'
  17. import { Status } from './models/Status'
  18. export class LunchClient {
  19. mnemonic: string
  20. axiosClient: AxiosInstance
  21. proxyAgent: HttpsProxyAgent<any>
  22. key: MnemonicKey
  23. isLogin: boolean = false
  24. constructor(mnemonic: string, useProxy: boolean = true) {
  25. this.mnemonic = mnemonic
  26. this.proxyAgent = useProxy ? getProxyAgent() : undefined
  27. this.key = new MnemonicKey({ mnemonic: mnemonic })
  28. }
  29. async login() {
  30. const account = await DBClient.instance.account.findFirst({
  31. where: { address: this.key.accAddress },
  32. })
  33. if (!account.gmail) {
  34. account.gmail = `${generateRandomString(8)}@gmail.com`
  35. }
  36. if (!account.xrpPrivateKey) {
  37. account.xrpPrivateKey = xrpl.Wallet.generate().seed
  38. }
  39. const evmWallet = new ethers.Wallet(this.key.privateKey.toString('hex'))
  40. const message = JSON.stringify({
  41. signedAt: formatDateTime(new Date()),
  42. })
  43. const evmSignedMessage = await evmWallet.signMessage(message)
  44. const proxyAgent = undefined
  45. // let isAndroid = Math.random() > 0.5
  46. let isAndroid = false
  47. if (account.duid) {
  48. isAndroid = !account.duid.includes('-')
  49. }
  50. if (isAndroid && !account.deviceModel) {
  51. account.deviceModel = getAndroidModel()
  52. }
  53. if (!account.duid) {
  54. account.duid = isAndroid
  55. ? await getDeviceId(isAndroid, account.deviceModel, proxyAgent)
  56. : uuidv4().toUpperCase()
  57. }
  58. if (!account.deviceOS) {
  59. account.deviceOS = isAndroid ? getAndroidOS() : getIOS()
  60. }
  61. const rawMessage = await getRawMessage(
  62. evmWallet.address,
  63. message,
  64. account.duid,
  65. )
  66. this.axiosClient = isAndroid
  67. ? axios.create({
  68. headers: {
  69. 'Lunch-Language': 'EN',
  70. 'lunch-fiat-currency': 'USD',
  71. 'lunch-app-duid': account.duid,
  72. 'lunch-app-version': '0.17.3',
  73. 'lun-app-build': 46,
  74. 'Lunch-Device-Model': account.deviceModel,
  75. 'Lunch-Device-OS': account.deviceOS,
  76. 'Lunch-Platform': 'Android',
  77. 'user-agent': `lunch/0.17.3(46) (Linux; ${account.deviceOS}; ${account.deviceModel} Build/PQ3B.190801.05281822)`,
  78. },
  79. httpsAgent: proxyAgent,
  80. })
  81. : axios.create({
  82. headers: {
  83. 'lunch-language': 'en',
  84. 'lunch-app-platform': 'iOS',
  85. 'lunch-app-version': '45',
  86. 'lunch-fiat-currency': 'USD',
  87. 'lunch-app-duid': account.duid,
  88. 'user-agent': `Lunch/1.0 (xyz.lunchlunch.app; build:45; ${account.deviceOS}) Alamofire/5.8.0`,
  89. },
  90. })
  91. const resp = await this.axiosClient.post(
  92. 'https://api.lunchlunch.xyz/v1/auth/sign-in',
  93. {
  94. walletAddress: evmWallet.address,
  95. signedMessage: evmSignedMessage,
  96. rawMessage: rawMessage,
  97. },
  98. )
  99. console.log(`${account.address}: sign-in success.`)
  100. // register
  101. this.axiosClient.defaults.headers[
  102. 'authorization'
  103. ] = `Bearer ${resp.data.accessToken}`
  104. const xrplWallet = xrpl.Wallet.fromSeed(account.xrpPrivateKey)
  105. let needRegister = false
  106. // try {
  107. // await this.axiosClient.get('https://api.lunchlunch.xyz/v1/member')
  108. // } catch (e) {
  109. // if (e.response.status === 404) {
  110. // needRegister = true
  111. // }
  112. // }
  113. if (needRegister) {
  114. await this.axiosClient.post(
  115. 'https://api.lunchlunch.xyz/v1/member/register',
  116. {
  117. evmWalletAddress: evmWallet.address,
  118. initiaWalletAddress: this.key.accAddress,
  119. isImportedWallet: true,
  120. firstInitiaWalletAddress: this.key.accAddress,
  121. email: account.gmail,
  122. xrplWalletAddress: xrplWallet.address,
  123. },
  124. )
  125. console.log(`${this.key.accAddress}: register done`)
  126. } else {
  127. console.log(`${this.key.accAddress}: already registered`)
  128. }
  129. await DBClient.instance.account.update({
  130. where: { id: account.id },
  131. data: {
  132. status: Status.Fauceted,
  133. lastRun: new Date(),
  134. xrpPrivateKey: account.xrpPrivateKey,
  135. gmail: account.gmail,
  136. duid: account.duid,
  137. deviceModel: account.deviceModel,
  138. deviceOS: account.deviceOS,
  139. },
  140. })
  141. this.isLogin = true
  142. }
  143. async submitOnchain(txHash: string) {
  144. if (!this.isLogin) throw new Error('Please login first')
  145. return await this.axiosClient.post(
  146. `https://api.lunchlunch.xyz/v1/dish/submit-action/onchain`,
  147. {
  148. dishId: 7,
  149. txHash: txHash,
  150. },
  151. )
  152. }
  153. async claimEgg(txHash: string) {
  154. if (!this.isLogin) throw new Error('Please login first')
  155. await this.axiosClient.post(
  156. `https://api.lunchlunch.xyz/v1/dish/submit-claim/egg`,
  157. {
  158. dishId: 7,
  159. txHash: txHash,
  160. },
  161. )
  162. }
  163. async getEggBalance() {
  164. if (!this.isLogin) throw new Error('Please login first')
  165. const resp = await this.axiosClient.get(
  166. 'https://api.lunchlunch.xyz/v1/member/egg/balance',
  167. )
  168. return resp.data
  169. }
  170. }