# web3mc - multicall library for web3py
Based on makerdao's [multicall contract](https://github.com/makerdao/multicall)and
[brownie](https://github.com/eth-brownie/brownie) implementation with batching and asynchronous support. Works
directly with web3py contract functions and parameters
## Installation
```shell
pip install web3mc
```
## Quickstart
Basic usage
(this is default value if empty - set by web3py)
```shell
export WEB3_HTTP_PROVIDER_URI=http://localhost:8545
```
```python
from web3.auto import w3
from web3mc.auto import multicall
abi = [{"constant": True, "inputs": [], "name": "name", "outputs": [{"name": "", "type": "string"}], "payable": False,
"stateMutability": "view", "type": "function", },
{"constant": True, "inputs": [], "name": "symbol", "outputs": [{"name": "", "type": "string"}], "payable": False,
"stateMutability": "view", "type": "function", },
{"constant": True, "inputs": [{"name": "", "type": "address"}], "name": "balanceOf",
"outputs": [{"name": "", "type": "uint256"}], "payable": False, "stateMutability": "view", "type": "function"}]
weth_erc20 = w3.eth.contract("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", abi=abi)
calls = [weth_erc20.functions.name(), weth_erc20.functions.symbol(), weth_erc20.functions.balanceOf("vitalik.eth")]
result = multicall.aggregate(calls)
print(result) # ['Wrapped Ether', 'WETH', 26992040046283229929]
```
Call multiple contracts with same abi (implementation)
```python
...
weth_erc20 = w3.eth.contract("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", abi=abi)
calls = [weth_erc20.functions.name(),weth_erc20.functions.symbol(),weth_erc20.functions.balanceOf("vitalik.eth")] * 2
# WBTC, USDC
addresses = ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"] * 3 + ["0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599"] * 3
result = multicall.aggregate(calls, use_try=True, addresses=addresses) # tryAggregate()
print(result) # ['Wrapped BTC', 'WBTC', 0, 'USD Coin', 'USDC', 396267093705]
```
## Parameters
### Environment variable
- `WEB3_HTTP_PROVIDER_URI` - can be overwritten directly (from web3py)
### Custom parameters
```python
from web3mc import Multicall
multicall = Multicall(
provider_url="<your custom provider url>", # Overrides env parameter
batch=100, # can lead to overflow
max_retries=3, # retries without use_try (aggregate function in contract)
gas_limit=50_000_000, # gas limit for calls
_semaphore=1000, # max concurrent coroutines, change carefully!
)
```
## Testing
Install dependencies, make sure you set `WEB3_HTTP_PROVIDER_URI` environment variable
```shell
pytest tests
```
Raw data
{
"_id": null,
"home_page": "https://github.com/amfet42/web3mc",
"name": "web3mc",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "web3, multicall",
"author": "amfet42",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/53/65/1104d42301ce756126d121506c99529934effabe24364ea89a26123fb0bb/web3mc-0.1.8.tar.gz",
"platform": null,
"description": "# web3mc - multicall library for web3py\n\nBased on makerdao's [multicall contract](https://github.com/makerdao/multicall)and\n[brownie](https://github.com/eth-brownie/brownie) implementation with batching and asynchronous support. Works\ndirectly with web3py contract functions and parameters\n\n## Installation\n\n```shell\npip install web3mc\n```\n\n## Quickstart\n\nBasic usage\n\n(this is default value if empty - set by web3py)\n```shell\nexport WEB3_HTTP_PROVIDER_URI=http://localhost:8545\n```\n\n```python\nfrom web3.auto import w3\nfrom web3mc.auto import multicall\n\nabi = [{\"constant\": True, \"inputs\": [], \"name\": \"name\", \"outputs\": [{\"name\": \"\", \"type\": \"string\"}], \"payable\": False,\n \"stateMutability\": \"view\", \"type\": \"function\", },\n {\"constant\": True, \"inputs\": [], \"name\": \"symbol\", \"outputs\": [{\"name\": \"\", \"type\": \"string\"}], \"payable\": False,\n \"stateMutability\": \"view\", \"type\": \"function\", },\n {\"constant\": True, \"inputs\": [{\"name\": \"\", \"type\": \"address\"}], \"name\": \"balanceOf\",\n \"outputs\": [{\"name\": \"\", \"type\": \"uint256\"}], \"payable\": False, \"stateMutability\": \"view\", \"type\": \"function\"}]\n\nweth_erc20 = w3.eth.contract(\"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", abi=abi)\n\ncalls = [weth_erc20.functions.name(), weth_erc20.functions.symbol(), weth_erc20.functions.balanceOf(\"vitalik.eth\")]\n\nresult = multicall.aggregate(calls)\nprint(result) # ['Wrapped Ether', 'WETH', 26992040046283229929]\n```\n\nCall multiple contracts with same abi (implementation)\n\n```python\n...\nweth_erc20 = w3.eth.contract(\"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\", abi=abi)\n\ncalls = [weth_erc20.functions.name(),weth_erc20.functions.symbol(),weth_erc20.functions.balanceOf(\"vitalik.eth\")] * 2\n# WBTC, USDC\naddresses = [\"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\"] * 3 + [\"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\"] * 3\n\nresult = multicall.aggregate(calls, use_try=True, addresses=addresses) # tryAggregate()\nprint(result) # ['Wrapped BTC', 'WBTC', 0, 'USD Coin', 'USDC', 396267093705]\n\n```\n\n## Parameters\n\n### Environment variable\n\n- `WEB3_HTTP_PROVIDER_URI` - can be overwritten directly (from web3py)\n\n### Custom parameters\n\n```python\nfrom web3mc import Multicall\n\nmulticall = Multicall(\n provider_url=\"<your custom provider url>\", # Overrides env parameter\n batch=100, # can lead to overflow\n max_retries=3, # retries without use_try (aggregate function in contract)\n gas_limit=50_000_000, # gas limit for calls\n _semaphore=1000, # max concurrent coroutines, change carefully!\n)\n\n```\n\n\n## Testing\nInstall dependencies, make sure you set `WEB3_HTTP_PROVIDER_URI` environment variable\n\n```shell\npytest tests\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Multicall library for aggregating web3py contract calls",
"version": "0.1.8",
"project_urls": {
"Homepage": "https://github.com/amfet42/web3mc",
"Repository": "https://github.com/amfet42/web3mc"
},
"split_keywords": [
"web3",
" multicall"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4d3454d4a15aac1a1566b83f9c5239746d9f5611f40ed51d8e9e241c22b90c2b",
"md5": "0c99d764178678f7591fb882445474b7",
"sha256": "cd0a9aa37b2680ea150b4e6fcfd00da61c4ff0c65d314a19056ced56382e25fc"
},
"downloads": -1,
"filename": "web3mc-0.1.8-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0c99d764178678f7591fb882445474b7",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 12902,
"upload_time": "2024-06-21T11:21:58",
"upload_time_iso_8601": "2024-06-21T11:21:58.904547Z",
"url": "https://files.pythonhosted.org/packages/4d/34/54d4a15aac1a1566b83f9c5239746d9f5611f40ed51d8e9e241c22b90c2b/web3mc-0.1.8-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "53651104d42301ce756126d121506c99529934effabe24364ea89a26123fb0bb",
"md5": "a270ed6316eea803d08866f74d828d4b",
"sha256": "b6bc2c1a69f3916499e893930e7e55602449ed81ff561ed51b85d5d12d17f381"
},
"downloads": -1,
"filename": "web3mc-0.1.8.tar.gz",
"has_sig": false,
"md5_digest": "a270ed6316eea803d08866f74d828d4b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 12686,
"upload_time": "2024-06-21T11:22:00",
"upload_time_iso_8601": "2024-06-21T11:22:00.585183Z",
"url": "https://files.pythonhosted.org/packages/53/65/1104d42301ce756126d121506c99529934effabe24364ea89a26123fb0bb/web3mc-0.1.8.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-21 11:22:00",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "amfet42",
"github_project": "web3mc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "web3mc"
}