├── 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 | [![Telegram channel](https://img.shields.io/endpoint?url=https://runkit.io/damiankrawczyk/telegram-badge/branches/master?url=https://t.me/developercode1)](https://t.me/developercode1) 2 | [![PyPI supported Python versions](https://img.shields.io/badge/Python%203.10.10-8A2BE2)](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 | --------------------------------------------------------------------------------