node-libs-react-native icon indicating copy to clipboard operation
node-libs-react-native copied to clipboard

TypeError:null is not an object(evaluating 'RNRdandomBytes.seed')

Open leeeverest opened this issue 5 years ago • 13 comments

Error:Requiring module "node_modules\react-native-crypto\index.js",which threw an exception:TypeError:null is not an object(evaluating 'RNRdandomBytes.seed')

leeeverest avatar Dec 25 '19 02:12 leeeverest

I have the same issue, but there's a small typo in the text @leeeverest included in the issue name and description:

RNRdandomBytes.seed -> RNRandomBytes.seed

pcowgill avatar Dec 30 '19 21:12 pcowgill

The advice to get RNRandomBytes working seems to be that you should link the react native package react-native-randombytes (a peer dep of react-native-crypto) (see the docs here).

Of course, if your project doesn't need a shim for the crypto node core module, leaving the crypto polyfill out in your metro.config.js is a better solution than doing a react-native link, especially now that autolinking is the new way of doing things.

const nodelibs = require("node-libs-react-native");

nodelibs.crypto = null;

module.exports = {
  resolver: {
    extraNodeModules: nodelibs
  }
};

pcowgill avatar Dec 30 '19 21:12 pcowgill

Perhaps we should remove this polyfill and just mention it in the docs instead of automatically including it since it requires a manual build. This has been my strategy with other modules that require react-native link: https://github.com/parshap/node-libs-react-native#other-react-native-modules

parshap avatar Dec 30 '19 22:12 parshap

@parshap Yep, that seems like a good change to make!

pcowgill avatar Dec 30 '19 22:12 pcowgill

Sorry for the typo @pcowgill ,i try react-native link ,but it did't work(EXPO bare flow,SDK 36,RN version 0.61.4),using react-native-crypto-js instead,it works,my fork: https://github.com/leeeverest/node-libs-react-native @parshap

leeeverest avatar Dec 31 '19 01:12 leeeverest

@leeeverest Thanks for the updated. You might want to update the README in your fork too to reflect the library you're using now.

Looks like the package you're using instead, react-native-crypto-js, doesn't have many crypto functions implemented. I guess it covered the ones you needed to use for your app?

pcowgill avatar Dec 31 '19 18:12 pcowgill

No,you are exactly right! @pcowgill ,i need ecdsa-secp256k1 or ed25519 algorithm,but this package didn't have these functions,i got new error in my app:not implemented yet,so sad.

leeeverest avatar Jan 01 '20 10:01 leeeverest

@leeeverest did you ever get it to work? I'm encountering the same issue.

noahhayespluto avatar Apr 07 '20 23:04 noahhayespluto

If I understand correctly, the react-native-crypto & react-native-randombytes require rn-nodeify to work. Because there is a require('crypto') in their code. This will lead to require cycle error. But we want to avoid rn-nodeify.

I end up a solution making custom crypto.js file within my app.

The only function I need for my crypto is randomBytes function which return a Buffer, and I need a native implementation without resulting require cycle error. This looks like what I need.

yarn add react-native-get-random-values
// metro.config.js
const nodelibs = require("node-libs-react-native");

nodelibs.crypto = `${__dirname}/src/crypto.js`;

module.exports = {
  resolver: {
    extraNodeModules: nodelibs,
  },
};
// src/crypto.js
'use strict'
import { Buffer } from 'buffer';
const { NativeModules } = require('react-native');

const randomBytes = (size) => {
  if (NativeModules.RNGetRandomValues) {
    return Buffer(NativeModules.RNGetRandomValues.getRandomBase64(size));
  } else {
    throw new Error('Native module not found')
  }
};

exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes;

This solves my need for crypto module. Until there is a 100% compatible crypto package for React Native.

quybeans avatar Jun 20 '21 10:06 quybeans

Following @quybeans suggestion and code, I was able to patch the react-native-crypto package, replacing the randomBytes function, removing all require cycles and still having all the react-native-crypto functions by doing the following:

  • Add react-native-get-random-values and patch-package package:
$ yarn add react-native-get-random-values patch-package
  • Create a patches directory in your project root to patch react-native-crypto using patch-package.
  • Create a file in the patches directory name react-native-crypto+2.2.0.patch. Note that the 2.2.0 depends on your react-native-crypto version, so the patch might not work if you have a different version. But this should be due to differences like new lines, spaces etc which can manually correct.
  • Add the following contents to the file
diff --git a/node_modules/react-native-crypto/index.js b/node_modules/react-native-crypto/index.js
index f644543..e2ff55a 100644
--- a/node_modules/react-native-crypto/index.js
+++ b/node_modules/react-native-crypto/index.js
@@ -1,7 +1,17 @@
 'use strict'
 
-import { randomBytes } from 'react-native-randombytes'
-exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes
+import { Buffer } from 'buffer';
+const { NativeModules } = require('react-native');
+
+const randomBytes = (size) => {
+  if (NativeModules.RNGetRandomValues) {
+    return Buffer(NativeModules.RNGetRandomValues.getRandomBase64(size));
+  } else {
+    throw new Error('Native module not found')
+  }
+};
+
+exports.randomBytes = exports.rng = exports.pseudoRandomBytes = exports.prng = randomBytes;
 
 // implement window.getRandomValues(), for packages that rely on it
 if (typeof window === 'object') {
  • Finally run
$ yarn patch-package
  • Also add a postinstall script to you package.json so the changes are re-applied after you install other packages
"scripts": {
// other scripts
"postinstall": "patch-package"
}

jfamousket avatar Feb 09 '22 16:02 jfamousket

Here is a package written for Expo projects, which fixed this issue for me. I have been running into this issue for some time now, but following the instructions to define crypto globally in expo-standard-web-crypto fixed it.

If you are not running an Expo project you could easily apply the same technique to fix this issue. The "magic" can be found in index.js, provided here for convenience.

/*global crypto*/
import getRandomValues from './getRandomValues';

class Crypto {
  getRandomValues<TArray extends ArrayBufferView>(values: TArray): TArray {
    return getRandomValues(values);
  }
}

const webCrypto = typeof crypto !== 'undefined' ? crypto : new Crypto();

export default webCrypto;

export function polyfillWebCrypto(): void {
  if (typeof crypto === 'undefined') {
    Object.defineProperty(window, 'crypto', {
      configurable: true,
      enumerable: true,
      get: () => webCrypto,
    });
  }
}

mellertson avatar May 07 '22 06:05 mellertson

Hey there 👋

I'm running in this error too. Will this been solved one day or should we do the workaround ?

Tjerk-Haaye-Henricus avatar Oct 27 '22 13:10 Tjerk-Haaye-Henricus

To add the react-native-crypto and react-native-randombytes libraries to your React Native project without any errors or changes to node_modules, follow these steps:

  1. Open a terminal in your project directory.

  2. Run the following command to install the two libraries:

npm install --save react-native-crypto react-native-randombytes
  1. Add the following lines to your Podfile:
pod 'ReactNativeCrypto', :path => '../node_modules/react-native-crypto'
pod 'ReactNativeRandomBytes', :path => '../node_modules/react-native-randombytes'
  1. Save the changes in your Podfile, close it, and run the following command to install the pods:
pod install
  1. After the installation is complete, run the following command to link the libraries:
react-native link react-native-crypto && react-native link react-native-randombytes
  1. Make sure to rebuild your project by running the following command:
react-native run-ios // or react-native run-android

Now, you should have successfully added the two libraries to your project.

pipaliyadesk avatar Apr 22 '23 09:04 pipaliyadesk