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

[bug] Account hook rpc not update on chain switch #365

Closed
1 task done
bryantoh opened this issue Apr 27, 2022 · 25 comments
Closed
1 task done

[bug] Account hook rpc not update on chain switch #365

bryantoh opened this issue Apr 27, 2022 · 25 comments

Comments

@bryantoh
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Package Version

0.3.0

Current Behavior

After I connect to the Rainbow wallet on Rinkeby chain, the Account hook, didn't automatically change the rpc to Rinkeby, instead it still showing Mainnet
image

Expected Behavior

It should auto update the rpc on network switch from wallet.

Steps To Reproduce

No response

Link to Minimal Reproducible Example (CodeSandbox, StackBlitz, etc.)

No response

Anything else?

No response

@jxom
Copy link
Member

jxom commented Apr 27, 2022

Hi @bryantoh,

Have you set up your WalletConnectConnector to be chain aware?

There is an example of this here.

If you have, can you share a code snippet of your setup?

Thanks.

@bryantoh
Copy link
Author

bryantoh commented Apr 27, 2022

Hi @bryantoh,

Have you set up your WalletConnectConnector to be chain aware?

There is an example of this here.

If you have, can you share a code snippet of your setup?

Thanks.

@jxom , I followed exactly example in above link. I did a console.log printout and I can see the chainId being updated. But the problem is the Account hook didn't take the updated RPC URL. I need to manually refresh the browser in order to get the updated RPC URL.

Based on the screenshot below, it show that chainId auto updated "4" and the url is Rinkeby. But when I check the Account hook data, the"rpc" still under Mainnet. ( Always need to manual trigger refresh browser.) This issue happened to Coinbase Wallet too.

image

@bryantoh bryantoh reopened this Apr 27, 2022
@bryantoh
Copy link
Author

Basically when ever the network change, it didn't notify all the hook. When I tried to call the mint function it hit the wrong provider RPC URL.

@jxom
Copy link
Member

jxom commented Apr 27, 2022

What exactly are you using the WalletConnect options.rpc object for? Are you just wanting to use the RPC URL? If so, I'd recommend using the RPC URL constants or chain[name].rpcUrls (I see you used that in your example).

The data you're seeing there is stale (we need to fix this), however, internally you should automatically be connected to Rinkeby and the hooks should update to reflect that (and use the rinkeby RPC URLs). If you are seeing otherwise, can you provide an example of your code? Thanks.

@bryantoh
Copy link
Author

@jxom Below is my code. Basically click the button, to call the "onMintPressed", and it will call the contract mint function.
But every time it will call the Mainnet instead of Rinkeby (connected with Rainbow wallet).

App.js

function App() {

    const live = process.env.REACT_APP_LIVE === "true" ? true : false;

    // API key for Ethereum node
    // Two popular services are Infura (infura.io) and Alchemy (alchemy.com)
    //const infuraId = process.env.REACT_APP_INFURA_KEY;
    const alchemyId = process.env.REACT_APP_ALCHEMY_KEY2
    //const infuraId = process.env.INFURA_ID;
    console.log("alchemyId")
    console.log(alchemyId)

    const chains = defaultChains;
    const defaultChain = chain.mainnet;


    // Set up connectors
    const client = createClient({
        autoConnect: true,
        connectors({ chainId }) {
            console.log("chainId: " + chainId);
            const chain = chains.find((x) => x.id === chainId) ?? defaultChain;
            console.log("chain.Id: " + chain.id);
            console.log(chain.rpcUrls);
            console.log("chain.rpcUrls.alchemy: " + chain.rpcUrls.alchemy);
            const rpcUrl = chain.rpcUrls.alchemy
                ? `${chain.rpcUrls.alchemy}/${alchemyId}`
                : chain.rpcUrls.default

            console.log("RPCURL: " + rpcUrl)
            return [
                new InjectedConnector(),
                new CoinbaseWalletConnector({
                    options: {
                        appName: 'Abokado',
                        chainId: chain.id,
                        jsonRpcUrl: rpcUrl,
                    },
                }),
                new WalletConnectConnector({
                    options: {
                        qrcode: true,
                        rpc: {
                            [chain.id]: rpcUrl,
                        },
                    },
                }),
            ]
        },
    })


    return (
        <Provider client={client}>
            <Router>
                <ScrollToTop>
                    <Routes>
                        {live &&
                            <Route>
                                <Route index element={<Home />} />
                                <Route path="provenance" element={<Provenance />} />
                            </Route>
                        }
                        {!live &&
                            <Route>
                                <Route index element={<div className="img-fluid comingsoon">
                                    <img src="./comingsoon.png" alt="abokado banner" />
                                </div>} />
                            </Route>
                        }
                    </Routes>
                </ScrollToTop>
            </Router>
        </Provider>
    );
}

Minter.js

