Unable to resolve module crypto
Tags: crypto, reactnative, bitcoin, expo
Published: 2021-10-02 17:36:37

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tfmrdmiykj195p06qc98.jpeg)

###Problem
If you're a JavaScript/Web developer interested in working with Bitcoin then you've undoubtedly come across, *bitcore*, one of the widely used libraries. It is an open-source software published and maintained by Bitpay and used in many popular tutorials such as [BCH Wallet](https://www.youtube.com/watch?v=_o-zcP1AyQc&list=PL1mkWlKl32oddt02un0if2ooy7w2jOczP) and [Pluralsight](https://www.pluralsight.com/courses/bitcoin-decentralized-technology).

However, the library was designed for web apps and will break your React Native mobile app if used 'out-of-the-box'.

In our basic code example below, we try to initialize a new private key on initial app render.

**App.js**
```
export default function App() {

  const [privateKey, setPrivateKey] = useState();

  useEffect(() => {
    setPrivateKey(new bitcore.PrivateKey("testnet"));
  }, []);

  return (
    <View style={styles.container}>
      <Text>{`Testnet private key: ${privateKey}`}</Text>
      <StatusBar style="auto" />
    </View>
  );
}
```

The *bitcore.privateKey* method will throw the following error message: **Unable to resolve module crypto...** which results in the 'red screen of death'.

Alternatively, you may also see **Unable to resolve module buffer...** message.

![Unable to resolve module crypto](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d7cjay9rwdxmn0try4g9.png)

###Reason
The gist of it is that React Native does not use the Node runtime environment and thus does not have access to specific libraries such as 'crypto', 'assert', 'url', etc. For the vast majority of use cases, this is not a problem, but working with cryptocurrency happens to be an exception.

###Solution
There are [several workarounds](https://gist.github.com/parshap/e3063d9bf6058041b34b26b7166fd6bd) that exist and unfortunately all of them lack elegance.

In this example, we use rn-nodeify to enable core node modules in our React Native app.

**Step 1: eject expo**
If your app is using the expo managed workflow, you'll need to eject.

This is an irreversible process.

By ejecting, you will no longer be able to use some of the expo cli commands such as start, build, etc. Also, you'll need to use xcode and android studio directly in order to run  the app in the development environment.

On the other hand, all expo specific libraries (i.e. @expo/vector-icons, expo-splash-screen, etc) will work with little to no tweaks.

To eject:
> From your project directory, run `expo eject`. This will download the required dependencies and build native projects under the ios and android directories.

Source: [expo docs](https://docs.expo.dev/expokit/eject/)

After running the above command, your project directory should now contain *android* & *ios* directories and *index.js* & *metro.config.js* files.

**Step 1.5: run app in simulator via xcode**
Update libraries:
* Delete package-lock file if you have one
* Run `yarn`
* Change to ios directory `cd ios`
* Delete the podfile.lock if you have one
* Run `pod install`

Open xcode and select *Open a project or file* option. Navigate to the **ios** directory and select open.

Click the play button to build and run your app on ios simulator.

It is very common at this stage to run into issues usually dealing with updating packages.

**Step 2: install package rn-nodeify**
In the root directory of your app run the following command:
`yarn add rn-nodeify -D`

This command creates a boilerplate file, *shim.js*, in the root directory. Import this file at the very top of your *index.js*.

`import "./shim";`

**Step 3: modify package.json file**
Update the package.json file to include a *postinstall* script.
```
 "scripts": {
    "start": "react-native start",
    ~~~
    "postinstall": "node_modules/.bin/rn-nodeify --install crypto,assert,url,stream,events --hack"
  },
```
Through a bit of trial and error I discovered that the above packages in the postinstall script are necessary dependencies for the bitcore library.

**Step 4: restart your app**
Close down your metro terminal, simulator and then restart your app by pressing the *play* button in Xcode.

You should see the following screen:
![crypto error fixed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ui551scgcqerpn5kr9bu.png)

Congratulations, you're now on your way to creating the next crypto app.

It is possible to run into additional errors at this stage. For example, on my second attempt at this process, I was getting 'Process could not be found in this project' error. I simply had to 'yarn add process' to get it working again.

As an aside, this method hasn't been battle tested and could potentially have security issues.