Ethereum client
Ethereum client
- class xchainpy2_ethereum.eth_client.EthereumClient(network=NetworkType.MAINNET, phrase: str | None = None, private_key: str | bytes | callable | None = None, root_derivation_paths: Dict[NetworkType, str] | None = None, explorer_providers=None, wallet_index=0, provider: str | BaseProvider | None = None, extra_data_provider: EVMDataProvider | None = None, **kwargs)
Bases:
XChainClient- async approve_erc20_token(spender: str, amount: CryptoAmount, gas: Gas) str
Approve ERC20 token for a spender.
- Parameters:
spender – Spender address
amount – Amount to approve
gas – Gas options. Default is Gas.auto(FeeOption.FAST)
- Returns:
Transaction hash
- async broadcast_tx(tx_hex: str) str
Broadcast a signed transaction to the network.
- Parameters:
tx_hex – Signed transaction in hex format
- Returns:
Transaction ID that is broadcast to the network
- property chain_id: int
Get the chain ID for the current network. 1 for Ethereum mainnet and so on.
- Returns:
int chain ID
- enable_web3_caching()
Enable Web3 caching middlewares
- erc20_asset_from_contract(contract: Contract | str, symbol: str)
Create an Asset object from a contract address.
- Parameters:
contract – Contract address or Contract object
symbol – Symbol of the token
- Returns:
Asset object
- async estimate_gas_limit(tx_with_data: dict) int
- async estimate_gas_of_transfer(what: CryptoAmount, recipient: str, memo: str | None = None, gas: Gas | None = None, nonce: int | None = None) CryptoAmount
Estimate gas for a transfer transaction.
- Parameters:
what – Amount to transfer
recipient – Recipient address or contract address to call
memo – Optional memo (not supported for ERC20 token transfer)
gas – Optional Gas object. If not provided, it will use Gas.auto(FeeOption.FAST).
nonce – Optional nonce. If not provided, it will fetch the nonce from the blockchain.
- Returns:
- gas_limit_estimation
If True, it will estimate the gas limit for the transaction before sending it. It is useful for complex transactions where the gas limit is not known in advance. This action requires an extra RPC call to the node. Otherwise, it will use the default gas limit for the transaction.
- gas_transfer_margin
Gas transfer margin is a percentage of the gas limit that is added to the gas limit to prevent gas underestimation.
- get_account() Account
Get the account object (web3) for the current wallet.
- get_address() str
Get the address for the given wallet index. The address returned is check-summed.
- Returns:
string address
- async get_balance(address: str = '', with_erc20=False) List[CryptoAmount]
Get the balance of a given address.
- Parameters:
address – By default, it will return the balance of the current wallet. (optional)
with_erc20 – If True, it will return the balance of all ERC20 tokens as well. (optional). Experimental!
- Returns:
- async get_block_timestamp(block_number: int) int
Get the timestamp of a given block number.
- Parameters:
block_number – int
- Returns:
Timestamp
- async get_erc20_allowance(contract_address: str | Asset | Contract, spender: str, address: str = '') CryptoAmount
Get the allowance of a given address.
- Parameters:
contract_address – ERC20 Contract address. Can be an Asset object or a string.
spender – Spender address
address – By default, it will return the allowance of the current wallet. (optional)
- Returns:
CryptoAmount
- get_erc20_as_contract(contract_address: str | Asset | Contract)
Get the ERC20 contract object for a given contract address.
- Parameters:
contract_address – Contract address, or Asset object, or Contract object
- Returns:
Contract object
- async get_erc20_token_balance(contract_address: str | Asset | Contract, address: str = '') CryptoAmount
Get the balance of a given address.
- async get_erc20_token_info(contract: str | Asset | Contract) TokenInfo
Returns zero balance and token symbol for a given contract address. The balance is zero because we are only interested in the token symbol and decimals.
- Parameters:
contract – Contract object or contract address or Asset object
- get_explorer_tx_url(tx_id: str) str
Get the explorer url for the given transaction id.
- Parameters:
tx_id – str The transaction id
- Returns:
str The explorer url for the given transaction id based on the network.
- async get_fees(fee_multiplier=1.0) EVMFees
Get EVM gas rates for the current network. Fees are estimated based on the last 20 blocks. All FeeRate are in Gwei!
- Parameters:
fee_multiplier – Fee multiplier. Default is 1.0
- Returns:
Fees object
- async get_last_fee() CryptoAmount
Get the last Ethereum fee from Web3 provider.
- Returns:
CryptoAmount
- async get_nonce(address: str = '') int
Get the nonce for a given address. Otherwise, it will return the nonce of the current wallet. Nonce is the number of transactions sent from an address.
- Parameters:
address (str) – Address of a wallet (optional)
- Returns:
Nonce
- Return type:
int
- get_public_key()
Get the public key for the current wallet.
- async get_transaction_data(tx_id: str, with_timestamp=False) XcTx | None
Get transaction details by transaction ID (hash).
- Parameters:
tx_id – Transaction ID (hash)
with_timestamp – If True, it will return the timestamp of the block. Extra API call!
- Returns:
Optional[XcTx]
- async get_transactions(address: str = '', offset: int = 0, limit: int = 0, start_time: datetime | None = None, end_time: datetime | None = None, asset: Asset | None = None) TxPage
Get transactions of a given address. Works only if you have provided an extra data provider. Etherscan Pro and Moralis are supported.
- Parameters:
address – Address of wallet to inspect its history
offset – (not supported)
limit – Maximum number of transactions to return
start_time – (not supported)
end_time – (not supported)
asset – (not supported)
- Returns:
- async make_contract_call(method_pointer, value, gas: Gas, nonce: int | None = None) str
Make a contract call.
- Parameters:
method_pointer – Contract method pointer
value – Value to send
gas – Gas options
nonce – Nonce (optional) if not provided, it will fetch the nonce from the blockchain
- Returns:
Transaction hash
- property provider
Get the current Web3 provider.
- Returns:
BaseProvider
- async revoke_erc20_token_allowance(spender: str, token: str | Asset, gas: Gas) str
Revoke ERC20 token allowance for a spender.
- Parameters:
spender – Spender address
token – Token symbol or Asset object
gas – Gas options. Default is Gas.auto(FeeOption.FAST)
- async transfer(what: CryptoAmount, recipient: str, memo: str | None = None, gas: Gas | None = None, **kwargs) str
Transfer Ethereum or ERC20 token. Do not use it for swap or something like this. Use AMM’s deposit method instead.
- Parameters:
what – Amount to transfer
recipient – Recipient address or contract address to call
memo – Memo (optional, not supported for ERC20 token transfer)
gas – Gas object is optional. If not provided, it will use Gas.auto(FeeOption.FAST).
- Returns:
Transaction hash
- validate_address(address: str) bool
Validates an Ethereum address.
- Parameters:
address – Address string
- Returns:
True if valid, False otherwise.
- validated_checksum_address(address: str) str
Validate and checksum an Ethereum address if it’s not checksummed.
- Parameters:
address – str Address to validate
- Returns:
bool True if valid, False otherwise.
- async wait_for_transaction(tx_id: str, timeout: int = 120, with_timestamp=False, *args, **kwargs) XcTx | None
Wait for a transaction to be mined. This method does not perform polling explicitly. It uses the web3.wait_for_transaction_receipt method. If the transaction is not mined within the timeout, it will raise a TimeExhausted exception.
- Parameters:
tx_id – Transaction ID
timeout – Timeout in seconds. Default is 120 seconds
with_timestamp – If True, it will return the timestamp of the block
- Returns:
Transaction object XcTx
Ethereum constants
- xchainpy2_ethereum.const.DEFAULT_ETH_EXPLORER_PROVIDERS = {NetworkType.MAINNET: ('https://etherscan.io', 'https://etherscan.io/address/{address}', 'https://etherscan.io/tx/{tx_id}'), NetworkType.STAGENET: ('https://etherscan.io', 'https://etherscan.io/address/{address}', 'https://etherscan.io/tx/{tx_id}'), NetworkType.TESTNET: ('https://sepolia.etherscan.io/', 'https://sepolia.etherscan.io/address/{address}', 'https://sepolia.etherscan.io/tx/{tx_id}')}
Ethereum Default Explorer URLS
- xchainpy2_ethereum.const.ETH_CHAIN_ID = {NetworkType.MAINNET: 1, NetworkType.STAGENET: 1, NetworkType.TESTNET: 11155111}
Ethereum Chain IDs. In the Ethereum Virtual Machine (EVM), the Chain ID is a unique identifier assigned to each blockchain to prevent replay attacks, where a transaction on one chain could be copied and reused on another. The Chain ID was introduced in EIP-155 to add an additional layer of security and to help distinguish between different Ethereum-compatible networks, like Ethereum mainnet, testnets, and sidechains.
- xchainpy2_ethereum.const.ETH_DECIMALS = 18
Ethereum Decimals The resolution of eth is 18 decimals, which means that 1 eth = “1 followed by 18 zeros” wei eth.
- xchainpy2_ethereum.const.ETH_NORMAL_PRIORITY_FEE_WEI = 1500000000
Ethereum Normal Fee in gwei This is a typical fee for a transaction but it can be increased or decreased based on your needs
- xchainpy2_ethereum.const.ETH_ROOT_DERIVATION_PATHS = {NetworkType.MAINNET: "m/44'/60'/0'/0/", NetworkType.STAGENET: "m/44'/60'/0'/0/", NetworkType.TESTNET: "m/44'/60'/0'/0/"}
Ethereum Root Derivation Paths
- xchainpy2_ethereum.const.ETH_TOKEN_LIST = '/home/docs/checkouts/readthedocs.org/user_builds/xchainpy2/checkouts/develop/packages/xchainpy_ethereum/xchainpy2_ethereum/data/eth_mainnet_latest.json'
Ethereum ERC20 Token List Source: 1inch
- xchainpy2_ethereum.const.EVM_NULL_ADDRESS = '0x0000000000000000000000000000000000000000'
Ethereum Null Address
- xchainpy2_ethereum.const.FREE_ETH_PROVIDERS = {NetworkType.MAINNET: ['https://rpc.ankr.com/eth', 'https://eth-mainnet.public.blastapi.io', 'https://eth.llamarpc.com', 'https://cloudflare-eth.com/', 'https://rpc.flashbots.net/'], NetworkType.STAGENET: ['https://rpc.ankr.com/eth', 'https://eth-mainnet.public.blastapi.io', 'https://eth.llamarpc.com', 'https://cloudflare-eth.com/', 'https://rpc.flashbots.net/'], NetworkType.TESTNET: ['https://rpc2.sepolia.org', 'https://sepolia.drpc.org', 'wss://sepolia.gateway.tenderly.co']}
Free public Ethereum WEB3 Providers. These providers are used by default, and they may have some limitations. You better use your own provider for production.
- xchainpy2_ethereum.const.GAS_LIMITS = {NetworkType.MAINNET: (200000, 23000, 170000, 180000, 30000000000), NetworkType.STAGENET: (200000, 23000, 170000, 180000, 30000000000), NetworkType.TESTNET: (200000, 23000, 170000, 180000, 30000000000)}
Ethereum default gas limits
- xchainpy2_ethereum.const.MAIN_NET_ETHERSCAN_PROVIDER = ('https://etherscan.io', 'https://etherscan.io/address/{address}', 'https://etherscan.io/tx/{tx_id}')
Ethereum Mainnet explorer URLS (Etherscan.io)
- xchainpy2_ethereum.const.MAX_APPROVAL = 115792089237316195423570985008687907853269984665640564039457584007913129639935
Maximum approval value for ERC20 tokens
Ethereum Gas Management
- class xchainpy2_ethereum.gas.EVMFees(fees: Dict[FeeOption, CryptoAmount], priority_fee: CryptoAmount, base_fee: CryptoAmount)
Bases:
FeeProgressive
- class xchainpy2_ethereum.gas.EVMGas(gas_price: int | None = None, max_fee_per_gas: int | None = None, max_priority_fee_per_gas: int | None = None, gas_limit: int | None = None)
Bases:
IGasExplicitSettingsGas options for transaction invocation in Ethereum-like chains.
- classmethod eip1559(max_fee_per_gas: int, max_priority_fee_per_gas: int, gas_limit: int)
max_priority_fee_per_gas is your “tip” (what goes to the miner). base_fee_per_gas is the protocol-burned minimum fee for that block. max_fee_per_gas is the total ceiling you’re willing to pay per gas; it must cover both the base fee and your tip.
In other words: maxFeePerGas ≥ baseFeePerGas + maxPriorityFeePerGas
- Parameters:
max_fee_per_gas – Maximum fee per gas you are willing to pay for the transaction in Wei.
max_priority_fee_per_gas – Maximum priority fee per gas you are willing to pay for the transaction in Wei.
gas_limit – Gas limit for the transaction in Wei.
- Returns:
EVMGas instance with EIP-1559 parameters.
- classmethod eip1559_in_gwei(max_fee_per_gas: float, max_priority_fee_per_gas: float, gas_limit: int)
- property is_valid: bool
Validates the gas configuration: - Either legacy (gas_price) or EIP-1559 (max_fee_per_gas + max_priority_fee_per_gas), not both. - gas_limit must be set >= 0 or 0 for automatic estimation. - For legacy: gas_price must be set, EIP-1559 fields must be None. - For EIP-1559: both max_fee_per_gas and max_priority_fee_per_gas must be set, and gas_price must be None. - max_fee_per_gas >= max_priority_fee_per_gas.
- classmethod legacy(gas_price: int, gas_limit: int)
- classmethod legacy_in_gwei(gas_price: float, gas_limit: int)
- class xchainpy2_ethereum.gas.EVMGasLimits(approve_gas_limit: int, transfer_gas_asset_gas_limit: int, transfer_token_gas_limit: int, deposit_gas_limit: int, gas_price: int)
Bases:
NamedTupleSufficient gas limits for various transaction types in Ethereum-like chains.
- approve_gas_limit: int
Alias for field number 0
- classmethod default()
- deposit_gas_limit: int
Alias for field number 3
- gas_price: int
Alias for field number 4
- transfer_gas_asset_gas_limit: int
Alias for field number 1
- transfer_token_gas_limit: int
Alias for field number 2
- class xchainpy2_ethereum.gas.EVMGasPriceEstimator(w3: Web3, chain: Chain, gas_asset: Asset, percentiles=(20, 50, 80), block_count=10, base_fee_multiplier=1.0)
Bases:
object- async base_fee()
- async static call_service(sync_method, *args)
- async estimate() EVMFees
Estimate the gas fees based on the current network conditions. This method fetches the fee history, base fee, and max priority fee, and calculates the average, fast, and fastest fees based on the reward history.
- Returns:
FeesEVM object containing the estimated fees
- async fee_history()
- async max_priority_fee_safe_low()
Get the priority fee needed to be included in a block. You can consider this value as “safe-low” priority fee This value is returned by the RPC node
- xchainpy2_ethereum.gas.wei_to_gwei(wei)
Convert Wei to Gwei.
- Parameters:
wei – Amount in Wei to be converted to Gwei.
- Returns:
Other Ethereum Utils
- exception xchainpy2_ethereum.utils.EVMCallError
Bases:
ExceptionThis kind of exception is raised when there are issues with Web3 provider communication
- xchainpy2_ethereum.utils.get_erc20_abi()
Loads and returns standard ERC20 token ABI as a Python dictionary See: https://eips.ethereum.org/EIPS/eip-20
- Returns:
dict
- xchainpy2_ethereum.utils.get_router_abi()
Loads and returns ABI of the THORChain router v4 as a Python dictionary See: https://dev.thorchain.org/protocol-development/chain-clients/evm-chains.html?highlight=router#router
- Returns:
dict
- xchainpy2_ethereum.utils.is_valid_eth_address(address)
Validates Ethereum address, including checksum validation
- Parameters:
address – Ethereum address to be validated
- Returns:
bool
- xchainpy2_ethereum.utils.select_random_free_provider(network: NetworkType, source: dict) BaseProvider
Selects a random free RPC provider from the source list
- Parameters:
network (NetworkType) – Type of network
source – Dictionary of free RPC providers grouped by network
- Returns:
Web3 provider instance
:rtype web3.providers.BaseProvider
- xchainpy2_ethereum.utils.validated_checksum_address(web3_pr: BaseWeb3, address: str) str
This function validates and returns a checksum address. In case the address is in uppercase, that means it probably came from THORChain or other similar AMM. it converts it to checksum address. Otherwise, it validates the address and returns it.
- Parameters:
web3_pr (BaseWeb3) – Web3 instance
address – EVM Address to be validated
- Returns:
Validated checksum address
- Return type:
str