const Minter = (props) => {

    //State variables
    const [walletAddress, setWallet] = useState("");
    const [status, setStatus] = useState("");
    const [quantity, setQuantity] = useState("");
    const [totalSupply, setTotalSupply] = useState(1);
    const [buttonDisable, setButtonDisable] = useState(true);


    const { data: accountData, refetch, isLoading } = useAccount();
    console.log(accountData);

    const contract = useContractWrite(
        {
            addressOrName: contractAddress,
            contractInterface: contractABI.abi,
        },
        'mint',
    )



    const onMintPressed = async () => {
        console.log("on Mint");
        console.log(quantity);

        contract.write(
            {
                args: [1],
                overrides: { value: ethers.utils.parseEther(0.02 + '') }
            });

    };


    return (
        <button id="mintButton" onClick={onMintPressed} >
            MINT NOW
        </button>
    );
};

export default Minter;

@jxom
Copy link
Member

jxom commented Apr 27, 2022

Ah yep! I can reproduce now, thanks! This is a bug on our end. Having a look into it.

@bryantoh
Copy link
Author

Ah yep! I can reproduce now, thanks! This is a bug on our end. Having a look into it.

Hopefully can be fixed ASAP. I have switched my project to Wagmi and this is the show stopper to my project.

@bryantoh
Copy link
Author

May I know when will this fix release to npm?

@jxom
Copy link
Member

jxom commented Apr 28, 2022

Probably will need to investigate this one a bit further as it is not a simple fix, so I can't give you a timeframe right now.

For the meantime, maybe specify an RPC URL map to the Wallet Connect connector:

new WalletConnectConnector({
  chains,
  options: {
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`
    }
  }
})

@bryantoh
Copy link
Author

bryantoh commented Apr 29, 2022

Probably will need to investigate this one a bit further as it is not a simple fix, so I can't give you a timeframe right now.

For the meantime, maybe specify an RPC URL map to the Wallet Connect connector:

new WalletConnectConnector({
  chains,
  options: {
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`
    }
  }
})

I have followed your suggested method. But couldn't solved the issue. When I trigger mint, it will trigger the mainnet URL instead of the actual wallet connected network. Unless I do a manual refresh. For the testing work around, I will manual refresh. In production anyway only mainnet is allow.

@holic
Copy link
Contributor

holic commented May 4, 2022

Not sure if this is related, but thought I'd ask before opening a new issue. I am seeing behavior where calling a contract with the provider/signer from wagmi seems to have missing RPC data. Does this look like the same thing?

image

image

(JSON error above is misleading because the /undefined path on the Infura URL is returning a non-JSON response, but something in the stack expects to be able to parse JSON and chokes on it.)

I have tried:

  • various methods for getting the provider/signer (via hooks, via activeConnector.getSigner(), etc.)
  • setting the rpc option in the WalletConnectConnector constructor when creating client
  • setting the provider option when creating client to return an Achemy provider

No luck so far!

@jxom
Copy link
Member

jxom commented May 4, 2022

@holic – can you send a snippet of your createClient setup?

Also, FYI, there is a WIP PR for first-class API provider support. This includes the issue discovered in this PR (stale active connectors), as well as introducing a configureChains API to make handling RPC URLs & providers easier.

@holic
Copy link
Contributor

holic commented May 4, 2022

After stepping through all of my previous attempts, I think I figured out what was going on:

My code looked something like this (including the rpc option):

