- That means, no using
rn-nodeify
nor runningpod install
.
I based the development process off of Solana's "Building Solana Mobile dApps with Expo", their codebase and this draftbit polyfills demo.
Let's get down to business:
- You want to modify
metro.config.js
to resolve any extraNodeModules, which are not default included in the react-native environment. It'll look something like this:
config.resolver.extraNodeModules = {
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("readable-stream"),
path: require.resolve("path-browserify"),
buffer: require.resolve('buffer'),
events: require.resolve('events'),
process: require.resolve('process/browser'),
assert: require.resolve('assert'),
inherits: require.resolve('inherits'),
};
- You will also want to set the resolver's
unstable_enablePackageExports
to true. This is useful in case anyone tries to use the imports as a package. For example if anyone doesinclude "createHmac" from "crypto"
, it'll return the right export.
config.resolver.unstable_enablePackageExports = true;
- You will want to set all globals in shims.ts:
import { getRandomValues as expoCryptoGetRandomValues } from "expo-crypto";
import createHmac from "create-hmac";
import createHash from "create-hash";
class Crypto {
getRandomValues = expoCryptoGetRandomValues;
createHmac = createHmac;
createHash = createHash;
}
const webCrypto = typeof crypto !== "undefined" ? crypto : new Crypto();
(() => {
if (typeof crypto === "undefined") {
Object.defineProperty(window, "crypto", {
configurable: true,
enumerable: true,
get: () => webCrypto,
});
}
})();
import { Buffer } from "buffer";
global.Buffer = Buffer;
import "fast-text-encoding"; // This import statement sets the globals for TextEncoder and TextDecoder
if (typeof __dirname === "undefined") global.__dirname = "/";
if (typeof __filename === "undefined") global.__filename = "";
if (typeof process === "undefined") {
global.process = require("process");
} else {
const bProcess = require("process");
for (var p in bProcess) {
if (!(p in process)) {
(process as any)[p] = bProcess[p];
}
}
}
(process as any).browser = false;
// global.location = global.location || { port: 80 }
const isDev = typeof __DEV__ === "boolean" && __DEV__;
process.env["NODE_ENV"] = isDev ? "development" : "production";
if (typeof localStorage !== "undefined") {
localStorage.debug = isDev ? "*" : "";
}
- Import your
shims.ts
in yourApp.tsx
:
import "./shims"
- Make sure to include your packages for installment in your package.json!
"@bitcoinerlab/secp256k1": "^1.1.1",
"assert": "^2.1.0",
"bitcoinjs-lib": "^7.0.0-rc.0",
"buffer": "^6.0.3",
"create-hash": "^1.2.0",
"create-hmac": "^1.1.7",
"crypto-browserify": "^3.12.1",
"ecpair": "^3.0.0-rc.0",
"events": "^3.3.0",
"expo-crypto": "~12.8.1",
"fast-text-encoding": "^1.0.6",
"inherits": "^2.0.4",
"path-browserify": "^1.0.1",
"process": "^0.11.10",
"readable-stream": "^4.5.2",
And then run the install: yarn install
or npm i
.
To test if everything is working as expected place the following in App.tsx:
import './shim';
import ECPairFactory from 'ecpair';
import ecc from '@bitcoinerlab/secp256k1';
const bitcoin = require('bitcoinjs-lib');
const ECPair = ECPairFactory(ecc);
const keyPair = ECPair.makeRandom();
const {address} = bitcoin.payments.p2pkh({pubkey: keyPair.publicKey});
console.log(address);
I do tech consulting so if you want my services hit me up - jddominguez.com.