# 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": "",
"docs_url": null,
"requires_python": ">=3.10,<4.0",
"maintainer_email": "",
"keywords": "web3,multicall",
"author": "amfet42",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/1d/22/5f9e233b82c00770c3f0eccec8cc3a370297aa62976f42cf11e3885a7eaf/web3mc-0.1.6.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.6",
"project_urls": {
"Homepage": "https://github.com/amfet42/web3mc",
"Repository": "https://github.com/amfet42/web3mc"
},
"split_keywords": [
"web3",
"multicall"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4a3e99b8eb8a5369bcbeea9e96a38460feb38c8a4120e024123b76be4cd66523",
"md5": "259ee18bfbad2b1807bacc5c213ba840",
"sha256": "526622df624f7578de4532e06395856eedd7cf6f54ad679d3559f688e5b6dc96"
},
"downloads": -1,
"filename": "web3mc-0.1.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "259ee18bfbad2b1807bacc5c213ba840",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10,<4.0",
"size": 12746,
"upload_time": "2023-12-31T14:19:40",
"upload_time_iso_8601": "2023-12-31T14:19:40.515148Z",
"url": "https://files.pythonhosted.org/packages/4a/3e/99b8eb8a5369bcbeea9e96a38460feb38c8a4120e024123b76be4cd66523/web3mc-0.1.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1d225f9e233b82c00770c3f0eccec8cc3a370297aa62976f42cf11e3885a7eaf",
"md5": "6c8ecaccf322f35efbb4a0183d7a3518",
"sha256": "b8e3d71390c3e1e8322f63aedd1a9e6725e3a33e9f3c12bf3629929c95645631"
},
"downloads": -1,
"filename": "web3mc-0.1.6.tar.gz",
"has_sig": false,
"md5_digest": "6c8ecaccf322f35efbb4a0183d7a3518",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10,<4.0",
"size": 12523,
"upload_time": "2023-12-31T14:19:42",
"upload_time_iso_8601": "2023-12-31T14:19:42.088653Z",
"url": "https://files.pythonhosted.org/packages/1d/22/5f9e233b82c00770c3f0eccec8cc3a370297aa62976f42cf11e3885a7eaf/web3mc-0.1.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-31 14:19:42",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "amfet42",
"github_project": "web3mc",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "web3mc"
}