export const connectors = {
  injected: new InjectedConnector(),
  qrcode: new WalletConnectConnector({
    options: {
      qrcode: false,
      rpc: {
        [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
        [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`,
      },
    },
  }),
  mobile: new WalletConnectConnector({
    options: {},
  }),
};

export const client = createClient({
  autoConnect: true,
  connectors: Object.values(connectors),
});

(The map of connectors is used later to render custom display depending on the connector + screen size. Curious if there's a better approach!)

I think the issue stems from both connectors.qrcode and connectors.mobile using a WalletConnectConnector (therefore both ids are walletConnect). If I connect to connector.qrcode, caching/restoring based on the id was finding/pulling from connectors.mobile first, which doesn't have rpc configured. Therefore it was empty. If I add rpc to both WalletConnectConnector, it works just fine.

Ultimately my goal here is to use the default WalletConnect modal/UI when connecting on mobile screens, but on desktop the modal is replaced by a custom QR code display (similar to how Shields did their mint). Aside from rpc in both, an alternative option could be a custom connector with its own id that is meant for the QR code override (so that this is the connector that is cached/restored). Let me know if you have any ideas/suggestions for a better approach!

@sambacha
Copy link

sambacha commented May 5, 2022

After stepping through all of my previous attempts, I think I figured out what was going on:

My code looked something like this (including the rpc option):

export const connectors = {
  injected: new InjectedConnector(),
  qrcode: new WalletConnectConnector({
    options: {
      qrcode: false,
      rpc: {
        [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
        [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`,
      },
    },
  }),
  mobile: new WalletConnectConnector({
    options: {},
  }),
};

export const client = createClient({
  autoConnect: true,
  connectors: Object.values(connectors),
});

(The map of connectors is used later to render custom display depending on the connector + screen size. Curious if there's a better approach!)

I think the issue stems from both connectors.qrcode and connectors.mobile using a WalletConnectConnector (therefore both ids are walletConnect). If I connect to connector.qrcode, caching/restoring based on the id was finding/pulling from connectors.mobile first, which doesn't have rpc configured. Therefore it was empty. If I add rpc to both WalletConnectConnector, it works just fine.

Ultimately my goal here is to use the default WalletConnect modal/UI when connecting on mobile screens, but on desktop the modal is replaced by a custom QR code display (similar to how Shields did their mint). Aside from rpc in both, an alternative option could be a custom connector with its own id that is meant for the QR code override (so that this is the connector that is cached/restored). Let me know if you have any ideas/suggestions for a better approach!

This use case sounds like a perfect fit for this proposed EIP, your feedback is greatly appreciated! https://ethereum-magicians.org/t/eip-wallet-switchactiverpcprovider-rpc-method-for-supporting-aa-custom-rpc-methods-more/9142

@bryantoh
Copy link
Author

bryantoh commented May 9, 2022

@jxom ,

When I tried to tigger contract write function, it show below error. I think it tried to use the "http" instead of the custom url.

image

@jxom
Copy link
Member

jxom commented May 9, 2022

@bryantoh – you are probably experiencing this because you are connected to mainnet and do not have an RPC URL defined for it on the WalletConnectConnector. Ensure that you also have the mainnet chain (id: 1) in your rpc in WalletConnectConnector.

new WalletConnectConnector({
  chains,
  options: {
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`
    }
  }
})

@bryantoh
Copy link
Author

bryantoh commented May 10, 2022

@bryantoh – you are probably experiencing this because you are connected to mainnet and do not have an RPC URL defined for it on the WalletConnectConnector. Ensure that you also have the mainnet chain (id: 1) in your rpc in WalletConnectConnector.

new WalletConnectConnector({
  chains,
  options: {
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`
    }
  }
})

I have follow about method, at least now can show proper mainnet URL. I did choose Rinkeby when connecting to the wallet, but it still show mainnet URL. The screenshot below it show connected to Rinkeby. I need to manual browser refresh in order to solve this issue.
image

@bryantoh
Copy link
Author

@bryantoh – you are probably experiencing this because you are connected to mainnet and do not have an RPC URL defined for it on the WalletConnectConnector. Ensure that you also have the mainnet chain (id: 1) in your rpc in WalletConnectConnector.

new WalletConnectConnector({
  chains,
  options: {
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`
    }
  }
})

I have follow about method, at least now can show proper mainnet URL. I did choose Rinkeby when connecting to the wallet, but it still show mainnet URL. The screenshot below it show connected to Rinkeby. I need to manual browser refresh in order to solve this issue. image

This issue seems only happened on WalletConnect( tested on Rainbow and Metamask mobile wallet).
No problem with Coinbase mobile wallet/chrome extension and Metamask chrome extension.

@holic
Copy link
Contributor

holic commented May 10, 2022

Did you try setting the chainId in your options?

new WalletConnectConnector({
  options: {
    qrcode: true,
    chainId,
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`,
    },
  },
});

@bryantoh
Copy link
Author

Did you try setting the chainId in your options?

new WalletConnectConnector({
  options: {
    qrcode: true,
    chainId,
    rpc: {
      [chain.mainnet.id]: `${chain.mainnet.rpcUrls.alchemy}/${alchemyId}`,
      [chain.rinkeby.id]: `${chain.rinkeby.rpcUrls.alchemy}/${alchemyId}`,
    },
  },
});

Still the same issue. Only manual refresh will help.

@jxom
Copy link
Member

jxom commented May 11, 2022

#408 should fix the issues seen here.

@outdoteth
Copy link

outdoteth commented May 14, 2022

just adding a comment to say that i get the same thing.

connect wallet via wallet connect -> select rinkeby in wallet -> app uses mainnet -> manual refresh -> app uses rinkeby

@jxom when will that be released? or is it already released?

@tmm
Copy link
Member

tmm commented May 14, 2022

@outdoteth will be released once #445 is merged in. (You can subscribe to the PR if you want to get notified.)

@bryantoh
Copy link
Author

Even with this issue I still able release my app to production. Just add logic to enforce user connect to mainnet otherwise show "switch network" button to switch to mainnet.

Copy link
Contributor

This issue has been locked since it has been closed for more than 14 days.

If you found a concrete bug or regression related to it, please open a new bug report with a reproduction against the latest wagmi version. If you have any other comments you can create a new discussion.

@github-actions github-actions bot locked and limited conversation to collaborators Jan 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants