javascriptreact-nativeexpo

Getting crypto not found error in React Native Expo


I keep getting this error below

ERROR  ReferenceError: Property 'crypto' doesn't exist, js engine: hermes 
    at ContextNavigator (http://localhost:8081/node_modules/expo-router/entry.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.testlio.deviceverificationapp.Clip&transform.routerRoot=app&transform.engine=hermes&transform.bytecode=true:145632:24)
    at ExpoRoot (http://localhost:8081/node_modules/expo-router/entry.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.testlio.deviceverificationapp.Clip&transform.routerRoot=app&transform.engine=hermes&transform.bytecode=true:145588:28)
    at App
    at ErrorToastContainer (http://localhost:8081/node_modules/expo-router/entry.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.testlio.deviceverificationapp.Clip&transform.routerRoot=app&transform.engine=hermes&transform.bytecode=true:242934:24)
    at ErrorOverlay
    at withDevTools(ErrorOverlay) (http://localhost:8081/node_modules/expo-router/entry.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.testlio.deviceverificationapp.Clip&transform.routerRoot=app&transform.engine=hermes&transform.bytecode=true:242437:27)
    at RCTView
    at View (http://localhost:8081/node_modules/expo-router/entry.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.testlio.deviceverificationapp.Clip&transform.routerRoot=app&transform.engine=hermes&transform.bytecode=true:41517:43)
    at RCTView
    at View (http://localhost:8081/node_modules/expo-router/entry.bundle//&platform=ios&dev=true&lazy=true&minify=false&inlineSourceMap=false&modulesOnly=false&runModule=true&app=com.testlio.deviceverificationapp.Clip&transform.routerRoot=app&transform.engine=hermes&transform.bytecode=true:41517:43)

whenever I try to run my React Native Expo application in Xcode. I don't seem to know why. It however works when I run npm run ios on my vscode

I have tried regenerating the pod file, removing hermes from the pod file definition but still does not work on Xcode.

Here is my React Native Expo Component


import * as crypto from 'crypto';
import React, { useEffect, useState } from 'react';
import { View, Text, Image, StyleSheet } from 'react-native';
import DeviceInfo from 'react-native-device-info';
import * as Device from 'expo-device';
import { useVerifyDeviceMutation } from './verifyDeviceQuery.generated';

type DeviceVerificationPayload = {
    deviceVariantIdentifier: string;
    deviceOsVersion: string;
};

const encrypt = (payload: DeviceVerificationPayload) => {
    const algorithm = ‘aes-256-cbc’;
    const encryptionAlgoKey = ‘Key’;
    const encryptionKey = base64ToUtf8(encryptionAlgoKey);
    const key = CryptoJS.SHA256(encryptionKey);
    const iv = CryptoJS.lib.WordArray.create(key.words.slice(0, 4));
    const stringifiedPayload = JSON.stringify(payload);
    const cipher = crypto.createCipheriv(algorithm, key, iv); 
    let encrypted = cipher.update(stringifiedPayload, 'utf8', 'hex'); 
    encrypted += cipher.final('hex'); return encrypted;
    return encrypted;
};

export default function HomeScreen() {
    const deviceVerificationGuid = 'deviceVerificationGuid';
    const [isVerifying, setIsVerifying] = useState<boolean>(true);
    const [deviceVerificationFailure, setDeviceVerificationFailure] = useState<boolean>(false);

    const [verifyDevice, { loading }] = useVerifyDeviceMutation({
        onCompleted: () => {
            setIsVerifying(false);
        },
        onError: (data) => {
            setIsVerifying(false);
            setDeviceVerificationFailure(true);
        }
    });

    useEffect(() => {
            const deviceVariantIdentifier = Device.modelName || '';
            const deviceOsVersion = Device.osVersion || '';
            const signature = encrypt({
                deviceVariantIdentifier,
                deviceOsVersion
            });

            verifyDevice({
                variables: {
                    input: {
                        deviceVariantIdentifier,
                        deviceOsVersion,
                        signature,
                        deviceVerificationGuid
                    }
                }
            });
    }, [deviceVerificationGuid, verifyDevice]);

    if (!deviceVerificationGuid) {
        return (
            <View style={styles.container}>
                <Image source={require('./assets/loadicon.gif')} style={styles.image} />
            </View>
        );
    }

    return (
        <View style={styles.container}>
          User Interface Logic
        </View>
    );
}

The above works whenever I run npm run ios but specifically fails when I run it on Xcode.
Not really sure why this is happening


Solution

  • The problem is from

    import * as crypto from 'crypto';
    

    The Crypto module is only available on server side javascript applications, i.e applications that is run on node. React and React Native is client based so the native crypto library would not work. You can instead use the inbuilt expo crypto library or use a third party package like crypto-js