{"id":16872920,"url":"https://github.com/enzoferey/multicall-nitro","last_synced_at":"2026-03-10T01:33:12.757Z","repository":{"id":49338018,"uuid":"517277595","full_name":"enzoferey/multicall-nitro","owner":"enzoferey","description":"Supercharge Multicall.js with nitro features 💨","archived":false,"fork":false,"pushed_at":"2022-08-05T21:59:39.000Z","size":14,"stargazers_count":6,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-05T08:37:49.004Z","etag":null,"topics":["batching","blockchain","multicall","react"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/enzoferey.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-24T09:17:53.000Z","updated_at":"2023-02-15T18:25:56.000Z","dependencies_parsed_at":"2022-08-12T20:01:39.512Z","dependency_job_id":null,"html_url":"https://github.com/enzoferey/multicall-nitro","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/enzoferey/multicall-nitro","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enzoferey%2Fmulticall-nitro","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enzoferey%2Fmulticall-nitro/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enzoferey%2Fmulticall-nitro/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enzoferey%2Fmulticall-nitro/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/enzoferey","download_url":"https://codeload.github.com/enzoferey/multicall-nitro/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/enzoferey%2Fmulticall-nitro/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30320889,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-09T20:05:46.299Z","status":"ssl_error","status_checked_at":"2026-03-09T19:57:04.425Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["batching","blockchain","multicall","react"],"created_at":"2024-10-13T15:18:10.578Z","updated_at":"2026-03-10T01:33:12.707Z","avatar_url":"https://github.com/enzoferey.png","language":"TypeScript","readme":"# multicall-nitro\n\n![Tests](https://github.com/enzoferey/multicall-nitro/actions/workflows/test.yml/badge.svg)\n[![npm version](https://badge.fury.io/js/@enzoferey%2Fmulticall-nitro.svg)](https://badge.fury.io/js/@enzoferey%2Fmulticall-nitro)\n[![codecov](https://codecov.io/gh/enzoferey/multicall-nitro/branch/main/graph/badge.svg?token=8KLY137H6P)](https://codecov.io/gh/enzoferey/multicall-nitro)\n\nSupercharge Multicall.js with nitro features 💨\n\n## Highlights\n\n- TypeScript support ✅\n- Ready-to-use calls ✍🏻\n- React hook ⚛️\n- One time call 🎯\n- Simplified API ✨\n\n## Why\n\nWhile [Multicall.js](https://github.com/makerdao/multicall.js) provides a JavaScript interface to the amazing [Multicall](https://github.com/makerdao/multicall) contract by MakerDAO, it still requires a bit of work to integrate it into a real world production application. This is where `multicall-nitro` comes in.\n\nThe goal is to provide a layer on top of Multicall.js that supercharges its features and eases its usage in different contexts. Thanks to fully typed and simplified APIs plus different utilities, your Multicall integration will be on nitro 💨\n\n## Getting started\n\n1. Install the package \u0026 its peer dependency\n\n```sh\nyarn add @enzoferey/multicall-nitro @makerdao/multicall\n```\n\n2. Follow along the use cases below 👇🏻\n\n\u003e 💡 No matter the use case, you will need to provide a configuration object containing:\n\u003e\n\u003e - `rpcUrl`: the url of the RPC node you want to use to make the calls (it could be Infura, Alchemy, etc.)\n\u003e - `multicallAddress`: the address of the Multicall contract in your target blockchain. See [here](https://github.com/makerdao/multicall)\n\n### Get batched values and subscribe to changes\n\nThe most common use case is to get batched values from the blockchain and subscribe to changes.\n\n```ts\nimport {\n  createWatcher,\n  BigNumber,\n  getErc20BalanceMulticall,\n} from \"@enzoferey/multicall-nitro\";\n\ntype Value = { balanceToken1: BigNumber; balanceToken2: BigNumber };\n\nconst connectedAccountAddress = \"0x...\";\n\nconst tokenAddress1 = \"0x...\";\nconst tokenAddress2 = \"0x...\";\n\nconst calls = [\n  getErc20BalanceMulticall(tokenAddress1, connectedAccountAddress, {\n    label: \"balanceToken1\",\n  }),\n  getErc20BalanceMulticall(tokenAddress2, connectedAccountAddress, {\n    label: \"balanceToken2\",\n  }),\n];\n\nconst watcher = createWatcher\u003cValue\u003e(calls, {\n  rpcUrl: \"INSERT HERE YOUR RPC NODE URL\",\n  multicallAddress: \"INSERT HERE THE TARGET MULTICALL CONTRACT ADDRESS\",\n});\n\n// Start watching for the values\nawait watcher.start();\n\n// Subscribe to values changes\nwatcher.subscribe((update) =\u003e {\n  // `update` contains the value for one of the calls\n  //  -\u003e `update.type` is the label of the call\n  //  -\u003e `update.value` is the value of the call\n  //\n  // For example, with the calls above, we could get `{ type: \"balanceToken1\", value: BigNumber(...) }`\n  console.log(`Call with label ${update.type} returned value ${update.value}`);\n});\n\n// Later when finished\nawait watcher.stop();\n```\n\n### Get batched values once\n\nSometimes you do not want to subscribe to values updates but just get them once. The returned promise will resolve when all values have been received.\n\n```ts\nimport {\n  getBatchedValuesOnce,\n  BigNumber,\n  getErc20BalanceMulticall,\n} from \"@enzoferey/multicall-nitro\";\n\ntype Value = { balanceToken1: BigNumber; balanceToken2: BigNumber };\n\nconst connectedAccountAddress = \"0x...\";\n\nconst tokenAddress1 = \"0x...\";\nconst tokenAddress2 = \"0x...\";\n\nconst calls = [\n  getErc20BalanceMulticall(tokenAddress1, connectedAccountAddress, {\n    label: \"balanceToken1\",\n  }),\n  getErc20BalanceMulticall(tokenAddress2, connectedAccountAddress, {\n    label: \"balanceToken2\",\n  }),\n];\n\nconst batchedValues = await getBatchedValuesOnce\u003cValue\u003e(calls, {\n  rpcUrl: \"INSERT HERE YOUR RPC NODE URL\",\n  multicallAddress: \"INSERT HERE THE TARGET MULTICALL CONTRACT ADDRESS\",\n});\n\n// At this point `batchedValues` contains the values of the specified calls\n// -\u003e `batchedValues.balanceToken1` is the value of the call with label \"balanceToken1\"\n// -\u003e `batchedValues.balanceToken2` is the value of the call with label \"balanceToken2\"\n```\n\n### Get ERC20 token values\n\nWriting calls is tedious and error-prone, use these utilities to get values of ERC20 tokens.\n\n```ts\nimport {\n  getErc20BalanceMulticall,\n  getErc20DecimalsMulticall,\n  getErc20AllowanceMulticall,\n} from \"@enzoferey/multicall-nitro\";\n\nconst tokenAddress1 = \"0x...\";\nconst connectedAccountAddress = \"0x...\";\nconst someOtherAccountAddress = \"0x...\";\n\nconst calls = [\n  // Get the ERC20 token balance of `connectedAccountAddress`\n  getErc20BalanceMulticall(tokenAddress1, connectedAccountAddress, {\n    label: \"balanceToken1\",\n  }),\n  // Get the ERC20 token decimals\n  getErc20DecimalsMulticall(tokenAddress1, {\n    label: \"decimalsToken1\",\n  }),\n  // Get the ERC20 token allowance provided by `connectedAccountAddress` to `someOtherAccountAddress`\n  getErc20AllowanceMulticall(\n    tokenAddress1,\n    connectedAccountAddress,\n    someOtherAccountAddress,\n    {\n      label: \"allowanceToken1\",\n    }\n  ),\n];\n\n// you can then pass these `calls` into `createWatcher`, `getBatchedValuesOnce` or any other entry point\n```\n\nAre you missing any utility for ERC20 tokens values ? Please open an issue or pull request 🙏🏻\n\n### Get blockchain values\n\nWriting calls is tedious and error-prone, use these utilities to get values of the blockchain you connect to.\n\n```ts\nimport { getBlockchainNativeTokenBalanceMulticall } from \"@enzoferey/multicall-nitro\";\n\nconst connectedAccountAddress = \"0x...\";\n\nconst calls = [\n  // Get the native token (ETH, MATIC, BNB, etc.) balance of `connectedAccountAddress`\n  getBlockchainNativeTokenBalanceMulticall(connectedAccountAddress, {\n    label: \"nativeTokenBalance\",\n  }),\n];\n\n// you can then pass these `calls` into `createWatcher`, `getBatchedValuesOnce` or any other entry point\n```\n\nAre you missing any utility for blockchain values ? Please open an issue or pull request 🙏🏻\n\n### Custom calls\n\nOn top of the built-in utilities that enable you to construct common calls, you can write your own custom calls.\n\n```ts\nimport { Call } from \"@enzoferey/multicall-nitro\";\n\nconst calls = [\n  // Call method \"getResult\" on contract address 0x2222222222222222222222222222222222222222\n  // This method takes an `uint256` and a `string` as argument and returns a `string`\n  {\n    target: \"0x2222222222222222222222222222222222222222\",\n    call: [\"getResult(uint256,string)(string)\", 10, \"hello\"],\n    label: \"someCustomCallLabel1\",\n  },\n  // Call method \"getBestNumber\" on contract address 0x3333333333333333333333333333333333333333\n  // This method takes three `uint16` and returns a `uint16`\n  {\n    target: \"0x3333333333333333333333333333333333333333\",\n    call: [\"getBestNumber(uint16,uint16,uint16)(uint16)\", 10, 12, 14],\n    label: \"someCustomCallLabel2\",\n  },\n  // any other call you want to make\n];\n\n// you can then pass these `calls` into `createWatcher`, `getBatchedValuesOnce` or any other entry point\n```\n\n### Use batched values in React\n\nWraps [`createWatcher`](#get-batched-values-and-subscribe-to-changes) into a React hook.\n\n\u003e 💡 In order to use this hook, you need to have the `react` peer dependency installed.\n\u003e\n\u003e ```sh\n\u003e yarn add react\n\u003e ```\n\u003e\n\u003e Notice the trailing `/react` on the import statement, this is for reducing bundle size\n\u003e if you don't use the React specific code.\n\n```ts\nimport { useBatchedValues } from \"@enzoferey/multicall-nitro/react\";\nimport { Call, BigNumber } from \"@enzoferey/multicall-nitro\";\n\n// You can define your calls outside the render function if statis\nconst calls = [\n  getErc20BalanceMulticall(\"0x...\", connectedAddress, { label: \"balance\" }),\n  getErc20DecimalsMulticall(\"0x...\", {\n    label: \"decimals\",\n  }),\n];\n\nconst MyComponent = (props) =\u003e {\n  const { tokenAddress } = props;\n\n  // You can define your calls inside the render function if dynamic\n  const calls = React.useMemo\u003cCall[]\u003e(() =\u003e {\n    return [\n      getErc20BalanceMulticall(tokenAddress, connectedAddress, {\n        label: \"balance\",\n      }),\n      getErc20DecimalsMulticall(tokenAddress, {\n        label: \"decimals\",\n      }),\n    ];\n  }, []);\n\n  // In both cases, you can then use `useBatchedValues` to get the values of your calls\n  const batchedValues = useBatchedValues\u003c{\n    balance: BigNumber;\n    decimals: number;\n  }\u003e(calls);\n\n  // First, `batchedValues` will be `null` until the first value arrives\n  // Then, `batchedValues` will be the partial object defined by the type passed, in this case:\n  // `{ balance?: BigNumber, decimals?: number }`\n};\n```\n\n### Use batched values once in React\n\nWraps [`getBatchedValuesOnce`](#get-batched-values-once) into a React hook. The returned value will be `null` until all values have been received.\n\n\u003e 💡 In order to use this hook, you need to have the `react` peer dependency installed.\n\u003e\n\u003e ```sh\n\u003e yarn add react\n\u003e ```\n\u003e\n\u003e Notice the trailing `/react` on the import statement, this is for reducing bundle size\n\u003e if you don't use the React specific code.\n\n```ts\nimport { useBatchedValuesOnce } from \"@enzoferey/multicall-nitro/react\";\nimport { Call, BigNumber } from \"@enzoferey/multicall-nitro\";\n\n// You can define your calls outside the render function if statis\nconst calls = [\n  getErc20BalanceMulticall(\"0x...\", connectedAddress, { label: \"balance\" }),\n  getErc20DecimalsMulticall(\"0x...\", {\n    label: \"decimals\",\n  }),\n];\n\nconst MyComponent = (props) =\u003e {\n  const { tokenAddress } = props;\n\n  // You can define your calls inside the render function if dynamic\n  const calls = React.useMemo\u003cCall[]\u003e(() =\u003e {\n    return [\n      getErc20BalanceMulticall(tokenAddress, connectedAddress, {\n        label: \"balance\",\n      }),\n      getErc20DecimalsMulticall(tokenAddress, {\n        label: \"decimals\",\n      }),\n    ];\n  }, []);\n\n  // In both cases, you can then use `useBatchedValuesOnce` to get the values of your calls\n  const batchedValues = useBatchedValuesOnce\u003c{\n    balance: BigNumber;\n    decimals: number;\n  }\u003e(calls);\n\n  // First, `batchedValues` will be `null` until all values are received\n  // Then, `batchedValues` will be the object defined by the type passed\n};\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenzoferey%2Fmulticall-nitro","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fenzoferey%2Fmulticall-nitro","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fenzoferey%2Fmulticall-nitro/lists"}