faucet.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import {
  2. forEachAsync,
  3. generateRandomString,
  4. getAxiosClient,
  5. getProxyAgent,
  6. } from '../utils'
  7. import { getAltchaPayload, getRecaptcha, solveHCaptcha } from './captcha'
  8. import { DBClient } from '../singletons'
  9. import { Status } from '../models/Status'
  10. import polly from 'polly-js'
  11. import { MnemonicKey } from '@initia/initia.js'
  12. import { ethers } from 'ethers'
  13. import { v4 as uuidv4 } from 'uuid'
  14. import axios from 'axios'
  15. import xrpl from 'xrpl'
  16. export async function faucetAccount(address: string) {
  17. const client = getAxiosClient(true)
  18. const altcha = await getAltchaPayload(client)
  19. const hCaptcha = await solveHCaptcha(address)
  20. try {
  21. const res = await client.post(
  22. `https://faucet-api.initiation-1.initia.xyz/claim`,
  23. {
  24. address: address,
  25. altcha_payload: altcha,
  26. denom: 'uinit',
  27. h_captcha: hCaptcha,
  28. },
  29. )
  30. console.log(JSON.stringify(res.data))
  31. } catch (e) {
  32. console.log(e)
  33. throw e
  34. }
  35. }
  36. async function startFaucet(concurrency, index) {
  37. const accountsRaw = await DBClient.instance.account.findMany({
  38. where: {
  39. status: Status.Inited,
  40. },
  41. })
  42. const accounts = accountsRaw.filter(account => account.id % 10 === index)
  43. await forEachAsync(accounts, concurrency, async (account, index) => {
  44. console.log(`${index}/${accounts.length}: processing ${account.address}`)
  45. try {
  46. await faucetAccount(account.address)
  47. await DBClient.instance.account.update({
  48. where: { id: account.id },
  49. data: { status: Status.Fauceted },
  50. })
  51. } catch (e) {
  52. console.log(e)
  53. await DBClient.instance.account.update({
  54. where: { id: account.id },
  55. data: { status: Status.FaucetFailed, message: e.message },
  56. })
  57. }
  58. })
  59. }
  60. async function faucetLunch(concurrency: number = 8) {
  61. const now = new Date()
  62. const accounts = await DBClient.instance.account.findMany({
  63. where: {
  64. lastRun: {
  65. lt: new Date(now.getTime() - 24 * 60 * 60 * 1000),
  66. },
  67. status: 0,
  68. },
  69. orderBy: {
  70. id: 'desc',
  71. },
  72. })
  73. await forEachAsync(accounts, concurrency, async (account, index) => {
  74. console.log(`${index}/${accounts.length}: processing ${account.address}`)
  75. try {
  76. if (!account.gmail) account.gmail = `${generateRandomString(8)}@gmail.com`
  77. if (!account.xrpPrivateKey)
  78. account.xrpPrivateKey = xrpl.Wallet.generate().seed
  79. if (!account.duid) account.duid = uuidv4().toUpperCase()
  80. await polly()
  81. .waitAndRetry(2)
  82. .executeForPromise(async () => {
  83. const key = new MnemonicKey({ mnemonic: account.mnemonic })
  84. const evmWallet = new ethers.Wallet(key.privateKey.toString('hex'))
  85. const message = JSON.stringify({ signedAt: new Date().toISOString() })
  86. const client = axios.create({
  87. headers: {
  88. 'user-agent':
  89. 'Lunch/1.0 (xyz.lunchlunch.app; build:41; iOS 17.4.1) Alamofire/5.8.0',
  90. 'lunch-app-version': 41,
  91. 'lunch-fiat-currency': 'USD',
  92. 'lunch-app-duid': account.duid,
  93. },
  94. httpsAgent: getProxyAgent(),
  95. })
  96. const resp = await client.post(
  97. 'https://api.lunchlunch.xyz/v1/auth/sign-in',
  98. {
  99. walletAddress: evmWallet.address,
  100. signedMessage: await evmWallet.signMessage(message),
  101. rawMessage: message,
  102. },
  103. )
  104. console.log(`${index}: sign-in success.`)
  105. client.defaults.headers[
  106. 'authorization'
  107. ] = `Bearer ${resp.data.accessToken}`
  108. const xrplWallet = xrpl.Wallet.fromSeed(account.xrpPrivateKey)
  109. const register = await client.post(
  110. 'https://api.lunchlunch.xyz/v1/member/register',
  111. {
  112. evmWalletAddress: evmWallet.address,
  113. initiaWalletAddress: key.accAddress,
  114. isImportedWallet: true,
  115. firstInitiaWalletAddress: key.accAddress,
  116. email: account.gmail,
  117. xrplWalletAddress: xrplWallet.address,
  118. },
  119. )
  120. console.log(`${index}: register done`)
  121. const airdropResp = await client.post(
  122. 'https://api.lunchlunch.xyz/v1/dish/submit-action/airdrop',
  123. {
  124. dishId: 42,
  125. },
  126. )
  127. console.log(`${index}: airdrop done`)
  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. },
  138. })
  139. } catch (e) {
  140. console.log(e)
  141. await DBClient.instance.account.update({
  142. where: { id: account.id },
  143. data: {
  144. status: Status.FaucetFailed,
  145. message: e.message,
  146. lastRun: new Date(),
  147. xrpPrivateKey: account.xrpPrivateKey,
  148. gmail: account.gmail,
  149. duid: account.duid,
  150. },
  151. })
  152. }
  153. })
  154. }
  155. await faucetLunch(50)