├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── SUPPORTED_NETWORKS.md ├── package.json ├── src ├── Multicall.ts ├── abi │ └── Multicall.json ├── constants.ts ├── contract │ └── Multicall.sol └── index.ts ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Microbundle cache 58 | .rpt2_cache/ 59 | .rts2_cache_cjs/ 60 | .rts2_cache_es/ 61 | .rts2_cache_umd/ 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | .env.production 76 | 77 | # parcel-bundler cache (https://parceljs.org/) 78 | .cache 79 | .parcel-cache 80 | 81 | # Next.js build output 82 | .next 83 | out 84 | 85 | # Nuxt.js build / generate output 86 | .nuxt 87 | dist 88 | 89 | # Gatsby files 90 | .cache/ 91 | # Comment in the public line in if your project uses Gatsby and not Next.js 92 | # https://nextjs.org/blog/next-9-1#public-directory-support 93 | # public 94 | 95 | # vuepress build output 96 | .vuepress/dist 97 | 98 | # Serverless directories 99 | .serverless/ 100 | 101 | # FuseBox cache 102 | .fusebox/ 103 | 104 | # DynamoDB Local files 105 | .dynamodb/ 106 | 107 | # TernJS port file 108 | .tern-port 109 | 110 | # Stores VSCode versions used for testing VSCode extensions 111 | .vscode-test 112 | 113 | # yarn v2 114 | .yarn/cache 115 | .yarn/unplugged 116 | .yarn/build-state.yml 117 | .yarn/install-state.gz 118 | .pnp.* -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # web3-multicall 2 | 3 | ## 0.1.10 4 | 5 | - Update all dependencies 6 | 7 | ## 0.1.9 8 | 9 | - Move web3.js to a peer dependency 10 | 11 | ## 0.1.8 12 | 13 | - Add an option for defaultBlock to the multicall contract 14 | - Update all dependencies (updated web3 to 1.7.x) 15 | 16 | ## 0.1.7 17 | 18 | - Add a parameters option to the aggregate function 19 | - Update all dependencies 20 | 21 | ## 0.1.6 22 | 23 | - Update all dependencies 24 | 25 | ## 0.1.5 26 | 27 | - Added Arbitrum One support 28 | - Update all dependencies 29 | 30 | ## 0.1.4 31 | 32 | - Updated web3 to 1.6.0 and updated other dependencies 33 | 34 | ## 0.1.3 35 | 36 | - Allow proper usage of internal types in result 37 | 38 | ## 0.1.2 39 | 40 | - Skipped 41 | 42 | ## 0.1.1 43 | 44 | - Remove return types from the helper functions as they were incorrect 45 | 46 | ## 0.1.0 47 | 48 | - Adds helper functions from the Multicall contract 49 | - Add provider type from `web3-core` to the web3 provider constructor argument 50 | 51 | ## First Release - 0.0.1 52 | 53 | This release adds the initial code implementation 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Dopex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # web3-multicall 2 | 3 | [![npm version](https://badge.fury.io/js/%40dopex-io%2Fweb3-multicall.svg)](https://badge.fury.io/js/%40dopex-io%2Fweb3-multicall) 4 | 5 | A library to do multiple calls via a single `eth_call` using [web3](https://github.com/ChainSafe/web3.js). 6 | 7 | ## Installation 8 | 9 | - via yarn 10 | 11 | ```bash 12 | yarn add @dopex-io/web3-multicall 13 | ``` 14 | 15 | - via npm 16 | 17 | ```bash 18 | npm i @dopex-io/web3-multicall 19 | ``` 20 | 21 | ## Usage 22 | 23 | > [Contract Reference](/src/contract/Multicall.sol) 24 | 25 | [Default Supported Networks](./SUPPORTED_NETWORKS.md) 26 | 27 | ### Constructing 28 | 29 | - With `chainId` 30 | 31 | ```js 32 | import Multicall from '@dopex-io/web3-multicall'; 33 | 34 | import erc20Abi from './abi/erc20.json'; 35 | 36 | async function main() { 37 | const web3 = new Web3(provider /* Your Web3 provider here */); 38 | 39 | const multicall = new Multicall({ 40 | chainId: 1, 41 | provider: 'Your Web3 provider here', 42 | defaultBlock: 1000 /* Optional */ 43 | }); 44 | 45 | ... 46 | } 47 | 48 | main() 49 | ``` 50 | 51 | - With custom Multicall address 52 | 53 | ```js 54 | import Multicall from '@dopex-io/web3-multicall'; 55 | 56 | import erc20Abi from './abi/erc20.json'; 57 | 58 | async function main() { 59 | const web3 = new Web3(provider /* Your Web3 provider here */); 60 | 61 | const multicall = new Multicall({ 62 | multicallAddress: "The address of the deployed multicall contract", 63 | provider: 'Your Web3 provider here', 64 | defaultBlock: 1000 /* Optional */ 65 | }); 66 | 67 | ... 68 | } 69 | 70 | main(); 71 | ``` 72 | 73 | ### Aggregating 74 | 75 | ```js 76 | const dpxContract = new web3.eth.Contract(dpxAddress, erc20Abi); 77 | 78 | const balances = await multicall.aggregate([ 79 | dpxContract.methods.balanceOf('Address 1'), 80 | dpxContract.methods.balanceOf('Address 2'), 81 | multicall.getEthBalance('Address 3'), 82 | ]); 83 | 84 | console.log('DPX balance of Address 1', balances[0]); 85 | console.log('DPX balance of Address 2', balances[1]); 86 | console.log('ETH balance of Address 3', balances[2]); 87 | ``` 88 | 89 | ### Helper Functions 90 | 91 | - `getEthBalance` 92 | Gets the ETH balance of an address 93 | 94 | ```js 95 | const ethBalance = multicall.getEthBalance('address'); 96 | ``` 97 | 98 | - `getBlockHash` 99 | Gets the block hash 100 | 101 | ```js 102 | const blockHash = multicall.getBlockHash(blockNumber); 103 | ``` 104 | 105 | - `getLastBlockHash` 106 | Gets the last blocks hash 107 | 108 | ```js 109 | const lastBlockHash = multicall.getLastBlockHash(); 110 | ``` 111 | 112 | - `getCurrentBlockTimestamp` 113 | Gets the current block timestamp 114 | 115 | ```js 116 | const currentBlockTimestamp = multicall.getCurrentBlockTimestamp(); 117 | ``` 118 | 119 | - `getCurrentBlockDifficulty` 120 | Gets the current block difficulty 121 | 122 | ```js 123 | const currentBlockDifficulty = multicall.getCurrentBlockDifficulty(); 124 | ``` 125 | 126 | - `getCurrentBlockGasLimit` 127 | Gets the current block gas limit 128 | 129 | ```js 130 | const currentBlockGasLimit = multicall.getCurrentBlockGasLimit(); 131 | ``` 132 | 133 | - `getCurrentBlockCoinbase` 134 | Gets the current block coinbase 135 | 136 | ```js 137 | const currentBlockCoinbase = multicall.getCurrentBlockCoinbase(); 138 | ``` 139 | 140 | ## License 141 | 142 | This project is licensed under the MIT License - Copyright (c) 2023 Dopex 143 | -------------------------------------------------------------------------------- /SUPPORTED_NETWORKS.md: -------------------------------------------------------------------------------- 1 | # Supported Networks 2 | 3 | Name: Ethereum Mainnet 4 | 5 | ChainID: 1 6 | 7 | Contract: [0xeefba1e63905ef1d7acba5a8513c70307c1ce441](https://etherscan.io/address/0xeefba1e63905ef1d7acba5a8513c70307c1ce441) 8 | 9 | --- 10 | 11 | Name: Ethereum Testnet Ropsten 12 | 13 | ChainID: 3 14 | 15 | Contract: [0xF24b01476a55d635118ca848fbc7Dab69d403be3](https://ropsten.etherscan.io/address/0xF24b01476a55d635118ca848fbc7Dab69d403be3) 16 | 17 | --- 18 | 19 | Name: Ethereum Testnet Rinkeby 20 | 21 | ChainID: 4 22 | 23 | Contract: [0x42ad527de7d4e9d9d011ac45b31d8551f8fe9821](https://rinkeby.etherscan.io/address/0x42ad527de7d4e9d9d011ac45b31d8551f8fe9821) 24 | 25 | --- 26 | 27 | Name: Ethereum Testnet Görli 28 | 29 | ChainID: 5 30 | 31 | Contract: [0x77dca2c955b15e9de4dbbcf1246b4b85b651e50e](https://goerli.etherscan.io/address/0x77dca2c955b15e9de4dbbcf1246b4b85b651e50e) 32 | 33 | --- 34 | 35 | Name: Ethereum Testnet Kovan 36 | 37 | ChainID: 42 38 | 39 | Contract: [0x2cc8688c5f75e365aaeeb4ea8d6a480405a48d2a](https://kovan.etherscan.io/address/0x2cc8688c5f75e365aaeeb4ea8d6a480405a48d2a) 40 | 41 | --- 42 | 43 | Name: Binance Smart Chain Mainnet 44 | 45 | ChainID: 56 46 | 47 | Contract: [0x1Ee38d535d541c55C9dae27B12edf090C608E6Fb](https://bscscan.com/address/0x1Ee38d535d541c55C9dae27B12edf090C608E6Fb) 48 | 49 | --- 50 | 51 | Name: xDAI Chain 52 | 53 | ChainID: 100 54 | 55 | Contract: [0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a](https://blockscout.com/xdai/mainnet/address/0xb5b692a88BDFc81ca69dcB1d924f59f0413A602a/transactions) 56 | 57 | --- 58 | 59 | Name: Polygon Mainnet 60 | 61 | ChainID: 137 62 | 63 | Contract: [0xc4f1501f337079077842343Ce02665D8960150B0](https://polygonscan.com/address/0xc4f1501f337079077842343Ce02665D8960150B0) 64 | 65 | --- 66 | 67 | Name: Polygon Testnet Mumbai 68 | 69 | ChainID: 80001 70 | 71 | Contract: [0x5a0439824F4c0275faa88F2a7C5037F9833E29f1](https://mumbai.polygonscan.com/address/0x5a0439824F4c0275faa88F2a7C5037F9833E29f1) 72 | 73 | --- 74 | 75 | Name: Arbitrum One 76 | 77 | ChainID: 42161 78 | 79 | Contract: [0x813715eF627B01f4931d8C6F8D2459F26E19137E](https://arbiscan.io/address/0x813715eF627B01f4931d8C6F8D2459F26E19137E) 80 | 81 | --- 82 | 83 | Name: Arbitrum Testnet Rinkeby 84 | 85 | ChainID: 421611 86 | 87 | Contract: [0xc72e0331e2e7aeb30aa7d3d250d245ebf2f27037](https://testnet.arbiscan.io/address/0xc72e0331e2e7aeb30aa7d3d250d245ebf2f27037) 88 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@dopex-io/web3-multicall", 3 | "version": "0.1.10", 4 | "description": "A library to do multiple calls via a single eth_call using web3.js", 5 | "main": "dist/index.js", 6 | "source": "src/index.ts", 7 | "author": { 8 | "name": "witherblock", 9 | "email": "wb@dopex.io", 10 | "url": "https://github.com/witherblock" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/dopex-io/web3-multicall" 15 | }, 16 | "license": "MIT", 17 | "private": false, 18 | "scripts": { 19 | "build": "microbundle", 20 | "dev": "microbundle watch", 21 | "prepare": "yarn build" 22 | }, 23 | "devDependencies": { 24 | "microbundle": "^0.15.0", 25 | "prettier": "^3.0.0", 26 | "typescript": "^5.1.6", 27 | "web3": "^1.0.0" 28 | }, 29 | "peerDependencies": { 30 | "web3": "^1.0.0" 31 | }, 32 | "prettier": { 33 | "singleQuote": true 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Multicall.ts: -------------------------------------------------------------------------------- 1 | import Web3 from 'web3'; 2 | import { AbiItem } from 'web3-utils'; 3 | import { Contract } from 'web3-eth-contract'; 4 | import { provider } from 'web3-core'; 5 | 6 | import { CHAIN_ID_TO_MULTICALL_ADDRESS } from './constants'; 7 | import mulitcallAbi from './abi/Multicall.json'; 8 | 9 | interface ConstructorArgs { 10 | chainId?: number; 11 | provider: provider; 12 | defaultBlock?: number | ''; 13 | multicallAddress?: string; 14 | } 15 | 16 | export default class Multicall { 17 | web3: Web3; 18 | multicall: Contract; 19 | 20 | constructor({ 21 | chainId, 22 | provider, 23 | multicallAddress, 24 | defaultBlock, 25 | }: ConstructorArgs) { 26 | this.web3 = new Web3(provider); 27 | 28 | const _multicallAddress = multicallAddress 29 | ? multicallAddress 30 | : chainId 31 | ? CHAIN_ID_TO_MULTICALL_ADDRESS[chainId] 32 | : undefined; 33 | 34 | if (!_multicallAddress) { 35 | throw new Error( 36 | 'No address found via chainId. Please specify multicallAddress.' 37 | ); 38 | } 39 | 40 | this.multicall = new this.web3.eth.Contract( 41 | mulitcallAbi as AbiItem[], 42 | _multicallAddress 43 | ); 44 | 45 | if (defaultBlock) this.multicall.defaultBlock = defaultBlock; 46 | } 47 | 48 | async aggregate(calls: any[], parameters = {}) { 49 | const callRequests = calls.map((call) => { 50 | const callData = call.encodeABI(); 51 | return { 52 | target: call._parent._address, 53 | callData, 54 | }; 55 | }); 56 | 57 | const { returnData } = await this.multicall.methods 58 | .aggregate(callRequests) 59 | .call(parameters); 60 | 61 | return returnData.map((hex: string, index: number) => { 62 | const types = calls[index]._method.outputs.map((o: any) => 63 | o.internalType !== o.type && o.internalType !== undefined ? o : o.type 64 | ); 65 | 66 | let result = this.web3.eth.abi.decodeParameters(types, hex); 67 | 68 | delete result.__length__; 69 | 70 | result = Object.values(result); 71 | 72 | return result.length === 1 ? result[0] : result; 73 | }); 74 | } 75 | 76 | getEthBalance(address: string) { 77 | return this.multicall.methods.getEthBalance(address); 78 | } 79 | 80 | getBlockHash(blockNumber: string | number) { 81 | return this.multicall.methods.getBlockHash(blockNumber); 82 | } 83 | 84 | getLastBlockHash() { 85 | return this.multicall.methods.getLastBlockHash(); 86 | } 87 | 88 | getCurrentBlockTimestamp() { 89 | return this.multicall.methods.getCurrentBlockTimestamp(); 90 | } 91 | 92 | getCurrentBlockDifficulty() { 93 | return this.multicall.methods.getCurrentBlockDifficulty(); 94 | } 95 | 96 | getCurrentBlockGasLimit() { 97 | return this.multicall.methods.getCurrentBlockGasLimit(); 98 | } 99 | 100 | getCurrentBlockCoinbase() { 101 | return this.multicall.methods.getCurrentBlockCoinbase(); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/abi/Multicall.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "constant": true, 4 | "inputs": [], 5 | "name": "getCurrentBlockTimestamp", 6 | "outputs": [{ "name": "timestamp", "type": "uint256" }], 7 | "payable": false, 8 | "stateMutability": "view", 9 | "type": "function" 10 | }, 11 | { 12 | "constant": false, 13 | "inputs": [ 14 | { 15 | "components": [ 16 | { "name": "target", "type": "address" }, 17 | { "name": "callData", "type": "bytes" } 18 | ], 19 | "name": "calls", 20 | "type": "tuple[]" 21 | } 22 | ], 23 | "name": "aggregate", 24 | "outputs": [ 25 | { "name": "blockNumber", "type": "uint256" }, 26 | { "name": "returnData", "type": "bytes[]" } 27 | ], 28 | "payable": false, 29 | "stateMutability": "nonpayable", 30 | "type": "function" 31 | }, 32 | { 33 | "constant": true, 34 | "inputs": [], 35 | "name": "getLastBlockHash", 36 | "outputs": [{ "name": "blockHash", "type": "bytes32" }], 37 | "payable": false, 38 | "stateMutability": "view", 39 | "type": "function" 40 | }, 41 | { 42 | "constant": true, 43 | "inputs": [{ "name": "addr", "type": "address" }], 44 | "name": "getEthBalance", 45 | "outputs": [{ "name": "balance", "type": "uint256" }], 46 | "payable": false, 47 | "stateMutability": "view", 48 | "type": "function" 49 | }, 50 | { 51 | "constant": true, 52 | "inputs": [], 53 | "name": "getCurrentBlockDifficulty", 54 | "outputs": [{ "name": "difficulty", "type": "uint256" }], 55 | "payable": false, 56 | "stateMutability": "view", 57 | "type": "function" 58 | }, 59 | { 60 | "constant": true, 61 | "inputs": [], 62 | "name": "getCurrentBlockGasLimit", 63 | "outputs": [{ "name": "gaslimit", "type": "uint256" }], 64 | "payable": false, 65 | "stateMutability": "view", 66 | "type": "function" 67 | }, 68 | { 69 | "constant": true, 70 | "inputs": [], 71 | "name": "getCurrentBlockCoinbase", 72 | "outputs": [{ "name": "coinbase", "type": "address" }], 73 | "payable": false, 74 | "stateMutability": "view", 75 | "type": "function" 76 | }, 77 | { 78 | "constant": true, 79 | "inputs": [{ "name": "blockNumber", "type": "uint256" }], 80 | "name": "getBlockHash", 81 | "outputs": [{ "name": "blockHash", "type": "bytes32" }], 82 | "payable": false, 83 | "stateMutability": "view", 84 | "type": "function" 85 | } 86 | ] 87 | -------------------------------------------------------------------------------- /src/constants.ts: -------------------------------------------------------------------------------- 1 | export const CHAIN_ID_TO_MULTICALL_ADDRESS: { [key: number]: string } = { 2 | 1: '0xeefba1e63905ef1d7acba5a8513c70307c1ce441', 3 | 3: '0xF24b01476a55d635118ca848fbc7Dab69d403be3', 4 | 4: '0x42ad527de7d4e9d9d011ac45b31d8551f8fe9821', 5 | 5: '0x77dca2c955b15e9de4dbbcf1246b4b85b651e50e', 6 | 42: '0x2cc8688c5f75e365aaeeb4ea8d6a480405a48d2a', 7 | 56: '0x1Ee38d535d541c55C9dae27B12edf090C608E6Fb', 8 | 100: '0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a', 9 | 137: '0xc4f1501f337079077842343Ce02665D8960150B0', 10 | 80001: '0x5a0439824F4c0275faa88F2a7C5037F9833E29f1', 11 | 42161: '0x813715eF627B01f4931d8C6F8D2459F26E19137E', 12 | 421611: '0xc72e0331e2e7aeb30aa7d3d250d245ebf2f27037', 13 | }; 14 | -------------------------------------------------------------------------------- /src/contract/Multicall.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | 3 | pragma solidity =0.7.6; 4 | 5 | pragma experimental ABIEncoderV2; 6 | 7 | /// @title Multicall - Aggregate results from multiple read-only function calls 8 | /// @author Michael Elliot 9 | /// @author Joshua Levine 10 | /// @author Nick Johnson 11 | 12 | contract Multicall { 13 | struct Call { 14 | address target; 15 | bytes callData; 16 | } 17 | 18 | function aggregate(Call[] memory calls) 19 | public 20 | returns (uint256 blockNumber, bytes[] memory returnData) 21 | { 22 | blockNumber = block.number; 23 | returnData = new bytes[](calls.length); 24 | for (uint256 i = 0; i < calls.length; i++) { 25 | (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); 26 | require(success); 27 | returnData[i] = ret; 28 | } 29 | } 30 | 31 | // Helper functions 32 | function getEthBalance(address addr) public view returns (uint256 balance) { 33 | balance = addr.balance; 34 | } 35 | 36 | function getBlockHash(uint256 blockNumber) public view returns (bytes32 blockHash) { 37 | blockHash = blockhash(blockNumber); 38 | } 39 | 40 | function getLastBlockHash() public view returns (bytes32 blockHash) { 41 | blockHash = blockhash(block.number - 1); 42 | } 43 | 44 | function getCurrentBlockTimestamp() public view returns (uint256 timestamp) { 45 | timestamp = block.timestamp; 46 | } 47 | 48 | function getCurrentBlockDifficulty() public view returns (uint256 difficulty) { 49 | difficulty = block.difficulty; 50 | } 51 | 52 | function getCurrentBlockGasLimit() public view returns (uint256 gaslimit) { 53 | gaslimit = block.gaslimit; 54 | } 55 | 56 | function getCurrentBlockCoinbase() public view returns (address coinbase) { 57 | coinbase = block.coinbase; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import Multicall from './Multicall'; 2 | 3 | export default Multicall; 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Basic Options */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ 8 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 9 | // "lib": [], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ 13 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | // "outDir": "./", /* Redirect output structure to the directory. */ 18 | // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 21 | // "removeComments": true, /* Do not emit comments to output. */ 22 | // "noEmit": true, /* Do not emit outputs. */ 23 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 24 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 25 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 26 | 27 | /* Strict Type-Checking Options */ 28 | "strict": true, /* Enable all strict type-checking options. */ 29 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 30 | // "strictNullChecks": true, /* Enable strict null checks. */ 31 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 32 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 33 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 34 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 35 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 36 | 37 | /* Additional Checks */ 38 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 39 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 40 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 41 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 42 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 43 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an 'override' modifier. */ 44 | // "noPropertyAccessFromIndexSignature": true, /* Require undeclared properties from index signatures to use element accesses. */ 45 | 46 | /* Module Resolution Options */ 47 | "resolveJsonModule": true, 48 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 49 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 50 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 51 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 52 | // "typeRoots": [], /* List of folders to include type definitions from. */ 53 | // "types": [], /* Type declaration files to be included in compilation. */ 54 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 55 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 56 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 57 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 58 | 59 | /* Source Map Options */ 60 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 61 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 62 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 63 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 64 | 65 | /* Experimental Options */ 66 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 67 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 68 | 69 | /* Advanced Options */ 70 | "skipLibCheck": true, /* Skip type checking of declaration files. */ 71 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ 72 | } 73 | } 74 | --------------------------------------------------------------------------------