-
Notifications
You must be signed in to change notification settings - Fork 94
/
pet_core.py
448 lines (356 loc) · 47.8 KB
/
pet_core.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
from typing import List, Tuple, Union
import copy
from web3 import Web3
from .utils import utils as pet_utils
SERENDALE_CONTRACT_ADDRESS = '0xAC9AFb5900C8A27B766bCad3A37423DC0F4C22d3'
CRYSTALVALE_CONTRACT_ADDRESS = '0x1990F87d6BC9D9385917E3EDa0A7674411C3Cd7F'
SERENDALE2_CONTRACT_ADDRESS = '0x6362b205b539afb5FC369277365441c1dC6fAa28'
ABI = '''
[
{"anonymous":false,"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enumIDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"indexed":false,"internalType":"structIDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"indexed":false,"internalType":"address","name":"_init","type":"address"},{"indexed":false,"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"DiamondCut","type":"event"},
{"inputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"enumIDiamondCut.FacetCutAction","name":"action","type":"uint8"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"structIDiamondCut.FacetCut[]","name":"_diamondCut","type":"tuple[]"},{"internalType":"address","name":"_init","type":"address"},{"internalType":"bytes","name":"_calldata","type":"bytes"}],"name":"diamondCut","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"bytes4","name":"_functionSelector","type":"bytes4"}],"name":"facetAddress","outputs":[{"internalType":"address","name":"facetAddress_","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"facetAddresses","outputs":[{"internalType":"address[]","name":"facetAddresses_","type":"address[]"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"_facet","type":"address"}],"name":"facetFunctionSelectors","outputs":[{"internalType":"bytes4[]","name":"facetFunctionSelectors_","type":"bytes4[]"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"facets","outputs":[{"components":[{"internalType":"address","name":"facetAddress","type":"address"},{"internalType":"bytes4[]","name":"functionSelectors","type":"bytes4[]"}],"internalType":"structIDiamondLoupe.Facet[]","name":"facets_","type":"tuple[]"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},
{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},
{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},
{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"petId","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"}],"indexed":false,"internalType":"structPet","name":"pet","type":"tuple"}],"name":"PetHatched","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"petId","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"},{"internalType":"address","name":"fedBy","type":"address"},{"internalType":"enumPetFoodType","name":"foodType","type":"uint8"}],"indexed":false,"internalType":"structPetV2","name":"pet","type":"tuple"}],"name":"PetHatchedV2","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"petId","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"}],"indexed":false,"internalType":"structPet","name":"pet","type":"tuple"}],"name":"PetUpdated","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"petId","type":"uint256"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"},{"internalType":"address","name":"fedBy","type":"address"},{"internalType":"enumPetFoodType","name":"foodType","type":"uint8"}],"indexed":false,"internalType":"structPetV2","name":"pet","type":"tuple"}],"name":"PetUpdatedV2","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},
{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},
{"inputs":[],"name":"BRIDGE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"MODERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"PET_MODERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"baseHungryTime","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"bonusCount","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"address","name":"_to","type":"address"}],"name":"bridgeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"gold","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"heroCore","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"heroToPet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"nextPetId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"powerUpManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"uint64","name":"_baseHungryTime","type":"uint64"}],"name":"setBaseHungryTime","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"_gold","type":"address"}],"name":"setGold","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"_heroCore","type":"address"}],"name":"setHeroCore","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"enumTreatType","name":"_treatType","type":"uint8"},{"internalType":"address[]","name":"_ingredients","type":"address[]"},{"internalType":"uint256[]","name":"_ingredientAmounts","type":"uint256[]"}],"name":"setIngredients","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"uint256","name":"_nextPetId","type":"uint256"}],"name":"setNextPetId","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"_powerUpManager","type":"address"}],"name":"setPowerUpManager","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"enumTreatType","name":"_treatType","type":"uint8"},{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"uint256","name":"_goldCost","type":"uint256"}],"name":"setTreatType","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"enumTreatType","name":"","type":"uint8"}],"name":"treatInfo","outputs":[{"internalType":"address","name":"treatAddress","type":"address"},{"internalType":"uint256","name":"goldCost","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"enumTreatType","name":"","type":"uint8"},{"internalType":"address","name":"","type":"address"}],"name":"treatIngredientRequirements","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[],"name":"ReentrancyGuard__ReentrantCall","type":"error"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"enumTreatType","name":"treatType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"BonusTreatsAwarded","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fedBy","type":"address"},{"indexed":false,"internalType":"uint256","name":"petId","type":"uint256"},{"indexed":false,"internalType":"enumPetFoodType","name":"foodType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"hungryAt","type":"uint256"}],"name":"PetFed","type":"event"},
{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"enumTreatType","name":"treatType","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"address","name":"item1","type":"address"},{"indexed":false,"internalType":"address","name":"item2","type":"address"}],"name":"TreatCrafted","type":"event"},
{"inputs":[],"name":"PREMIUM_PROVISIONS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},
{"inputs":[{"components":[{"internalType":"enumTreatType","name":"treatType","type":"uint8"},{"internalType":"uint256","name":"treatQuantity","type":"uint256"},{"internalType":"address","name":"item1","type":"address"},{"internalType":"address","name":"item2","type":"address"}],"internalType":"structTreatCraftingInput[]","name":"_treatData","type":"tuple[]"}],"name":"craftTreats","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"components":[{"internalType":"uint256","name":"petId","type":"uint256"},{"internalType":"enumTreatType","name":"treatType","type":"uint8"}],"internalType":"structPetFeedingInput[]","name":"_feedData","type":"tuple[]"}],"name":"feedPets","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"components":[{"internalType":"uint256","name":"petId","type":"uint256"},{"internalType":"enumTreatType","name":"treatType","type":"uint8"}],"internalType":"structPetFeedingInput[]","name":"_feedData","type":"tuple[]"},{"internalType":"address","name":"_account","type":"address"}],"name":"feedPetsOnBehalf","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"uint256[]","name":"_heroIds","type":"uint256[]"}],"name":"getDuelPetData","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint8[]","name":"","type":"uint8[]"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"_heroId","type":"uint256"}],"name":"isHeroPetHungry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"_petId","type":"uint256"}],"name":"isPetHungry","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getPet","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"}],"internalType":"structPet","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getPetV2","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"},{"internalType":"address","name":"fedBy","type":"address"},{"internalType":"enumPetFoodType","name":"foodType","type":"uint8"}],"internalType":"structPetV2","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getUserPets","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"}],"internalType":"structPet[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},
{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getUserPetsV2","outputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"},{"internalType":"address","name":"fedBy","type":"address"},{"internalType":"enumPetFoodType","name":"foodType","type":"uint8"}],"internalType":"structPetV2[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},
{"inputs":[{"components":[{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"}],"internalType":"structPetOptions","name":"_petOptions","type":"tuple"},{"internalType":"address","name":"owner","type":"address"}],"name":"hatchPet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_petId","type":"uint256"}],"name":"transferPetOnBehalf","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"}],"internalType":"structPet","name":"_pet","type":"tuple"}],"name":"updatePet","outputs":[],"stateMutability":"nonpayable","type":"function"},
{"inputs":[{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint8","name":"originId","type":"uint8"},{"internalType":"string","name":"name","type":"string"},{"internalType":"uint8","name":"season","type":"uint8"},{"internalType":"uint8","name":"eggType","type":"uint8"},{"internalType":"uint8","name":"rarity","type":"uint8"},{"internalType":"uint8","name":"element","type":"uint8"},{"internalType":"uint8","name":"bonusCount","type":"uint8"},{"internalType":"uint8","name":"profBonus","type":"uint8"},{"internalType":"uint8","name":"profBonusScalar","type":"uint8"},{"internalType":"uint8","name":"craftBonus","type":"uint8"},{"internalType":"uint8","name":"craftBonusScalar","type":"uint8"},{"internalType":"uint8","name":"combatBonus","type":"uint8"},{"internalType":"uint8","name":"combatBonusScalar","type":"uint8"},{"internalType":"uint16","name":"appearance","type":"uint16"},{"internalType":"uint8","name":"background","type":"uint8"},{"internalType":"uint8","name":"shiny","type":"uint8"},{"internalType":"uint64","name":"hungryAt","type":"uint64"},{"internalType":"uint64","name":"equippableAt","type":"uint64"},{"internalType":"uint256","name":"equippedTo","type":"uint256"},{"internalType":"address","name":"fedBy","type":"address"},{"internalType":"enumPetFoodType","name":"foodType","type":"uint8"}],"internalType":"structPetV2","name":"_pet","type":"tuple"}],"name":"updatePetV2","outputs":[],"stateMutability":"nonpayable","type":"function"}
]
'''
REGULAR_TREAT_TYPE = 0
PREMIUM_TREAT_TYPE = 1
def block_explorer_link(contract_address, txid):
if hasattr(contract_address, 'address'):
contract_address = str(contract_address.address)
contract_address = str(contract_address).upper()
if contract_address == SERENDALE_CONTRACT_ADDRESS.upper():
return 'https://explorer.harmony.one/tx/' + str(txid)
elif contract_address == CRYSTALVALE_CONTRACT_ADDRESS.upper():
return 'https://subnets.avax.network/defi-kingdoms/dfk-chain/explorer/tx/' + str(txid)
elif contract_address == SERENDALE2_CONTRACT_ADDRESS.upper():
return 'https://scope.klaytn.com/tx/' + str(txid)
else:
return str(txid)
def balance_of(contract_address, account, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.balanceOf(Web3.to_checksum_address(account)).call()
def get_pet_v1(contract_address, pet_id, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return _parse_pet_struct(contract.functions.getPet(pet_id).call())
def get_pet_v2(contract_address, pet_id, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return _parse_pet_struct(contract.functions.getPetV2(pet_id).call())
def get_user_pets_v1(contract_address, account, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.getUserPets(account).call()
def get_user_pets_v2(contract_address, account, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
pet_structs = contract.functions.getUserPetsV2(account).call()
pets = []
for p in pet_structs:
pets.append(_parse_pet_struct(p))
return pets
def _parse_pet_struct(pet_struct):
pet = {}
pet['id'] = pet_struct[0]
pet['originId'] = pet_struct[1]
pet['name'] = pet_struct[2]
pet['season'] = pet_struct[3]
pet['eggType'] = pet_struct[4]
pet['rarity'] = pet_struct[5]
pet['element'] = pet_struct[6]
pet['bonusCount'] = pet_struct[7]
pet['profBonus'] = pet_struct[8]
pet['profBonusScalar'] = pet_struct[9]
pet['craftBonus'] = pet_struct[10]
pet['craftBonusScalar'] = pet_struct[11]
pet['combatBonus'] = pet_struct[12]
pet['combatBonusScalar'] = pet_struct[13]
pet['appearance'] = pet_struct[14]
pet['background'] = pet_struct[15]
pet['shiny'] = pet_struct[16]
pet['hungryAt'] = pet_struct[17]
pet['equippableAt'] = pet_struct[18]
pet['equippedTo'] = pet_struct[19]
if len(pet_struct) > 20:
pet['fedBy'] = pet_struct[20]
pet['foodType'] = pet_struct[21] # TODO: overwrite with -1 when hungry so food type is 'none'
return pet
def owner_of(contract_address, pet_id, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.ownerOf(pet_id).call()
def next_pet_id(contract_address, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.nextPetId().call()
def is_approved_for_all(contract_address, owner, operator, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.isApprovedForAll(Web3.to_checksum_address(owner), Web3.to_checksum_address(operator)).call()
def is_hero_pet_hungry(contract_address, hero_id, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.isHeroPetHungry(hero_id).call()
def is_pet_hungry(contract_address, pet_id, rpc_address):
w3 = Web3(Web3.HTTPProvider(rpc_address))
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
return contract.functions.isPetHungry(pet_id).call()
def craft_treats(contract_address, treats: List[Tuple[int, int, str, str]], private_key, nonce, gas_price_gwei, tx_timeout_seconds, rpc_address, logger):
"""
:param contract_address:
:param treats: List of treats to craft [(treat_type, quantity, address_item_1, address_item_2), ...]
:param private_key:
:param nonce:
:param gas_price_gwei:
:param tx_timeout_seconds:
:param rpc_address:
:param logger:
:return:
"""
w3 = Web3(Web3.HTTPProvider(rpc_address))
account = w3.eth.account.from_key(private_key)
w3.eth.default_account = account.address
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
tx = contract.functions.craftTreats(treats)
if isinstance(gas_price_gwei, dict): # dynamic fee
tx = tx.build_transaction(
{'maxFeePerGas': w3.to_wei(gas_price_gwei['maxFeePerGas'], 'gwei'),
'maxPriorityFeePerGas': w3.to_wei(gas_price_gwei['maxPriorityFeePerGas'], 'gwei'), 'nonce': nonce})
else: # legacy
tx = tx.build_transaction({'gasPrice': w3.to_wei(gas_price_gwei, 'gwei'), 'nonce': nonce})
logger.debug("Signing transaction")
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
logger.debug("Sending transaction " + str(tx))
ret = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
logger.debug("Transaction successfully sent !")
logger.info("Waiting for transaction " + block_explorer_link(contract_address, signed_tx.hash.hex()) + " to be mined")
tx_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=signed_tx.hash, timeout=tx_timeout_seconds,
poll_latency=2)
logger.info("Transaction mined !")
return tx_receipt
def feed_pets(contract_address, feeds: List[Tuple[int, int]], private_key, nonce, gas_price_gwei, tx_timeout_seconds, rpc_address, logger):
"""
:param contract_address:
:param feeds: List of pets to feeds [(pet_id, treat_type), ...]
:param private_key:
:param nonce:
:param gas_price_gwei:
:param tx_timeout_seconds:
:param rpc_address:
:param logger:
:return:
"""
w3 = Web3(Web3.HTTPProvider(rpc_address))
account = w3.eth.account.from_key(private_key)
w3.eth.default_account = account.address
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
tx = contract.functions.feedPets(feeds)
if isinstance(gas_price_gwei, dict): # dynamic fee
tx = tx.build_transaction(
{'maxFeePerGas': w3.to_wei(gas_price_gwei['maxFeePerGas'], 'gwei'),
'maxPriorityFeePerGas': w3.to_wei(gas_price_gwei['maxPriorityFeePerGas'], 'gwei'), 'nonce': nonce})
else: # legacy
tx = tx.build_transaction({'gasPrice': w3.to_wei(gas_price_gwei, 'gwei'), 'nonce': nonce})
logger.debug("Signing transaction")
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
logger.debug("Sending transaction " + str(tx))
ret = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
logger.debug("Transaction successfully sent !")
logger.info("Waiting for transaction " + block_explorer_link(contract_address, signed_tx.hash.hex()) + " to be mined")
tx_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=signed_tx.hash, timeout=tx_timeout_seconds,
poll_latency=2)
logger.info("Transaction mined !")
return tx_receipt
def feed_pets_on_behalf(contract_address, feeds: List[Tuple[int, int]], account_address, private_key, nonce, gas_price_gwei, tx_timeout_seconds, rpc_address, logger):
"""
:param contract_address:
:param feeds: List of pets to feeds [(pet_id, treat_type), ...]
:param account_address: account owner ?
:param private_key:
:param nonce:
:param gas_price_gwei:
:param tx_timeout_seconds:
:param rpc_address:
:param logger:
:return:
"""
w3 = Web3(Web3.HTTPProvider(rpc_address))
account = w3.eth.account.from_key(private_key)
w3.eth.default_account = account.address
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
tx = contract.functions.feedPetsOnBehalf(feeds, account_address)
if isinstance(gas_price_gwei, dict): # dynamic fee
tx = tx.build_transaction(
{'maxFeePerGas': w3.to_wei(gas_price_gwei['maxFeePerGas'], 'gwei'),
'maxPriorityFeePerGas': w3.to_wei(gas_price_gwei['maxPriorityFeePerGas'], 'gwei'), 'nonce': nonce})
else: # legacy
tx = tx.build_transaction({'gasPrice': w3.to_wei(gas_price_gwei, 'gwei'), 'nonce': nonce})
logger.debug("Signing transaction")
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
logger.debug("Sending transaction " + str(tx))
ret = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
logger.debug("Transaction successfully sent !")
logger.info("Waiting for transaction " + block_explorer_link(contract_address, signed_tx.hash.hex()) + " to be mined")
tx_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=signed_tx.hash, timeout=tx_timeout_seconds,
poll_latency=2)
logger.info("Transaction mined !")
return tx_receipt
def safe_transfer_from(contract_address, _from, to, egg_id, private_key, nonce, gas_price_gwei, tx_timeout_seconds, rpc_address, logger):
w3 = Web3(Web3.HTTPProvider(rpc_address))
account = w3.eth.account.from_key(private_key)
w3.eth.default_account = account.address
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
tx = contract.functions.safeTransferFrom(_from, to, egg_id)
if isinstance(gas_price_gwei, dict): # dynamic fee
tx = tx.build_transaction(
{'maxFeePerGas': w3.to_wei(gas_price_gwei['maxFeePerGas'], 'gwei'),
'maxPriorityFeePerGas': w3.to_wei(gas_price_gwei['maxPriorityFeePerGas'], 'gwei'), 'nonce': nonce})
else: # legacy
tx = tx.build_transaction({'gasPrice': w3.to_wei(gas_price_gwei, 'gwei'), 'nonce': nonce})
logger.debug("Signing transaction")
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
logger.debug("Sending transaction " + str(tx))
ret = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
logger.debug("Transaction successfully sent !")
logger.info("Waiting for transaction " + block_explorer_link(contract_address, signed_tx.hash.hex()) + " to be mined")
tx_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=signed_tx.hash, timeout=tx_timeout_seconds,
poll_latency=2)
logger.info("Transaction mined !")
return tx_receipt
def transfer_from(contract_address, receiver_address, egg_id, private_key, nonce, gas_price_gwei, tx_timeout_seconds, rpc_address, logger):
w3 = Web3(Web3.HTTPProvider(rpc_address))
account = w3.eth.account.from_key(private_key)
w3.eth.default_account = account.address
contract_address = Web3.to_checksum_address(contract_address)
contract = w3.eth.contract(contract_address, abi=ABI)
owner = contract.functions.ownerOf(egg_id).call()
if logger is not None:
logger.info("Pet {} owner {}".format(egg_id, owner))
if owner != account.address:
raise Exception("Owner mismatch")
tx = contract.functions.transferFrom(owner, receiver_address, egg_id)
if isinstance(gas_price_gwei, dict): # dynamic fee
tx = tx.build_transaction(
{'maxFeePerGas': w3.to_wei(gas_price_gwei['maxFeePerGas'], 'gwei'),
'maxPriorityFeePerGas': w3.to_wei(gas_price_gwei['maxPriorityFeePerGas'], 'gwei'), 'nonce': nonce})
else: # legacy
tx = tx.build_transaction({'gasPrice': w3.to_wei(gas_price_gwei, 'gwei'), 'nonce': nonce})
logger.debug("Signing transaction")
signed_tx = w3.eth.account.sign_transaction(tx, private_key=private_key)
logger.debug("Sending transaction " + str(tx))
ret = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
logger.debug("Transaction successfully sent !")
logger.info("Waiting for transaction " + block_explorer_link(contract_address, signed_tx.hash.hex()) + " to be mined")
tx_receipt = w3.eth.wait_for_transaction_receipt(transaction_hash=signed_tx.hash, timeout=tx_timeout_seconds,
poll_latency=2)
logger.info("Transaction mined !")
return tx_receipt
def human_readable_pet(raw_pet):
readable_pet = copy.deepcopy(raw_pet)
readable_pet['eggType'] = pet_utils.parse_egg_type(readable_pet['eggType'])
readable_pet['rarity'] = pet_utils.parse_egg_rarity(readable_pet['rarity'])
readable_pet['element'] = pet_utils.parse_egg_element(readable_pet['element'])
readable_pet['profBonus'] = pet_utils.parse_bonus_type(readable_pet['eggType'], readable_pet['profBonus'])
readable_pet['background'] = pet_utils.parse_background(readable_pet['background'])
if len(raw_pet) > 20:
readable_pet['foodType'] = pet_utils.parse_food_type(readable_pet['foodType']) #TODO: overwrite with -1 when hungry so food type is 'none'
return readable_pet