Giter Club home page Giter Club logo

ethers-multicall's People

Contributors

bitwise343 avatar c0rv0s avatar cavanmflynn avatar dependabot[bot] avatar froggiedev avatar guotie avatar halaprix avatar iflp avatar josh-richardson avatar larrythecucumber321 avatar mushroomsforest avatar not-reed avatar pajicf avatar shelvak avatar tobowers avatar xba5ed avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

ethers-multicall's Issues

Not sure why ethers-multicall not work in Fantom

We are trying to use ethers-multicall (https://www.npmjs.com/package/ethers-multicall) to group multiple calls to Fantom RPC, but it seems not working. Would you mind to take a look at and share any thoughts/guidance if possible?

image
sample reproduction code:

let mushContract = new Contract("0x883fb00742161dce2235bbf4a67df84cd0e50c08", "contractABI");

let marketPriceCall = mushContract.getMarkPrice("0x321162Cd933E2Be498Cd2267a90534A804051b11");
let exposureBalanceCall = mushContract.exposureBalances("0x43229759E12eFbe3e2A0fB0510B15e516d046442", "0x321162Cd933E2Be498Cd2267a90534A804051b11");
let tokenBalanceCall = mushContract.tokenBalances("0x43229759E12eFbe3e2A0fB0510B15e516d046442", "0x321162Cd933E2Be498Cd2267a90534A804051b11");
let exposureLeverageBpsCall = mushContract.exposureLeverageBps("0x43229759E12eFbe3e2A0fB0510B15e516d046442","0x321162Cd933E2Be498Cd2267a90534A804051b11");


let [
    marketPrice,
    exposureBalance,
    tokenBalance,
    exposureLeverageBps,
] = await callProvider.all([
    marketPriceCall,
    exposureBalanceCall,
    tokenBalanceCall,
    exposureLeverageBpsCall,
]);

Doesn't work with Web3 provider in browser

I'm getting this error:

Unhandled Rejection (Error): call revert exception (method="aggregate((address,bytes)[])", errorSignature=null, errorArgs=[null], reason=null, code=CALL_EXCEPTION, version=abi/5.1.0)

image

Wrong eth balance for the first account generated by Ganache

Code:

import { Provider } from 'ethers-multicall';
import { ethers } from 'ethers';

(async function() {
    const provider = new ethers.providers.JsonRpcProvider('http://localhost:8545/');
    const ethcallProvider = new Provider(provider);
    await ethcallProvider.init();

    const ganche_account_0 = '0x66aB6D9362d4F35596279692F0251Db635165871';
    const ethBalance = await provider.getBalance(ganche_account_0);
    const [ethBalanceMulticall] = await ethcallProvider.all([ethcallProvider.getEthBalance(ganche_account_0)]);

    console.log('ETH Balance:', ethers.utils.formatUnits(ethBalance));
    console.log('ETH Balance multicall:', ethers.utils.formatUnits(ethBalanceMulticall));
})()

Output:

ETH Balance: 100.0
ETH Balance multicall: 180143885.09481982

Getting: Error: underlying network changed

Hi, I'm using ethers-multicall in my app but getting the following error on network change:

index.js?4a96:219 Uncaught (in promise) Error: underlying network changed (event="changed", network={"name":"matic","chainId":137,"ensAddress":null}, detectedNetwork={"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"}, code=NETWORK_ERROR, version=providers/5.6.8)

I'm calling a getBalances() function in order to fetch the user's balances of multi tokens:

export const getMultipleTokenBalancesByMultiCall = async (
  tokens: Token[],
  userAddress: string,
  chainId: number,
  provider: ethers.providers.Provider
): Promise<TokenWithBalance[]> => {
  const ethCallProvider = new Provider(provider, chainId);
  const balanceCalls = tokens.map((token) => {
    if (NATIVE[chainId].equals(token)) {
      return ethCallProvider.getEthBalance(userAddress);
    }
    return getERC20Contract_MultiCall(token.address).balanceOf(userAddress);
  });
  const balances = await ethCallProvider?.all(balanceCalls);
  return tokens.map(
    (token, index) =>
      ({
        ...token,
        balance: FixBigNumber.fromWei(
          balances[index].toString(),
          token.decimals
        ),
      } as TokenWithBalance)
  );
};

The function is called like below:

export const useGetUserAssetsBalances = (assets: any): TokenWithBalance[] => {
  const { account, provider, chainId } = useWeb3React();
  const [balances, setBalances] = useState<TokenWithBalance[]>([]);
  const fetchBalances = useCallback(async () => {
    const tokens: Token[] = Object.values(assets);
    const data = (await getMultipleTokenBalancesByMultiCall(
      tokens,
      account!,
      chainId!,
      provider!,
    )) as TokenWithBalance[];

    setBalances(data);
  }, [account, provider, assets, chainId]);

  useEffect(() => {
    if (account && assets && provider && chainId) {
      fetchBalances();
    }
  }, [account, chainId, provider, assets, setBalances, fetchBalances]);
  return balances;
};

I don't have any idea on what happens here. Do someone has an idea?

Goerli multicall address

deployed at address 0x77dca2c955b15e9de4dbbcf1246b4b85b651e50e, chainID 5. no reason not to add this in

Can't make Contract with ABI that contains event types

When providing the full ABI to the multicall Contract, I get an error "TypeError: Cannot read properties of null (reading 'type')"

Here is where the code brings me to. If I remove all event types and only leave function types, it will work.

Contract.js line 12
for (var _i = 0, callFunctions_1 = callFunctions; _i < callFunctions_1.length; _i++) { var callFunction = callFunctions_1[_i]; var name = callFunction.name; var getCall = makeCallFunction(this, name); if (!this[name]) { defineReadOnly(this, name, getCall); } };

(avalanche mainnet) Error: invalid contract address or ENS name (argument="addressOrName", value=undefined, code=INVALID_ARGUMENT, version=contracts/5.5.0)

      const callProvider = new Provider(
        new ethers.providers.JsonRpcProvider(
          "https://api.avax.network/ext/bc/C/rpc"
        )
      );
      callProvider.init();
      const daiContract = new Contract(daiAddress, daiAbi);
      const poolDaiBalanceCall = daiContract.balanceOf(poolAddress);
      const myDaiBalanceCall = daiContract.balanceOf(account);
      const [poolDaiBalance, myDaiBalance] = await callProvider.all([
        poolDaiBalanceCall,
        myDaiBalanceCall,
      ]);

in

const [poolDaiBalance, myDaiBalance] = await callProvider.all([
        poolDaiBalanceCall,
        myDaiBalanceCall,
      ]);

Error pop up, Error: invalid contract address or ENS name (argument="addressOrName", value=undefined, code=INVALID_ARGUMENT, version=contracts/5.5.0)

How to add getAmountsOut?

I am using a custom ABI,
I can use without problems balanceOf and symbol.

but if I try to use the getAmountOut function
"function getAmountsOut (uint amountIn, address [] memory path) public view returns (uint [] memory amounts)"

I get the following error:

const error: any = new Error(message);
                           ^
Error: types/values length mismatch (count={"types":2,"values":0}, value={"types":[{"name":"amountIn","type":"uint256","indexed":null,"components":null,"arrayLength":null,"arrayChildren":null,"baseType":"uint256","_isParamType":true},{"name":"path","type":"address[]","indexed":null,"components":null,"arrayLength":-1,"arrayChildren":{"name":null,"type":"address","indexed":null,"components":null,"arrayLength":null,"arrayChildren":null,"baseType":"address","_isParamType":true},"baseType":"array","_isParamType":true}],"values":[]}, code=INVALID_ARGUMENT, version=abi/5.7.0)

which is the correct way?

`ethers-multicall-provider` has a similar, simpler API

This repository seems to not be maintained anymore: last commit dates back to beginning of January 2022.

I encourage anyone willing to get support to start using ethers-multicall-provider, which is well tested and has a similar API. The move should not be cumbersome, as it boilds down to the following changes:

- import { Contract, Provider } from 'ethers-multicall';
+ import { MulticallProvider } from 'ethers-multicall-provider';

- const multicallProvider = new Provider(provider);
+ const multicallProvider = MulticallProvider.wrap(provider);

Error with receive functions

For some reasons, if the ABI contains a receive payable function with no further arguments, instantiating a new Contract will throw an TypeError: Cannot read property 'type' of null error.
The problem seems to be coming from the Fragment from ethersprojects, but can also be fixed in the library.

Can be reproduced by using this ABI:

  const abi = [
    {
        constant: true,
        inputs: [],
        name: 'totalSupply',
        outputs: [
            {
                internalType: 'uint256',
                name: '',
                type: 'uint256'
            }
        ],
        payable: false,
        stateMutability: 'view',
        type: 'function'
    },
    {
      stateMutability: 'payable',
      type: 'receive'
    }
  ]

in the tests.

Uncaught (in promise) Error: invalid address (argument="address", value=0, code=INVALID_ARGUMENT, version=address/5.7.0) (argument=null, value=0, code=INVALID_ARGUMENT, version=abi/5.7.0)

Hello, I am trying to run a multicall using your API (thank you by the way), however I am running in to the following issue.

Uncaught (in promise) Error: invalid address (argument="address", value=0, code=INVALID_ARGUMENT, version=address/5.7.0) (argument=null, value=0, code=INVALID_ARGUMENT, version=abi/5.7.0)

The following is my code for running the multiCall API.

`
async loadDataUsingMulticall() {
const { web3 } = this.state;
var multicall = null;

// Your multicall code here

console.log("test zero -");

multicall = new Multicall({
  web3Instance: web3,
  tryAggregate: true,
});

console.log("test zero");

const contractCallContext = [
  {
    reference: "mirrorBalance",
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [
      {
        methodName: "balanceOf",
        methodParameters: [this.state.account[0]],
      },
    ],
  },
  {
    reference: "morWholeBurn",
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [
      {
        methodName: "balanceOf",
        methodParameters: ["0x0000000000000000000000000000000000000000"],
      },
    ],
  },
  {
    reference: "morRFIBurn",
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [
      {
        methodName: "balanceOf",
        methodParameters: ["0x000000000000000000000000000000000000dead"],
      },
    ],
  },
  {
    reference: "totalFees",
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [{ methodName: "totalFees", methodParameters: [] }],
  },
  {
    reference: "numFarmers",
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [{ methodName: "numFarmers", methodParameters: [] }],
  },
];

console.log("test before");
console.log(MIRROR_ADDRESS);

// Loop for dynamic method calls like 'farmers' and 'farmingLeaderboard'
for (let i = 0; i < 5; i++) {
  contractCallContext.push({
    reference: `farmer${i}`,
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [{ methodName: "farmers", methodParameters: [i] }],
  });
  contractCallContext.push({
    reference: `farmer${i}amt`,
    contractAddress: MIRROR_ADDRESS,
    abi: MIRRORABI,
    calls: [{ methodName: "farmingLeaderboard", methodParameters: [i] }],
  });
}
////////////

const callResults = await multicall.call(contractCallContext);
console.log("test)");
console.log(callResults);

//THE ISSUE COULD BE HERE TO THE WAY: callResults.results.<nameofId>.callsReturnContext[0].returnValues
// Accessing individual results
const mirrorBalance = Web3.utils.fromWei(
  callResults.results.mirrorBalance.callsReturnContext[0].returnValues[0],
  "ether",
);
const morWholeBurn = Web3.utils.fromWei(
  callResults.results.morWholeBurn.callsReturnContext[0].returnValues[0],
  "ether",
);
const morRFIBurn = Web3.utils.fromWei(
  callResults.results.morRFIBurn.callsReturnContext[0].returnValues[0],
  "ether",
);
const totalFees = Web3.utils.fromWei(
  callResults.results.totalFees.callsReturnContext[0].returnValues[0],
  "ether",
);
const numFarmers = parseInt(
  callResults.results.numFarmers.callsReturnContext[0].returnValues[0],
);
console.log("This is mirror Balance");
console.log(mirrorBalance);
console.log("This is morWhole Burn");
console.log(morWholeBurn);
console.log("This is total Farmers");
console.log(numFarmers);
// Loop to access farmers and farmingLeaderboard data
let farmerData = {};
for (let i = 0; i < 5; i++) {
  farmerData[`farmer${i}`] =
    callResults.results[`farmer${i}`].callsReturnContext[0].returnValues[0];
  farmerData[`farmer${i}amt`] =
    callResults.results[
      `farmer${i}amt`
    ].callsReturnContext[0].returnValues[0];
}

// Update state with all the gathered data
this.setState({
  mirrorBalance,
  morWholeBurn,
  morRFIBurn,
  totalFees,
  numFarmers,
  ...farmerData,
  loadingLeaderBoard: false,
});

}`

Multicall.all() yields Cannot read properties of undefined (reading 'length')

I am currently running into this error when await-ing the result of a multicall.all() call.

ethers-multicall: ^0.2.3
ethers: ^5.7.2

Below is the relevant code:

const multicallProvider = new Provider(provider, 1); //Provider is an AlchemyProvider
const call1 = new Contract(address, abi).liquidity; // ethers-multicall contract
const call2 = new Contract(address, abi).protocolFees; //ethers-multicall-contract
await multicallProvider.all([call1, call2]) //Fails and throws error

Thanks!

Please add Aurora support

Our team has deployed Multicall contract on Aurora mainnet and testnet for our own use

Easy two line addition here -

80001: '0x08411ADd0b5AA8ee47563b146743C13b3556c9Cc',

    1313161554: '0xdc1522872E440cF9cD48E237EAFEfaa5F157Ca1d',
    1313161555: '0x8f81207F59A4f86d68608fF90b259A0927242967'

Strongly-typed contracts

Is there a way to currently (or in the future) make the contract aware of the functions it supports? Example:

Screen Shot 2021-05-09 at 01 36 19

Thanks to TypeChain we have a generated contract type which would be as follows for the example above:

start_time(
  overrides?: CallOverrides
): Promise<{
  0: BigNumber;
}>;

I'm thinking there might be a way to pass it to the Contract class if we make it generic โ€” taking contract type as a type argument.

Doesn't support call by blockTag

async function lpTokenUsd(currentBlock) { await multiCallProvider.init(); const oneLPAmount = BigNumber.from(10).pow(18); const calculateBlocks = 10; const priceCalls = []; for (let i = 1; i < calculateBlocks; i += 1) { const block = currentBlock - i; priceCalls.push( swapPool.calc_withdraw_one_coin(oneLPAmount, 0, { blockTag: block }) ); } const result = await multiCallProvider.all(priceCalls); console.log(result : ${JSON.stringify(result)}); }

run above function will get error:
Error: types/values length mismatch (count={"types":2,"values":3}, value={"types":[{"name":"_token_amount","type":"uint256","indexed":null,"components":null,"arrayLength":null,"arrayChildren":null,"baseType":"uint256","_isParamType":true},{"name":"i","type":"int128","indexed":null,"components":null,"arrayLength":null,"arrayChildren":null,"baseType":"int128","_isParamType":true}],"values":[{"type":"BigNumber","hex":"0x0de0b6b3a7640000"},0,{"blockTag":11135382}]}, code=INVALID_ARGUMENT, version=abi/5.4.1)

Once I removed the blockTag, it will work and return result.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.