Mobile Phone Browser

Hi All my moralis Dapp works perfectly well on desktop for both MetaMask connect and walletconnect. However when I tested it with my mobile phone browser on IPhone the following observations are made.

  1. Works fine with opening up the Dapp on MetaMask Browser on IPhone with regards to authentication, sending transactions.

  2. On safari and Google Chrome on IPhone. Clicked on walletconnect clicked on either MetaMask or trustwallet prompted for authentication and sign which is fine. Then it prompted to go back to browser that’s where the issue happens once I go back to the browser the Dapp is behaving like as if it has not been connected to either MetaMask or Trust wallet. I can’t select the tokens to swap etc .

Anyone able to shed light on how we can address the issue ?

What tech stack did you use? react, vanilla js?
Do you have a minimal code example that replicates this problem?

Dear Sir the following is my main.js

const serverUrl = "https://4yjda7y7rljv.moralishost.com:2053/server"; //Server url from moralis.io
const appId = "JxwZmqnP0FWfj24rMM4D454SaIcxY48FtRILkRrO"; // Application id from moralis.io
let currentTrade = {};
let currentSelectSide;
let tokens;
let web3;
async function init() {
  await Moralis.start({ serverUrl, appId });
  await Moralis.enableWeb3();
  await listAvailableTokens();
  currentUser = Moralis.User.current();
  if (currentUser) {
    document.getElementById("swap_button").disabled = false;
  }
}
async function listAvailableTokens() {
  tokens ={
      "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee":{
          "symbol":"BNB",
          "name":"BNB",
          "decimals": 18,
          "address":"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
          "logoURI":"https://tokens.1inch.io/0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c.png",  
          },
      "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82":{
          "symbol":"CAKE",
          "name":"CAKE",
          "decimals": 18,
          "address":"0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82",
          "logoURI":"https://tokens.1inch.io/0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82.png",
          },
          };
  let parent = document.getElementById("token_list");
  for (const address in tokens) {
    let token = tokens[address];
    let div = document.createElement("div");
    div.setAttribute("data-address", address);
    div.className = "token_row";
    let html = `
        <img class="token_list_img" src="${token.logoURI}">
        <span class="token_list_text">${token.symbol}</span>
        `;
    div.innerHTML = html;
    div.onclick = () => {
      selectToken(address);
    };
    parent.appendChild(div);
  }
}
function selectToken(address) {
  closeModal();
  console.log(tokens);
  currentTrade[currentSelectSide] = tokens[address];
  console.log(currentTrade);
  renderInterface();
  getQuote();
}
function renderInterface() {
  if (currentTrade.from) {
    document.getElementById("from_token_img").src = currentTrade.from.logoURI;
    document.getElementById("from_token_text").innerHTML = currentTrade.from.symbol;
  }
  if (currentTrade.to) {
    document.getElementById("to_token_img").src = currentTrade.to.logoURI;
    document.getElementById("to_token_text").innerHTML = currentTrade.to.symbol;
  }
}
async function login() {
  try {
    currentUser = Moralis.User.current();
    if (!currentUser) {
      currentUser = await Moralis.authenticate();
    }
    document.getElementById("swap_button").disabled = false;
  } catch (error) {
    console.log(error);
  }
}
async function login1() {
  try {
      currentUser = Moralis.User.current();
      if(!currentUser){
         currentUser = await Moralis.Web3.authenticate({
              provider: "walletconnect",
              chainId: 56,
              mobileLinks: ["metamask","trust"]});
         web3 = await Moralis.Web3.enable({
                provider: "walletconnect",
                chainId: 56,
                mobileLinks: ["metamask","trust"]});                 
      }
      document.getElementById("swap_button").disabled = false;
  } catch (error) {
      console.log(error);
  }
}
async function logOut() {
  try {
      currentUser = await Moralis.User.logOut();
      console.log("user logged out");
      init();
  }catch (error) {
      console.log(error);
  }
}
function openModal(side) {
  currentSelectSide = side;
  document.getElementById("token_modal").style.display = "block";
}
function closeModal() {
  document.getElementById("token_modal").style.display = "none";
}
async function getQuote() {
  if (!currentTrade.from || !currentTrade.to || !document.getElementById("from_amount").value) return;
  let amount = Number(document.getElementById("from_amount").value * 10 ** currentTrade.from.decimals);
  const quote = await Moralis.Plugins.oneInch.quote({
    chain: "bsc", // The blockchain you want to use (eth/bsc/polygon)
    fromTokenAddress: currentTrade.from.address, // The token you want to swap
    toTokenAddress: currentTrade.to.address, // The token you want to receive
    amount: amount,
  });
  console.log(quote);
  document.getElementById("gas_estimate").innerHTML = quote.estimatedGas;
  document.getElementById("to_amount").value = quote.toTokenAmount / 10 ** quote.toToken.decimals;
}
async function trySwap() {
  let address = Moralis.User.current().get("ethAddress");
  let amount = Number(document.getElementById("from_amount").value * 10 ** currentTrade.from.decimals);
  if (currentTrade.from.symbol !== "BNB") {
    const allowance = await Moralis.Plugins.oneInch.hasAllowance({
      chain: "bsc", // The blockchain you want to use (eth/bsc/polygon)
      fromTokenAddress: currentTrade.from.address, // The token you want to swap
      fromAddress: address, // Your wallet address
      amount: amount,
    });
    console.log(allowance);
    if (!allowance) {
      await Moralis.Plugins.oneInch.approve({
        chain: "bsc", // The blockchain you want to use (eth/bsc/polygon)
        tokenAddress: currentTrade.from.address, // The token you want to swap
        fromAddress: address, // Your wallet address
      });
    }
  }
  try {
    let receipt = await doSwap(address, amount);
    alert("Swap Complete");
  } catch (error) {
    console.log(error);
  }
}
function doSwap(userAddress, amount) {
  return Moralis.Plugins.oneInch.swap({
    chain: "bsc", // The blockchain you want to use (eth/bsc/polygon)
    fromTokenAddress: currentTrade.from.address, // The token you want to swap
    toTokenAddress: currentTrade.to.address, // The token you want to receive
    amount: amount,
    fromAddress: userAddress, // Your wallet address
    slippage: 15,
  });
}
init();
document.getElementById("modal_close").onclick = closeModal;
document.getElementById("from_token_select").onclick = () => {
  openModal("from");
};
document.getElementById("to_token_select").onclick = () => {
  openModal("to");
};
document.getElementById("login_button").onclick = login;
document.getElementById("login_button1").onclick = login1;
document.getElementById("logout_button").onclick = logOut;
document.getElementById("from_amount").onblur = getQuote;
document.getElementById("swap_button").onclick = trySwap;

And the following is the index.html

<!DOCTYPE html>

<html>
  <head>

    <meta charset="utf-8">

    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <title>My DEX</title>

    <script src="https://cdn.jsdelivr.net/npm/web3@latest/dist/web3.min.js"></script>

    <script src="https://github.com/WalletConnect/walletconnect-monorepo/releases/download/1.6.6/web3-provider.min.js"></script>

    <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>

    <script src="https://unpkg.com/moralis/dist/moralis.js"></script>

    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

    <link rel="stylesheet" href="./style.css">

  </head>

  <body>

    <nav class="navbar navbar-expand-lg navbar-light bg-light">

        <a class="navbar-brand" href="#">My DEX</a>

        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">

          <span class="navbar-toggler-icon"></span>

        </button>

     

        <div class="collapse navbar-collapse" id="navbarSupportedContent">

            <ul class="navbar-nav mr-auto">

                <li class="nav-item active">

                <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>

                </li>

            </ul>

            <button id="login_button" class="btn btn-outline-primary my-2 my-sm-0" type="submit">Login Metamask</button>

            <button id="login_button1" class="btn btn-outline-primary my-2 my-sm-0" type="submit">WalletConnect</button>

            <button id="logout_button" class="btn btn-outline-primary my-2 my-sm-0" type="submit">Logout</button>

        </div>

      </nav>

    <div class="container">

        <div class="row">

            <div class="col col-md-6 offset-md-3" id="window">

                <h4>Swap</h4>

                <div id="form">

                    <div class="swapbox">

                        <div class="swapbox_select token_select" id="from_token_select">

                            <img class="token_image" id="from_token_img">

                            <span id="from_token_text"></span>

                        </div>

                        <div class="swapbox_select">

                            <input class="number form-control" placeholder="amount" id="from_amount">

                        </div>

                    </div>

                    <div class="swapbox">

                        <div class="swapbox_select token_select"  id="to_token_select">

                            <img class="token_image" id="to_token_img">

                            <span id="to_token_text"></span>

                        </div>

                        <div class="swapbox_select">

                            <input class="number form-control" placeholder="amount" id="to_amount">

                        </div>

                    </div>

                    <div>Estimated Gas: <span id="gas_estimate"></span></div>

                    <button disabled class="btn btn-large btn-primary btn-block" id="swap_button">

                        Swap

                    </button>

                </div>

            </div>

        </div>

    </div>

    <div class="modal" id="token_modal" tabindex="-1" role="dialog">

        <div class="modal-dialog" role="document">

          <div class="modal-content">

            <div class="modal-header">

              <h5 class="modal-title">Select token</h5>

              <button id="modal_close" type="button" class="close" data-dismiss="modal" aria-label="Close">

                <span aria-hidden="true">&times;</span>

              </button>

            </div>

            <div class="modal-body">

              <div id="token_list"></div>

            </div>

          </div>

        </div>

      </div>

    <script type="text/javascript" src="./main.js"></script>

  </body>

