Skip to content

Instantly share code, notes, and snippets.

@techiejd
Last active October 24, 2024 03:09
Show Gist options
  • Save techiejd/a14442315b5bfe0cba4ede7d2971a52f to your computer and use it in GitHub Desktop.
Save techiejd/a14442315b5bfe0cba4ede7d2971a52f to your computer and use it in GitHub Desktop.
How to add bitcoinjs-lib to an Expo project (and by extension react-native)

Add bitcoinjs-lib without ejecting from Expo.

  • That means, no using rn-nodeify nor running pod 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:

  1. 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'),
};
  1. 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 does include "createHmac" from "crypto", it'll return the right export.

config.resolver.unstable_enablePackageExports = true;

  1. 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 ? "*" : "";
}
  1. Import your shims.ts in your App.tsx:

import "./shims"

  1. 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);

Thank you!

I do tech consulting so if you want my services hit me up - jddominguez.com.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment