├── README.md
├── abi
├── gas_v1.txt
└── gas_v2.txt
├── data
├── accounts_data.xlsx
└── log.txt
├── main.py
├── requirements.txt
├── settings.py
└── utils
├── chain.py
├── func.py
├── gas_bridge.py
├── retry.py
└── wallet.py
/README.md:
--------------------------------------------------------------------------------
1 | [](https://t.me/developercode1)
2 | [](https://www.python.org/downloads/release/python-31010/)
3 |
4 |
5 |

6 |
LAYERZERO GAZ ZIP
7 |
Софт на lz.gas.zip - позволяет отправлять в одной транзакции сразу несколько сообщений через LayerZero - он включает в себя 5 дешевых маршрутов и настройку софта под себя
8 |
9 |
10 | ---
11 |
12 | 🤠👉 Наш канал: [PYTHON DAO](https://t.me/developercode1)
13 |
14 | 🤗 Поддержка: elez-dev.eth
15 |
16 | ---
17 | 🙊 INFO
18 |
19 | Для работы нужен [Python 3.10.10](https://www.python.org/downloads/release/python-31010/)
20 |
21 | В данном гайде подробно описано как установить Python - [link](https://mirror.xyz/wiedzmin.eth/Z06W81VrxO9KI88vkcxeW0Lc8f2nBo5Wdyqce0HTNm8)
22 |
23 | ---
24 | В папке _data_ заполняем Excel файл с приватными ключами.
25 |
26 | Все настройки происходят в файле _settings.py_ - каждая строчка подписана.
27 |
28 | ---
29 | 🚀 УСТАНОВКА СОФТА
30 |
31 | ```
32 | git clone https://github.com/Elez-dev/gasZip.git
33 |
34 |
35 | cd gasZip-master
36 |
37 |
38 | pip3.10 install -r requirements.txt
39 |
40 |
41 | python3.10 main.py
42 | ```
43 | ---
44 | 🤖 ВОЗМОЖНОСТИ СОФТА:
45 |
46 | 1. Запуск по выбранным вами настройкам
47 |
48 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
49 |
50 | 2.1 Polygon -> Gnosis, Fuse, CoreDAO, Klaytn, Celo, Harmony, Loot, Moonbeam, Moonriver, opBNB, Viction - LayerZero V1 Fee: $0.74
51 |
52 | 2.2 Polygon -> Gnosis, Fuse, CoreDAO, Klaytn, Celo, Harmony, Loot, Moonbeam, Moonriver, opBNB, Viction - LayerZero V2 Fee: $0.67
53 |
54 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
55 |
56 | 3.1 Optimism -> Gnosis, Fuse, CoreDAO, Moonriver, Viction, Klaytn, Celo, Harmony, Loot, Moonbeam, Nova, opBNB, Moonriver - LayerZero V1 Fee: $0.68
57 |
58 | 3.2 Optimism -> Gnosis, Fuse, CoreDAO, Moonriver, Viction, Klaytn, Celo, Harmony, Loot, Moonbeam, Nova, opBNB, Moonriver - LayerZero V1 Fee: $0.63
59 |
60 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
61 |
62 | 4.1 Celo -> Fuse, Gnosis, Moonbeam - LayerZero V1 Fee: $0.16
63 |
64 | 4.2 Celo -> Fuse, Gnosis, Viction, Klaytn, Kava, Moonriver, Moonbeam, Loot, Harmony, CoreDAO - LayerZero V2 Fee: $0.55
65 |
66 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
67 |
68 | 5.1 Base -> Gnosis, opBNB, Moonbeam, Nova, Zora - LayerZero V1 Fee: $0.43
69 |
70 | 5.2 Base -> Gnosis, Celo, Fuse, Kava, Klaytn, Harmony, CoreDAO, Moonbeam, Moonriver, Viction, Loot - LayerZero V1 Fee: $0.56
71 |
72 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
73 |
74 | 6.1 Gnosis -> Fuse, Celo, Moonbeam, Klaytn - LayerZero V1 Fee: $0.19
75 |
76 | 6.2 Gnosis -> Fuse, Celo, Moonbeam, Moonriver, Klaytn, CoreDAO, Kava, Harmony, Loot, Viction, - LayerZero V2 Fee: $0.49
77 |
78 | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
79 |
80 | 7.1 Fantom -> Gnosis, Moonbeam, Moonriver, opBNB, Fuse, Celo, Harmony - LayerZero V1 Fee: $0.40
81 |
82 | 7.2 Fantom -> Gnosis, Moonbeam, Moonriver, opBNB, Fuse, Celo, Harmony, CoreDAO, Klaytn, Kava, Loot, Viction - LayerZero V2 Fee: $0.62
83 |
84 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
85 |
86 | 8. Check price
87 |
88 | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
89 |
90 | 9. Мега-маршрут: 2-7 модули вместе рандомно - LayerZero Fee: $2.5
91 |
92 | -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
93 | ❤️ По всем вопросам в наш чат - https://t.me/pythondao
94 |
--------------------------------------------------------------------------------
/abi/gas_v1.txt:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"_lzEndpoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"dstChainId","type":"uint16"},{"internalType":"uint256","name":"nativeAmount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"createAdapterParams","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultGasLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_depositParams","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_dstChainIds","type":"uint16[]"},{"internalType":"bytes[]","name":"_adapterParams","type":"bytes[]"}],"name":"estimateFees","outputs":[{"internalType":"uint256[]","name":"nativeFees","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateFees","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"gasLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_defaultGasLimit","type":"uint256"}],"name":"setDefaultGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_remoteChainIds","type":"uint16[]"},{"internalType":"uint256[]","name":"_gasLimits","type":"uint256[]"}],"name":"setGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_remoteChainIds","type":"uint16[]"},{"internalType":"address[]","name":"_remoteAddresses","type":"address[]"}],"name":"setTrusted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
--------------------------------------------------------------------------------
/abi/gas_v2.txt:
--------------------------------------------------------------------------------
1 | [{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_endpoint","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"params","type":"uint256[]"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"SentDeposits","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32[]","name":"eids","type":"uint32[]"},{"indexed":false,"internalType":"bytes[]","name":"messages","type":"bytes[]"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"}],"name":"SentMessages","type":"event"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"origin","type":"tuple"}],"name":"allowInitializePath","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"uint128","name":"_nativeAmount","type":"uint128"},{"internalType":"address","name":"_to","type":"address"}],"name":"createNativeDropOption","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"}],"name":"createReceiveOption","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultGasLimit","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endpoint","outputs":[{"internalType":"contract ILayerZeroEndpointV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_dstEids","type":"uint32[]"},{"internalType":"bytes[]","name":"_messages","type":"bytes[]"},{"internalType":"bytes[]","name":"_options","type":"bytes[]"}],"name":"estimateFees","outputs":[{"internalType":"uint256[]","name":"nativeFees","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"gasLimitLookup","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint32","name":"srcEid","type":"uint32"},{"internalType":"bytes32","name":"sender","type":"bytes32"},{"internalType":"uint64","name":"nonce","type":"uint64"}],"internalType":"struct Origin","name":"","type":"tuple"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nextNonce","outputs":[{"internalType":"uint64","name":"nonce","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"peers","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_dstEid","type":"uint32"},{"internalType":"bytes","name":"_message","type":"bytes"},{"internalType":"bytes","name":"_options","type":"bytes"}],"name":"quote","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_depositParams","type":"uint256[]"},{"internalType":"address","name":"_to","type":"address"}],"name":"sendDeposits","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_dstEids","type":"uint32[]"},{"internalType":"bytes[]","name":"_messages","type":"bytes[]"}],"name":"sendMessages","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_defaultGasLimit","type":"uint128"}],"name":"setDefaultGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_delegate","type":"address"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_remoteEids","type":"uint32[]"},{"internalType":"uint128[]","name":"_gasLimits","type":"uint128[]"}],"name":"setGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32[]","name":"_remoteEids","type":"uint32[]"},{"internalType":"bytes32[]","name":"_remoteAddresses","type":"bytes32[]"}],"name":"setPeers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lib","type":"address"},{"internalType":"uint64","name":"confirmations","type":"uint64"},{"internalType":"uint32[]","name":"eids","type":"uint32[]"},{"internalType":"address","name":"dvn","type":"address"}],"name":"setUlnConfigs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
--------------------------------------------------------------------------------
/data/accounts_data.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Elez-dev/gasZip/def20a03b1d5044b61d0643559d56f160899b8f5/data/accounts_data.xlsx
--------------------------------------------------------------------------------
/data/log.txt:
--------------------------------------------------------------------------------
1 | 2024-01-23 23:56:48.104 | INFO | __main__::57 - Number of wallets: 4
2 |
3 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | from loguru import logger
2 | from utils.func import get_accounts_data, shuffle, sleeping
3 | from utils.gas_bridge import GasZip
4 | from web3 import Web3
5 | from settings import *
6 | import sys
7 | import time
8 | import random
9 |
10 | logger.remove()
11 | logger.add("./data/log.txt")
12 | logger.add(sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss} | {level: <7} | {message}")
13 | web3_eth = Web3(Web3.HTTPProvider('https://rpc.ankr.com/eth', request_kwargs={'timeout': 60}))
14 |
15 |
16 | class Worker:
17 |
18 | def __init__(self):
19 | self.version = None
20 | self.action = None
21 | self.chain_from = [None, None, Polygon, Celo, Base, Gnosis, Fantom, Optimism]
22 | self.chain_lists = {
23 | 1: {
24 | 2: [Gnosis, Fuse, Core, Klaytn, Celo, Harmony, Loot, Moonbeam, Moonriver, opBNB, Viction],
25 | 3: [Fuse, Gnosis, Moonbeam],
26 | 4: [Gnosis, opBNB, Moonbeam, Nova, Zora],
27 | 5: [Fuse, Celo, Moonbeam, Klaytn],
28 | 6: [Gnosis, Moonbeam, Moonriver, opBNB, Fuse, Celo, Harmony],
29 | 7: [Gnosis, Fuse, Core, Moonriver, Viction, Klaytn, Celo, Harmony, Loot, Moonbeam, Nova, opBNB, Moonriver]
30 | },
31 | 2: {
32 | 2: [Gnosis, Fuse, Core, Klaytn, Celo, Harmony, Loot, Moonbeam, Moonriver, opBNB, Viction],
33 | 3: [Fuse, Gnosis, Viction, Klaytn, Kava, Moonriver, Moonbeam, Loot, Harmony, Core],
34 | 4: [Gnosis, Celo, Fuse, Kava, Klaytn, Harmony, Core, Moonbeam, Moonriver, Viction, Loot],
35 | 5: [Fuse, Celo, Moonbeam, Moonriver, Klaytn, Core, Kava, Harmony, Loot, Viction],
36 | 6: [Gnosis, Moonbeam, Moonriver, opBNB, Fuse, Celo, Harmony, Core, Klaytn, Kava, Loot, Viction],
37 | 7: [Gnosis, Fuse, Core, Moonriver, Viction, Klaytn, Celo, Harmony, Loot, Moonbeam, Nova, opBNB, Moonriver]
38 | }
39 | }
40 |
41 | @staticmethod
42 | def add_random_elements():
43 | random.shuffle(CHAIN_DEP)
44 | random.shuffle(CHAIN_DEP_RANDOM)
45 | chain_dep = CHAIN_DEP.copy()
46 | chain_dep_random = CHAIN_DEP_RANDOM
47 | num_elements_to_add = random.randint(0, len(chain_dep_random))
48 | if num_elements_to_add == 0:
49 | return chain_dep
50 | random_elements = random.sample(chain_dep_random, num_elements_to_add)
51 | chain_dep.extend(random_elements)
52 | return chain_dep
53 |
54 | @staticmethod
55 | def chek_gas_eth():
56 | while True:
57 | try:
58 | res = int(round(Web3.from_wei(web3_eth.eth.gas_price, 'gwei')))
59 | logger.info(f'Газ сейчас - {res} gwei\n')
60 | if res <= MAX_GAS_ETH:
61 | break
62 | else:
63 | time.sleep(60)
64 | continue
65 | except Exception as error:
66 | logger.error(error)
67 | time.sleep(30)
68 | continue
69 |
70 | @staticmethod
71 | def remove_crlf(input_string):
72 | return input_string.replace("\r", "").replace("\n", "")
73 |
74 | def work(self):
75 | i = 0
76 | for number, account in keys_list:
77 | str_number = f'{number} / {all_wallets}'
78 | prv_key, proxy = account
79 |
80 | key = self.remove_crlf(prv_key)
81 |
82 | i += 1
83 | address = web3_eth.eth.account.from_key(key).address
84 | logger.info(f'Account #{i} || {address}\n')
85 |
86 | if self.action == 1:
87 | chain_list = self.add_random_elements()
88 | zp = GasZip(key, CHAIN_FROM, chain_list, str_number, proxy)
89 | number_trans = random.randint(NUMBER_OF_REPETITION[0], NUMBER_OF_REPETITION[1])
90 | logger.info(f'Number of transactions - {number_trans}\n')
91 | for _ in range(number_trans):
92 | self.chek_gas_eth()
93 | zp.refuel(self.version)
94 | sleeping(TIME_DELAY[0], TIME_DELAY[1])
95 |
96 | if self.action in range(2, 8):
97 | zp = GasZip(key, self.chain_from[self.action], self.chain_lists[self.version][self.action], str_number, proxy)
98 | self.chek_gas_eth()
99 | zp.refuel(self.version)
100 |
101 | if self.action == 9:
102 | zp = GasZip(key, CHAIN_FROM, [], str_number, proxy)
103 | if self.version == 1:
104 | zp.check_gas_v1()
105 | else:
106 | zp.check_gas_v2()
107 | return
108 |
109 | if self.action == 8:
110 | random.shuffle(MODULE)
111 | for module in MODULE:
112 | if module == 1:
113 | chain_list = self.add_random_elements()
114 | zp = GasZip(key, CHAIN_FROM, chain_list, str_number, proxy)
115 | number_trans = random.randint(NUMBER_OF_REPETITION[0], NUMBER_OF_REPETITION[1])
116 | logger.info(f'Number of transactions - {number_trans}\n')
117 | for _ in range(number_trans):
118 | self.chek_gas_eth()
119 | zp.refuel(self.version)
120 | sleeping(TIME_DELAY[0], TIME_DELAY[1])
121 |
122 | if module in range(2, 8):
123 | zp = GasZip(key, self.chain_from[module], self.chain_lists[self.version][module], str_number, proxy)
124 | self.chek_gas_eth()
125 | zp.refuel(self.version)
126 | sleeping(TIME_DELAY[0], TIME_DELAY[1])
127 |
128 | logger.success(f'Account completed, sleep and move on to the next one\n')
129 | sleeping(TIME_ACCOUNT_DELAY[0], TIME_ACCOUNT_DELAY[1])
130 |
131 | def display_menu(self):
132 | logger.info('''
133 | Select LayerZero version:
134 | 1 - LayerZero V1
135 | 2 - LayerZero V2
136 | ''')
137 | time.sleep(0.1)
138 | self.version = int(input('Choose a version: '))
139 |
140 | def display_version_menu(self):
141 | if self.version == 1:
142 | logger.info('''
143 | 1 - Run according to your chosen settings
144 | 2 - Polygon -> Gnosis, Fuse, CoreDAO, Klaytn, Celo, Harmony, Loot, Moonbeam, Moonriver, opBNB, Viction - Fee: $0.74
145 | 3 - Celo -> Fuse, Gnosis, Moonbeam - Fee: $0.16
146 | 4 - Base -> Gnosis, opBNB, Moonbeam, Nova, Zora - Fee: $0.43
147 | 5 - Gnosis -> Fuse, Celo, Moonbeam, Klaytn - Fee: $0.19
148 | 6 - Fantom -> Gnosis, Moonbeam, Moonriver, opBNB, Fuse, Celo, Harmony - Fee: $0.40
149 | 7 - Optimism -> Gnosis, Fuse, CoreDAO, Moonriver, Viction, Klaytn, Celo, Harmony, Loot, Moonbeam, Nova, opBNB, Moonriver - Fee: $0.68
150 | 8 - Mega route: 1 - 7 modules together randomly
151 | 9 - Check price
152 | ''')
153 | else:
154 | logger.info('''
155 | 1 - Run according to your chosen settings
156 | 2 - Polygon -> Gnosis, Fuse, CoreDAO, Klaytn, Celo, Harmony, Loot, Moonbeam, Moonriver, opBNB, Viction - Fee: $0.67
157 | 3 - Celo -> Fuse, Gnosis, Viction, Klaytn, Kava, Moonriver, Moonbeam, Loot, Harmony, CoreDAO - Fee: $0.55
158 | 4 - Base -> Gnosis, Celo, Fuse, Kava, Klaytn, Harmony, CoreDAO, Moonbeam, Moonriver, Viction, Loot - Fee: $0.56
159 | 5 - Gnosis -> Fuse, Celo, Moonbeam, Moonriver, Klaytn, CoreDAO, Kava, Harmony, Loot, Viction - Fee: $0.49
160 | 6 - Fantom -> Gnosis, Moonbeam, Moonriver, opBNB, Fuse, Celo, Harmony, CoreDAO, Klaytn, Kava, Loot, Viction - Fee: $0.62
161 | 7 - Optimism -> Gnosis, Fuse, CoreDAO, Moonriver, Viction, Klaytn, Celo, Harmony, Loot, Moonbeam, Nova, opBNB, Moonriver - Fee: $0.63
162 | 8 - Mega route: 1 - 7 modules together randomly
163 | 9 - Check price
164 | ''')
165 |
166 | self.action = int(input('Choose an action: '))
167 |
168 | def run(self):
169 | while True:
170 | while True:
171 | self.display_menu()
172 | if self.version in range(1, 3):
173 | break
174 |
175 | while True:
176 | self.display_version_menu()
177 | if self.action in range(1, 10):
178 | break
179 |
180 | self.work()
181 |
182 |
183 | if __name__ == '__main__':
184 | list1 = get_accounts_data()
185 | all_wallets = len(list1)
186 | logger.info(f'Number of wallets: {all_wallets}\n')
187 | keys_list = shuffle(list1)
188 |
189 | worker = Worker()
190 | worker.run()
191 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pandas==2.1.4
2 | loguru==0.7.2
3 | tqdm==4.66.1
4 | web3==6.13.0
5 | requests==2.31.0
6 | openpyxl==3.1.2
7 | msoffcrypto-tool==5.1.1
--------------------------------------------------------------------------------
/settings.py:
--------------------------------------------------------------------------------
1 | from utils.chain import *
2 |
3 | EXCEL_PASSWORD = False # Если ставите пароль на Excel с приватниками || True/ False
4 | SHUFFLE_WALLETS = True # Перемешка кошельков || True/ False
5 |
6 | CHAIN_RPC = {
7 | Arbitrum : 'https://1rpc.io/arb',
8 | Optimism : 'https://1rpc.io/op',
9 | Polygon : 'https://1rpc.io/matic',
10 | Zora : 'https://rpc.zora.energy', # https://zora.rpc.thirdweb.com
11 | Base : 'https://rpc.ankr.com/base',
12 | Nova : 'https://rpc.ankr.com/arbitrumnova',
13 | BSC : 'https://rpc.ankr.com/bsc',
14 | Celo : 'https://rpc.ankr.com/celo',
15 | Gnosis : 'https://rpc.ankr.com/gnosis',
16 | Fantom : 'https://rpc.ankr.com/fantom',
17 | Core : 'https://rpc.ankr.com/core',
18 | Moonriver: 'https://moonriver.publicnode.com',
19 | Moonbeam : 'https://rpc.ankr.com/moonbeam',
20 | Harmony : 'https://rpc.ankr.com/harmony',
21 | Linea : 'https://1rpc.io/linea',
22 | Scroll : 'https://rpc.ankr.com/scroll',
23 | zkEVM : 'https://rpc.ankr.com/polygon_zkevm',
24 | Kava : 'https://rpc.ankr.com/http/kava_api',
25 | Klaytn : 'https://rpc.ankr.com/klaytn'
26 | }
27 |
28 | MAX_GAS_ETH = 40 # gas в gwei (смотреть здесь : https://etherscan.io/gastracker)
29 | ZORA_GASPRICE_PRESCALE = 0.0001 # Использовать Max base fee и Priority fee для газа в Zora, экономия 0.3-0.5$
30 | BASE_GASPRICE_PRESCALE = 0.05 # Использовать Max base fee и Priority fee для газа в Base
31 | BSC_GWEI = [1.1, 1.2]
32 |
33 | RETRY = 5 # Количество попыток при ошибках / фейлах
34 | TIME_DELAY = [200, 250] # Задержка после ТРАНЗАКЦИЙ [min, max]
35 | TIME_ACCOUNT_DELAY = [20, 30] # Задержка между АККАУНТАМИ [min, max]
36 | TIME_DELAY_ERROR = [10, 20] # Задержка при ошибках / фейлах [min, max]
37 |
38 |
39 | VALUE = [0.000005, 0.0000005, 8] # Количество получаемых токенов [min, max, round_decimal] Общая настройка для всех модулей
40 |
41 | # 1 module -----------------------------------------------------------------------------------------------------------------------------------------------------------
42 |
43 | CHAIN_FROM = Fantom # Из какой сети делать транзы. Доступно || Arbitrum, Optimism, Polygon, Zora,
44 | # Base, Nova, BSC, Celo, Gnosis, Fantom, Core, Moonriver, Moonbeam, Harmony, Linea, Scroll, zkEVM, Kava, Klaytn
45 |
46 | CHAIN_DEP = [Moonbeam] # Сюда пишем сети которые полюбому будут
47 | CHAIN_DEP_RANDOM = [] # Сюда пишем сети которые будут рандомно
48 | # Доступные сети
49 | # Polygon, Arbitrum, Optimism, BSC, Avax, Base, Gnosis, Core, Celo, Moonriver, Fantom, Kava, Linea, Moonbeam, Harmony,
50 | # Canto, Mantle, Nova, Fuse, Beam, Metis, Astar, Conflux, Horizen, Klaytn, Loot, Manta, Meter, OKX, opBNB, Orderly,
51 | # PGN, zkEVM, Scroll, Telos, Tenet, Viction, XPLA, Zora
52 |
53 | NUMBER_OF_REPETITION = [1, 2] # количество транз [min, max]
54 |
55 | # 8 module -----------------------------------------------------------------------------------------------------------------------------------------------
56 |
57 | MODULE = [1, 2, 3, 4, 5, 6, 7]
58 |
--------------------------------------------------------------------------------
/utils/chain.py:
--------------------------------------------------------------------------------
1 | Polygon = 'Polygon'
2 | Arbitrum = 'Arbitrum'
3 | Optimism = 'Optimism'
4 | BSC = 'BSC'
5 | Avax = 'Avax'
6 | Base = 'Base'
7 | Gnosis = 'Gnosis'
8 | Core = 'CORE'
9 | Celo = 'CELO'
10 | Moonriver = 'Moonriver'
11 | Fantom = 'Fantom'
12 | Kava = 'Kava'
13 | Linea = 'Linea'
14 | Moonbeam = 'Moonbeam'
15 | Harmony = 'Harmony'
16 | Canto = 'Canto'
17 | Mantle = 'Mantle'
18 | Nova = 'Nova'
19 | Fuse = 'Fuse'
20 | Beam = 'Beam'
21 | Metis = 'Metis'
22 | Astar = 'Astar'
23 | Conflux = 'Conflux'
24 | Horizen = 'Horizen'
25 | Klaytn = 'Klaytn'
26 | Loot = 'Loot'
27 | Manta = 'Manta'
28 | Meter = 'Meter'
29 | OKX = 'OKX'
30 | opBNB = 'opBNB'
31 | Orderly = 'Orderly'
32 | PGN = 'PGN'
33 | zkEVM = 'zkEVM'
34 | Scroll = 'Scroll'
35 | Telos = 'Telos'
36 | Tenet = 'Tenet'
37 | Viction = 'Viction'
38 | XPLA = 'XPLA'
39 | Zora = 'Zora'
40 |
--------------------------------------------------------------------------------
/utils/func.py:
--------------------------------------------------------------------------------
1 | import io
2 | from msoffcrypto.exceptions import DecryptionError, InvalidKeyError
3 | from loguru import logger
4 | from settings import EXCEL_PASSWORD, SHUFFLE_WALLETS
5 | from utils.chain import *
6 | import random
7 | from tqdm import tqdm
8 | import time
9 | import msoffcrypto
10 | import pandas as pd
11 |
12 | lz_id_chain = {
13 | Polygon: 109,
14 | Arbitrum: 110,
15 | Optimism: 111,
16 | BSC: 102,
17 | Avax: 106,
18 | Base: 184,
19 | Gnosis: 145,
20 | Core: 153,
21 | Celo: 125,
22 | Moonriver: 167,
23 | Fantom: 112,
24 | Kava: 177,
25 | Linea: 183,
26 | Moonbeam: 126,
27 | Harmony: 116,
28 | Canto: 159,
29 | Mantle: 181,
30 | Nova: 175,
31 | Fuse: 138,
32 | Beam: 198,
33 | Metis: 151,
34 | Astar: 210,
35 | Conflux: 212,
36 | Horizen: 215,
37 | Klaytn: 150,
38 | Loot: 197,
39 | Manta: 217,
40 | Meter: 176,
41 | OKX: 155,
42 | opBNB: 202,
43 | Orderly: 213,
44 | PGN: 218,
45 | zkEVM: 158,
46 | Scroll: 214,
47 | Telos: 199,
48 | Tenet: 173,
49 | Viction: 196,
50 | XPLA: 216,
51 | Zora: 195
52 | }
53 |
54 |
55 | def shuffle(wallets_list):
56 | if SHUFFLE_WALLETS is True:
57 | numbered_wallets = list(enumerate(wallets_list, start=1))
58 | random.shuffle(numbered_wallets)
59 | elif SHUFFLE_WALLETS is False:
60 | numbered_wallets = list(enumerate(wallets_list, start=1))
61 | else:
62 | raise ValueError("\nНеверное значение переменной 'shuffle_wallets'. Ожидается 'True' or 'False'.")
63 | return numbered_wallets
64 |
65 |
66 | def sleeping(sleep_from: int, sleep_to: int):
67 | delay = random.randint(sleep_from, sleep_to)
68 | time.sleep(1)
69 | with tqdm(
70 | total=delay,
71 | desc="💤 Sleep",
72 | bar_format="{desc}: |{bar:20}| {percentage:.0f}% | {n_fmt}/{total_fmt}",
73 | colour="green"
74 | ) as pbar:
75 | for _ in range(delay):
76 | time.sleep(1)
77 | pbar.update(1)
78 | time.sleep(1)
79 | print()
80 |
81 |
82 | def get_accounts_data():
83 | decrypted_data = io.BytesIO()
84 | with open('./data/accounts_data.xlsx', 'rb') as file:
85 | if EXCEL_PASSWORD:
86 | time.sleep(1)
87 | password = input('Enter the password: ')
88 | office_file = msoffcrypto.OfficeFile(file)
89 |
90 | try:
91 | office_file.load_key(password=password)
92 | except msoffcrypto.exceptions.DecryptionError:
93 | logger.info('\n⚠️ Incorrect password to decrypt Excel file! ⚠️\n')
94 | raise DecryptionError('Incorrect password')
95 |
96 | try:
97 | office_file.decrypt(decrypted_data)
98 | except msoffcrypto.exceptions.InvalidKeyError:
99 | logger.info('\n⚠️ Incorrect password to decrypt Excel file! ⚠️\n')
100 | raise InvalidKeyError('Incorrect password')
101 |
102 | except msoffcrypto.exceptions.DecryptionError:
103 | logger.info('\n⚠️ Set password on your Excel file first! ⚠️\n')
104 | raise DecryptionError('Excel without password')
105 |
106 | office_file.decrypt(decrypted_data)
107 |
108 | try:
109 | wb = pd.read_excel(decrypted_data)
110 | except ValueError as error:
111 | logger.info('\n⚠️ Wrong page name! ⚠️\n')
112 | raise ValueError(f"{error}")
113 | else:
114 | try:
115 | wb = pd.read_excel(file)
116 | except ValueError as error:
117 | logger.info('\n⚠️ Wrong page name! ⚠️\n')
118 | raise ValueError(f"{error}")
119 |
120 | accounts_data = {}
121 | for index, row in wb.iterrows():
122 | private_key_evm = row["Private Key EVM"]
123 | proxy = row['PROXY']
124 | accounts_data[int(index) + 1] = {
125 | "private_key_evm": private_key_evm,
126 | "proxy": proxy,
127 | }
128 |
129 | priv_key_evm, prx = [], []
130 | for k, v in accounts_data.items():
131 | priv_key_evm.append(v['private_key_evm'])
132 | prx.append(v['proxy'] if isinstance(v['proxy'], str) else None)
133 |
134 | return combine_lists(priv_key_evm, prx)
135 |
136 |
137 | def combine_lists(list1, list2):
138 | combined_list = []
139 | length = len(list1)
140 |
141 | for i in range(length):
142 | combined_list.append((list1[i], list2[i]))
143 |
144 | return combined_list
145 |
--------------------------------------------------------------------------------
/utils/gas_bridge.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | from utils.wallet import Wallet
4 | from loguru import logger
5 | import json as js
6 | from web3 import Web3
7 | from settings import VALUE
8 | import random
9 | from utils.retry import exception_handler
10 | from utils.func import lz_id_chain
11 |
12 |
13 | class GasZip(Wallet):
14 |
15 | def __init__(self, private_key, chain, chain_list, number, proxy):
16 | super().__init__(private_key, chain, number, proxy)
17 | self.chain_list = chain_list
18 | self.abi_v1 = js.load(open('./abi/gas_v1.txt'))
19 | self.abi_v2 = js.load(open('./abi/gas_v2.txt'))
20 | self.contract_v1 = self.web3.eth.contract(address=Web3.to_checksum_address('0xBf94Ed69281709958c8f60bc15cD1bB6BADCd4A4'), abi=self.abi_v1)
21 | self.contract_v2 = self.web3.eth.contract(address=Web3.to_checksum_address('0x26da582889f59eaae9da1f063be0140cd93e6a4f'), abi=self.abi_v2)
22 |
23 | @staticmethod
24 | def dst_chain_id_list(mass):
25 | chain_id_list = [lz_id_chain[chain] for chain in mass]
26 | return chain_id_list
27 |
28 | @staticmethod
29 | def native_amount_list(mass):
30 | native_amount_list = [Web3.to_wei(round(random.uniform(VALUE[0], VALUE[1]), VALUE[2]), 'ether') for _ in mass]
31 | return native_amount_list
32 |
33 | @staticmethod
34 | def create_data_v1(chain_id_list, value_list):
35 | data = []
36 | for i in range(len(chain_id_list)):
37 | deposit_param = chain_id_list[i] << 240
38 | value = value_list[i]
39 | replacement_bytes = value.to_bytes(30, byteorder='big')
40 | deposit_param_bytes = deposit_param.to_bytes(32, byteorder='big')
41 | modified_bytes = deposit_param_bytes[:-30] + replacement_bytes
42 | data.append(int.from_bytes(modified_bytes, byteorder='big'))
43 | return data
44 |
45 | @staticmethod
46 | def create_data_v2(chain_id_list, value_list):
47 | data = []
48 | for i in range(len(chain_id_list)):
49 | deposit_param = chain_id_list[i] << 224
50 | value = value_list[i]
51 | mask = (1 << 128) - 1
52 | modified_bytes = (deposit_param & ~mask) | (value & mask)
53 | data.append(modified_bytes)
54 | return data
55 |
56 | def check_gas_v1(self):
57 | for name, _id in lz_id_chain.items():
58 | amount_list = self.native_amount_list([_id])
59 | adapter_params = [self.contract_v1.functions.createAdapterParams([_id][i], amount_list[i], self.address_wallet).call() for i in range(len([_id]))]
60 | try:
61 | fees = Web3.from_wei(sum(self.contract_v1.functions.estimateFees([_id], adapter_params).call()), 'ether')
62 | except:
63 | fees = None
64 | logger.info(f'Bridge from {self.chain} to {name} || {fees}')
65 | time.sleep(0.1)
66 |
67 | @exception_handler
68 | def refuel_v1(self):
69 | logger.info(f'Bridge from {self.chain} to {self.chain_list}')
70 | id_list = self.dst_chain_id_list(self.chain_list)
71 | amount_list = self.native_amount_list(self.chain_list)
72 | adapter_params = [self.contract_v1.functions.createAdapterParams(id_list[i], amount_list[i], self.address_wallet).call() for i in range(len(self.chain_list))]
73 | fees = sum(self.contract_v1.functions.estimateFees(id_list, adapter_params).call())
74 | deposit_param = self.create_data_v1(id_list, amount_list)
75 | dick = {
76 | "from": self.address_wallet,
77 | "value": fees,
78 | "nonce": self.web3.eth.get_transaction_count(self.address_wallet),
79 | ** self.get_gas_price()
80 | }
81 | txn = self.contract_v1.functions.deposit(deposit_param, self.address_wallet).build_transaction(dick)
82 | self.send_transaction_and_wait(txn, f'Bridge Gas.zip from {self.chain} to {len(self.chain_list)} chain')
83 |
84 | def check_gas_v2(self):
85 | for name, _id in lz_id_chain.items():
86 | _id += 30000
87 | amount_list = self.native_amount_list([_id])
88 | adapter_params = [self.contract_v2.functions.createNativeDropOption([_id][i], amount_list[i], self.address_wallet).call() for i in range(len([_id]))]
89 | try:
90 | fees = Web3.from_wei(sum(self.contract_v2.functions.estimateFees([_id], ['0x' for _ in range(len([_id]))], adapter_params).call()), 'ether')
91 | except:
92 | fees = None
93 | logger.info(f'Bridge from {self.chain} to {name} || {fees}')
94 | time.sleep(0.1)
95 |
96 | @exception_handler
97 | def refuel_v2(self):
98 | logger.info(f'Bridge from {self.chain} to {self.chain_list}')
99 | id_list = [ids + 30000 for ids in self.dst_chain_id_list(self.chain_list)]
100 | amount_list = self.native_amount_list(self.chain_list)
101 | adapter_params = [self.contract_v2.functions.createNativeDropOption(id_list[i], amount_list[i], self.address_wallet).call() for i in range(len(self.chain_list))]
102 | list_message = ['0x' for _ in range(len(id_list))]
103 | fees = sum(self.contract_v2.functions.estimateFees(id_list, list_message, adapter_params).call())
104 | deposit_param = self.create_data_v2(id_list, amount_list)
105 | dick = {
106 | "from": self.address_wallet,
107 | "value": fees,
108 | "nonce": self.web3.eth.get_transaction_count(self.address_wallet),
109 | ** self.get_gas_price()
110 | }
111 | txn = self.contract_v2.functions.sendDeposits(deposit_param, self.address_wallet).build_transaction(dick)
112 | self.send_transaction_and_wait(txn, f'Bridge Gas.zip from {self.chain} to {len(self.chain_list)} chain')
113 |
114 | def refuel(self, version):
115 | if version == 1:
116 | self.refuel_v1()
117 | else:
118 | self.refuel_v2()
119 |
--------------------------------------------------------------------------------
/utils/retry.py:
--------------------------------------------------------------------------------
1 | from web3.exceptions import TransactionNotFound
2 | from web3.exceptions import ContractLogicError
3 | from loguru import logger
4 | from settings import RETRY
5 | import time
6 |
7 |
8 | def exception_handler(func):
9 | def wrapper(self, *args, **kwargs):
10 | for _ in range(RETRY):
11 | try:
12 | return func(self, *args, **kwargs)
13 |
14 | except TransactionNotFound:
15 | logger.error('Транзакция не смайнилась за долгий промежуток времени, пытаюсь еще раз\n')
16 | time.sleep(30)
17 |
18 | except ConnectionError:
19 | logger.error('Ошибка подключения к интернету или проблемы с РПЦ\n')
20 | time.sleep(30)
21 |
22 | except ContractLogicError as cle:
23 | if 'insufficien' in cle.args[0]:
24 | logger.error('Ошибка, скорее всего нехватает комсы\n')
25 | return 'balance'
26 | else:
27 | logger.error(f'{cle}' + '\n')
28 | time.sleep(30)
29 |
30 | except Exception as error:
31 | if isinstance(error.args[0], dict):
32 | if 'insufficien' in error.args[0]['message']:
33 | logger.error('Ошибка, скорее всего нехватает комсы\n')
34 | return 'balance'
35 | else:
36 | logger.error(f'{error}' + '\n')
37 | time.sleep(30)
38 | else:
39 | logger.error(f'{error}' + '\n')
40 | time.sleep(30)
41 | else:
42 | return False
43 | return wrapper
44 |
--------------------------------------------------------------------------------
/utils/wallet.py:
--------------------------------------------------------------------------------
1 | from web3 import Web3
2 | import time
3 | from settings import CHAIN_RPC
4 | from web3.middleware import geth_poa_middleware
5 | from requests.adapters import Retry
6 | import requests
7 | from loguru import logger
8 | from settings import ZORA_GASPRICE_PRESCALE, BASE_GASPRICE_PRESCALE, BSC_GWEI
9 | from utils.chain import *
10 | import random
11 |
12 | SCAN = {
13 | Arbitrum: 'https://arbiscan.io/tx/',
14 | Optimism: 'https://optimistic.etherscan.io/tx/',
15 | Polygon: 'https://polygonscan.com/tx/',
16 | Base: 'https://basescan.org/tx/',
17 | Zora: 'https://explorer.zora.energy/tx/',
18 | Nova: 'https://nova.arbiscan.io/tx/',
19 | BSC: 'https://bscscan.com/tx/',
20 | Celo: 'https://celoscan.io/tx/',
21 | Gnosis: 'https://gnosisscan.io/tx/',
22 | Fantom: 'https://ftmscan.com/tx/',
23 | Moonriver: 'https://moonriver.moonscan.io/tx/',
24 | Moonbeam: 'https://moonscan.io/tx/',
25 | Harmony: 'https://explorer.harmony.one/tx/',
26 | Linea: 'https://lineascan.build/tx/',
27 | Scroll: 'https://scrollscan.com/tx/',
28 | zkEVM: 'https://zkevm.polygonscan.com/tx/',
29 | Kava: 'https://kavascan.com/tx/',
30 | Klaytn: 'https://klaytnscope.com/tx/',
31 | Core: 'https://scan.coredao.org/tx/'
32 | }
33 |
34 |
35 | class Wallet:
36 |
37 | def __init__(self, private_key, chain, number, proxy):
38 | self.private_key = private_key
39 | self.chain = chain
40 | self.number = number
41 | self.proxy = proxy
42 | self.web3 = self.get_web3(chain)
43 | self.scan = self.get_scan(chain)
44 | self.address_wallet = self.web3.eth.account.from_key(private_key).address
45 |
46 | def get_web3(self, chain):
47 | retries = Retry(total=10, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
48 | adapter = requests.adapters.HTTPAdapter(max_retries=retries)
49 | session = requests.Session()
50 | session.mount('http://', adapter)
51 | session.mount('https://', adapter)
52 | if self.proxy is not None:
53 | proxy_dick = {'https': 'http://' + self.proxy, 'http': 'http://' + self.proxy}
54 | session.proxies = proxy_dick
55 | return Web3(Web3.HTTPProvider(CHAIN_RPC[chain], request_kwargs={'timeout': 60}, session=session))
56 |
57 | @staticmethod
58 | def get_scan(chain):
59 | return SCAN[chain]
60 |
61 | @staticmethod
62 | def to_wei(decimal, amount):
63 | if decimal == 6:
64 | unit = 'picoether'
65 | else:
66 | unit = 'ether'
67 |
68 | return Web3.to_wei(amount, unit)
69 |
70 | @staticmethod
71 | def from_wei(decimal, amount):
72 | if decimal == 6:
73 | unit = 'picoether'
74 | elif decimal == 8:
75 | return float(amount / 10 ** 8)
76 | else:
77 | unit = 'ether'
78 |
79 | return Web3.from_wei(amount, unit)
80 |
81 | def send_transaction_and_wait(self, tx, message):
82 | signed_txn = self.web3.eth.account.sign_transaction(tx, private_key=self.private_key)
83 | tx_hash = self.web3.eth.send_raw_transaction(signed_txn.rawTransaction)
84 | logger.info('Sent a transaction')
85 | time.sleep(5)
86 | tx_receipt = self.web3.eth.wait_for_transaction_receipt(tx_hash, timeout=900, poll_latency=5)
87 | if tx_receipt.status == 1:
88 | logger.success('The transaction was successfully mined')
89 | else:
90 | logger.error("Transaction failed, I'm trying again")
91 | raise ValueError('')
92 |
93 | logger.success(f'[{self.number}] {message} || {self.scan}{tx_hash.hex()}\n')
94 | return tx_hash
95 |
96 | def get_native_balance(self):
97 | return self.web3.eth.get_balance(self.address_wallet)
98 |
99 | def get_gas_price(self):
100 | if self.chain in ["Polygon", "Avax", 'Zora']:
101 | try:
102 | self.web3.middleware_onion.inject(geth_poa_middleware, layer=0)
103 | except:
104 | pass
105 |
106 | if self.chain in [Zora, BSC, Base, Fantom, Core, Moonriver, Moonbeam, Harmony, Scroll, Kava, Klaytn]:
107 | if self.chain == BSC:
108 | gwei = round(random.uniform(BSC_GWEI[0], BSC_GWEI[1]), 1)
109 | return {'gasPrice': Web3.to_wei(gwei, 'gwei')}
110 | elif self.chain == Zora:
111 | return {'maxFeePerGas': int(self.web3.eth.gas_price * ZORA_GASPRICE_PRESCALE), 'maxPriorityFeePerGas': int(self.web3.eth.max_priority_fee * ZORA_GASPRICE_PRESCALE)}
112 | elif self.chain == Base:
113 | return {'maxFeePerGas': int(self.web3.eth.gas_price * BASE_GASPRICE_PRESCALE), 'maxPriorityFeePerGas': int(self.web3.eth.max_priority_fee * BASE_GASPRICE_PRESCALE)}
114 | else:
115 | return {'gasPrice': self.web3.eth.gas_price}
116 | return {'maxFeePerGas': self.web3.eth.gas_price, 'maxPriorityFeePerGas': self.web3.eth.max_priority_fee}
117 |
118 | @staticmethod
119 | def get_api_call_data_post(url, json):
120 |
121 | with requests.Session() as s:
122 | call_data = s.post(url, json=json, timeout=60)
123 | if call_data.status_code < 400:
124 | api_data = call_data.json()
125 | return api_data
126 | else:
127 | logger.error("Couldn't get a response")
128 | raise ValueError('')
129 |
--------------------------------------------------------------------------------