bitcoinjs / bitcoinjs-lib

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

Using bitcoinjs in the browser: tx.addInput() : "Expected property \"0\" of type Buffer, got String ... #1724

Closed 0xpsi closed 3 years ago

0xpsi commented 3 years ago

I somehow, after many many attempts of using browserify, got it to produce a bitcoin.min.js file. Now using that in my webpage, I am unable to use some calls such as transaction.addInput(), it complains the input must be a "Buffer", not string, (although I was copying the exact example on the page here: http://coinpunk.github.io/bitcoinjs-lib/)

I've tried using Buffer.from() to convert the string to a buffer but then it complains "Buffer is not defined"

I am frustrated and cannot seem to get this project working in the browser, any advice is appreciated.

junderw commented 3 years ago

Buffer is not in the browser.

  1. Make your project in NodeJS (not browser JS) and use Buffer as much as you want.
  2. Import bitcoinjs-lib as a dependency
  3. Bundle your project. Not this library.

Otherwise, you can also create a tiny wrapper that exposes Buffer etc.

ie.

index.js

const bitcoin = require('bitcoinjs-lib')

module.exports = {
  Buffer,
  bitcoin,
}

Then bundle that. You can then access Buffer from this wrapper in the browser.

0xpsi commented 3 years ago

ok so I copied your javascript code into a file "index.js", and in a seperate directory, then I ran the following: browserify -r ./index.js -o bitcoin.js it produced a bitcoin.js file which I then included into my webpage. However I'm getting ReferenceErrors, did I miss something?

0xpsi commented 3 years ago

Do I really need Buffer in the browser to use bitcoinjs-lib ?

junderw commented 3 years ago

Sorry, you need to actually require and destructure Buffer when using browserify.

const bitcoin = require('bitcoinjs-lib')
const { Buffer } = require('buffer')

module.exports = {
  Buffer,
  bitcoin,
}
browserify -r ./index.js -s bitcoinWrapper -o bitcoin.js

Then inside the browser you can grab your wrapper from the specified global variable and destructure it.

const { Buffer, bitcoin } = bitcoinWrapper

Do I really need Buffer in the browser to use bitcoinjs-lib ?

Yes. bitcoinjs-lib is a NodeJS library, and is not made for the browser. The ability to browserify it is an added bonus, but any dependencies required to use the library must also be browserified for use in the browser if they are not present.

The ideal solution would be to develop your app in the NodeJS environment using whatever frontend framework you use (react etc.) and then bundle the whole app into one big bundled js file. Then Buffer will be contained and used internally inside the bundle and you won't have to worry about exporting Buffer to the browser context.

junderw commented 3 years ago

http://coinpunk.github.io/bitcoinjs-lib/

This page is out of date. Look at the top, it says "1.0.0 is released!" and we are currently on v5.x.x The Transaction class has changed since then. Also, the Psbt class is recommended for creating transactions.

See the tests to get an idea of how to create transactions.

https://github.com/bitcoinjs/bitcoinjs-lib/blob/33f36f3fb3e2e5c64e8da968960720c50912bbd5/test/integration/transactions.spec.ts

0xpsi commented 3 years ago

Sorry, you need to actually require and destructure Buffer when using browserify.

const bitcoin = require('bitcoinjs-lib')
const { Buffer } = require('buffer')

module.exports = {
  Buffer,
  bitcoin,
}
browserify -r ./index.js -s bitcoinWrapper -o bitcoin.js

Then inside the browser you can grab your wrapper from the specified global variable and destructure it.

const { Buffer, bitcoin } = bitcoinWrapper

Do I really need Buffer in the browser to use bitcoinjs-lib ?

Yes. bitcoinjs-lib is a NodeJS library, and is not made for the browser. The ability to browserify it is an added bonus, but any dependencies required to use the library must also be browserified for use in the browser if they are not present.

The ideal solution would be to develop your app in the NodeJS environment using whatever frontend framework you use (react etc.) and then bundle the whole app into one big bundled js file. Then Buffer will be contained and used internally inside the bundle and you won't have to worry about exporting Buffer to the browser context.

alright, thank you for the help :)