[UNRESOLVED] Cors error when using Walletconnect

Did you get this error when user balance functions? 9ul6v.csb.app/:1 Access to XMLHttpRequest at 'https://speedy-nodes-nyc.moralis.io/WalletConnect/bsc/testnet' from origin 'https://9ul6v.csb.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

balance doesnā€™t work either

Do you see cors problem before? Sometimes on api projects user need to add domain to account, to approve it on cors policy

I donā€™t know exactly now what to expect, I didnā€™t do too many tests with walletconnect in the past

@Marynets, did you get this solved? if not, you cant get it to work using moralis you can use web3 react to get wallet connect working. If your using react then you can do the folloowng. Npm install web3React

npm i @web3-react/core

then you need to install the wallet connect connector from reactweb3

@web3-react/walletconnect-connector

now the first thing you need to do to init wev3 react is to wrap your enite App.js return in the web3ReactProvider component. consider the dummy code below to show you what i mean

import Web3 from "web3"

function getLibrary(provider) {
  return new Web3(provider)
}
function App() {

  return (
        
      <>
      <Web3ReactProvider getLibrary={getLibrary}>
       APP COMPONENTS GOES INSIDE HERE
    </Web3ReactProvider>
    </>
  );
}

export default App;

you need to declare that getLibrary() function too so that you can pass it as props to the web3ReactProvider component. Just copy it its the exact same you dont need to make any changes.

Ok so this is the setup. Now to use wallet connect i suggest making a hook. Call it useAuth or something. The logic in the file required for connecting with wallet connect will look like this

import { useState, useEffect } from 'react';
import Web3 from 'web3';
import { useWeb3React } from "@web3-react/core"
import { WalletConnectConnector } from '@web3-react/walletconnect-connector'

export const walletconnect = new WalletConnectConnector({
    rpc: { 1: "https://mainnet.infura.io/v3/ba5ee6592e68419cab422190121eca4c" },
    qrcode: true
})

export default function useAuth() {

    const [loading, setLoading] = useState(false);
    var { active, account, library, connector, activate, deactivate } = useWeb3React()
   
    async function connectOnClickWalletConnect() {
        
        if(active) {

            alert("You must dissconnect first")
            return
        }

        setLoading(true)

           
            try {
                await activate(walletconnect, undefined, true)
                
                loggedInAccount = localStorage.setItem("account", account);
                provider = localStorage.setItem("provider", "walletconnect");
                setTimeout(() => {

                    setLoading(false)
                }, 800)
               
            } catch (err) {

                console.log(err)
                deactivate()
                setLoading(false)
            }

            // const data = localStorage.getItem("walletconnect")
            // local.setItem("walletconnect", data)


    }

    async function disconnect() {
        try {

        deactivate()
        setTimeout(function() {
            alert("you are no longer connected")
        }, 250)
        localStorage.removeItem("provider");

        } catch (err) {

            console.error(err)
        }
    }


  return { connectOnClickWalletConnect, disconnect,  active, account, loading}
}

Ok so the first thing in this hook is to import web3React, walletConnectconnector so that we can make an instance of the walletConnect provider. Note you will need an infura endpoint to do it this way. Just copy thw code for the connector i have above and swap out the infura endpoint with your own

export const walletconnect = new WalletConnectConnector({
    rpc: { 1: "https://mainnet.infura.io/v3/${INFURA_ID}" },
    qrcode: true
})

ok so the first ting we do in this hook is to get the ā€œactiveā€ var, and the ā€œactivate()ā€ and ā€œdeactivate()ā€ functions form web3React. We can use active as a bool check to know whther the user is connected or not. Then we create a function called connectOnClickWalletConnect() this function first checks if active is true. you dont need this here amd the reason I use it is for the case where you app supports multiple wallets you should prompt the user to disconnect from their current wallet before connecting with another. but this connect function should get called on the click of some connect wallet button. When the user clicks the button we setLoading to true. Doing this we could if you want make a loading popup that shows until the connect process is done. Then we have a try catch we then call activate using the walletconnect connector I set the provdider to localStroage again so we can use this to allow us to reconnect automatically onLoad (through another function which is not implemented here). Then we set Loading to false.

