2

I have a weird bug, which happens only on Android in Trust Wallet. My dApp requires the user to sign the message, but after reports, I found out this happens only for Android. I tried multiple devices and multiple wallets. For example, metamask worked in every condition I tried.

What I'm using:

How to reproduce:

  1. Open the demo website https://react-wagmi-walletconnect.vercel.app/ on your desktop computer (doesn't matter which browser)
  2. Click Connect Wallet
  3. Scan the QR code with the Trust Wallet on your Android device
  4. Click any of the "sign" buttons on the demo
  5. You will see a log with "mutate" - this is the event called from wagmi, which is called whenever a sign is invoked
  6. In your wallet either sign the message or decline it, but no event will happen on the website.

Note: sometimes (mostly when calling multiple times or trying again), the success event is called, and everything works as it should. I recommend to first disconnect and connect later to reproduce the bug.

Now try this exact method with an iOS device or a different wallet (such as metamask) and the success event "will happen".

The demo is followed by the docs found here: https://docs.walletconnect.com/2.0/web3modal/react/installation

I'm really not sure, where is the problem - is it wagmi (wrong parse of the trust events), walletconnect (maybe problem with deeplinking the trust), or trust wallet itself? Help me find the cause so I can connect with their developers and fix the issue. If you ever run into this problem before, please, describe your fix even if it's an old answer.

This is my "wallet context" which contains setup code for wagmi and walletconnect:

import React, { useEffect, useState } from 'react';
import { EthereumClient, w3mConnectors, w3mProvider } from '@web3modal/ethereum';
import { Web3Modal } from '@web3modal/react';
import { configureChains, createClient, WagmiConfig } from 'wagmi';
import { bsc } from 'wagmi/chains';
import { publicProvider } from 'wagmi/providers/public';

const chains = [bsc];
const projectId = import.meta.env.VITE_WALLET_CONNECT_KEY || '';

// Wagmi provider
const { provider } = configureChains(chains, [
    publicProvider({
        stallTimeout: 1000,
    }),
    w3mProvider({ projectId }),
]);

// Wagmi client
const wagmiClient = createClient({
    autoConnect: true,
    connectors: w3mConnectors({ projectId, version: 1, chains }),
    provider,
});

// Web3Modal Ethereum Client
const ethereumClient = new EthereumClient(wagmiClient, chains);

export function WalletProvider({ children }) {
    return <>
        <WagmiConfig client={wagmiClient}>
            {children}
        </WagmiConfig>

        <Web3Modal projectId={projectId} ethereumClient={ethereumClient} themeMode="dark" />
    </>;
}

And this is the demo code (full source code can be found on the demo website):

import React, { useState, useEffect } from 'react';
import { Web3Button } from '@web3modal/react';
import { useSignMessage } from 'wagmi';
import { signMessage } from '@wagmi/core';

export default function App() {
    ...

    const wagmiSign = useSignMessage({
        onSuccess(...args) {
            log('sign SYNC success:', ...args);
        },
        onError(...args) {
            log('sign SYNC error:', ...args);
        },
        onMutate(...args) {
            log('sign mutate:', ...args);
        },
        onSettled(...args) {
            log('sign settled:', ...args);
        },
    });

    const signMessageAsync = () => {
        wagmiSign.signMessageAsync({
            message: 'Custom async message',
        }).then((...args) => {
            log('sign ASYNC success:', ...args);
        }).catch((...args) => {
            log('sign ASYNC error:', ...args);
        });
    };

    const signMessageSync = () => {
        wagmiSign.signMessage({
            message: 'Custom sync message',
        });
    };

    ...

    return <>
        ...

        <h2>2. Try sign</h2>
        <div className="buttons">
            <button onClick={signMessageAsync}>Sign asynchronous</button>
            <button onClick={signMessageSync}>Sign synchronous</button>
            <button onClick={signMessageCore}>Sign through @wagmi/core</button>
        </div>

        ...
    </>;
}
Patrik Krehák
  • 2,595
  • 8
  • 32
  • 62

1 Answers1

0

Have you tried deeplinking with your dapp? here is an example :

 <Web3Modal
    projectId={projectId} 
    ethereumClient={ethereumClient} 
    themeMode="dark"
    mobileWallets={[
      {
        id: 'metaMask',
        name: 'Metamask',
        links: {
          native: 'metamask://',
          universal: `https://metamask.app.link/dapp/${your_url}`,
        },
      },
      {
        id: 'trust',
        name: 'Trust Wallet',
        links: {
          native: `trust://open_url?coin_id=${coin_id}&url=${your_url}`,
        },
      },
      {
        id: 'rainbow',
        name: 'Rainbow',
        links: { native: 'rainbow://', universal: 'https://rainbow.me' },
      },
      {
        id: 'zerion',
        name: 'Zerion',
        links: {
          native: 'zerion://',
          universal: 'https://wallet.zerion.io',
        },
      },
      {
        id: 'tokenary',
        name: 'Tokenary',
        links: { native: 'tokenary://', universal: 'https://tokenary.io' },
      },
    ]}
  />
Sepanta
  • 91
  • 5