Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multicall get balances of a native currency in a wallet #79

Open
ImDuong opened this issue Dec 19, 2023 · 1 comment
Open

Multicall get balances of a native currency in a wallet #79

ImDuong opened this issue Dec 19, 2023 · 1 comment

Comments

@ImDuong
Copy link

ImDuong commented Dec 19, 2023

Hi, I would like to ask how can I get balance of a native token in a wallet. Like the below code,

import {ContractCallContext, Multicall,} from 'ethereum-multicall';
import {ethers} from 'ethers';
import ERC20_ABI from './abi.json' assert {type: 'json'}

let provider = ethers.getDefaultProvider("https://polygon-rpc.com/");

try {
    const walletAddress = "0xe7804c37c13166fF0b37F5aE0BB07A3aEbb6e245"
    const tokenAddresses = ["0x0000000000000000000000000000000000000000"]
    const network = await provider.getNetwork()
    // you can use any ethers provider context here this example is
    // just shows passing in a default provider, ethers hold providers in
    // other context like wallet, signer etc all can be passed in as well.
    const multicall = new Multicall({ ethersProvider: provider, tryAggregate: true });

    const contractCallContext: ContractCallContext[] = tokenAddresses.map((it) => ({
        reference: `${it}`,
        contractAddress: it,
        abi: ERC20_ABI,
        calls: [{ reference: `callBalanceOf:${it}`, methodName: 'balanceOf', methodParameters: [walletAddress] }],
    }))
    const callResults = await multicall.call(contractCallContext)
    const tokenBalancesMap = {} as Record<string, bigint>
    for (const address in callResults.results) {
        try {
            tokenBalancesMap[address] = BigInt(callResults.results[address].callsReturnContext[0].returnValues[0].hex)
        } catch (e) {
            console.warn(`parsing token balance from multicall failed for token ${address} in chain ${network.chainId}`)
        }
    }
    console.log(tokenBalancesMap)
}catch (e) {
    console.error('!-- ERROR:', e)
    console.log('Is there anything to inspect?')
} finally {
}
  • input: token address as null address
  • output: empty object. For more info, if I set tryAggregate to false, the error would be
ERROR: Error: data out-of-bounds (length=0, offset=32, code=BUFFER_OVERRUN, version=abi/5.7.0)

In the particular case is polygon chain, I can replace null address with matic token address 0x0000000000000000000000000000000000001010, and it works well. But if moving to another chain like Ethereum and BNB, there are no address like that but the null address.
How could I call get balance of a native currency for a wallet in such chains? On the other hand, in the library https://github.com/indexed-finance/multicall?tab=readme-ov-file#querying-token-balances, I could able to get balance with null address.

Thank you and have a great day.
P.S: Really appreciate your multicall package, and wishes you have awesome features in the future.

@ImDuong
Copy link
Author

ImDuong commented Dec 19, 2023

I find a work around is calling getEthBalance function from the multicall contract.

const multicallContractAddress = "0xcA11bde05977b3631167028862bE2a173976CA11"
const contractCallContext: ContractCallContext[] = tokenAddresses.map((it) => ({
        reference: `${it}`,
        contractAddress: multicallContractAddress,
        abi: MULTICALL_ABI,
        calls: [{ reference: `callBalanceOf:${it}`, methodName: 'getEthBalance', methodParameters: [walletAddress] }],
    }))

My questions now are:

  1. Can I still use null address for ERC20 ABI like in the topic? If yes, how would I need to adjust the code?
  2. If the original way does not work, could I not specify particular contractAddress and multicall contract's abi? Like the package already support these and I can reuse them?
    • I find out that there is public static ABI field of Multicall class, but it only has write functions, but not getEthBalance function
    • And there is function getContractBasedOnNetwork suits my needs but it is not published unfortunately. Hence, the work around would be duplicated that function into my own code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant