Ethereum client

Ethereum client

class xchainpy2_ethereum.eth_client.EthereumClient(network=NetworkType.MAINNET, phrase: str | None = None, private_key: str | bytes | callable | None = None, fee_bound: FeeBounds | None = None, root_derivation_paths: Dict[NetworkType, str] | None = None, explorer_providers=None, wallet_index=0, provider: BaseProvider | None = None, extra_data_provider: EVMDataProvider | None = None, **kwargs)

Bases: XChainClient

async approve_erc20_token(spender: str, amount: CryptoAmount, gas: GasOptions) str

Approve ERC20 token for a spender :param spender: Spender address :param amount: Amount to approve :param gas: Gas options. Default is GasOptions.automatic(FeeOption.FAST) :return: Transaction hash

async broadcast_tx(tx_hex: str) str

Broadcast a signed transaction to the network. :param tx_hex: Signed transaction in hex format :return: Transaction ID that is broadcast to the network

enable_web3_caching()

Enable Web3 caching middlewares

erc20_asset_from_contract(contract: Contract | str, symbol: str)

Create an Asset object from a contract address :param contract: Contract address or Contract object :param symbol: Symbol of the token :return: Asset object

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 checksummed. :return: string address

async get_balance(address: str = '', with_erc20=False) List[CryptoAmount]

Get the balance of a given address. :param address: By default, it will return the balance of the current wallet. (optional) :param with_erc20: If True, it will return the balance of all ERC20 tokens as well. (optional). Experimental! :return:

async get_block_timestamp(block_number: int) int

Get the timestamp of a given block number :param block_number: Block number :return: Timestamp

property get_chain_id
async get_erc20_allowance(contract_address: Asset | str, spender: str, address: str = '') CryptoAmount

Get the allowance of a given address. :param contract_address: ERC20 Contract address. Can be an Asset object or a string. :param spender: Spender address :param address: By default, it will return the allowance of the current wallet. (optional) :return: CryptoAmount

get_erc20_as_contract(contract_address: str)

Get the ERC20 contract object for a given contract address. :param contract_address: Contract address :return: Contract object

async get_erc20_token_balance(contract_address: str, 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. :param 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. :param tx_id: The transaction id :return: str The explorer url for the given transaction id based on the network.

async get_fees(fee_multiplier=1.0) Fees

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() float

Get the last Ethereum fee FeeRate is in Gwei

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. :param address: Address of a wallet (optional) :type address: str :return: Nonce :rtype: 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) :param tx_id: Transaction ID (hash) :param with_timestamp: If True, it will return the timestamp of the block. Extra API call! :return: 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. :param address: Address of wallet to inspect its history :param offset: (not supported) :param limit: Maximum number of transactions to return :param start_time: (not supported) :param end_time: (not supported) :param asset: (not supported) :return:

async make_contract_call(method_pointer, value, gas: GasOptions, gas_limit=-1, nonce=-1) str

Make a contract call :param method_pointer: Contract method pointer :param value: Value to send :param gas: Gas options :param gas_limit: Gas limit :param nonce: Nonce (optional) if not provided, it will fetch the nonce from the blockchain :return: Transaction hash

property provider
async revoke_erc20_token_allowance(spender: str, token: str | Asset, gas: GasOptions) str

Revoke ERC20 token allowance for a spender :param spender: Spender address :param token: Token symbol or Asset object :param gas: Gas options. Default is GasOptions.automatic(FeeOption.FAST)

async transfer(what: CryptoAmount, recipient: str, memo: str | None = None, gas: GasOptions | 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. :param what: Amount to transfer :param recipient: Recipient address or contract address to call :param memo: Memo (optional, not supported for ERC20 token transfer) :param gas: Gas options. Default is GasOptions.automatic(FeeOption.FAST)

Returns:

Transaction hash

validate_address(address: str) bool

Validates an Ethereum address. :param address: Address string :return: True if valid, False otherwise.

validated_checksum_address(address: str) str

Validate and checksum an Ethereum address if it’s not checksummed. :param address: :return:

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/latest/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, 100000, 160000, 30000000000), NetworkType.STAGENET: (200000, 23000, 100000, 160000, 30000000000), NetworkType.TESTNET: (200000, 23000, 100000, 160000, 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.GasEstimator(w3: Web3, 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()
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

class xchainpy2_ethereum.gas.GasLimits(approve_gas_limit, transfer_gas_asset_gas_limit, transfer_token_gas_limit, deposit_gas_limit, gas_price)

Bases: NamedTuple

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.GasOptions(fee_option: FeeOption | None = None, 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: NamedTuple

Gas options for transaction invocation

classmethod automatic(fee_option: FeeOption)
classmethod average()
classmethod eip1559(max_fee_per_gas: int, max_priority_fee_per_gas: int, gas_limit: int)
classmethod eip1559_in_gwei(max_fee_per_gas: float, max_priority_fee_per_gas: float, gas_limit: int)
classmethod fast()
classmethod fastest()
fee_option: FeeOption | None

Alias for field number 0

gas_limit: int | None

Alias for field number 4

gas_price: int | None

Alias for field number 1

property is_automatic
classmethod legacy(gas_price: int, gas_limit: int)
classmethod legacy_in_gwei(gas_price: float, gas_limit: int)
max_fee_per_gas: int | None

Alias for field number 2

max_priority_fee_per_gas: int | None

Alias for field number 3

updates_gas_limit(gas_limit: int)
validate()
xchainpy2_ethereum.gas.mean_fee(items)
xchainpy2_ethereum.gas.wei_to_gwei(wei)

Other Ethereum Utils

exception xchainpy2_ethereum.utils.EVMCallError

Bases: Exception

This 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