Web3js MetaMask Binance – Running BUSD Smart Contract Methods on Android Chrome Using Web3js and WalletConnect

binance-smart-chainmetamasksmart-contract-walletswalletconnectweb3js

I have a website that works fine on desktop chrome.

Website provides you a possibility to transfer BUSD in BSC Mainnet to some accounts with Metamask.

For mobile i use walletconnect in browser and Metamask android app. It is possible to login. But transaction cannot be ran.

const Web3Modal = window.Web3Modal.default;
const WalletConnectProvider = window.WalletConnectProvider.default;
const providerOptions = {
    walletconnect: {
        package: WalletConnectProvider,
        options: {
            infuraId: "8043bb2cf99347b1bfadfb233c5325c0",
        }
    }
};

const detectProvider = async () => {
    let provider;

    if (window.ethereum) {

        provider = window.ethereum;
        console.log(provider);
        await provider.enable();

    } else if (window.web3) {

        provider = window.web3.currentProvider;
        await provider.request({ method: 'eth_requestAccounts' });

    } else {

        const web3Modal = new Web3Modal({
            cacheProvider: false,
            providerOptions,
            disableInjectedProvider: false,
        });

        provider = await web3Modal.connect();

    }
    return provider;
};

Afterall, when i get provider and create Contract examplar, i call BUSD method to transfer coins:

const res = await contract.methods.transfer(toAddress, amount).send({ from: selectedAccount });

This works perfectly on desktop, but on mobile there isn't even exception, the execution of code just stops at that line.

How to solve it? Any one stumbled upon similar issue?

Best Answer

I needed to set up my own infura project (https://infura.io/) and get infuraId.

UPD:

I've decided to do it without infura. To solve problem with mobile version you will have to navigate your mobile to metamask embedded browser. Only that way you will not need to exit browser to comfirm transaction (and all other operations with your account).

This is how i navigate the phone (i put the following url to a tag href, when user clicks it he will go to my site page in desktop browser (on PC) or my site page in metamask browser (on mobile)):

let url = navigator.userAgentData.mobile ? 'https://metamask.app.link/dapp/YOUR_WEB_SITE_PAGE' : 'YOUR_WEB_SITE_PAGE';

Logic for making transactions:

const Web3Modal = window.Web3Modal.default;
const WalletConnectProvider = window.WalletConnectProvider.default;
const providerOptions = {
    walletconnect: {
        package: WalletConnectProvider,
        options: {
            rpc: {
                56: 'https://bsc-dataseed1.binance.org'
            },
            chainId: 56
        }
    }
};

const detectEthereumProvider = async () => {
    let provider;

    if (window.ethereum) {
        
        provider = window.ethereum;
        await provider.enable();

    } else if (window.web3) {

        provider = window.web3.currentProvider;
        await provider.request({ method: 'eth_requestAccounts' });

    } else {

        const web3Modal = new Web3Modal({
            network: "mainnet",
            cacheProvider: true,
            providerOptions
        });

        provider = await web3Modal.connect();
        await web3Modal.toggleModal();

    }
    return provider;
};

..................

connect: async function () {
            try {

                this.provider = await detectEthereumProvider();

                this.provider.on("accountsChanged", async (accounts) => {
                    await this.fetchAccountData();
                });

                this.provider.on("chainChanged", async (chainId) => {
                    await this.fetchAccountData();
                });

                this.provider.on("networkChanged", async (networkId) => {
                    await this.fetchAccountData();
                });

                await this.fetchAccountData();

                this.connected = true;
            }
            catch (e) {
                this.connected = false;
            }
        },

..................

fetchAccountData: async function () {
            this.web3 = new Web3(this.provider);
            this.accounts = await this.web3.eth.getAccounts();
            this.selectedAccount = this.accounts[0];
        },

..................

const contract = new this.web3.eth.Contract(
                smartContractAbiJson,
                smartContractAddress
            );

contract.defaultAccount = selectedAccount;

let res = await contract.methods.transfer(toAddress, amount).send({ from: selectedAccount });
Related Topic