- Safe-eth-py includes a set of libraries to work with Ethereum and relevant Ethereum projects:
- EthereumClient, a wrapper over Web3.py Web3 client including utilities to deal with ERC20/721 tokens and tracing.
- Safe classes and utilities.
- Price oracles for Uniswap, Kyber...
- Django serializers, models and utils.
Just run uv add safe-eth-py
If you want django ethereum utils (models, serializers, filters...) you need to run
uv add safe-eth-py[django]
If you have issues building coincurve maybe you are missing some libraries
Clone the repo, then to set it up:
uv sync --group dev --frozen
source .venv/bin/activate
pre-commit install -fIf you want to add Safe Smart Account support for a new chain you must open a new issue.
Once the issue is created or edited, an automatic validation will be executed and a Pull Request will be created if everything is ok. Finally, the Safe team will review and merge the automatic Pull Request generated from the issue.
class EthereumClient (ethereum_node_url: str): Class to connect and do operations with an ethereum node. Uses web3 and raw rpc calls for things not supported in web3. Onlyhttp/httpsurls are supported for the node url.
EthereumClient has some utils that improve a lot performance using Ethereum nodes, like
the possibility of doing batch_calls (a single request making read-only calls to multiple contracts):
from safe_eth.eth import EthereumClient
from safe_eth.eth.contracts import get_erc721_contract
ethereum_client = EthereumClient(ETHEREUM_NODE_URL)
erc721_contract = get_erc721_contract(self.w3, token_address)
name, symbol = ethereum_client.batch_call([
erc721_contract.functions.name(),
erc721_contract.functions.symbol(),
])If you want to use the underlying web3.py library:
from safe_eth.eth import EthereumClient
ethereum_client = EthereumClient(ETHEREUM_NODE_URL)
ethereum_client.w3.eth.get_block(57)NULL_ADDRESS (0x000...0): Solidityaddress(0).SENTINEL_ADDRESS (0x000...1): Used for Safe's linked lists (modules, owners...).- Maximum and minimum values for R, S and V in ethereum signatures.
Price oracles for Uniswap, UniswapV2, Kyber, SushiSwap, Aave, Balancer, Curve, Mooniswap, Yearn... Example:
from safe_eth.eth import EthereumClient
from safe_eth.eth.oracles import UniswapV2Oracle
ethereum_client = EthereumClient(ETHEREUM_NODE_URL)
uniswap_oracle = UniswapV2Oracle(ethereum_client)
gno_token_mainnet_address = '0x6810e776880C02933D47DB1b9fc05908e5386b96'
weth_token_mainnet_address = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
price = uniswap_oracle.get_price(gno_token_mainnet_address, uniswap_oracle.weth_address)Contains utils for ethereum operations:
mk_contract_address_2(from_: Union[str, bytes], salt: Union[str, bytes], init_code: [str, bytes]) -> str: Calculates the address of a new contract created using the new CREATE2 opcode.
Django utils are available under safe_eth.eth.django.
You can find a set of helpers for working with Ethereum using Django and Django Rest framework.
It includes:
- safe_eth.eth.django.filters: EthereumAddressFilter.
- safe_eth.eth.django.models: Model fields (Ethereum address, Ethereum big integer field).
- safe_eth.eth.django.serializers: Serializer fields (Ethereum address field, hexadecimal field).
- safe_eth.eth.django.validators: Ethereum related validators.
- safe_eth.safe.serializers: Serializers for Safe (signature, transaction...).
- All the tests are written using Django Test suite.
Interaction with the Safe Transaction Service API to manage Safes, transactions, delegates, and messages.
To use the default Transaction Service, you need an API key. You can set this API key either as an environment variable or pass it directly to the constructor using the api_key parameter. To obtain your API key, create an account on the Safe Developer Portal at https://developer.safe.global. Additionally, you can choose to use a custom service by setting the base_url parameter, the API key may not be required.
export SAFE_TRANSACTION_SERVICE_API_KEY=[api-key-jwt-token-value]Example:
from safe_eth.eth import EthereumNetwork
from safe_eth.safe.api import TransactionServiceApi
transaction_service_api = TransactionServiceApi(EthereumNetwork.GNOSIS)
transactions = transaction_service_api.get_transactions("0xAedF684C1c41B51CbD228116e11484425d2FACB9")Behaviour can be tuned with the following environment variables. All of them are optional and fall back to the defaults shown below.
These are read when the module-level EthereumClient singleton (safe_eth.eth.ethereum_client
and its async counterpart) is instantiated.
ETHEREUM_NODE_URL: RPC node url used by the defaultEthereumClientsingleton. No default (the singleton is not usable until it is set). In a Django application this variable is ignored:get_auto_ethereum_client/get_auto_async_ethereum_clientreadsettings.ETHEREUM_NODE_URLinstead, and that setting is required. The environment variable is only used as a fallback when Django is not installed.ETHEREUM_RPC_TIMEOUT: Timeout (seconds) for regular RPC calls. Default10.ETHEREUM_RPC_SLOW_TIMEOUT: Timeout (seconds) for slow RPC calls (e.g. tracing). Default60.ETHEREUM_RPC_RETRY_COUNT: Number of retries for RPC calls. Default1.ETHEREUM_RPC_BATCH_REQUEST_MAX_SIZE: Maximum number of calls bundled in a single batch request. Default500.
CACHE_KECCAK:lru_cachemax size for keccak256 hashing. Default1024.CACHE_CHECKSUM_ADDRESS:lru_cachemax size for checksummed address conversion. Default500000.
Override the default deterministic contract addresses (useful on chains where they were deployed to a different address).
SAFE_SINGLETON_FACTORY_ADDRESS: Safe singleton factory address. Default0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7.SAFE_SIMULATE_TX_ACCESSOR_ADDRESS:SimulateTxAccessorcontract address. Default0x3d4BA2E0884aa488718476ca2FB8Efc291A46199.
SAFE_TRANSACTION_SERVICE_API_KEY: API key (JWT) for the default Transaction Service. See Safe APIs above. No default.SAFE_TRANSACTION_SERVICE_REQUEST_TIMEOUT: Request timeout (seconds). Default10.
The *_MAX_REQUESTS variables tune the connection pool of the async clients only; the
synchronous Etherscan and Blockscout clients do not pool connections and ignore them.
ETHERSCAN_CLIENT_REQUEST_TIMEOUT: Request timeout (seconds). Default10.ETHERSCAN_CLIENT_MAX_REQUESTS: Max pool size of concurrent requests (AsyncEtherscanClientV2only). Default100.BLOCKSCOUT_CLIENT_REQUEST_TIMEOUT: Request timeout (seconds). Default10.BLOCKSCOUT_CLIENT_MAX_REQUESTS: Max pool size of concurrent requests (AsyncBlockscoutClientonly). Default100.SOURCIFY_BASE_URL_API: Sourcify API base url. Defaulthttps://sourcify.dev.SOURCIFY_CLIENT_REQUEST_TIMEOUT: Request timeout (seconds). Default10.SOURCIFY_CLIENT_MAX_REQUESTS: Max pool size of concurrent requests. Default100.ENS_CLIENT_REQUEST_TIMEOUT: ENS client request timeout (seconds). Default5.