If for whatever reason the activation fails we again setLoading to false to call deactivate to make absoluelty sure the user is disconnected(). And thats it wallet conect will prompt on your phone.

The next function is just a disconnect that gets called on some other button ans this deactivates the session and removes the provider from local storage. Then we return, active loading and connectOnClickWalletConnect. so that we can use them in different components.

To set this up just use the connectOnclick function as the onClick in your connect wallet component. Or beter declare this hook in App and pass down everything as props in your components.

One other thing to not is that the wallet connect provider is different that metamask. So if you want to use web3.js calls make sure you instiate web3 with the wallet connector provider. for example

//just like above just in different form
provider = new WalletConnectProvider({
                infuraId: "ba5ee6592e68419cab422190121eca4c",
 });
              
await provider1.enable();
web3 = new Web3(provider1);

Lastly if you want to sign messages with wallectconnect. The usual web3.eth.personal.sign or any of the other signing methods wont work. Instead you need to use a lower level call. an example of a sign that will work with walletconnect is (credits to stack overflow)

//AND USING THE PROVIDER FROM THE ABOVE SNIPPET WE CAN SIGN WITH THIS CODE
signature = await provider.send(
                    'personal_sign',
                    [ ethers.utils.hexlify(ethers.utils.toUtf8Bytes(`message`)), publicAddress ]
                );

you need to use ethers so that you can use that hexilfy function on your sign message.

Hope you get this working. I know this isnt moralis but if you keep getting that cors error this could be a good work around with minial effort

1 Like

Have a nice day, but i build it on angular, and npm pakages (moralis, web3, wallet-connect) dont work good on it, so i rebuild again all app (specialy moralis and web3 side) and cors problem gone, but write methods still does not work, so we find problem in web3 lib, and now we use web3 1.7.0 and only now its start works

2 Likes

@cryptokid can we set this to UNRESOLVED please?

See Ethereum Boilerplate: Metamask Authentication not working on Mobile, Wallet connect not working either

I was happy to see this morning no CORS errors when testing WC! I thought you fixed somethingā€¦
But, now it started again and it seems to be related to the RPC being overloaded:

Whoā€™s working anyway on Sunday? :woman_mage:

Can you try again now to see if it is solved?

works fine at the moment, will post here if it happens again :+1:

would be an idea though to be able to override the RPC in options, for now thatā€™s a benefit of integrating outside of moralis. If 1 RPC is down itā€™s good to gave alternative options.

I think Iā€™m having a related issue here. I appear to be able to log-in via walletconnect. but when I call web3Provider.send("eth_requestAccounts", []); I get the CORS error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://speedy-nodes-nyc.moralis.io/WalletConnect/eth/mainnet. (Reason: CORS header ā€˜Access-Control-Allow-Originā€™ missing). Status code: 401.

if you check in network tab, it was a timeout or really CORS error?

how would the RPC node know what to return for eth_requestAccounts?

itā€™s really a CORS errorā€¦ the response is ā€˜unauthorizedā€™

Screen Shot 2022-02-20 at 12.52.53 PM

it looks like trying to send a command (eth_requestAccounts) that it is not allowed by the node

" how would the RPC node know what to return for eth_requestAccounts?"

Not sure what you mean by thisā€¦ I am not querying the node directly, the underlying Moralis.js library is doing that. I am just using the ethers.js way of asking for the list of associated accounts, using the provider handle returned by: const web3Provider = await Moralis.enableWeb3(). This method works fine on desktop with the injected provider, but fails when connecting through WalletConnect.

maybe that eth_requestAccounts command is specific to metamask

this is still Metamask, just via WalletConnect. Iā€™m open to suggestions for alternatives. The problem I have is I need to know the currently selected wallet address, and that is typically returned at index 0 in the eth_getAccounts call. there is the const account = await Moralis.accountcall, however this does not appear to return the currently selected account, only the primary one.

not sure if this helps:

not really as thatā€™s a web3.js call and not an ethers.js call, old post may no longer be applicable to the current state as the moralis.js library is ethers.js based now. But thanks.