bitcoinjs / bitcoinjs-lib

A javascript Bitcoin library for node.js and browsers.
MIT License
5.71k stars 2.11k forks source link

Can't use tiny-secp256k1 (required by bitcoinjs-lib for ECC) in browser: fs_1.readFileSync is not a function #2106

Closed SuperHenkie closed 5 months ago

SuperHenkie commented 5 months ago

I'm having trouble getting BitcoinJS to work in a browser. Very unfamiliar with node/npm so maybe I'm missing something, here are my exact steps to reproduce the issue. In a new directory I do this:

npm init -y npm install bitcoinjs-lib tiny-secp256k1 browserify

I create a file main.js containing:

const bitcoin = require('bitcoinjs-lib'); const ecc = require('tiny-secp256k1'); window.bitcoin = bitcoin;

Then I do browserify main.js -o bundle.js to create a browserified package.

I create a file test.html containing:

<!DOCTYPE html><html><head><meta charset="utf-8"> <script src="bundle.js"></script> </head><body></body></html>

When I open this test.html in the browser (latest Firefox or Chrome or Brave) the console shows an error:

Uncaught TypeError: (0 , fs_1.readFileSync) is not a function

Note that this error does NOT occur when I remove or comment the const ecc = ... line in main.js. However I need tiny-secp256k1 for functionality like ECPair etc.

Am I doing something wrong or is BitcoinJS not supposed to be used in the browser with tiny-secp256k1 features?

VictorZhang2014 commented 5 months ago

The first option, you need to use bundle.js in an environment, like http://localhost:3000 or https://google.com/web3, but do not use the file like index.html opened in the browser directly, it won't work in this way.

The second option, find the error position like(0 , fs_1.readFileSync) and annotate the code, and replace it by loading the wasm file through fetch.

SuperHenkie commented 5 months ago

Thanks, how do you mean I can't open test.html in the browser directly? Note that I'm running this in an offline environment, just on my local computer (that doesn't run a webserver). It always worked like this with previous BitcoinJS versions (v5 and earlier) but I think since v6 there have been some changes resulting in this browser incompatibility.

Note that it works fine if I comment the const ecc line, it's just this particular tiny-secp256k1 that seems to cause an issue when using in a browserified package (this was not the case with previous versions).

I'm not sure sure what you mean by the second option. Note that I don't use any wasm file myself, it's just the code from one of the libraries used in BitcoinJS, I use it as-is. I'd rather not manually change it or mess with its internals, otherwise I'll have the same trouble whenever I update to a newer version.

jasonandjay commented 5 months ago

Thanks, how do you mean I can't open test.html in the browser directly? Note that I'm running this in an offline environment, just on my local computer (that doesn't run a webserver). It always worked like this with previous BitcoinJS versions (v5 and earlier) but I think since v6 there have been some changes resulting in this browser incompatibility.

Note that it works fine if I comment the const ecc line, it's just this particular tiny-secp256k1 that seems to cause an issue when using in a browserified package (this was not the case with previous versions).

I'm not sure sure what you mean by the second option. Note that I don't use any wasm file myself, it's just the code from one of the libraries used in BitcoinJS, I use it as-is. I'd rather not manually change it or mess with its internals, otherwise I'll have the same trouble whenever I update to a newer version.

use @bitcoinerlab/secp256k1 replace tiny-secp256k1 have a try

VictorZhang2014 commented 5 months ago

If you are using tiny-secp256k1, undoutedly, it uses wasm file because the library was built by Rust. So when you load it in your test.html, the js environment needs to fetch the wasm file at first. Simply speaking, remove the fs and replace it by fetch.

By the way, if you are use @bitcoinerlab/secp256k1 which already removed the wasm file, hence, there shouldn't be an issue occurred like you posted fs_1.readFileSync not found. I suggest you search the fs module in your output bundle script, and check what's going on there because there's no wasm indeed.

junderw commented 5 months ago

@bitcoinerlab/secp256k1 is a great alternative implementation that works well with browser bundlers.

WASM support in bundlers is still very iffy.

@bitcoinjs-lib/tiny-secp256k1-asmjs is also available, but a bit slower than bitcoinerlab. But it is generated from the WASM.

SuperHenkie commented 5 months ago

use @bitcoinerlab/secp256k1 replace tiny-secp256k1 have a try

Thanks! That did the trick! πŸ‘

P.S. may I suggest to include this in the using bitcoinjs-lib in browser instructions as I can imagine it may save people a lot of troubleshooting.

Much appreciated! πŸ™

junderw commented 5 months ago

use @bitcoinerlab/secp256k1 replace tiny-secp256k1 have a try

Thanks! That did the trick! πŸ‘

P.S. may I suggest to include this in the using bitcoinjs-lib in browser instructions as I can imagine it may save people a lot of troubleshooting.

Much appreciated! πŸ™

https://github.com/bitcoinjs/tiny-secp256k1#alternatives

It is mentioned on tiny-secp256k1.

Please make a suggestion as to how you would change it, pull requests to update READMEs etc. are always welcome (even if they tend to get bike-sheddy)