</html>

I made this small changes:

document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "hidden") {
    window.localStorage.removeItem("WALLETCONNECT_DEEPLINK_CHOICE");
  }
});

async function init() {
  await Moralis.start({ serverUrl, appId });
  // await Moralis.enableWeb3();
  const provider = window.localStorage.walletconnect ? "walletconnect" : null;
  await Moralis.enableWeb3({ provider });

  await listAvailableTokens();
  let currentUser = Moralis.User.current();
  if (currentUser) {
    document.getElementById("swap_button").disabled = false;
    document.getElementById("address").innerText = currentUser.get(
      "ethAddress"
    );
  }
}

    <title>My DEX</title>
    <p id="address"></p>

You can try to see if there is any improvement on your side.

Hi Sir, I have tried incorporated your changes but unfortunately does not work. Can I repeat what i have tested.

  1. I am using Iphone. Instead of using the web browser in metamask. I used Safari on Iphone.
  2. After accessing the Dapp via Safari on Iphone, i clicked on “WalletConnect” and i tried with both metamask and trust wallet.
  3. I was directed to Metamask and Trust Wallet respectively to be authorized and sign. Prompted me to go back to browser in this case Safari browser on the Iphone.
  4. Once back on the browser click on list of tokens but an empty list appears.
  5. On desktop everything works well.




I’ll look again in 2-3 hours on what you have on your server.

Thank you sir for your help

It looks like this will make your tokens appear:

async function init() {
  await Moralis.start({ serverUrl, appId });
  // await Moralis.enableWeb3();
  const provider = window.localStorage.walletconnect ? "walletconnect" : null;
  //await Moralis.enableWeb3({ provider });

  await listAvailableTokens();
  let currentUser = Moralis.User.current();
  if (currentUser) {
    document.getElementById("swap_button").disabled = false;
    document.getElementById("address").innerText = currentUser.get(
      "ethAddress"
    );
  }
}

Dear Sir

Appreciate your help on this. I can see the tokens now. However I run into another issue where, I click swap and nothing happens on the iPhone safari browser when I am connected to either MetaMask or trust wallet

Hi Sir

I further tested it . Apparently after clicking swap on the Safari browser I have to manually switch back to MetaMask or trustwallet that’s where I see the confirmation for swap. Is there anyway on the browser it auto directs back to MetaMask or trustwallet without manually switching to it