WalletConnect / walletconnect-monorepo

WalletConnect Monorepo
Apache License 2.0
1.46k stars 714 forks source link

await universalProvider.connect never completes its Promise #2060

Closed DJilanov closed 1 year ago

DJilanov commented 1 year ago

Describe the bug Once we fire the "connect" method of the '@walletconnect/universal-provider', the promise is never completed and there are no errors into the terminal

SDK Version (if relevant)

To Reproduce Code snipped to reproduce the behavior:

//App.tsx
import 'react-native-gesture-handler';
import '@ethersproject/shims';
import "@walletconnect/react-native-compat";
import { Assets } from '@react-navigation/elements';
import { registerRootComponent } from 'expo';
import { Asset } from 'expo-asset';
import './shim.js'

import App from './src/index';

Asset.loadAsync(Assets);

registerRootComponent(App);
// hook.tsx
import 'react-native-get-random-values';
import '@ethersproject/shims';
import {ethers} from 'ethers';

import {useCallback, useEffect, useState} from 'react';
import {
  createUniversalProvider,
  universalProvider,
} from '../Utils/UniversalProvider';

export let web3Provider: ethers.providers.Web3Provider;

export default function useInitialization() {
  const [initialized, setInitialized] = useState(false);

  const onInitialize = useCallback(async () => {
    try {
      await createUniversalProvider();
      web3Provider = new ethers.providers.Web3Provider(universalProvider);
      setInitialized(true);
    } catch (err: unknown) {
      console.log('Error for initializing', err);
    }
  }, []);

  useEffect(() => {
    if (!initialized) {
      onInitialize();
    }
  }, [initialized, onInitialize]);

  return initialized;
}
// Provider.tsx
import UniversalProvider from '@walletconnect/universal-provider';

// @ts-expect-error - `@env` is a virtualised module via Babel config.
import {ENV_PROJECT_ID, ENV_RELAY_URL} from '@env';

export let universalProvider;
export let currentWCURI;
export let universalProviderSession;

export async function createUniversalProvider() {
  console.log('[CONFIG] ENV_PROJECT_ID:', ENV_PROJECT_ID);
  console.log('[CONFIG] ENV_RELAY_URL:', ENV_RELAY_URL);

  try {
    universalProvider = await UniversalProvider.init({
      logger: 'info',
      relayUrl: ENV_RELAY_URL,
      projectId: ENV_PROJECT_ID,
      metadata: {
        name: 'React Native V2 dApp',
        description: 'RN dApp by WalletConnect',
        url: 'https://walletconnect.com/',
        icons: ['https://avatars.githubusercontent.com/u/37784886'],
      },
    });

    universalProvider.on('display_uri', uri => {
      currentWCURI = uri;
      console.log('UniversalProvider display_uri event:', uri);
    });

    // Subscribe to session ping
    universalProvider.on('session_ping', ({id, topic}) => {
      console.log('session_ping', id, topic);
    });

    // Subscribe to session event
    universalProvider.on('session_event', ({event, chainId}) => {
      console.log('session_event', event, chainId);
    });

    // Subscribe to session update
    universalProvider.on('session_update', ({topic, params}) => {
      console.log('session_update', topic, params);
    });

    // Subscribe to session delete
    universalProvider.on('session_delete', ({id, topic}) => {
      console.log('session_delete', id, topic);
    });

    console.log('Hits the log before await');

    universalProviderSession = await universalProvider.connect({
      namespaces: {
        eip155: {
          methods: [
            'eth_sendTransaction',
            'eth_signTransaction',
            'eth_sign',
            'personal_sign',
            'eth_signTypedData',
          ],
          chains: ['eip155:1'],
          events: ['chainChanged', 'accountsChanged'],
          rpcMap: {
            80001: "https://rpc.walletconnect.com?chainId=eip155:80001&projectId=${ENV_PROJECT_ID}",
          },
        },
      },
    });
    console.log('Never returns from the await');
  } catch {
    console.log('Error for connecting');
  }
}

All of the logs I got

 INFO  {"context": "core"} {"context": "core/relayer"} {"context": "core/relayer/subscription"} Emitting subscription_deleted
 INFO  {"context": "core"} {"context": "core/expirer"} Emitting expirer_deleted
 INFO  {"context": "core"} Core Initialization Success
 INFO  {"context": "core"} {"context": "core/expirer"} Emitting expirer_deleted
 INFO  {"context": "client"} SignClient Initialization Success
 INFO  Cleaning up inactive pairings...
 INFO  Inactive pairings cleared: 0
 INFO  {"context": "core"} {"context": "core/relayer"} {"context": "core/relayer/subscription"} Emitting subscription_created
 INFO  {"context": "core"} {"context": "core/expirer"} Emitting expirer_created
 INFO  {"context": "core"} {"context": "core/history"} Emitting history_created
 INFO  {"context": "core"} {"context": "core/expirer"} Emitting expirer_created
 LOG  UniversalProvider display_uri event: wc:88673605c93234ff67954cfb7f8d549c0461462a166de5383d1534881a54774f@2?relay-protocol=irn&symKey=68e82db1add14cfbfdcf26c41390fac1b0336005923a3f8b36fee21f87c90d42

Expected behavior The method to finish its promise and return <SessionTypes.Struct | undefined>. If needed i can prepare a demo app that reproduces the problem.

Smartphone (please complete the following information):

ganchoradkov commented 1 year ago

Hey @DJilanov, the provider.connect resolves when a session is created. From the code snippet, I'm seeing you're already listening to display_uri so when this event is emitted, you should use that URI to pair with a wallet. Once the session is approved, the .connect will resolve with it.