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

Here is a better alternative to rn-nodeify #753

Closed
cdiddy77 opened this issue Feb 8, 2022 · 26 comments
Closed

Here is a better alternative to rn-nodeify #753

cdiddy77 opened this issue Feb 8, 2022 · 26 comments
Labels
env: react-native type: dependencies Pull requests that update a dependency file

Comments

@cdiddy77
Copy link

cdiddy77 commented Feb 8, 2022

At the beginning of the quick start for Dapps (React Native) it proposes that folks use npx rn-nodeify --install --hack. This is problematic for a couple of reasons:

  1. It doesn't appear to work. I was not able to get it to work despite much effort. I finally gave up after applying sed hacks and many rm -rf node_mdules and pod installs.
  2. It's an ugly hack. (See rn-nodeify author's remarks). Not that co-opting the bundler to replace all your nodejs modules is not a hack, but at least its a hack that more or less the entire web dev world depends on. And even if rn-nodeify did work, it has consequences and is fragile.

Here is a better way:

Use the new metro bundler to do essentially what browserfy and webpack do. Here's how I got it to work:

In package.json:

  "dependencies": {
    . . . 
    "@react-native-async-storage/async-storage": "^1.15.17",
    "@walletconnect/react-native-dapp": "^1.7.1",
    "react-native-qrcode-svg": "6.0.6",
    "react-native-randombytes": "^3.6.1",
    "react-native-svg": "9.6.4"
  },
  "devDependencies": {
    . . . 
    "node-libs-react-native": "^1.2.1",
  },

The various react-native* deps are because even though new RN is good about having pod install take care of installing pods for native modules, it doesn't detect second- and greater order native deps. Note the specific versions. These are the versions that @WalletConnect transitively requires. Blindly doing npm install -s react-native-svg for example will result in 2 versions of the SVG package being brought in, which results in a crash at startup.

The important one is the devDependency for node-libs-react-native

Next, create or edit metro.config.js :

module.exports = {
  resolver: {
    extraNodeModules: require("node-libs-react-native")
  },
  . . . 
};

This is the magic: It says: hey, metro, if you see, oh, say import * from "crypto"; and you can't find crypto, go ask node-libs-react-native, which then hooks up react-native-crypto.

There's one more little step, which is that Node.js modules often depend on certain globals. You hook these up by adding:

require("node-libs-react-native/globals.js");
 . . . 

at the top of index.js

It was just about that simple. I would strongly encourage to update the documentation for this amazing codebase and enable more folks to get it working faster. rn-nodeify is really an abominable hack, and whereas a better cleaner solution exists, now that the metro bundler has become sufficiently enhanced.

@giovanni-caiazzo
Copy link

Hi! This is great, however how can WalletConnect be used alongside ethers?
The other project @walletconnect/web3-provider exposes the provider that can be digested by ethers, but this one does not... The rpcUrl field in the connector property is empty and so I can't use that as well and @walletconnect/web3-provider is not usable in a react native project even with this awesome solution. I'm stumped, can anyone help me?

@giovanni-caiazzo
Copy link

Hi! This is great, however how can WalletConnect be used alongside ethers? The other project @walletconnect/web3-provider exposes the provider that can be digested by ethers, but this one does not... The rpcUrl field in the connector property is empty and so I can't use that as well and @walletconnect/web3-provider is not usable in a react native project even with this awesome solution. I'm stumped, can anyone help me?

I found a solution. @walletconnect/web3-provider must be used together with @walletconnect/react-native-dapp so that you can set (example for BSC chain):

const provider = new WalletConnectProvider({
        rpc: {
            56: 'https://bsc-dataseed1.binance.org:443',
        },
        chainId: 56,
        connector: connector,
        qrcode: false,
    });
    ```
where `connector` is the instance passed by `@walletconnect/react-native-dapp` and `qrcode: false` is needed because otherwise it tries to call window.document.

Also for expo users: unfortunately to get walletconnect working on Android 11+ you need at least to `expo prebuild` to add 
``` Otherwise your app can't see which apps are installed that support wallet connect and can't also send websocket requests (this last part I am not too sure, but at least you need the wc intent)

