[UNRESOLVED] Cors error when using Walletconnect

Have a nice day everyone!

I have a problem, when i use walletconnect into moralis

steps to reproduce, using bsc testnet (also tryed an other networks)

1 STEP, connect via walletconnect (by qr code)

Moralis.enableWeb3({  provider: "walletconnect", chainId: networkId }).then(res => {
web3 = res
})

2 STEP, get user address, and create contract

const accounts = await web3.eth.getAccounts();
address = accounts[0];
dataContract = new web3.eth.Contract(ContractAbi, ContractAddress);

3 STEP, try to do call() or send() functions via contract, for example

await this.dataContract.methods.balanceOf(address).call();

or

    const check = {
        contractAddress: ContractAddress,
        functionName: "balanceOf",
        abi: ContractAbi,
        params: {
            address: address
        },
    };
    Moralis.executeFunction(claim).then(
        res => {
            console.log(res);
        }
    );

as the result i have message in console

Access to XMLHttpRequest at ‘https://speedy-nodes-nyc.moralis.io/WalletConnect/bsc/testnet’ from origin ‘clientsite’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’
ethereum-provider min js:8 POST speedy-nodes-nyc moralis io WalletConnect bsc testnet
Access to XMLHttpRequest at ‘speedy-nodes-nyc moralis io WalletConnect bsc testnet’ from origin 'client
site’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
ethereum-provider min js:8 POST speedy-nodes-nyc moralis io WalletConnect bsc testnet net::ERR_FAILED 401

When use metamask from pc everything works fine (walletconnect needed for connecting via qr code)

this happens every time? or it happened once

It happened every time. I tried on 3 domains and localhost

Maybe i must add domain somewhere in account. I don’t know …

did you try to upload the site on your Moralis Server with moralis-admin-cli and to try from there? or from codesandbox?

Sorry, but how i understand Morallis Server is for backend functional

I develop on firebase at this time, and i create link on codesandbox and you can check cors by yourself https://codesandbox.io/s/modest-darkness-9ul6v?file=/index.html (network is BSC testnet)

I got this in console after scanning the QR code when accessing https://9ul6v.csb.app/:

Contract successfully created
Authenticate success
Address not found
Chain id is wrong

Please choose

BSC testnet when connect https://academy.binance.com/ru/articles/connecting-metamask-to-binance-smart-chain

and also approve address connection (for example in metamask)

Contract successfully created
Authenticate success
Address not found
Chain id is ok
Uncaught (in promise) Error: No "from" address specified in neither the given options, nor the default options.

i dont know why this function await web3.eth.getAccounts() does not see your address, okay, i changed address in balance1 and balance2 to static now try again please

it looks like it tries to connect to this server: gjz3mjfkxfo8.usemoralis.com that it looks like it doesn’t work.

Changed server to enabled https://tdpit5r0okmd.usemoralis.com:2053/server Same problem, i just tryed so many times and so many configurations …

I get that error when clicking approve, what does that approve do?

Balance working fine for you? Approve is write method to approve contract manipulate with address finances, you cant do this function without address from this function await web3.eth.getAccounts() this function uses for something like nft marketplace

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