JennieModule.ts 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. import { BaseClient } from './BaseClient'
  2. import { bcs, Coin, Coins, Fee, MsgExecute } from '@initia/initia.js'
  3. import { getAxiosClient } from './utils'
  4. export abstract class JennieModule extends BaseClient {
  5. protected constructor(mnemonic: string, useProxy: boolean = false) {
  6. super(mnemonic, useProxy)
  7. }
  8. async getXpAmount() {
  9. const viewResult = await this.lcd.move.viewFunction(
  10. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  11. 'initia_xp',
  12. 'get_xp_amount',
  13. undefined,
  14. [bcs.address().serialize(this.key.accAddress).toBase64()],
  15. )
  16. return viewResult
  17. }
  18. async drawFood() {
  19. const res = await this.claimableXp()
  20. if (res != `done`) {
  21. return `needFood`
  22. }
  23. const xp = await this.getXpAmount()
  24. if (Number(xp) < 700 && Number(xp) > 200) {
  25. const msg = new MsgExecute(
  26. this.key.accAddress,
  27. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  28. 'jennie',
  29. 'draw_food',
  30. [],
  31. ['AQ=='],
  32. )
  33. return await this.broadcast(msg)
  34. } else if (Number(xp) >= 700 && Number(xp) < 1200) {
  35. const msg = new MsgExecute(
  36. this.key.accAddress,
  37. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  38. 'jennie',
  39. 'draw_food',
  40. [],
  41. ['Ag=='],
  42. )
  43. return await this.broadcast(msg)
  44. } else if (Number(xp) >= 1200) {
  45. const msg = new MsgExecute(
  46. this.key.accAddress,
  47. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  48. 'jennie',
  49. 'draw_food',
  50. [],
  51. ['Aw=='],
  52. )
  53. return await this.broadcast(msg)
  54. } else {
  55. return `done`
  56. }
  57. }
  58. async feedJennie() {
  59. const viewResult: { hp: string; update_at: string } =
  60. await this.lcd.move.viewFunction(
  61. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  62. 'jennie',
  63. 'get_jennie_state',
  64. undefined,
  65. [bcs.address().serialize(this.key.accAddress).toBase64()],
  66. )
  67. // const stageInfo: {
  68. // current_stage: number
  69. // stage_interval: number
  70. // start_timestamp: number
  71. // } = await this.lcd.move.viewFunction(
  72. // '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  73. // 'jennie',
  74. // 'stage_info',
  75. // undefined,
  76. // [],
  77. // )
  78. const kt = Number(viewResult.update_at)
  79. const now = 1718765974
  80. // const currentStage = stageInfo.current_stage
  81. // const stageInternal = stageInfo.stage_interval
  82. // const stTimestamp = stageInfo.start_timestamp
  83. // const yt =
  84. // stTimestamp +
  85. // Math.floor(((currentStage ?? 1) - 1) / 7) * stageInternal * 7
  86. // const St =
  87. // stTimestamp +
  88. // (Math.floor(((currentStage ?? 1) - 1) / 7) + 1) * stageInternal * 7
  89. // const canFeed = kt < Math.floor(yt / 1000000)
  90. if (!(kt < now)) {
  91. return `done`
  92. }
  93. const rep = await getAxiosClient(true).get(
  94. `${this.rpcUrlUsing}initia/move/v1/accounts/${this.key.accAddress}/resources/by_struct_tag?struct_tag=0x9065fda28f52bb14ade545411f02e8e07a9cb4ba::jennie::FoodStore`,
  95. )
  96. const store = JSON.parse(rep.data.resource.move_resource)
  97. const data = store.data
  98. if (Number(data.tier2) > 0) {
  99. const msg = new MsgExecute(
  100. this.key.accAddress,
  101. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  102. 'jennie',
  103. 'feed_jennie',
  104. [],
  105. [bcs.u8().serialize(2).toBase64()],
  106. )
  107. return await this.broadcast(msg)
  108. } else if (Number(data.tier3) > 0) {
  109. const msg = new MsgExecute(
  110. this.key.accAddress,
  111. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  112. 'jennie',
  113. 'feed_jennie',
  114. [],
  115. [bcs.u8().serialize(3).toBase64()],
  116. )
  117. return await this.broadcast(msg)
  118. } else if (Number(data.tier1) > 0) {
  119. const msg = new MsgExecute(
  120. this.key.accAddress,
  121. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  122. 'jennie',
  123. 'feed_jennie',
  124. [],
  125. [bcs.u8().serialize(1).toBase64()],
  126. )
  127. return await this.broadcast(msg)
  128. } else {
  129. await this.drawFood()
  130. return `needFood`
  131. }
  132. }
  133. async mintJennie() {
  134. // Fetch mint progress details for 'jennie'
  135. const mintProgress: MintProgress = await this.lcd.move.viewFunction(
  136. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  137. 'jennie',
  138. 'get_jennie_mint_progress',
  139. [],
  140. [bcs.address().serialize(this.key.accAddress).toBase64()],
  141. )
  142. console.log(mintProgress)
  143. // Check if 'jennie' is already minted
  144. if (mintProgress.is_minted) {
  145. return `done`
  146. }
  147. // Initialize a flag to determine if all parts are minted
  148. let allPartsMinted = true
  149. // Iterate over each part progress
  150. for (const partProgress of mintProgress.jennie_part_progresses) {
  151. // If any part is not minted, set the flag to false
  152. if (!partProgress.is_minted) {
  153. allPartsMinted = false
  154. break // No need to check further parts
  155. }
  156. }
  157. // If not all parts are minted, exit the function
  158. if (!allPartsMinted) {
  159. return `undone`
  160. }
  161. // Prepare the minting message
  162. const msg = new MsgExecute(
  163. this.key.accAddress,
  164. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  165. 'jennie',
  166. 'mint_jennie',
  167. [],
  168. [],
  169. )
  170. // Broadcast the minting message
  171. return await this.broadcast(msg)
  172. }
  173. async mintPartApprovedAll() {
  174. const axios = getAxiosClient(true)
  175. const res = await axios.get(
  176. `https://xp-api.initiation-1.initia.xyz/xp/mint_parts/${this.key.accAddress}`,
  177. )
  178. const data = res.data
  179. let undone = [1, 2, 3, 4, 5, 6]
  180. for (const item of data) {
  181. const task = Number(item.task_id) + 1
  182. undone = undone.filter(value => value !== task)
  183. }
  184. console.log(undone)
  185. return undone
  186. }
  187. async mintPart() {
  188. // 获取 'jennie' 的铸造进度
  189. const axios = getAxiosClient(true)
  190. const res = await axios.get(
  191. `https://xp-api.initiation-1.initia.xyz/xp/mint_parts/${this.key.accAddress}`,
  192. )
  193. const data = res.data
  194. if (data.length !== 6) {
  195. return `undone`
  196. }
  197. const msgs = []
  198. const mintProgress: MintProgress = await this.lcd.move.viewFunction(
  199. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  200. 'jennie',
  201. 'get_jennie_mint_progress',
  202. [],
  203. [bcs.address().serialize(this.key.accAddress).toBase64()],
  204. )
  205. const progresses = mintProgress.jennie_part_progresses
  206. console.log(progresses)
  207. for (const item of progresses) {
  208. if (item.is_minted) {
  209. continue
  210. }
  211. for (let i = 0; i < data.length; i++) {
  212. if (Number(data[i].task_id) === Number(item.task)) {
  213. const sig = data[i]
  214. const msg = new MsgExecute(
  215. this.key.accAddress,
  216. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  217. 'jennie',
  218. 'mint_part_v2',
  219. [],
  220. [
  221. bcs.u8().serialize(sig.task_id).toBase64(),
  222. bcs
  223. .vector(bcs.u8())
  224. .serialize(Buffer.from(sig.signature, 'base64'))
  225. .toBase64(),
  226. ],
  227. )
  228. msgs.push(msg)
  229. }
  230. }
  231. }
  232. // 初始化消息数组
  233. if (msgs.length === 0) {
  234. return `done`
  235. }
  236. return await this.broadcast(msgs)
  237. }
  238. async claimableXp() {
  239. //https://xp-api.initiation-1.initia.xyz/xp/claimable/init1w6ftxlsv7y5putq955ymxh2kd0wru7nqshetka
  240. const res = getAxiosClient(true)
  241. const data = await res.get(
  242. `https://xp-api.initiation-1.initia.xyz/xp/claimable/${this.key.accAddress}`,
  243. )
  244. if (data.data.claimable_list.length > 0) {
  245. const msgs = []
  246. for (let i = 0; i < data.data.claimable_list.length; i++) {
  247. const proofs = data.data.claimable_list[i].merkle_proofs
  248. const proofsu8vec = proofs.map(p =>
  249. Uint8Array.from(Buffer.from(p, 'base64')),
  250. )
  251. const sd = bcs
  252. .vector(bcs.vector(bcs.u8()))
  253. .serialize(proofsu8vec)
  254. .toBase64()
  255. const msg = new MsgExecute(
  256. this.key.accAddress,
  257. '0x9065fda28f52bb14ade545411f02e8e07a9cb4ba',
  258. 'initia_xp',
  259. 'claim_point',
  260. [],
  261. [
  262. bcs.u64().serialize(data.data.claimable_list[i].stage).toBase64(),
  263. sd,
  264. bcs
  265. .u64()
  266. .serialize(data.data.claimable_list[i].task_point)
  267. .toBase64(),
  268. bcs
  269. .u64()
  270. .serialize(data.data.claimable_list[i].referral_point)
  271. .toBase64(),
  272. ],
  273. )
  274. msgs.push(msg)
  275. }
  276. return await this.broadcast(msgs)
  277. // console.log(broadcast.raw_log)
  278. // console.log(this.key.accAddress)
  279. } else {
  280. return `done`
  281. }
  282. }
  283. }