@gate3
Copy link

gate3 commented Feb 19, 2022

@cdiddy77 thank you for the alternative its absolutely necessary. However I ran into another issue, actually a recurring one, I keep getting this error

null is not an object(evaluating 'RNRandomBytes.seed')

Any clues on how to solve this will be greatly appreciated

@cdiddy77
Copy link
Author

I don't think that I saw this one. If you think it's related to your dependencies, I might check the versions of what you have in your package.json with what is in other deps. 'Yarn why' is your friend.

@gate3
Copy link

gate3 commented Feb 20, 2022

Thank @cdiddy77 .. used yarn why and I think the issue is coming from the wallet connect crypto library. I've followed your setup a few times and still get exactly thesame result. I can push a copy of my code if you have the time to take a look.

@cdiddy77
Copy link
Author

Happy to take a look

@gate3
Copy link

gate3 commented Feb 21, 2022

Thank you.. here is a codesandbox https://codesandbox.io/s/l2pnn5

@gate3
Copy link

gate3 commented Feb 21, 2022

Happy to take a look

Thank you @cdiddy77 .. this works now. Apparently it can only work in a project with native module capability. I tried it using the bare workflow from expo and it works great. Thanks once again

@andiskim
Copy link

At the beginning of the quick start for Dapps (React Native) it proposes that folks use npx rn-nodeify --install --hack. This is problematic for a couple of reasons:

  1. It doesn't appear to work. I was not able to get it to work despite much effort. I finally gave up after applying sed hacks and many rm -rf node_mdules and pod installs.
  2. It's an ugly hack. (See rn-nodeify author's remarks). Not that co-opting the bundler to replace all your nodejs modules is not a hack, but at least its a hack that more or less the entire web dev world depends on. And even if rn-nodeify did work, it has consequences and is fragile.

Here is a better way:

Use the new metro bundler to do essentially what browserfy and webpack do. Here's how I got it to work:

In package.json:

  "dependencies": {
    . . . 
    "@react-native-async-storage/async-storage": "^1.15.17",
    "@walletconnect/react-native-dapp": "^1.7.1",
    "react-native-qrcode-svg": "6.0.6",
    "react-native-randombytes": "^3.6.1",
    "react-native-svg": "9.6.4"
  },
  "devDependencies": {
    . . . 
    "node-libs-react-native": "^1.2.1",
  },

The various react-native* deps are because even though new RN is good about having pod install take care of installing pods for native modules, it doesn't detect second- and greater order native deps. Note the specific versions. These are the versions that @WalletConnect transitively requires. Blindly doing npm install -s react-native-svg for example will result in 2 versions of the SVG package being brought in, which results in a crash at startup.

The important one is the devDependency for node-libs-react-native

Next, create or edit metro.config.js :

module.exports = {
  resolver: {
    extraNodeModules: require("node-libs-react-native")
  },
  . . . 
};

This is the magic: It says: hey, metro, if you see, oh, say import * from "crypto"; and you can't find crypto, go ask node-libs-react-native, which then hooks up react-native-crypto.

There's one more little step, which is that Node.js modules often depend on certain globals. You hook these up by adding:

require("node-libs-react-native/globals.js");
 . . . 

at the top of index.js

It was just about that simple. I would strongly encourage to update the documentation for this amazing codebase and enable more folks to get it working faster. rn-nodeify is really an abominable hack, and whereas a better cleaner solution exists, now that the metro bundler has become sufficiently enhanced.

THANK YOU! it works

@emzet93
Copy link

emzet93 commented Mar 1, 2022

@cdiddy77 thanks! I love your approach! rn-nodeify really seems like a huge hack and it brings a lot of issues with build and create mess in project dependencies.

I tried your method and it seems to work - app is building, launching and I'm able to connect with my metamask wallet. However, I faced some other issues and I'm wondering if any of them sounds familiar:

  1. There are some problems with AsyncStorage - I'm able to connect to my wallet and I can see that all data is saved properly in AsyncStorage. However, after killing the app, the data is not rehydrated and connector.connected points to false.
  2. Connecting to wallet works properly in debug mode on iOS. But when I change scheme to release, executing connector.connect() results with getBrowerCrypto().getRandomValues is not a function error. So it looks like it's not able to resolve crypto package or sth
  3. I'm not able to disconnect the wallet - executing connector.killSession() throws TypeError: this._formatRequest is not a function

+1 to add this process in documantation

EDIT
My bad, I didn't configure metro.config.js properly - extraNodeModules was overridden by sth else.
So now 1 and 2 issues described above are gone and works as expected 🎉

There is still this issue with disconnecting the wallet, but I faced it even before when using rn-nodeify, so I beleive it's not connected with your soultion

@heymage
Copy link

heymage commented Mar 4, 2022

@gate3 What was the change that worked for you in the end regarding the null is not an object(evaluating 'RNRandomBytes.seed') error? I have the same issue and had a look at your code sandbox, but I don't get it to work :(

@gate3
Copy link

gate3 commented Mar 6, 2022

@gate3 What was the change that worked for you in the end regarding the null is not an object(evaluating 'RNRandomBytes.seed') error? I have the same issue and had a look at your code sandbox, but I don't get it to work :(

hi @mrcgrhrdt in my case I had two issues:

  1. I was using an expo project that was just a Js project without native app capabilities. If this is the same for you I will advice you eject or you create a new app with the bare workflow.

  2. I didn't configure the metro.config.js file properly. Here is what it looks like for me now in my non-expo app

extraNodeModules: modules.reduce(
      (acc, name) => {
        acc[name] = path.join(__dirname, 'node_modules', name);
        return acc;
      },
      { ...require('node-libs-react-native') }
    ),

Basically just make sure to spread the require('node-libs-react-native') in an object along with whatever was in extraModules before.

@bkrem bkrem added type: dependencies Pull requests that update a dependency file env: react-native labels Mar 31, 2022
@Cancuuu
Copy link

Cancuuu commented May 10, 2022

image

im facing that issue, i do this steps #753 (comment) and put the "require("node-libs-react-native/globals.js");" in App.js (im using Expo) and then the other instructions of quick start for Dapps (React Native).

@gate3
Copy link

gate3 commented May 11, 2022

image

im facing that issue, i do this steps #753 (comment) and put the "require("node-libs-react-native/globals.js");" in App.js (im using Expo) and then the other instructions of quick start for Dapps (React Native).

Hi @Cancuuu is this a managed expo app or a bare workflow expo app. From my experience i don't think the managed expo app works for this use case. And if its a barebones app, try uploading the repo and sharing a link, I can help take a look.

Apologies for misleading here, it works.. I will post a project once i bootstrap it.

@Cancuuu
Copy link

Cancuuu commented May 11, 2022

image
im facing that issue, i do this steps #753 (comment) and put the "require("node-libs-react-native/globals.js");" in App.js (im using Expo) and then the other instructions of quick start for Dapps (React Native).

Hi @Cancuuu is this a managed expo app or a bare workflow expo app. From my experience i don't think the managed expo app works for this use case. And if its a barebones app, try uploading the repo and sharing a link, I can help take a look.

Thank you so much gate! the repo is private rn, but I will send it to you asap when it becomes public 😉

@walidsahli
Copy link

@emzet93 i got the same issue as you
I'm not able to disconnect the wallet - executing connector.killSession() throws TypeError: this._formatRequest is not a function
i solve it by
image
and using connector.killSession() instead

@emzet93
Copy link

emzet93 commented May 19, 2022

@walidsahli yeah exactly. I think this is caused by using this inside of those methods and destructing object properties just causes loosing context.

@Abubakar672
Copy link

Hey everyone i am facing this error can some one help me out in this. I have tired alot of methods but none of them work, Do anyone of you know the solution to this.
Screen Shot 2022-05-24 at 7 16 36 PM
Screen Shot 2022-05-24 at 7 16 44 PM

@linxianxi
Copy link

linxianxi commented May 31, 2022

@gate3null is not an object(evaluating 'RNRandomBytes.seed')关于错误,最终对您有用的更改是什么?我有同样的问题,并查看了您的代码沙箱,但我没有让它工作:(

It works for me

npm i crypto-browserify stream-browserify

and

extraNodeModules: {
      ...require('node-libs-react-native'),
      crypto: require.resolve('crypto-browserify'),
      stream: require.resolve('stream-browserify'),
    },

@gate3
Copy link

gate3 commented May 31, 2022

Just putting this here in case anybody needs it.. its bootstrapped and ready to go. Already has walletConnect and ethersjs installed.

Bare Workflow https://github.com/weedle-app/weedle-expo-bare-workflow

Managed Workflow https://github.com/weedle-app/weedle-expo-managed-workflow

keithluchtel added a commit to functionland/fx-components that referenced this issue Jun 18, 2022
Initial setup for adding WalletConnect and its dependencies. Also
adds a button to the Box app to initiate connecting to a wallet.
Followed setup instruction outlined here:

https://docs.walletconnect.com/quick-start/dapps/react-native

One difference however, is instead of npx rn-nodeify --install --hack,
I followed the setup outlined here:

WalletConnect/walletconnect-monorepo#753 (comment)

This commit also removes the Jest test temporarily until I can come
back later and adjust configs to get things passing again.
@jtculbreth
Copy link

@cdiddy77 thanks! I love your approach! rn-nodeify really seems like a huge hack and it brings a lot of issues with build and create mess in project dependencies.

I tried your method and it seems to work - app is building, launching and I'm able to connect with my metamask wallet. However, I faced some other issues and I'm wondering if any of them sounds familiar:

  1. There are some problems with AsyncStorage - I'm able to connect to my wallet and I can see that all data is saved properly in AsyncStorage. However, after killing the app, the data is not rehydrated and connector.connected points to false.
  2. Connecting to wallet works properly in debug mode on iOS. But when I change scheme to release, executing connector.connect() results with getBrowerCrypto().getRandomValues is not a function error. So it looks like it's not able to resolve crypto package or sth
  3. I'm not able to disconnect the wallet - executing connector.killSession() throws TypeError: this._formatRequest is not a function

+1 to add this process in documantation

EDIT My bad, I didn't configure metro.config.js properly - extraNodeModules was overridden by sth else. So now 1 and 2 issues described above are gone and works as expected 🎉

There is still this issue with disconnecting the wallet, but I faced it even before when using rn-nodeify, so I beleive it's not connected with your soultion

Is the function "getBrowerCrypto" misspelled?

@aindong
Copy link

aindong commented Sep 6, 2022

Just putting this here in case anybody needs it.. its bootstrapped and ready to go. Already has walletConnect and ethersjs installed.

Bare Workflow https://github.com/weedle-app/weedle-expo-bare-workflow

Managed Workflow https://github.com/weedle-app/weedle-expo-managed-workflow

Thank you @gate3 this is the best solution reference to follow :)

@aditya172926
Copy link

I followed your steps and the app is building successfully on android device.
But when I click on connect wallet I get this warning on react native

Error: Secure random number generation is not supported by this browser.
Use Chrome, Firefox or Internet Explorer 11

@gate3

@finessevanes
Copy link
Contributor

@cdiddy77 thank you for your feedback and contribution! Since we are putting in all of our efforts into v2, I'm going to close this issue since it's a documentation update request for v1.

@drattansingh
Copy link

I followed all your steps in my react.js project however when I run it, the URL is incorrectly displaying as: https://localhost:3000/[object%20Object]

Any ideas?

@Count-Monte
Copy link

Hi @cdiddy77
In my latest project, I am using react-native-chart-kit and it requires react-native-svg@13.4.0, but this @walletconnect/react-native-dapp only supports 9.6.4 version. So it says "Tried to register two views with the same name RNSVGRect"
Could you please help me fix this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
env: react-native type: dependencies Pull requests that update a dependency file
Projects
None yet
Development

No branches or pull requests