Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Expo Sample App not work after updating the SDK version, send Transaction Not work with error shown #1094

Open
ram4444 opened this issue Oct 24, 2024 · 20 comments

Comments

@ram4444
Copy link

ram4444 commented Oct 24, 2024

SDK

React-Native

Provide environment information

OS: Arch Linux
Android Simulator SDK 34

MetaMask SDK Version

"@metamask/sdk-react": "^0.18.6", "^0.30.0",

MetaMask Mobile app Version

N/A

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

Expo

Describe the Bug

Here is my sample app which is working with dependencies in package,json below

"expo": "~49.0.9",
"@metamask/sdk-react": "^0.18.6",
"eciesjs": "0.3.20", <-not shown but I can find it in node module

As there is some dependency requires me to upgrade my expo to 51.0.0, so finally I start from zero and make a new project with package.json:

"expo": "^51.0.0",
"@metamask/sdk-react": "^0.30.0",
"eciesjs": "0.4.8", <-not shown but I can find it in node module

However the app no longer work with error message of

SDKConfigProvider not found or
unable to resolve @ecies/ciphers/aes from node_modules/eciesjs/dist/utils/symmetric.js

even I downgrade the eciesjs as

"expo": "^51.0.0",
"@metamask/sdk-react": "^0.30.0",
"eciesjs": "0.3.20", <-which I think it is OK with the previous setting

it is still not working

I got the same error message when I try it on the exposample app (with an updated sdk version) from
https://github.com/MetaMask/metamask-sdk/tree/main/packages/examples/expo-demo

Everything is working fine with package.json below so I don't think it is am expo issue

"expo": "^51.0.0",
"@metamask/sdk-react": "^0.18.6",
"eciesjs": "0.3.20", 

Expected Behavior

Expo can show up my app without error

Link to reproduction - Issues with a link to complete (but minimal) reproduction code will be addressed faster

No response

To Reproduce

npx expo run:android

@ram4444
Copy link
Author

ram4444 commented Oct 31, 2024

Please refer to my discussion with the ecies author @kigawas
Unable to resolve "@ecies/ciphers/aes" from "node_modules/eciesjs/dist/utils/symmetric.js" #808

@phabiulla
Copy link

Any news about this?! I'm facing the same issue..

@ram4444
Copy link
Author

ram4444 commented Nov 6, 2024

Author of ecies/cipher has a fix but the issue remains the same after I have applied it to my project package.json

@kigawas
Copy link

kigawas commented Nov 6, 2024

Any news about this?! I'm facing the same issue..

@phabiulla check this react native demo

https://github.com/ecies/js-rn-demo

@ram4444
Copy link
Author

ram4444 commented Nov 6, 2024

@kigawas sorry for any misleading to everyone. cause I am using expo example for my project and I will try to remove it using react native alone. But I think there should be some update to prove those examples from MetaMaskSDK repo are working perfectly.

@kigawas
Copy link

kigawas commented Nov 6, 2024

For expo example config.resolver.unstable_enablePackageExports=true is needed in metro.config.js

@ram4444
Copy link
Author

ram4444 commented Nov 6, 2024

@kigawas I have traced from the error log when launching the app. As the error log is showing something about ecies therefore I contacted you for a luck try. The issue may not be on your side.

My current issue is that with the old version of MetaMaskSDK, it is possible to launch the app but not able to deep link to the transaction screen using the transaction button provided (only switching to the MetaMask app) So I hope an update for MetaMaskSDK could make it works. Therefore I update the MetaMaskSDK but the result is what I have shown not able to launch the app

@ram4444
Copy link
Author

ram4444 commented Nov 7, 2024

with config.resolver.unstable_enablePackageExports=true I got the error of

 ERROR  TypeError: Cannot read property 'createHash' of undefined, js engine: hermes [Component Stack]
 ERROR  TypeError: Cannot read property 'createHash' of undefined, js engine: hermes [Component Stack]
 ERROR  TypeError: Cannot read property 'MetaMaskProvider' of undefined

This error is located at:
    in App (created by Index)
    in Index
    in Unknown (created by Route(index))
    in Suspense (created by Route(index))
    in Route (created by Route(index))
    in Route(index) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by Animated(Anonymous))
    in Animated(Anonymous) (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaProviderCompat)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator
    in Unknown (created by RootLayout)
    in RootLayout
    in Unknown (created by Route())
    in Suspense (created by Route())
    in Route (created by Route())
    in Route() (created by ContextNavigator)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by wrapper)
    in wrapper (created by ContextNavigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by ContextNavigator)
    in ContextNavigator (created by ExpoRoot)
    in ExpoRoot (created by App)
    in App (created by ErrorOverlay)
    in ErrorToastContainer (created by ErrorOverlay)
    in ErrorOverlay (created by withDevTools(ErrorOverlay))
    in withDevTools(ErrorOverlay)
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent), js engine: hermes
 ERROR  TypeError: Cannot read property 'MetaMaskProvider' of undefined

This error is located at:
    in App (created by Index)
    in Index
    in Unknown (created by Route(index))
    in Suspense (created by Route(index))
    in Route (created by Route(index))
    in Route(index) (created by SceneView)
    in StaticContainer
    in EnsureSingleNavigator (created by SceneView)
    in SceneView (created by SceneView)
    in RCTView (created by View)
    in View (created by DebugContainer)
    in DebugContainer (created by MaybeNestedStack)
    in MaybeNestedStack (created by SceneView)
    in RCTView (created by View)
    in View (created by SceneView)
    in RNSScreen (created by Animated(Anonymous))
    in Animated(Anonymous) (created by InnerScreen)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by InnerScreen)
    in InnerScreen (created by Screen)
    in Screen (created by SceneView)
    in SceneView (created by NativeStackViewInner)
    in Suspender (created by Freeze)
    in Suspense (created by Freeze)
    in Freeze (created by DelayedFreeze)
    in DelayedFreeze (created by ScreenStack)
    in RNSScreenStack (created by ScreenStack)
    in ScreenStack (created by NativeStackViewInner)
    in NativeStackViewInner (created by NativeStackView)
    in RCTView (created by View)
    in View (created by SafeAreaProviderCompat)
    in SafeAreaProviderCompat (created by NativeStackView)
    in NativeStackView (created by NativeStackNavigator)
    in PreventRemoveProvider (created by NavigationContent)
    in NavigationContent
    in Unknown (created by NativeStackNavigator)
    in NativeStackNavigator
    in Unknown (created by RootLayout)
    in RootLayout
    in Unknown (created by Route())
    in Suspense (created by Route())
    in Route (created by Route())
    in Route() (created by ContextNavigator)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by wrapper)
    in wrapper (created by ContextNavigator)
    in EnsureSingleNavigator
    in BaseNavigationContainer
    in ThemeProvider
    in NavigationContainerInner (created by ContextNavigator)
    in ContextNavigator (created by ExpoRoot)
    in ExpoRoot (created by App)
    in App (created by ErrorOverlay)
    in ErrorToastContainer (created by ErrorOverlay)
    in ErrorOverlay (created by withDevTools(ErrorOverlay))
    in withDevTools(ErrorOverlay)
    in RCTView (created by View)
    in View (created by AppContainer)
    in RCTView (created by View)
    in View (created by AppContainer)
    in AppContainer
    in main(RootComponent), js engine: hermes

@Apcozar
Copy link

Apcozar commented Nov 7, 2024

I´m working on a project and faced the same issue, I struggled trying multiple things, but this was the one working. Idk if i´m using best practices here but this solved my problems:
Here for app/_layout.tsx:

import 'node-libs-expo/globals';
import 'react-native-url-polyfill/auto';
import 'react-native-get-random-values';

import { MetaMaskProvider } from "@metamask/sdk-react";
import { Stack } from "expo-router";
import { Linking } from "react-native";

export default function RootLayout() {
  return (
    <MetaMaskProvider
      sdkOptions={{
        dappMetadata: {
          name: 'yourapp',
          url: 'yourappurl',
        },
        openDeeplink: (link) => {
          Linking.openURL(link);
        }
      }}
    >
      <Stack>
        <Stack.Screen name="index" />
        <Stack.Screen name="home" />
      </Stack>
    </MetaMaskProvider>
  );
}

This for the login button index.tsx:

import React from 'react';
import { View, Button } from 'react-native';
import { useRouter } from 'expo-router';
import { useSDK } from '@metamask/sdk-react';


export default function LoginScreen() {
  const router = useRouter();
  const { provider } = useSDK();
 
  const handleLogin = async () => {
    try {

      if (!provider) {
        console.error('Provider not available');
        return;
      }

      const accounts = await provider.request({ method: 'eth_requestAccounts' }) as string[];
      console.log(accounts);
      if (accounts && accounts.length > 0) {
        router.push({
          pathname: './home',
          params: { account: accounts[0] },
        });
      }
    } catch (error) {
      console.error('Error connecting with metamask:', error);
    }
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="Conectar con MetaMask" onPress={handleLogin} />
    </View>
  );
}

And my metro.config.js:

// Learn more https://docs.expo.io/guides/customizing-metro
const { getDefaultConfig } = require('expo/metro-config');

/** @type {import('expo/metro-config').MetroConfig} */
const config = getDefaultConfig(__dirname);

config.resolver.extraNodeModules = {
    ...require('node-libs-expo'),
    crypto: require.resolve('crypto-browserify'),
};

module.exports = config;

Using:
"@metamask/sdk-react": "^0.30.0",
"expo": "~51.0.28",

If you have any suggestion to improve my code, I will appreciate. Hope I´m helping someone!

@ram4444
Copy link
Author

ram4444 commented Nov 7, 2024

@Apcozar
@kigawas

Using the package.json dependency from @Apcozar I still got the message of
Unable to resolve "@ecies/ciphers/aes" from "node_modules/eciesjs/dist/utils/symmetric.js"

However after
npm uninstall eciesjs
I can confirm everythings works fine.

Anyway thanks for your help but I think the example code should have a update since I was starting from v0.18.6 and those demo apps RNonly/expo both have come differences in code and also config. Quite frustrated by trying everything out by guess & luck for days and days

Last question May I know I should use
yarn add / npm install / expo add
for adding new dependencies to React Native Project?

@ram4444
Copy link
Author

ram4444 commented Nov 8, 2024

After I have a try on updating @metamask/sdk to 0.30.2 as I notice there is an dependency update on eciesjs under @metamask/sdk-communication-layer, the app cannot be launched again any more

image

what I can do is

  1. turn it back to the backed-up package-lock.json
  2. yarn install
  3. npm uninstall eciesjs

to make it works again.
I can just launched the app,deeplink to the transaction screen but not sure there will be any issue for further steps
npm is a nightmare at all

@kigawas
Copy link

kigawas commented Nov 8, 2024

I recommend metamask/sdk to bump its dependency to use eciesjs v0.4, which is more multi platform friendly. You only need to polyfill Buffer (for React Native crypto.getRandomValues is also needed)

@ram4444
Copy link
Author

ram4444 commented Nov 8, 2024

@kigawas
image
image
the recent update has the latest eciesjs
but it will show up error
"@ecies/ciphers/aes" from "node_modules/eciesjs/dist/utils/symmetric.js"

and after adding
config.resolver.unstable_enablePackageExports=true
the error comes to

image

I think the unstable_enablePackageExports alter the other common dependencies behaviors
like axios which is very common
image

so i dont think it is a good way to add that line in metro config + the previous trick no longer works

@kigawas
Copy link

kigawas commented Nov 8, 2024

axios is very problematic, can you use undici instead?

@ram4444
Copy link
Author

ram4444 commented Nov 8, 2024

axios is very problematic, can you use undici instead?

After removing axios
with config.resolver.unstable_enablePackageExports=true
it is ok.

But how come it will make you a conclusion that axios is problematic I wanna know cause It is a common tools for http request. How about the other choices?

update:
with @metamask/sdk v0.30.2
pressing sendTransaction in the sample app shows error (which did not happened in 0.30.0)
[TypeError: v.persistAccounts is not a function (it is undefined)]

@kigawas
Copy link

kigawas commented Nov 9, 2024

Many common npm libraries are already outdated and full of glitches like axios, webpack, jest etc.

axios is common because it's old, now you should just use fetch api. If you need performance or other functionality like proxy agent, use undici

@ram4444
Copy link
Author

ram4444 commented Nov 9, 2024

seems undici is not working on react native proj and I am now using the build-in fetch instead
but once everythings works fine last night, it turns to back to error today.
Extremely frustrated by the dependency issue

@ram4444 ram4444 changed the title [Bug]: Expo Sample App not work after updating the SDK version [Bug]: Expo Sample App not work after updating the SDK version, send Transaction Not work with error shown Nov 9, 2024
@kigawas
Copy link

kigawas commented Nov 9, 2024

You can pin metamask sdk version to 0.30.0

@ram4444
Copy link
Author

ram4444 commented Nov 9, 2024

After deleting of node_modules, yarn install, and changed back to index.tsx recommend by @Apcozar
I can make it works in [email protected]
app is launch-able in android simulator
sendTransaction in the demo screen is able to switch to metamask app and trigger a transaction.

but I don't recommend to close this issue cause error messages
ERROR RemoteCommunication::on "wallet_init" -- error [TypeError: r.persistAccounts is not a function (it is undefined)]
[TypeError: v.persistAccounts is not a function (it is undefined)]
will be shown in some cases randomly.

I am afraid to tell this js lib metamask-sdk is still very buggy in react-native environment when some major library like react-native, expo is being updated in the future as well as the metamask app itself.

Thanks @kigawas for assist

@Apcozar
Copy link

Apcozar commented Nov 10, 2024

Hi everyone, I just found this way of connecting wallets to my app. Really helpful and smooth: https://docs.reown.com/appkit/overview It´s from walletconnetc. @ram4444

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants