bitcoinjs-lib
bitcoinjs-lib copied to clipboard
react-native bitcoinjs install issues
I'm trying to implement bitcoinjs-lib in react-native, but I get errors when it looks for Buffer and other crypto libraries. I have used rn-nodeify as referenced in #582 and #797 and imported the shim but it's still complaining. My install process to include bitcoinjs-lib/bip39 is as follows:
npm install --save bitcoinjs-lib bip39 react-native-crypto
npm install (at this point the post-install does rn-nodeify --install fs,dgram,process,path,console --hack)
react-native start and react-native run-android for my emulator
react-native is still complaining about stream, and once I include stream it complains about buffer/safe-buffer/cipher-base and once I include any of those and rebuild it gives the infamous "Can't find variable Buffer"
I've read around that others have got it to work but have yet to be able to build it myself. Any pointers in the install process?
@wmpedersen could you please post your log dump from npm install?
@dcousens it doesn't seem like an issue with my app including bitcoinjs - there's no problem with npm install (other than the dependencies), more of how I include it in a react-native app. I've got the dependencies listed below in my app's node_modules folder, so I don't know why it's not finding them...
EDIT: I did seem to figure it out - looks like I had most of the setup correct and followed #559's
npm i
npm i -S bitcoinjs-lib asyncstorage-down assert
npm i -D rn-nodeify
//Add the following to the scripts tag in your package.json file
"postinstall": "./node_modules/.bin/rn-nodeify --install buffer,events,process,stream,util,inherits,fs,path --hack"
And can properly generate a mnemonic with bip39. More testing needs to be done to confirm other crypto libraries, but if my helper library has made it this far, it's looking good.
weird, now it's giving me secure RNG issues...
@wmpedersen it may seem like no one is listening, but I guarantee any information you post about the problems you're having will help someone in the future, so please post the details :+1:
seems like it's doing the same thing but I have react-native-randombytes^3.0.0
I don't know what changed. I might just try from my test repo from the beginning again and add my code. I was messing about with things - I seem to remember import com.bitgo.randombytes.RandomBytesPackage in my android app - but for some reason it's gone now. It's good to know it was working at one point and I should be able to replicate it. I'll have to write down the steps as I go along.
So no matter what I've done I can't seem to put it back in my working state. My project uses react-native-randombytes properly in terms of importing it into the project again, but it seems bip39 is still complaining about my RNG because it's still trying to use non-react randombytes.
edit by @dcousens: Warning, this comment contains unsafe code, do not use for generating private keys
@wmpedersen If you're still having this issue hopefully the following will help you out. I created a repo here (https://github.com/coreyphillips/react-native-bitcoinjs-lib/blob/master/src/ecpair.js) if you would like to use it as an aid for the ecpair section below:
npm i -S bitcoinjs-lib react-native-randombytes buffer-reverse buffer@5npm i -D rn-nodeify- Add the following postinstall to your script in package.json:
"postinstall": "./node_modules/.bin/rn-nodeify --install buffer,stream,assert,events --hack && npm i -S buffer@5"
Resolve Item In Ecpair.js
- Open ecpair.js in .../bitcoinjs-lib/src/ecpair.js and replace
var randomBytes = require('randombytes')with the following:var randomBytes = require('react-native-randombytes')
Resolve Item in Transaction Builder
-
Open transaction_builder.js in .../bitcoinjs-lib/src/transaction_builder.js and require the following:
var bufferReverse = require('buffer-reverse') -
Locate the
TransactionBuilder.prototype.addInputfunction in transaction_builder.js and replacetxHash = Buffer.from(txHash, 'hex').reverse()with the following:txHash = bufferReverse(new Buffer(txHash, 'hex')) -
To test if everything is working as expected place the following in render:
import "./shim";
const bitcoin = require("bitcoinjs-lib");
const keyPair = bitcoin.ECPair.makeRandom();
const address = keyPair.getAddress();
console.log(address);
@coreyphillips phillips you understand you could pass in myRng as the options argument, { rng: myRng } instead of modifying the library?
Additionally, your RNG is initializing the mt19937 every time... what does autoSeed do? I wouldn't use the above code as it IT IS NOT CRYPTOGRAPHICALLY SAFE.
edit: mt19937 is defaulting to https://github.com/ckknight/random-js/blob/8a51f321c1fb1725a593fec59299af6ad7118631/lib/random.js#L49-L51.
That is terrible.
@coreyphillips if you have generated private keys with that code, I'd recommend sweeping them as fast as possible.
Thanks @dcousens. I've updated the makeRandom function to reflect your input.
Regarding the myRng function, is there anything that you would suggest implementing there that would be both cryptographically secure and compatible for a React Native implementation?
Edit: I haven't generated any private keys using this method. This is just my best effort in getting a working build going for React Native.
var num = random.int32();
buf.fill(num)
return buf
int32 is not 32-bytes, its 32-bits. That is a Buffer with 32 copies of the same number...
@coreyphillips I'd recommend you open an issue at random-bytes
@coreyphillips was the issue https://github.com/bitcoinjs/bitcoinjs-lib/issues/559#issuecomment-205040571 not helpful to you?
@dcousens I did see that. Unfortunately, react-native-randombytes continues to throw an error. Still more troubleshooting ahead. Almost there though :-)
Huzzah, looks like it may have been a linking issue with react-native-randombytes. It appears to be working now.
I've updated the ecpair.js file here. The only change made to the file is the require for react-native-randombytes instead of randombytes.
The only change made to the file is the require for react-native-randombytes instead of randombytes.
Again, you don't need to modify bitcoinjs for this. You can pass react-native-randombytes as an argument to ECPair.
Thanks @dabura667. Understood.
Edit: Just to clarify, while ecpair.js no longer requires any modification when using the library in RN. txHash = Buffer.from(txHash, 'hex').reverse() still fails in transaction_builder.js. To work around this I had to add and require buffer-reverse and replace txHash = Buffer.from(txHash, 'hex').reverse() with txHash = bufferReverse(new Buffer(txHash, 'hex')) Example here
This appears to be the only remaining issue encountered when using this library in RN.
This appears to be the only remaining issue encountered when using this library in RN.
@corey-phillips what about the other reverse() calls?
tx.getId()?
@dcousens, you are correct. The remaining .reverse() calls fail as well and would require a similar update as the example above in order to get it working in a RN project.
@corey-phillips OK... I'm not against re-introducing buffer-reverse for the sake of RN... but, it is a bit frustrating.
Why isn't RN addressing this with an up-to-date Buffer?
Why isn't RN addressing this with an up-to-date Buffer?
Facebook.
@dcousens Basically what dabura667 said.
@corey-phillips the solution mentioned here works fine on simulator or debugging on device: https://github.com/bitcoinjs/bitcoinjs-lib/issues/976#issuecomment-368261162, however, when I package an release APK file and install it on device, then I get error:
ReactNativeJS: TypeError: undefined is not a function (evaluating 'Error.captureStackTrace(this,y)')
@jackylimel great to know!
I wasn't aware that Error.captureStackTrace wasn't standard to JS, but V8-specific.
It is used by https://github.com/dcousens/typeforce ... that will need to be fixed.
The weird thing is. If I just call bjs.ECPair.makeRandom(), then it works fine on both debug and release mode, but if I call bjs.HDNode.fromBase58('example_xpub_key'), then it would succeed on debug mode but fails on release mode ( running as a signed apk file, even on simulator).
Could someone please help?
I've found the problem is caused by uglifijs and will use the solution here:
https://github.com/facebook/react-native/issues/9711#issuecomment-327552716
@jackylimel so, Error.captureStackTrace is no longer undefined?
Once I apply the patches for uglifyjs, then I no longer get typeforce error...
@jackylimel maybe it does exist in RN (via polyfill?), but was mangled. In any case, I'll leave https://github.com/dcousens/typeforce/issues/49 open
hello :) what is the status of this? is this documented somewhere?
Same problem here. The solution mentioned here not work for me. It make the project can't start.
Any other solution or document of this problem?