WalletConnect / web3modal

A single Web3 provider solution for all Wallets
https://web3modal.com
Apache License 2.0
4.76k stars 1.33k forks source link

[bug] <w3m-button> does not update balance after successful transaction #1402

Open spider9375 opened 9 months ago

spider9375 commented 9 months ago

Link to minimal reproducible example

-

Summary

I have a w3m-button that after a transaction does not update the balance. Correct one is 0.3539 which could get rounded to 0.354 but the w3m button shows 0.355

image

image

the getBalance wagmi action returns the correct amount. However the w3m button does not update

List of related npm package versions

"typescript": "5.0.2", "vite": "4.4.5", "@wagmi/core": "1.4.3", "@web3modal/wagmi": "3.1.0", "viem": "1.16.6"

xzilja commented 9 months ago

Call wagmi's fetchBalance after your tx is successful. https://wagmi.sh/core/actions/fetchBalance

This will update wagmi's state and in turn what's displayed in modal components.

jvanderbiest commented 8 months ago

@0xAsimetriq I have the same problem. Using react, calling fetchBalance after transaction completed.

import { fetchBalance } from 'wagmi/actions';
    useEffect(() => {
        const fetchData = async () => {
            var data = await fetchBalance({
                address: '0x7...E6d2d4C3B8',
            });
        }

        fetchData()
    }, [complete])

It's calling the code and I get the new balance, but the button does not reflect the change.

xzilja commented 8 months ago

@jvanderbiest it should be import { fetchBalance } from '@wagmi/core/actions but since you are using react (and probabli wagmi package and not their core one) you need to use https://wagmi.sh/react/hooks/useBalance

jvanderbiest commented 8 months ago

Thanks for your quick reply and for the insights. I still couldn't get it working though.

Console logs the new balance, <w3m-button /> doesn't reflect the balance.

import { useBalance } from 'wagmi';

const { data, refetch } = useBalance({
        address: '0x7...E6d2d4C3B8',
      });

useEffect(() => {
    const fetchData = async () => {
        var fetchData = await refetch();
        console.log(`fetched balance: ${fetchData.data?.value}`);
        console.log(`usebalance: ${data?.value}`);
    }

    fetchData()
}, [complete]);
KorbinianK commented 6 months ago

@0xAsimetriq I can confirm this bug with the latest version as well. We are using core inside svelte. We are creating the transaction via getContract() [...] .write.someFunction() and call fetchBalance afterwards. It logs the new balance, so wagmi has it, but it does not update the w3m-button state.

import { fetchBalance } from '@wagmi/core'

export const refreshUserBalance = async () => {
  const account = getAccount();
  if (account?.address) {

    const newBalance = await fetchBalance({
      address: account.address,
    })
    console.log("new balance", newBalance);
  }
};
glitch-txs commented 6 months ago

I'm not sure if this is possible though, there's no global track in wagmi for balance or balance RPC calls AFAIK

KorbinianK commented 6 months ago

I'm not sure if this is possible though, there's no global track in wagmi for balance or balance RPC calls AFAIK

Then there should be a way to call something like modal.refresh() which calls the internal fetchBalance. I feel like this is a pretty common use-case, refreshing the balance.

glitch-txs commented 6 months ago

sounds like a good addition, refetchBalance could work I guess, we'll look into this 👍

KorbinianK commented 6 months ago

@glitch-txs Looked into it a bit now, for wagmi/ethers for plain js it seems to be really simple, as syncBalance is already there, just missing the public exposed wrapper.

Adding this to packages/wagmi/src/client.ts (similar for ethers) exposes the necessary functionality and can then be called via modal.refetchBalance():

public async refetchBalance() {
    const { address, isConnected } = getAccount()
    const { chain } = getNetwork()
    if (isConnected && address && chain) {
      await this.syncBalance(address, chain)
    }
  }

I would provide a PR, but I was not yet able to make it work for react & vue derived from the scaffold package. Not sure it makes sense to only expose it for plain javascript for now? (biased, as that's all I need :P)