Socket
Socket
Sign inDemoInstall

bitcoinjs-lib

Package Overview
Dependencies
Maintainers
1
Versions
88
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bitcoinjs-lib - npm Package Compare versions

Comparing version 3.3.2 to 4.0.1

src/classify.js

58

CHANGELOG.md

@@ -0,1 +1,59 @@

# 4.0.1
__fixed__
- Fixed `tiny-secp256k1` dependency version (used `ecurve`) (#1139)
- Fixed `TransactionBuilder` throwing when trying to sign `P2WSH(P2WPKH)` (#1135)
# 4.0.0
__added__
- Added [`bip32`](https://github.com/bitcoinjs/bip32) dependency as a primary export (#1073)
- Added `ECPair.fromPrivateKey` (#1070)
- Added `payments` export, with support for `p2pkh`, `p2pk`, `p2ms`, `p2sh`, `p2wpkh`, `p2wsh` and `embed` payment types (#1096, #1119)
- Added `script.signature.encode/decode` for script signatures (#459)
__changed__
- `ECPair.prototype.sign` now returns a 64-byte signature `Buffer`, not an `ECSignature` object (#1084)
- `ECPair` (and all ECDSA code) now uses [`tiny-secp256k1`](http://github.com/bitcoinjs/tiny-secp256k1), which uses the [`libsecp256k1` library](https://github.com/bitcoin-core/secp256k1) (#1070)
- `TransactionBuilder` internal variables are now `__` prefixed to discourage public usage (#1038)
- `TransactionBuilder` now defaults to version 2 transaction versions (#1036)
- `script.decompile` now returns `Buffer` or `null`, if decompilation failed (#1039)
__fixed__
- Fixed `TransactionBuilder` rejecting uncompressed public keys to comply with BIP143 (#987)
__removed__
- Removed Node 4/5 LTS support (#1080)
- Removed `ECPair.fromPublicKeyBuffer`, use `ECPair.fromPublicKey` (#1070)
- Removed `ECPair.prototype.getAddress`, use `payments.p2pkh` instead (#1085)
- Removed `ECPair.prototype.getPrivateKey`, use `ECPair.prototype.privateKey` property (#1070)
- Removed `ECPair.prototype.getPublicKey`, use `ECPair.prototype.publicKey` property (#1070)
- Removed `ECPair.prototype.getNetwork`, use `ECPair.prototype.network` property (#1070)
- Removed `ECSignature`, use `script.signature.encode/decode` instead (#459)
- Removed `HDNode`, use `bip32` export instead (#1073)
- Removed `bufferutils` (#1035)
- Removed `networks.litecoin`, BYO non-Bitcoin networks instead (#1095)
- Removed `script.isCanonicalSignature`, use `script.isCanonicalScriptSignature` instead (#1094)
- Removed `script.*.input/output/check` functions (`templates`) (previously added in #681, #682) (#1119)
- Removed dependency `bigi`, uses `bn.js` internally now (via `tiny-secp256k1`) (#1070, #1112)
- Removed public access to `ECPair` constructor, use exported functions `ECPair.fromPrivateKey`, `ECPair.fromWIF`, `ECPair.makeRandom`, or `ECPair.fromPublicKey` (#1070)
# 3.3.2
__fixed__
- Fixed `decodeStack` arbitrarily supporting non-Array arguments (#942)
# 3.3.1
__changed__
- Increased the `TransactionBuilder` `maximumFeeRate` from 1000 to 2500 satoshis/byte. (#931)
# 3.3.0
__added__
- Added `ECSignature.prototype.toRSBuffer`/`ECSignature.fromRSBuffer` (#915)
- Added support to `TransactionBuilder` for 64-byte signatures via `.sign` (#915)
- Added support to `TransactionBuilder` for the `.publicKey` standard as an alternative to `.getPublicKey()` (#915)
# 3.2.1
__fixed__
- Fixed `script.scripthash.input.check` recursion (#898)
- Fixed `TransactionBuilder` sometimes ignoring witness value (#901)
- Fixed `script.witnessScriptHash.input` implementation (previously used the P2SH impl.) (#911)
# 3.2.0

@@ -2,0 +60,0 @@ __added__

30

package.json
{
"name": "bitcoinjs-lib",
"version": "3.3.2",
"version": "4.0.1",
"description": "Client-side Bitcoin JavaScript library",
"main": "./src/index.js",
"engines": {
"node": ">=4.0.0"
"node": ">=8.0.0"
},

@@ -34,13 +34,13 @@ "keywords": [

"bech32": "^1.1.2",
"bigi": "^1.4.0",
"bip32": "^1.0.0",
"bip66": "^1.1.0",
"bitcoin-ops": "^1.3.0",
"bitcoin-ops": "^1.4.0",
"bs58check": "^2.0.0",
"create-hash": "^1.1.0",
"create-hmac": "^1.1.3",
"ecurve": "^1.0.0",
"merkle-lib": "^2.0.10",
"pushdata-bitcoin": "^1.0.1",
"randombytes": "^2.0.1",
"safe-buffer": "^5.0.1",
"safe-buffer": "^5.1.1",
"tiny-secp256k1": "^1.0.0",
"typeforce": "^1.11.3",

@@ -51,16 +51,16 @@ "varuint-bitcoin": "^1.0.4",

"devDependencies": {
"async": "^2.0.1",
"bip39": "^2.3.0",
"bip65": "^1.0.1",
"bip68": "^1.0.3",
"bn.js": "^4.11.8",
"bs58": "^4.0.0",
"cb-http-client": "^0.2.0",
"coinselect": "^3.1.1",
"dhttp": "^2.3.5",
"dhttp": "^2.5.0",
"hoodwink": "^1.0.0",
"minimaldata": "^1.0.2",
"mocha": "^3.1.0",
"nyc": "^10.2.0",
"proxyquire": "^1.4.0",
"sinon": "^1.12.2",
"standard": "^9.0.2"
"mocha": "^5.2.0",
"nyc": "^11.8.0",
"proxyquire": "^2.0.1",
"standard": "^11.0.1"
},
"license": "MIT"
}
# BitcoinJS (bitcoinjs-lib)
[![Build Status](https://travis-ci.org/bitcoinjs/bitcoinjs-lib.png?branch=master)](https://travis-ci.org/bitcoinjs/bitcoinjs-lib)
[![NPM](https://img.shields.io/npm/v/bitcoinjs-lib.svg)](https://www.npmjs.org/package/bitcoinjs-lib)
[![tip for next commit](https://tip4commit.com/projects/735.svg)](http://tip4commit.com/projects/735)
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
The pure JavaScript Bitcoin library for node.js and browsers.
Estimated to be in use by over 15 million wallet users and is the backbone for almost all Bitcoin web wallets in production today.
A javascript Bitcoin library for node.js and browsers.
Released under the terms of the [MIT LICENSE](LICENSE).
## Features
- Clean: Pure JavaScript, concise code, easy to read.
- Tested: Coverage > 90%, third-party integration tests.
- Careful: Two person approval process for small, focused pull requests.
- Compatible: Works on Node.js and all modern browsers.
- Powerful: Support for advanced features, such as multi-sig, HD Wallets.
- Secure: Strong random number generation, PGP signed releases, trusted developers.
- Principled: No support for browsers with crap RNG (IE < 11)
- Standardized: Node community coding style, Browserify, Node's stdlib and Buffers.
- Fast: Optimized code, uses typed arrays instead of byte arrays for performance.
- Experiment-friendly: Bitcoin Mainnet and Testnet support.
- Altcoin-ready: Capable of working with bitcoin-derived cryptocurrencies (such as Dogecoin).
## Should I use this in production?
If you are thinking of using the master branch of this library in production, **stop**.
If you are thinking of using the *master* branch of this library in production, **stop**.
Master is not stable; it is our development branch, and [only tagged releases may be classified as stable](https://github.com/bitcoinjs/bitcoinjs-lib/tags).
## Installation
``` bash
npm install bitcoinjs-lib
```
## Can I trust this code?
> Don't trust. Verify.
## Setup
### Node.js
``` javascript
var bitcoin = require('bitcoinjs-lib')
```
We recommend every user of this library and the [bitcoinjs](https://github.com/bitcoinjs) ecosystem audit and verify any underlying code for its validity and suitability.
### Browser
If you're familiar with how to use browserify, ignore this and proceed normally.
These steps are advisory only, and may not be suitable for your application.
Mistakes and bugs happen, but with your help in resolving and reporting [issues](https://github.com/bitcoinjs/bitcoinjs-lib/issues), together we can produce open source software that is:
[Browserify](https://github.com/substack/node-browserify) is assumed to be installed for these steps.
- Easy to audit and verify,
- Tested, with test coverage >95%,
- Advanced and feature rich,
- Standardized, using [standard](http://github.com/standard/standard) and Node `Buffer`'s throughout, and
- Friendly, with a strong and helpful community, ready to answer questions.
For your project, create an `index.js` file
``` javascript
let bitcoin = require('bitcoinjs-lib')
## Documentation
Presently, we do not have any formal documentation other than our [examples](#Examples), please [ask for help](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new) if our examples aren't enough to guide you.
// your code here
function myFunction () {
return bitcoin.ECPair.makeRandom().toWIF()
}
module.exports = {
myFunction
}
```
Now, to compile for the browser:
## Installation
``` bash
browserify index.js --standalone foo > app.js
npm install bitcoinjs-lib
```
You can now put `<script src="app.js" />` in your web page, using `foo.myFunction` to create a new Bitcoin private key.
Typically we support the [Node Maintenance LTS version](https://github.com/nodejs/Release).
If in doubt, see the [.travis.yml](.travis.yml) for what versions are used by our continuous integration tests.
**NOTE**: If you uglify the javascript, you must exclude the following variable names from being mangled: `BigInteger`, `ECPair`, `Point`.
This is because of the function-name-duck-typing used in [typeforce](https://github.com/dcousens/typeforce).
**WARNING**: We presently don't provide any tooling to verify that the release on `npm` matches GitHub. As such, you should verify anything downloaded by `npm` against your own verified copy.
Example:
``` bash
uglifyjs ... --mangle reserved=['BigInteger','ECPair','Point']
```
**NOTE**: This library tracks Node LTS features, if you need strict ES5, use [`--transform babelify`](https://github.com/babel/babelify) in conjunction with your `browserify` step (using an [`es2015`](http://babeljs.io/docs/plugins/preset-es2015/) preset).
## Usage
### Browser
The recommended method of using `bitcoinjs-lib` in your browser is through [Browserify](https://github.com/substack/node-browserify).
If you're familiar with how to use browserify, ignore this and carry on, otherwise, it is recommended to read the tutorial at http://browserify.org/.
**NOTE**: We use Node Maintenance LTS features, if you need strict ES5, use [`--transform babelify`](https://github.com/babel/babelify) in conjunction with your `browserify` step (using an [`es2015`](http://babeljs.io/docs/plugins/preset-es2015/) preset).
**NOTE**: If you expect this library to run on an iOS 10 device, ensure that you are using [buffer@5.0.5](https://github.com/feross/buffer/pull/155) or greater.
### Typescript or VSCode users
Type declarations for Typescript [are available](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/0897921174860ec3d5318992d2323b3ae8100a68/types/bitcoinjs-lib) for version `^3.0.0` of the library.
### Typescript or VSCode users
Type declarations for Typescript are available for version `^3.0.0` of the library.
``` bash

@@ -88,22 +61,21 @@ npm install @types/bitcoinjs-lib

You can now use `bitcoinjs-lib` as a typescript compliant library.
``` javascript
import { HDNode, Transaction } from 'bitcoinjs-lib'
```
For VSCode (and other editors), it is advised to install the type declarations, as Intellisense uses that information to help you code (autocompletion, static analysis).
For VSCode (and other editors), users are advised to install the type declarations, as Intellisense uses that information to help you code (autocompletion, static analysis).
**WARNING**: These Typescript definitions are not maintained by the maintainers of this repository, and are instead maintained at [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped).
Please report any issues or problems there.
Report any typescript related bugs at [@dlebrecht DefinitelyTyped fork](https://github.com/dlebrecht/DefinitelyTyped), submit PRs to [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
### Flow
Definitions for [Flow typechecker](https://flowtype.org/) are available in flow-typed repository.
[Flow-type](https://flowtype.org/) definitions for are available in the [flow-*typed* repository](https://github.com/flowtype/flow-typed/tree/master/definitions/npm/bitcoinjs-lib_v2.x.x) for version `^2.0.0` of the library.
[You can either download them directly](https://github.com/flowtype/flow-typed/blob/master/definitions/npm/bitcoinjs-lib_v2.x.x/flow_v0.17.x-/bitcoinjs-lib_v2.x.x.js) from the repo, or with the flow-typed CLI
You can [download them directly](https://github.com/flowtype/flow-typed/blob/master/definitions/npm/bitcoinjs-lib_v2.x.x/flow_v0.17.x-/bitcoinjs-lib_v2.x.x.js), or using the flow-typed CLI:
# npm install -g flow-typed
$ flow-typed install -f 0.27 bitcoinjs-lib@2.2.0 # 0.27 for flow version, 2.2.0 for bitcoinjs-lib version
``` bash
npm install -g flow-typed
flow-typed install -f 0.27 bitcoinjs-lib@2.2.0
```
The definitions are complete and up to date with version 2.2.0. The definitions are maintained by [@runn1ng](https://github.com/runn1ng).
These definitions are maintained by [@runn1ng](https://github.com/runn1ng).
## Examples

@@ -114,37 +86,41 @@ The below examples are implemented as integration tests, they should be very easy to understand.

- [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L12)
- [Generate an address from a SHA256 hash](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L19)
- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L29)
- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L36)
- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L50)
- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L60)
- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L71)
- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L86)
- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L100)
- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L121)
- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L131)
- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L14)
- [Generate a random address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L22)
- [Generate an address from a SHA256 hash](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L29)
- [Import an address via WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L40)
- [Generate a 2-of-3 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L47)
- [Generate a SegWit address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L60)
- [Generate a SegWit P2SH address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L67)
- [Generate a SegWit 3-of-4 multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L76)
- [Generate a SegWit 2-of-2 P2SH multisig address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L90)
- [Support the retrieval of transactions for an address (3rd party blockchain)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L104)
- [Generate a Testnet address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L123)
- [Generate a Litecoin address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/addresses.js#L133)
- [Create a 1-to-1 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L13)
- [Create a 2-to-2 Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L28)
- [Create (and broadcast via 3PBP) a typical Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L46)
- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L88)
- [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L115)
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L151)
- [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L183)
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L8)
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L15)
- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L26)
- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L35)
- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L50)
- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L66)
- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L83)
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L37)
- [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L71)
- [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L104)
- [Create (and broadcast via 3PBP) a typical Transaction](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L47)
- [Create (and broadcast via 3PBP) a Transaction with an OP\_RETURN output](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L83)
- [Create (and broadcast via 3PBP) a Transaction with a 2-of-4 P2SH(multisig) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L105)
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2SH(P2WPKH) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L143)
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2WPKH input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L174)
- [Create (and broadcast via 3PBP) a Transaction with a SegWit P2PK input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L218)
- [Create (and broadcast via 3PBP) a Transaction with a SegWit 3-of-4 P2SH(P2WSH(multisig)) input](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L263)
- [Verify a Transaction signature](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/transactions.js#L304)
- [Import a BIP32 testnet xpriv and export to WIF](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L12)
- [Export a BIP32 xpriv, then import it](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L20)
- [Export a BIP32 xpub](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L31)
- [Create a BIP32, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L40)
- [Create a BIP44, bitcoin, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L55)
- [Create a BIP49, bitcoin testnet, account 0, external address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L71)
- [Use BIP39 to generate BIP32 addresses](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/bip32.js#L86)
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L43)
- [Create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L88)
- [Create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L144)
- [Create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/cltv.js#L190)
- [Recover a private key from duplicate R values](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L14)
- [Recover a BIP32 parent private key from the parent public key, and a derived, non-hardened child private key](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L115)
- [Generate a single-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L70:)
- [Generate a single-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L89:)
- [Recover parent recipient.d, if a derived private key is leaked (and nonce was revealed)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L105)
- [Generate a dual-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L122)
- [Generate a dual-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L145)
- [Recover a BIP32 parent private key from the parent public key, and a derived, non-hardened child private key](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/crypto.js#L68)
- [Generate a single-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L72)
- [Generate a single-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L91)
- [Recover parent recipient.d, if a derived private key is leaked (and nonce was revealed)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L107)
- [Generate a dual-key stealth address](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L124)
- [Generate a dual-key stealth address (randomly)](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/test/integration/stealth.js#L147)

@@ -154,23 +130,6 @@ If you have a use case that you feel could be listed here, please [ask for it](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new)!

## Projects utilizing BitcoinJS
- [BitAddress](https://www.bitaddress.org)
- [Blockchain.info](https://blockchain.info/wallet)
- [Blocktrail](https://www.blocktrail.com/)
- [Dark Wallet](https://www.darkwallet.is/)
- [DecentralBank](http://decentralbank.com/)
- [Dogechain Wallet](https://dogechain.info)
- [EI8HT Wallet](http://ei8.ht/)
- [GreenAddress](https://greenaddress.it)
- [Helperbit](https://helperbit.com)
- [Melis Wallet](https://melis.io)
- [Robocoin](https://wallet.robocoin.com)
- [Skyhook ATM](http://projectskyhook.com)
## Contributing
We are always accepting of pull requests, but we do adhere to specific standards in regards to coding style, test driven development and commit messages.
See [CONTRIBUTING.md](CONTRIBUTING.md).
Please make your best effort to adhere to these when contributing to save on trivial corrections.
### Running the test suite

@@ -177,0 +136,0 @@

@@ -1,12 +0,12 @@

var Buffer = require('safe-buffer').Buffer
var bech32 = require('bech32')
var bs58check = require('bs58check')
var bscript = require('./script')
var btemplates = require('./templates')
var networks = require('./networks')
var typeforce = require('typeforce')
var types = require('./types')
const Buffer = require('safe-buffer').Buffer
const bech32 = require('bech32')
const bs58check = require('bs58check')
const bscript = require('./script')
const networks = require('./networks')
const typeforce = require('typeforce')
const types = require('./types')
const payments = require('./payments')
function fromBase58Check (address) {
var payload = bs58check.decode(address)
const payload = bs58check.decode(address)

@@ -17,4 +17,4 @@ // TODO: 4.0.0, move to "toOutputScript"

var version = payload.readUInt8(0)
var hash = payload.slice(1)
const version = payload.readUInt8(0)
const hash = payload.slice(1)

@@ -25,4 +25,4 @@ return { version: version, hash: hash }

function fromBech32 (address) {
var result = bech32.decode(address)
var data = bech32.fromWords(result.words.slice(1))
const result = bech32.decode(address)
const data = bech32.fromWords(result.words.slice(1))

@@ -39,3 +39,3 @@ return {

var payload = Buffer.allocUnsafe(21)
const payload = Buffer.allocUnsafe(21)
payload.writeUInt8(version, 0)

@@ -48,3 +48,3 @@ hash.copy(payload, 1)

function toBech32 (data, version, prefix) {
var words = bech32.toWords(data)
const words = bech32.toWords(data)
words.unshift(version)

@@ -55,11 +55,11 @@

function fromOutputScript (outputScript, network) {
function fromOutputScript (output, network) {
network = network || networks.bitcoin
if (btemplates.pubKeyHash.output.check(outputScript)) return toBase58Check(bscript.compile(outputScript).slice(3, 23), network.pubKeyHash)
if (btemplates.scriptHash.output.check(outputScript)) return toBase58Check(bscript.compile(outputScript).slice(2, 22), network.scriptHash)
if (btemplates.witnessPubKeyHash.output.check(outputScript)) return toBech32(bscript.compile(outputScript).slice(2, 22), 0, network.bech32)
if (btemplates.witnessScriptHash.output.check(outputScript)) return toBech32(bscript.compile(outputScript).slice(2, 34), 0, network.bech32)
try { return payments.p2pkh({ output, network }).address } catch (e) {}
try { return payments.p2sh({ output, network }).address } catch (e) {}
try { return payments.p2wpkh({ output, network }).address } catch (e) {}
try { return payments.p2wsh({ output, network }).address } catch (e) {}
throw new Error(bscript.toASM(outputScript) + ' has no matching Address')
throw new Error(bscript.toASM(output) + ' has no matching Address')
}

@@ -70,3 +70,3 @@

var decode
let decode
try {

@@ -77,4 +77,4 @@ decode = fromBase58Check(address)

if (decode) {
if (decode.version === network.pubKeyHash) return btemplates.pubKeyHash.output.encode(decode.hash)
if (decode.version === network.scriptHash) return btemplates.scriptHash.output.encode(decode.hash)
if (decode.version === network.pubKeyHash) return payments.p2pkh({ hash: decode.hash }).output
if (decode.version === network.scriptHash) return payments.p2sh({ hash: decode.hash }).output
} else {

@@ -88,4 +88,4 @@ try {

if (decode.version === 0) {
if (decode.data.length === 20) return btemplates.witnessPubKeyHash.output.encode(decode.data)
if (decode.data.length === 32) return btemplates.witnessScriptHash.output.encode(decode.data)
if (decode.data.length === 20) return payments.p2wpkh({ hash: decode.data }).output
if (decode.data.length === 32) return payments.p2wsh({ hash: decode.data }).output
}

@@ -92,0 +92,0 @@ }

@@ -1,9 +0,9 @@

var Buffer = require('safe-buffer').Buffer
var bcrypto = require('./crypto')
var fastMerkleRoot = require('merkle-lib/fastRoot')
var typeforce = require('typeforce')
var types = require('./types')
var varuint = require('varuint-bitcoin')
const Buffer = require('safe-buffer').Buffer
const bcrypto = require('./crypto')
const fastMerkleRoot = require('merkle-lib/fastRoot')
const typeforce = require('typeforce')
const types = require('./types')
const varuint = require('varuint-bitcoin')
var Transaction = require('./transaction')
const Transaction = require('./transaction')

@@ -22,3 +22,3 @@ function Block () {

var offset = 0
let offset = 0
function readSlice (n) {

@@ -30,3 +30,3 @@ offset += n

function readUInt32 () {
var i = buffer.readUInt32LE(offset)
const i = buffer.readUInt32LE(offset)
offset += 4

@@ -37,3 +37,3 @@ return i

function readInt32 () {
var i = buffer.readInt32LE(offset)
const i = buffer.readInt32LE(offset)
offset += 4

@@ -43,3 +43,3 @@ return i

var block = new Block()
const block = new Block()
block.version = readInt32()

@@ -55,3 +55,3 @@ block.prevHash = readSlice(32)

function readVarInt () {
var vi = varuint.decode(buffer, offset)
const vi = varuint.decode(buffer, offset)
offset += varuint.decode.bytes

@@ -62,3 +62,3 @@ return vi

function readTransaction () {
var tx = Transaction.fromBuffer(buffer.slice(offset), true)
const tx = Transaction.fromBuffer(buffer.slice(offset), true)
offset += tx.byteLength()

@@ -68,7 +68,7 @@ return tx

var nTransactions = readVarInt()
const nTransactions = readVarInt()
block.transactions = []
for (var i = 0; i < nTransactions; ++i) {
var tx = readTransaction()
const tx = readTransaction()
block.transactions.push(tx)

@@ -101,3 +101,3 @@ }

Block.prototype.getUTCDate = function () {
var date = new Date(0) // epoch
const date = new Date(0) // epoch
date.setUTCSeconds(this.timestamp)

@@ -110,5 +110,5 @@

Block.prototype.toBuffer = function (headersOnly) {
var buffer = Buffer.allocUnsafe(this.byteLength(headersOnly))
const buffer = Buffer.allocUnsafe(this.byteLength(headersOnly))
var offset = 0
let offset = 0
function writeSlice (slice) {

@@ -141,3 +141,3 @@ slice.copy(buffer, offset)

this.transactions.forEach(function (tx) {
var txSize = tx.byteLength() // TODO: extract from toBuffer?
const txSize = tx.byteLength() // TODO: extract from toBuffer?
tx.toBuffer(buffer, offset)

@@ -155,5 +155,5 @@ offset += txSize

Block.calculateTarget = function (bits) {
var exponent = ((bits & 0xff000000) >> 24) - 3
var mantissa = bits & 0x007fffff
var target = Buffer.alloc(32, 0)
const exponent = ((bits & 0xff000000) >> 24) - 3
const mantissa = bits & 0x007fffff
const target = Buffer.alloc(32, 0)
target.writeUInt32BE(mantissa, 28 - exponent)

@@ -167,3 +167,3 @@ return target

var hashes = transactions.map(function (transaction) {
const hashes = transactions.map(function (transaction) {
return transaction.getHash()

@@ -178,3 +178,3 @@ })

var actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
return this.merkleRoot.compare(actualMerkleRoot) === 0

@@ -184,4 +184,4 @@ }

Block.prototype.checkProofOfWork = function () {
var hash = this.getHash().reverse()
var target = Block.calculateTarget(this.bits)
const hash = this.getHash().reverse()
const target = Block.calculateTarget(this.bits)

@@ -188,0 +188,0 @@ return hash.compare(target) <= 0

@@ -1,4 +0,1 @@

var pushdata = require('pushdata-bitcoin')
var varuint = require('varuint-bitcoin')
// https://github.com/feross/buffer/blob/master/index.js#L1127

@@ -13,8 +10,7 @@ function verifuint (value, max) {

function readUInt64LE (buffer, offset) {
var a = buffer.readUInt32LE(offset)
var b = buffer.readUInt32LE(offset + 4)
const a = buffer.readUInt32LE(offset)
let b = buffer.readUInt32LE(offset + 4)
b *= 0x100000000
verifuint(b + a, 0x001fffffffffffff)
return b + a

@@ -31,28 +27,5 @@ }

// TODO: remove in 4.0.0?
function readVarInt (buffer, offset) {
var result = varuint.decode(buffer, offset)
return {
number: result,
size: varuint.decode.bytes
}
}
// TODO: remove in 4.0.0?
function writeVarInt (buffer, number, offset) {
varuint.encode(number, buffer, offset)
return varuint.encode.bytes
}
module.exports = {
pushDataSize: pushdata.encodingLength,
readPushDataInt: pushdata.decode,
readUInt64LE: readUInt64LE,
readVarInt: readVarInt,
varIntBuffer: varuint.encode,
varIntSize: varuint.encodingLength,
writePushDataInt: pushdata.encode,
writeUInt64LE: writeUInt64LE,
writeVarInt: writeVarInt
writeUInt64LE: writeUInt64LE
}

@@ -1,2 +0,2 @@

var createHash = require('create-hash')
const createHash = require('create-hash')

@@ -3,0 +3,0 @@ function ripemd160 (buffer) {

@@ -1,64 +0,69 @@

var baddress = require('./address')
var bcrypto = require('./crypto')
var ecdsa = require('./ecdsa')
var randomBytes = require('randombytes')
var typeforce = require('typeforce')
var types = require('./types')
var wif = require('wif')
const ecc = require('tiny-secp256k1')
const randomBytes = require('randombytes')
const typeforce = require('typeforce')
const types = require('./types')
const wif = require('wif')
var NETWORKS = require('./networks')
var BigInteger = require('bigi')
const NETWORKS = require('./networks')
var ecurve = require('ecurve')
var secp256k1 = ecdsa.__curve
// TODO: why is the function name toJSON weird?
function isPoint (x) { return ecc.isPoint(x) }
const isOptions = typeforce.maybe(typeforce.compile({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}))
function ECPair (d, Q, options) {
if (options) {
typeforce({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}, options)
}
options = options || {}
if (d) {
if (d.signum() <= 0) throw new Error('Private key must be greater than 0')
if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order')
if (Q) throw new TypeError('Unexpected publicKey parameter')
this.compressed = options.compressed === undefined ? true : options.compressed
this.network = options.network || NETWORKS.bitcoin
this.d = d
} else {
typeforce(types.ECPoint, Q)
this.__d = d || null
this.__Q = null
if (Q) this.__Q = ecc.pointCompress(Q, this.compressed)
}
this.__Q = Q
}
Object.defineProperty(ECPair.prototype, 'privateKey', {
enumerable: false,
get: function () { return this.__d }
})
this.compressed = options.compressed === undefined ? true : options.compressed
this.network = options.network || NETWORKS.bitcoin
Object.defineProperty(ECPair.prototype, 'publicKey', { get: function () {
if (!this.__Q) this.__Q = ecc.pointFromScalar(this.__d, this.compressed)
return this.__Q
}})
ECPair.prototype.toWIF = function () {
if (!this.__d) throw new Error('Missing private key')
return wif.encode(this.network.wif, this.__d, this.compressed)
}
Object.defineProperty(ECPair.prototype, 'Q', {
get: function () {
if (!this.__Q && this.d) {
this.__Q = secp256k1.G.multiply(this.d)
}
ECPair.prototype.sign = function (hash) {
if (!this.__d) throw new Error('Missing private key')
return ecc.sign(hash, this.__d)
}
return this.__Q
}
})
ECPair.prototype.verify = function (hash, signature) {
return ecc.verify(hash, this.publicKey, signature)
}
ECPair.fromPublicKeyBuffer = function (buffer, network) {
var Q = ecurve.Point.decodeFrom(secp256k1, buffer)
function fromPrivateKey (buffer, options) {
typeforce(types.Buffer256bit, buffer)
if (!ecc.isPrivate(buffer)) throw new TypeError('Private key not in range [1, n)')
typeforce(isOptions, options)
return new ECPair(null, Q, {
compressed: Q.compressed,
network: network
})
return new ECPair(buffer, null, options)
}
ECPair.fromWIF = function (string, network) {
var decoded = wif.decode(string)
var version = decoded.version
function fromPublicKey (buffer, options) {
typeforce(isPoint, buffer)
typeforce(isOptions, options)
return new ECPair(null, buffer, options)
}
function fromWIF (string, network) {
const decoded = wif.decode(string)
const version = decoded.version
// list of networks?

@@ -79,5 +84,3 @@ if (types.Array(network)) {

var d = BigInteger.fromBuffer(decoded.privateKey)
return new ECPair(d, null, {
return fromPrivateKey(decoded.privateKey, {
compressed: decoded.compressed,

@@ -88,46 +91,21 @@ network: network

ECPair.makeRandom = function (options) {
function makeRandom (options) {
typeforce(isOptions, options)
options = options || {}
const rng = options.rng || randomBytes
var rng = options.rng || randomBytes
var d
let d
do {
var buffer = rng(32)
typeforce(types.Buffer256bit, buffer)
d = rng(32)
typeforce(types.Buffer256bit, d)
} while (!ecc.isPrivate(d))
d = BigInteger.fromBuffer(buffer)
} while (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0)
return new ECPair(d, null, options)
return fromPrivateKey(d, options)
}
ECPair.prototype.getAddress = function () {
return baddress.toBase58Check(bcrypto.hash160(this.getPublicKeyBuffer()), this.getNetwork().pubKeyHash)
module.exports = {
makeRandom,
fromPrivateKey,
fromPublicKey,
fromWIF
}
ECPair.prototype.getNetwork = function () {
return this.network
}
ECPair.prototype.getPublicKeyBuffer = function () {
return this.Q.getEncoded(this.compressed)
}
ECPair.prototype.sign = function (hash) {
if (!this.d) throw new Error('Missing private key')
return ecdsa.sign(hash, this.d)
}
ECPair.prototype.toWIF = function () {
if (!this.d) throw new Error('Missing private key')
return wif.encode(this.network.wif, this.d.toBuffer(32), this.compressed)
}
ECPair.prototype.verify = function (hash, signature) {
return ecdsa.verify(hash, signature, this.Q)
}
module.exports = ECPair

@@ -1,15 +0,6 @@

var script = require('./script')
const script = require('./script')
var templates = require('./templates')
for (var key in templates) {
script[key] = templates[key]
}
module.exports = {
bufferutils: require('./bufferutils'), // TODO: remove in 4.0.0
Block: require('./block'),
ECPair: require('./ecpair'),
ECSignature: require('./ecsignature'),
HDNode: require('./hdnode'),
Transaction: require('./transaction'),

@@ -19,6 +10,8 @@ TransactionBuilder: require('./transaction_builder'),

address: require('./address'),
bip32: require('bip32'),
crypto: require('./crypto'),
networks: require('./networks'),
opcodes: require('bitcoin-ops'),
payments: require('./payments'),
script: script
}

@@ -26,13 +26,3 @@ // https://en.bitcoin.it/wiki/List_of_address_prefixes

wif: 0xef
},
litecoin: {
messagePrefix: '\x19Litecoin Signed Message:\n',
bip32: {
public: 0x019da462,
private: 0x019d9cfe
},
pubKeyHash: 0x30,
scriptHash: 0x32,
wif: 0xb0
}
}

@@ -1,2 +0,2 @@

var Buffer = require('safe-buffer').Buffer
const Buffer = require('safe-buffer').Buffer

@@ -7,3 +7,3 @@ function decode (buffer, maxLength, minimal) {

var length = buffer.length
const length = buffer.length
if (length === 0) return 0

@@ -19,4 +19,4 @@ if (length > maxLength) throw new TypeError('Script number overflow')

if (length === 5) {
var a = buffer.readUInt32LE(0)
var b = buffer.readUInt8(4)
const a = buffer.readUInt32LE(0)
const b = buffer.readUInt8(4)

@@ -27,5 +27,4 @@ if (b & 0x80) return -(((b & ~0x80) * 0x100000000) + a)

var result = 0
// 32-bit / 24-bit / 16-bit / 8-bit
let result = 0
for (var i = 0; i < length; ++i) {

@@ -41,14 +40,14 @@ result |= buffer[i] << (8 * i)

return i > 0x7fffffff ? 5
: i > 0x7fffff ? 4
: i > 0x7fff ? 3
: i > 0x7f ? 2
: i > 0x00 ? 1
: 0
: i > 0x7fffff ? 4
: i > 0x7fff ? 3
: i > 0x7f ? 2
: i > 0x00 ? 1
: 0
}
function encode (number) {
var value = Math.abs(number)
var size = scriptNumSize(value)
var buffer = Buffer.allocUnsafe(size)
var negative = number < 0
let value = Math.abs(number)
const size = scriptNumSize(value)
const buffer = Buffer.allocUnsafe(size)
const negative = number < 0

@@ -55,0 +54,0 @@ for (var i = 0; i < size; ++i) {

@@ -1,11 +0,12 @@

var Buffer = require('safe-buffer').Buffer
var bip66 = require('bip66')
var pushdata = require('pushdata-bitcoin')
var typeforce = require('typeforce')
var types = require('./types')
var scriptNumber = require('./script_number')
const Buffer = require('safe-buffer').Buffer
const bip66 = require('bip66')
const ecc = require('tiny-secp256k1')
const pushdata = require('pushdata-bitcoin')
const typeforce = require('typeforce')
const types = require('./types')
const scriptNumber = require('./script_number')
var OPS = require('bitcoin-ops')
var REVERSE_OPS = require('bitcoin-ops/map')
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
const OPS = require('bitcoin-ops')
const REVERSE_OPS = require('bitcoin-ops/map')
const OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1

@@ -40,3 +41,3 @@ function isOPInt (value) {

var bufferSize = chunks.reduce(function (accum, chunk) {
const bufferSize = chunks.reduce(function (accum, chunk) {
// data chunk

@@ -56,4 +57,4 @@ if (Buffer.isBuffer(chunk)) {

var buffer = Buffer.allocUnsafe(bufferSize)
var offset = 0
const buffer = Buffer.allocUnsafe(bufferSize)
let offset = 0

@@ -64,3 +65,3 @@ chunks.forEach(function (chunk) {

// adhere to BIP62.3, minimal push policy
var opcode = asMinimalOP(chunk)
const opcode = asMinimalOP(chunk)
if (opcode !== undefined) {

@@ -93,24 +94,24 @@ buffer.writeUInt8(opcode, offset)

var chunks = []
var i = 0
const chunks = []
let i = 0
while (i < buffer.length) {
var opcode = buffer[i]
const opcode = buffer[i]
// data chunk
if ((opcode > OPS.OP_0) && (opcode <= OPS.OP_PUSHDATA4)) {
var d = pushdata.decode(buffer, i)
const d = pushdata.decode(buffer, i)
// did reading a pushDataInt fail? empty script
if (d === null) return []
// did reading a pushDataInt fail?
if (d === null) return null
i += d.size
// attempt to read too much data? empty script
if (i + d.number > buffer.length) return []
// attempt to read too much data?
if (i + d.number > buffer.length) return null
var data = buffer.slice(i, i + d.number)
const data = buffer.slice(i, i + d.number)
i += d.number
// decompile minimally
var op = asMinimalOP(data)
const op = asMinimalOP(data)
if (op !== undefined) {

@@ -141,3 +142,3 @@ chunks.push(op)

if (Buffer.isBuffer(chunk)) {
var op = asMinimalOP(chunk)
const op = asMinimalOP(chunk)
if (op === undefined) return chunk.toString('hex')

@@ -178,24 +179,13 @@ chunk = op

function isCanonicalPubKey (buffer) {
if (!Buffer.isBuffer(buffer)) return false
if (buffer.length < 33) return false
switch (buffer[0]) {
case 0x02:
case 0x03:
return buffer.length === 33
case 0x04:
return buffer.length === 65
}
return false
return ecc.isPoint(buffer)
}
function isDefinedHashType (hashType) {
var hashTypeMod = hashType & ~0x80
const hashTypeMod = hashType & ~0x80
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
return hashTypeMod > 0x00 && hashTypeMod < 0x04
}
function isCanonicalSignature (buffer) {
function isCanonicalScriptSignature (buffer) {
if (!Buffer.isBuffer(buffer)) return false

@@ -215,7 +205,8 @@ if (!isDefinedHashType(buffer[buffer.length - 1])) return false

number: require('./script_number'),
signature: require('./script_signature'),
isCanonicalPubKey: isCanonicalPubKey,
isCanonicalSignature: isCanonicalSignature,
isCanonicalScriptSignature: isCanonicalScriptSignature,
isPushOnly: isPushOnly,
isDefinedHashType: isDefinedHashType
}
// OP_0 [signatures ...]
var Buffer = require('safe-buffer').Buffer
var bscript = require('../../script')
var p2mso = require('./output')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const OPS = require('bitcoin-ops')
function partialSignature (value) {
return value === OPS.OP_0 || bscript.isCanonicalSignature(value)
return value === OPS.OP_0 || bscript.isCanonicalScriptSignature(value)
}
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
if (chunks.length < 2) return false

@@ -22,52 +19,6 @@ if (chunks[0] !== OPS.OP_0) return false

return chunks.slice(1).every(bscript.isCanonicalSignature)
return chunks.slice(1).every(bscript.isCanonicalScriptSignature)
}
check.toJSON = function () { return 'multisig input' }
var EMPTY_BUFFER = Buffer.allocUnsafe(0)
function encodeStack (signatures, scriptPubKey) {
typeforce([partialSignature], signatures)
if (scriptPubKey) {
var scriptData = p2mso.decode(scriptPubKey)
if (signatures.length < scriptData.m) {
throw new TypeError('Not enough signatures provided')
}
if (signatures.length > scriptData.pubKeys.length) {
throw new TypeError('Too many signatures provided')
}
}
return [].concat(EMPTY_BUFFER, signatures.map(function (sig) {
if (sig === OPS.OP_0) {
return EMPTY_BUFFER
}
return sig
}))
}
function encode (signatures, scriptPubKey) {
return bscript.compile(encodeStack(signatures, scriptPubKey))
}
function decodeStack (stack, allowIncomplete) {
typeforce(typeforce.Array, stack)
typeforce(check, stack, allowIncomplete)
return stack.slice(1)
}
function decode (buffer, allowIncomplete) {
var stack = bscript.decompile(buffer)
return decodeStack(stack, allowIncomplete)
}
module.exports = {
check: check,
decode: decode,
decodeStack: decodeStack,
encode: encode,
encodeStack: encodeStack
}
module.exports = { check }
// m [pubKeys ...] n OP_CHECKMULTISIG
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
const bscript = require('../../script')
const types = require('../../types')
const OPS = require('bitcoin-ops')
const OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)

@@ -16,4 +15,4 @@ if (chunks.length < 4) return false

if (!types.Number(chunks[chunks.length - 2])) return false
var m = chunks[0] - OP_INT_BASE
var n = chunks[chunks.length - 2] - OP_INT_BASE
const m = chunks[0] - OP_INT_BASE
const n = chunks[chunks.length - 2] - OP_INT_BASE

@@ -26,3 +25,3 @@ if (m <= 0) return false

var keys = chunks.slice(1, -2)
const keys = chunks.slice(1, -2)
return keys.every(bscript.isCanonicalPubKey)

@@ -32,36 +31,2 @@ }

function encode (m, pubKeys) {
typeforce({
m: types.Number,
pubKeys: [bscript.isCanonicalPubKey]
}, {
m: m,
pubKeys: pubKeys
})
var n = pubKeys.length
if (n < m) throw new TypeError('Not enough pubKeys provided')
return bscript.compile([].concat(
OP_INT_BASE + m,
pubKeys,
OP_INT_BASE + n,
OPS.OP_CHECKMULTISIG
))
}
function decode (buffer, allowIncomplete) {
var chunks = bscript.decompile(buffer)
typeforce(check, chunks, allowIncomplete)
return {
m: chunks[0] - OP_INT_BASE,
pubKeys: chunks.slice(1, -2)
}
}
module.exports = {
check: check,
decode: decode,
encode: encode
}
module.exports = { check }
// OP_RETURN {data}
var bscript = require('../script')
var types = require('../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../script')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)

@@ -16,20 +14,2 @@ return buffer.length > 1 &&

function encode (data) {
typeforce(types.Buffer, data)
return bscript.compile([OPS.OP_RETURN, data])
}
function decode (buffer) {
typeforce(check, buffer)
return buffer.slice(2)
}
module.exports = {
output: {
check: check,
decode: decode,
encode: encode
}
}
module.exports = { output: { check: check } }
// {signature}
var bscript = require('../../script')
var typeforce = require('typeforce')
const bscript = require('../../script')
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 1 &&
bscript.isCanonicalSignature(chunks[0])
bscript.isCanonicalScriptSignature(chunks[0])
}
check.toJSON = function () { return 'pubKey input' }
function encodeStack (signature) {
typeforce(bscript.isCanonicalSignature, signature)
return [signature]
}
function encode (signature) {
return bscript.compile(encodeStack(signature))
}
function decodeStack (stack) {
typeforce(typeforce.Array, stack)
typeforce(check, stack)
return stack[0]
}
function decode (buffer) {
var stack = bscript.decompile(buffer)
return decodeStack(stack)
}
module.exports = {
check: check,
decode: decode,
decodeStack: decodeStack,
encode: encode,
encodeStack: encodeStack
check: check
}
// {pubKey} OP_CHECKSIG
var bscript = require('../../script')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const OPS = require('bitcoin-ops')
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)

@@ -16,19 +15,2 @@ return chunks.length === 2 &&

function encode (pubKey) {
typeforce(bscript.isCanonicalPubKey, pubKey)
return bscript.compile([pubKey, OPS.OP_CHECKSIG])
}
function decode (buffer) {
var chunks = bscript.decompile(buffer)
typeforce(check, chunks)
return chunks[0]
}
module.exports = {
check: check,
decode: decode,
encode: encode
}
module.exports = { check }
// {signature} {pubKey}
var bscript = require('../../script')
var typeforce = require('typeforce')
const bscript = require('../../script')
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 2 &&
bscript.isCanonicalSignature(chunks[0]) &&
bscript.isCanonicalScriptSignature(chunks[0]) &&
bscript.isCanonicalPubKey(chunks[1])

@@ -15,39 +14,2 @@ }

function encodeStack (signature, pubKey) {
typeforce({
signature: bscript.isCanonicalSignature,
pubKey: bscript.isCanonicalPubKey
}, {
signature: signature,
pubKey: pubKey
})
return [signature, pubKey]
}
function encode (signature, pubKey) {
return bscript.compile(encodeStack(signature, pubKey))
}
function decodeStack (stack) {
typeforce(typeforce.Array, stack)
typeforce(check, stack)
return {
signature: stack[0],
pubKey: stack[1]
}
}
function decode (buffer) {
var stack = bscript.decompile(buffer)
return decodeStack(stack)
}
module.exports = {
check: check,
decode: decode,
decodeStack: decodeStack,
encode: encode,
encodeStack: encodeStack
}
module.exports = { check }
// OP_DUP OP_HASH160 {pubKeyHash} OP_EQUALVERIFY OP_CHECKSIG
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)

@@ -20,24 +18,2 @@ return buffer.length === 25 &&

function encode (pubKeyHash) {
typeforce(types.Hash160bit, pubKeyHash)
return bscript.compile([
OPS.OP_DUP,
OPS.OP_HASH160,
pubKeyHash,
OPS.OP_EQUALVERIFY,
OPS.OP_CHECKSIG
])
}
function decode (buffer) {
typeforce(check, buffer)
return buffer.slice(3, 23)
}
module.exports = {
check: check,
decode: decode,
encode: encode
}
module.exports = { check }
// <scriptSig> {serialized scriptPubKey script}
var Buffer = require('safe-buffer').Buffer
var bscript = require('../../script')
var typeforce = require('typeforce')
const Buffer = require('safe-buffer').Buffer
const bscript = require('../../script')
var p2ms = require('../multisig/')
var p2pk = require('../pubkey/')
var p2pkh = require('../pubkeyhash/')
var p2wpkho = require('../witnesspubkeyhash/output')
var p2wsho = require('../witnessscripthash/output')
const p2ms = require('../multisig/')
const p2pk = require('../pubkey/')
const p2pkh = require('../pubkeyhash/')
const p2wpkho = require('../witnesspubkeyhash/output')
const p2wsho = require('../witnessscripthash/output')
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
if (chunks.length < 1) return false
var lastChunk = chunks[chunks.length - 1]
const lastChunk = chunks[chunks.length - 1]
if (!Buffer.isBuffer(lastChunk)) return false
var scriptSigChunks = bscript.decompile(bscript.compile(chunks.slice(0, -1)))
var redeemScriptChunks = bscript.decompile(lastChunk)
const scriptSigChunks = bscript.decompile(bscript.compile(chunks.slice(0, -1)))
const redeemScriptChunks = bscript.decompile(lastChunk)
// is redeemScript a valid script?
if (redeemScriptChunks.length === 0) return false
if (!redeemScriptChunks) return false

@@ -49,38 +48,2 @@ // is redeemScriptSig push only?

function encodeStack (redeemScriptStack, redeemScript) {
var serializedScriptPubKey = bscript.compile(redeemScript)
return [].concat(redeemScriptStack, serializedScriptPubKey)
}
function encode (redeemScriptSig, redeemScript) {
var redeemScriptStack = bscript.decompile(redeemScriptSig)
return bscript.compile(encodeStack(redeemScriptStack, redeemScript))
}
function decodeStack (stack) {
typeforce(typeforce.Array, stack)
typeforce(check, stack)
return {
redeemScriptStack: stack.slice(0, -1),
redeemScript: stack[stack.length - 1]
}
}
function decode (buffer) {
var stack = bscript.decompile(buffer)
var result = decodeStack(stack)
result.redeemScriptSig = bscript.compile(result.redeemScriptStack)
delete result.redeemScriptStack
return result
}
module.exports = {
check: check,
decode: decode,
decodeStack: decodeStack,
encode: encode,
encodeStack: encodeStack
}
module.exports = { check }
// OP_HASH160 {scriptHash} OP_EQUAL
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)

@@ -18,18 +16,2 @@ return buffer.length === 23 &&

function encode (scriptHash) {
typeforce(types.Hash160bit, scriptHash)
return bscript.compile([OPS.OP_HASH160, scriptHash, OPS.OP_EQUAL])
}
function decode (buffer) {
typeforce(check, buffer)
return buffer.slice(2, 22)
}
module.exports = {
check: check,
decode: decode,
encode: encode
}
module.exports = { check }
// OP_RETURN {aa21a9ed} {commitment}
var Buffer = require('safe-buffer').Buffer
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const Buffer = require('safe-buffer').Buffer
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
var HEADER = Buffer.from('aa21a9ed', 'hex')
const HEADER = Buffer.from('aa21a9ed', 'hex')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)

@@ -25,3 +25,3 @@ return buffer.length > 37 &&

var buffer = Buffer.allocUnsafe(36)
const buffer = Buffer.allocUnsafe(36)
HEADER.copy(buffer, 0)

@@ -28,0 +28,0 @@ commitment.copy(buffer, 4)

// {signature} {pubKey}
var bscript = require('../../script')
var typeforce = require('typeforce')
const bscript = require('../../script')

@@ -11,6 +10,6 @@ function isCompressedCanonicalPubKey (pubKey) {

function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 2 &&
bscript.isCanonicalSignature(chunks[0]) &&
bscript.isCanonicalScriptSignature(chunks[0]) &&
isCompressedCanonicalPubKey(chunks[1])

@@ -20,28 +19,2 @@ }

function encodeStack (signature, pubKey) {
typeforce({
signature: bscript.isCanonicalSignature,
pubKey: isCompressedCanonicalPubKey
}, {
signature: signature,
pubKey: pubKey
})
return [signature, pubKey]
}
function decodeStack (stack) {
typeforce(typeforce.Array, stack)
typeforce(check, stack)
return {
signature: stack[0],
pubKey: stack[1]
}
}
module.exports = {
check: check,
decodeStack: decodeStack,
encodeStack: encodeStack
}
module.exports = { check }
// OP_0 {pubKeyHash}
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)

@@ -17,18 +15,4 @@ return buffer.length === 22 &&

function encode (pubKeyHash) {
typeforce(types.Hash160bit, pubKeyHash)
return bscript.compile([OPS.OP_0, pubKeyHash])
}
function decode (buffer) {
typeforce(check, buffer)
return buffer.slice(2)
}
module.exports = {
check: check,
decode: decode,
encode: encode
check
}
// <scriptSig> {serialized scriptPubKey script}
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
var p2ms = require('../multisig/')
var p2pk = require('../pubkey/')
var p2pkh = require('../pubkeyhash/')
const p2ms = require('../multisig/')
const p2pk = require('../pubkey/')
const p2pkh = require('../pubkeyhash/')

@@ -15,11 +15,11 @@ function check (chunks, allowIncomplete) {

var witnessScript = chunks[chunks.length - 1]
const witnessScript = chunks[chunks.length - 1]
if (!Buffer.isBuffer(witnessScript)) return false
var witnessScriptChunks = bscript.decompile(witnessScript)
const witnessScriptChunks = bscript.decompile(witnessScript)
// is witnessScript a valid script?
if (witnessScriptChunks.length === 0) return false
if (!witnessScriptChunks || witnessScriptChunks.length === 0) return false
var witnessRawScriptSig = bscript.compile(chunks.slice(0, -1))
const witnessRawScriptSig = bscript.compile(chunks.slice(0, -1))

@@ -40,27 +40,2 @@ // match types

function encodeStack (witnessData, witnessScript) {
typeforce({
witnessData: [types.Buffer],
witnessScript: types.Buffer
}, {
witnessData: witnessData,
witnessScript: witnessScript
})
return [].concat(witnessData, witnessScript)
}
function decodeStack (stack) {
typeforce(typeforce.Array, stack)
typeforce(check, stack)
return {
witnessData: stack.slice(0, -1),
witnessScript: stack[stack.length - 1]
}
}
module.exports = {
check: check,
decodeStack: decodeStack,
encodeStack: encodeStack
}
module.exports = { check }
// OP_0 {scriptHash}
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)

@@ -17,18 +15,2 @@ return buffer.length === 34 &&

function encode (scriptHash) {
typeforce(types.Hash256bit, scriptHash)
return bscript.compile([OPS.OP_0, scriptHash])
}
function decode (buffer) {
typeforce(check, buffer)
return buffer.slice(2)
}
module.exports = {
check: check,
decode: decode,
encode: encode
}
module.exports = { check }

@@ -1,174 +0,125 @@

var Buffer = require('safe-buffer').Buffer
var baddress = require('./address')
var bcrypto = require('./crypto')
var bscript = require('./script')
var btemplates = require('./templates')
var networks = require('./networks')
var ops = require('bitcoin-ops')
var typeforce = require('typeforce')
var types = require('./types')
var scriptTypes = btemplates.types
var SIGNABLE = [btemplates.types.P2PKH, btemplates.types.P2PK, btemplates.types.MULTISIG]
var P2SH = SIGNABLE.concat([btemplates.types.P2WPKH, btemplates.types.P2WSH])
const Buffer = require('safe-buffer').Buffer
const baddress = require('./address')
const bcrypto = require('./crypto')
const bscript = require('./script')
const networks = require('./networks')
const ops = require('bitcoin-ops')
const payments = require('./payments')
const typeforce = require('typeforce')
const types = require('./types')
const classify = require('./classify')
const SCRIPT_TYPES = classify.types
var ECPair = require('./ecpair')
var ECSignature = require('./ecsignature')
var Transaction = require('./transaction')
const ECPair = require('./ecpair')
const Transaction = require('./transaction')
function supportedType (type) {
return SIGNABLE.indexOf(type) !== -1
}
function expandInput (scriptSig, witnessStack, type, scriptPubKey) {
if (scriptSig.length === 0 && witnessStack.length === 0) return {}
if (!type) {
let ssType = classify.input(scriptSig, true)
let wsType = classify.witness(witnessStack, true)
if (ssType === SCRIPT_TYPES.NONSTANDARD) ssType = undefined
if (wsType === SCRIPT_TYPES.NONSTANDARD) wsType = undefined
type = ssType || wsType
}
function supportedP2SHType (type) {
return P2SH.indexOf(type) !== -1
}
function extractChunks (type, chunks, script) {
var pubKeys = []
var signatures = []
switch (type) {
case scriptTypes.P2PKH:
// if (redeemScript) throw new Error('Nonstandard... P2SH(P2PKH)')
pubKeys = chunks.slice(1)
signatures = chunks.slice(0, 1)
break
case SCRIPT_TYPES.P2WPKH: {
const { output, pubkey, signature } = payments.p2wpkh({ witness: witnessStack })
case scriptTypes.P2PK:
pubKeys[0] = script ? btemplates.pubKey.output.decode(script) : undefined
signatures = chunks.slice(0, 1)
break
case scriptTypes.MULTISIG:
if (script) {
var multisig = btemplates.multisig.output.decode(script)
pubKeys = multisig.pubKeys
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2WPKH,
pubkeys: [pubkey],
signatures: [signature]
}
}
signatures = chunks.slice(1).map(function (chunk) {
return chunk.length === 0 ? undefined : chunk
})
break
}
case SCRIPT_TYPES.P2PKH: {
const { output, pubkey, signature } = payments.p2pkh({ input: scriptSig })
return {
pubKeys: pubKeys,
signatures: signatures
}
}
function expandInput (scriptSig, witnessStack) {
if (scriptSig.length === 0 && witnessStack.length === 0) return {}
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2PKH,
pubkeys: [pubkey],
signatures: [signature]
}
}
var prevOutScript
var prevOutType
var scriptType
var script
var redeemScript
var witnessScript
var witnessScriptType
var redeemScriptType
var witness = false
var p2wsh = false
var p2sh = false
var witnessProgram
var chunks
case SCRIPT_TYPES.P2PK: {
const { signature } = payments.p2pk({ input: scriptSig })
var scriptSigChunks = bscript.decompile(scriptSig)
var sigType = btemplates.classifyInput(scriptSigChunks, true)
if (sigType === scriptTypes.P2SH) {
p2sh = true
redeemScript = scriptSigChunks[scriptSigChunks.length - 1]
redeemScriptType = btemplates.classifyOutput(redeemScript)
prevOutScript = btemplates.scriptHash.output.encode(bcrypto.hash160(redeemScript))
prevOutType = scriptTypes.P2SH
script = redeemScript
}
var classifyWitness = btemplates.classifyWitness(witnessStack, true)
if (classifyWitness === scriptTypes.P2WSH) {
witnessScript = witnessStack[witnessStack.length - 1]
witnessScriptType = btemplates.classifyOutput(witnessScript)
p2wsh = true
witness = true
if (scriptSig.length === 0) {
prevOutScript = btemplates.witnessScriptHash.output.encode(bcrypto.sha256(witnessScript))
prevOutType = scriptTypes.P2WSH
if (redeemScript !== undefined) {
throw new Error('Redeem script given when unnecessary')
return {
prevOutType: SCRIPT_TYPES.P2PK,
pubkeys: [undefined],
signatures: [signature]
}
// bare witness
} else {
if (!redeemScript) {
throw new Error('No redeemScript provided for P2WSH, but scriptSig non-empty')
}
witnessProgram = btemplates.witnessScriptHash.output.encode(bcrypto.sha256(witnessScript))
if (!redeemScript.equals(witnessProgram)) {
throw new Error('Redeem script didn\'t match witnessScript')
}
}
if (!supportedType(btemplates.classifyOutput(witnessScript))) {
throw new Error('unsupported witness script')
}
case SCRIPT_TYPES.MULTISIG: {
const { pubkeys, signatures } = payments.p2ms({
input: scriptSig,
output: scriptPubKey
}, { allowIncomplete: true })
script = witnessScript
scriptType = witnessScriptType
chunks = witnessStack.slice(0, -1)
} else if (classifyWitness === scriptTypes.P2WPKH) {
witness = true
var key = witnessStack[witnessStack.length - 1]
var keyHash = bcrypto.hash160(key)
if (scriptSig.length === 0) {
prevOutScript = btemplates.witnessPubKeyHash.output.encode(keyHash)
prevOutType = scriptTypes.P2WPKH
if (typeof redeemScript !== 'undefined') {
throw new Error('Redeem script given when unnecessary')
return {
prevOutType: SCRIPT_TYPES.MULTISIG,
pubkeys: pubkeys,
signatures: signatures
}
} else {
if (!redeemScript) {
throw new Error('No redeemScript provided for P2WPKH, but scriptSig wasn\'t empty')
}
witnessProgram = btemplates.witnessPubKeyHash.output.encode(keyHash)
if (!redeemScript.equals(witnessProgram)) {
throw new Error('Redeem script did not have the right witness program')
}
}
}
scriptType = scriptTypes.P2PKH
chunks = witnessStack
} else if (redeemScript) {
if (!supportedP2SHType(redeemScriptType)) {
throw new Error('Bad redeemscript!')
}
if (type === SCRIPT_TYPES.P2SH) {
const { output, redeem } = payments.p2sh({
input: scriptSig,
witness: witnessStack
})
script = redeemScript
scriptType = redeemScriptType
chunks = scriptSigChunks.slice(0, -1)
} else {
prevOutType = scriptType = btemplates.classifyInput(scriptSig)
chunks = scriptSigChunks
}
const outputType = classify.output(redeem.output)
const expanded = expandInput(redeem.input, redeem.witness, outputType, redeem.output)
if (!expanded.prevOutType) return {}
var expanded = extractChunks(scriptType, chunks, script)
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2SH,
redeemScript: redeem.output,
redeemScriptType: expanded.prevOutType,
witnessScript: expanded.witnessScript,
witnessScriptType: expanded.witnessScriptType,
var result = {
pubKeys: expanded.pubKeys,
signatures: expanded.signatures,
prevOutScript: prevOutScript,
prevOutType: prevOutType,
signType: scriptType,
signScript: script,
witness: Boolean(witness)
pubkeys: expanded.pubkeys,
signatures: expanded.signatures
}
}
if (p2sh) {
result.redeemScript = redeemScript
result.redeemScriptType = redeemScriptType
if (type === SCRIPT_TYPES.P2WSH) {
const { output, redeem } = payments.p2wsh({
input: scriptSig,
witness: witnessStack
})
const outputType = classify.output(redeem.output)
let expanded
if (outputType === SCRIPT_TYPES.P2WPKH) {
expanded = expandInput(redeem.input, redeem.witness, outputType)
} else {
expanded = expandInput(bscript.compile(redeem.witness), [], outputType, redeem.output)
}
if (!expanded.prevOutType) return {}
return {
prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2WSH,
witnessScript: redeem.output,
witnessScriptType: expanded.prevOutType,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures
}
}
if (p2wsh) {
result.witnessScript = witnessScript
result.witnessScriptType = witnessScriptType
return {
prevOutType: SCRIPT_TYPES.NONSTANDARD,
prevOutScript: scriptSig
}
return result
}

@@ -178,10 +129,10 @@

function fixMultisigOrder (input, transaction, vin) {
if (input.redeemScriptType !== scriptTypes.MULTISIG || !input.redeemScript) return
if (input.pubKeys.length === input.signatures.length) return
if (input.redeemScriptType !== SCRIPT_TYPES.MULTISIG || !input.redeemScript) return
if (input.pubkeys.length === input.signatures.length) return
var unmatched = input.signatures.concat()
const unmatched = input.signatures.concat()
input.signatures = input.pubKeys.map(function (pubKey) {
var keyPair = ECPair.fromPublicKeyBuffer(pubKey)
var match
input.signatures = input.pubkeys.map(function (pubKey) {
const keyPair = ECPair.fromPublicKey(pubKey)
let match

@@ -194,4 +145,4 @@ // check for a signature

// TODO: avoid O(n) hashForSignature
var parsed = ECSignature.parseScriptSignature(signature)
var hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType)
const parsed = bscript.signature.decode(signature)
const hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType)

@@ -212,261 +163,274 @@ // skip if signature does not match pubKey

function expandOutput (script, scriptType, ourPubKey) {
function expandOutput (script, ourPubKey) {
typeforce(types.Buffer, script)
const type = classify.output(script)
var scriptChunks = bscript.decompile(script)
if (!scriptType) {
scriptType = btemplates.classifyOutput(script)
}
switch (type) {
case SCRIPT_TYPES.P2PKH: {
if (!ourPubKey) return { type }
var pubKeys = []
// does our hash160(pubKey) match the output scripts?
const pkh1 = payments.p2pkh({ output: script }).hash
const pkh2 = bcrypto.hash160(ourPubKey)
if (!pkh1.equals(pkh2)) return { type }
switch (scriptType) {
// does our hash160(pubKey) match the output scripts?
case scriptTypes.P2PKH:
if (!ourPubKey) break
return {
type,
pubkeys: [ourPubKey],
signatures: [undefined]
}
}
var pkh1 = scriptChunks[2]
var pkh2 = bcrypto.hash160(ourPubKey)
if (pkh1.equals(pkh2)) pubKeys = [ourPubKey]
break
case SCRIPT_TYPES.P2WPKH: {
if (!ourPubKey) return { type }
// does our hash160(pubKey) match the output scripts?
case scriptTypes.P2WPKH:
if (!ourPubKey) break
// does our hash160(pubKey) match the output scripts?
const wpkh1 = payments.p2wpkh({ output: script }).hash
const wpkh2 = bcrypto.hash160(ourPubKey)
if (!wpkh1.equals(wpkh2)) return { type }
var wpkh1 = scriptChunks[1]
var wpkh2 = bcrypto.hash160(ourPubKey)
if (wpkh1.equals(wpkh2)) pubKeys = [ourPubKey]
break
return {
type,
pubkeys: [ourPubKey],
signatures: [undefined]
}
}
case scriptTypes.P2PK:
pubKeys = scriptChunks.slice(0, 1)
break
case SCRIPT_TYPES.P2PK: {
const p2pk = payments.p2pk({ output: script })
return {
type,
pubkeys: [p2pk.pubkey],
signatures: [undefined]
}
}
case scriptTypes.MULTISIG:
pubKeys = scriptChunks.slice(1, -2)
break
default: return { scriptType: scriptType }
case SCRIPT_TYPES.MULTISIG: {
const p2ms = payments.p2ms({ output: script })
return {
type,
pubkeys: p2ms.pubkeys,
signatures: p2ms.pubkeys.map(() => undefined)
}
}
}
return {
pubKeys: pubKeys,
scriptType: scriptType,
signatures: pubKeys.map(function () { return undefined })
}
return { type }
}
function checkP2SHInput (input, redeemScriptHash) {
if (input.prevOutType) {
if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH')
function prepareInput (input, ourPubKey, redeemScript, witnessValue, witnessScript) {
if (redeemScript && witnessScript) {
const p2wsh = payments.p2wsh({ redeem: { output: witnessScript } })
const p2wshAlt = payments.p2wsh({ output: redeemScript })
const p2sh = payments.p2sh({ redeem: { output: redeemScript } })
const p2shAlt = payments.p2sh({ redeem: p2wsh })
var prevOutScriptScriptHash = bscript.decompile(input.prevOutScript)[1]
if (!prevOutScriptScriptHash.equals(redeemScriptHash)) throw new Error('Inconsistent hash160(RedeemScript)')
}
}
// enforces P2SH(P2WSH(...))
if (!p2wsh.hash.equals(p2wshAlt.hash)) throw new Error('Witness script inconsistent with prevOutScript')
if (!p2sh.hash.equals(p2shAlt.hash)) throw new Error('Redeem script inconsistent with prevOutScript')
function checkP2WSHInput (input, witnessScriptHash) {
if (input.prevOutType) {
if (input.prevOutType !== scriptTypes.P2WSH) throw new Error('PrevOutScript must be P2WSH')
const expanded = expandOutput(p2wsh.redeem.output, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')')
if (input.signatures && input.signatures.some(x => x)) {
expanded.signatures = input.signatures
}
var scriptHash = bscript.decompile(input.prevOutScript)[1]
if (!scriptHash.equals(witnessScriptHash)) throw new Error('Inconsistent sha25(WitnessScript)')
}
}
let signScript = witnessScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2SH(P2WSH(P2WPKH)) is a consensus failure')
function prepareInput (input, kpPubKey, redeemScript, witnessValue, witnessScript) {
var expanded
var prevOutType
var prevOutScript
return {
redeemScript,
redeemScriptType: SCRIPT_TYPES.P2WSH,
var p2sh = false
var p2shType
var redeemScriptHash
witnessScript,
witnessScriptType: expanded.type,
var witness = false
var p2wsh = false
var witnessType
var witnessScriptHash
prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output,
var signType
var signScript
hasWitness: true,
signScript,
signType: expanded.type,
if (redeemScript && witnessScript) {
redeemScriptHash = bcrypto.hash160(redeemScript)
witnessScriptHash = bcrypto.sha256(witnessScript)
checkP2SHInput(input, redeemScriptHash)
pubkeys: expanded.pubkeys,
signatures: expanded.signatures
}
}
if (!redeemScript.equals(btemplates.witnessScriptHash.output.encode(witnessScriptHash))) throw new Error('Witness script inconsistent with redeem script')
if (redeemScript) {
const p2sh = payments.p2sh({ redeem: { output: redeemScript } })
expanded = expandOutput(witnessScript, undefined, kpPubKey)
if (!expanded.pubKeys) throw new Error('WitnessScript not supported "' + bscript.toASM(redeemScript) + '"')
if (input.prevOutScript) {
let p2shAlt
try {
p2shAlt = payments.p2sh({ output: input.prevOutScript })
} catch (e) { throw new Error('PrevOutScript must be P2SH') }
if (!p2sh.hash.equals(p2shAlt.hash)) throw new Error('Redeem script inconsistent with prevOutScript')
}
prevOutType = btemplates.types.P2SH
prevOutScript = btemplates.scriptHash.output.encode(redeemScriptHash)
p2sh = witness = p2wsh = true
p2shType = btemplates.types.P2WSH
signType = witnessType = expanded.scriptType
signScript = witnessScript
} else if (redeemScript) {
redeemScriptHash = bcrypto.hash160(redeemScript)
checkP2SHInput(input, redeemScriptHash)
const expanded = expandOutput(p2sh.redeem.output, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as redeemScript (' + bscript.toASM(redeemScript) + ')')
if (input.signatures && input.signatures.some(x => x)) {
expanded.signatures = input.signatures
}
expanded = expandOutput(redeemScript, undefined, kpPubKey)
if (!expanded.pubKeys) throw new Error('RedeemScript not supported "' + bscript.toASM(redeemScript) + '"')
let signScript = redeemScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output
}
prevOutType = btemplates.types.P2SH
prevOutScript = btemplates.scriptHash.output.encode(redeemScriptHash)
p2sh = true
signType = p2shType = expanded.scriptType
signScript = redeemScript
witness = signType === btemplates.types.P2WPKH
} else if (witnessScript) {
witnessScriptHash = bcrypto.sha256(witnessScript)
checkP2WSHInput(input, witnessScriptHash)
return {
redeemScript,
redeemScriptType: expanded.type,
expanded = expandOutput(witnessScript, undefined, kpPubKey)
if (!expanded.pubKeys) throw new Error('WitnessScript not supported "' + bscript.toASM(redeemScript) + '"')
prevOutType: SCRIPT_TYPES.P2SH,
prevOutScript: p2sh.output,
prevOutType = btemplates.types.P2WSH
prevOutScript = btemplates.witnessScriptHash.output.encode(witnessScriptHash)
witness = p2wsh = true
signType = witnessType = expanded.scriptType
signScript = witnessScript
} else if (input.prevOutType) {
// embedded scripts are not possible without a redeemScript
if (input.prevOutType === scriptTypes.P2SH ||
input.prevOutType === scriptTypes.P2WSH) {
throw new Error('PrevOutScript is ' + input.prevOutType + ', requires redeemScript')
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures
}
}
prevOutType = input.prevOutType
prevOutScript = input.prevOutScript
expanded = expandOutput(input.prevOutScript, input.prevOutType, kpPubKey)
if (!expanded.pubKeys) return
if (witnessScript) {
const p2wsh = payments.p2wsh({ redeem: { output: witnessScript } })
witness = (input.prevOutType === scriptTypes.P2WPKH)
signType = prevOutType
signScript = prevOutScript
} else {
prevOutScript = btemplates.pubKeyHash.output.encode(bcrypto.hash160(kpPubKey))
expanded = expandOutput(prevOutScript, scriptTypes.P2PKH, kpPubKey)
if (input.prevOutScript) {
const p2wshAlt = payments.p2wsh({ output: input.prevOutScript })
if (!p2wsh.hash.equals(p2wshAlt.hash)) throw new Error('Witness script inconsistent with prevOutScript')
}
prevOutType = scriptTypes.P2PKH
witness = false
signType = prevOutType
signScript = prevOutScript
}
const expanded = expandOutput(p2wsh.redeem.output, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')')
if (input.signatures && input.signatures.some(x => x)) {
expanded.signatures = input.signatures
}
if (signType === scriptTypes.P2WPKH) {
signScript = btemplates.pubKeyHash.output.encode(btemplates.witnessPubKeyHash.output.decode(signScript))
}
let signScript = witnessScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2WSH(P2WPKH) is a consensus failure')
if (p2sh) {
input.redeemScript = redeemScript
input.redeemScriptType = p2shType
}
return {
witnessScript,
witnessScriptType: expanded.type,
if (p2wsh) {
input.witnessScript = witnessScript
input.witnessScriptType = witnessType
prevOutType: SCRIPT_TYPES.P2WSH,
prevOutScript: p2wsh.output,
hasWitness: true,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures
}
}
input.pubKeys = expanded.pubKeys
input.signatures = expanded.signatures
input.signScript = signScript
input.signType = signType
input.prevOutScript = prevOutScript
input.prevOutType = prevOutType
input.witness = witness
}
if (input.prevOutType && input.prevOutScript) {
// embedded scripts are not possible without extra information
if (input.prevOutType === SCRIPT_TYPES.P2SH) throw new Error('PrevOutScript is ' + input.prevOutType + ', requires redeemScript')
if (input.prevOutType === SCRIPT_TYPES.P2WSH) throw new Error('PrevOutScript is ' + input.prevOutType + ', requires witnessScript')
if (!input.prevOutScript) throw new Error('PrevOutScript is missing')
function buildStack (type, signatures, pubKeys, allowIncomplete) {
if (type === scriptTypes.P2PKH) {
if (signatures.length === 1 && Buffer.isBuffer(signatures[0]) && pubKeys.length === 1) return btemplates.pubKeyHash.input.encodeStack(signatures[0], pubKeys[0])
} else if (type === scriptTypes.P2PK) {
if (signatures.length === 1 && Buffer.isBuffer(signatures[0])) return btemplates.pubKey.input.encodeStack(signatures[0])
} else if (type === scriptTypes.MULTISIG) {
if (signatures.length > 0) {
signatures = signatures.map(function (signature) {
return signature || ops.OP_0
})
if (!allowIncomplete) {
// remove blank signatures
signatures = signatures.filter(function (x) { return x !== ops.OP_0 })
}
const expanded = expandOutput(input.prevOutScript, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported (' + bscript.toASM(input.prevOutScript) + ')')
if (input.signatures && input.signatures.some(x => x)) {
expanded.signatures = input.signatures
}
return btemplates.multisig.input.encodeStack(signatures)
let signScript = input.prevOutScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output
}
} else {
throw new Error('Not yet supported')
return {
prevOutType: expanded.type,
prevOutScript: input.prevOutScript,
hasWitness: expanded.type === SCRIPT_TYPES.P2WPKH,
signScript,
signType: expanded.type,
pubkeys: expanded.pubkeys,
signatures: expanded.signatures
}
}
if (!allowIncomplete) throw new Error('Not enough signatures provided')
return []
}
const prevOutScript = payments.p2pkh({ pubkey: ourPubKey }).output
return {
prevOutType: SCRIPT_TYPES.P2PKH,
prevOutScript: prevOutScript,
function buildInput (input, allowIncomplete) {
var scriptType = input.prevOutType
var sig = []
var witness = []
hasWitness: false,
signScript: prevOutScript,
signType: SCRIPT_TYPES.P2PKH,
if (supportedType(scriptType)) {
sig = buildStack(scriptType, input.signatures, input.pubKeys, allowIncomplete)
pubkeys: [ourPubKey],
signatures: [undefined]
}
}
var p2sh = false
if (scriptType === btemplates.types.P2SH) {
// We can remove this error later when we have a guarantee prepareInput
// rejects unsignable scripts - it MUST be signable at this point.
if (!allowIncomplete && !supportedP2SHType(input.redeemScriptType)) {
throw new Error('Impossible to sign this type')
function build (type, input, allowIncomplete) {
const pubkeys = input.pubkeys || []
let signatures = input.signatures || []
switch (type) {
case SCRIPT_TYPES.P2PKH: {
if (pubkeys.length === 0) break
if (signatures.length === 0) break
return payments.p2pkh({ pubkey: pubkeys[0], signature: signatures[0] })
}
case SCRIPT_TYPES.P2WPKH: {
if (pubkeys.length === 0) break
if (signatures.length === 0) break
if (supportedType(input.redeemScriptType)) {
sig = buildStack(input.redeemScriptType, input.signatures, input.pubKeys, allowIncomplete)
return payments.p2wpkh({ pubkey: pubkeys[0], signature: signatures[0] })
}
case SCRIPT_TYPES.P2PK: {
if (pubkeys.length === 0) break
if (signatures.length === 0) break
// If it wasn't SIGNABLE, it's witness, defer to that
if (input.redeemScriptType) {
p2sh = true
scriptType = input.redeemScriptType
return payments.p2pk({ signature: signatures[0] })
}
}
switch (scriptType) {
// P2WPKH is a special case of P2PKH
case btemplates.types.P2WPKH:
witness = buildStack(btemplates.types.P2PKH, input.signatures, input.pubKeys, allowIncomplete)
break
case btemplates.types.P2WSH:
// We can remove this check later
if (!allowIncomplete && !supportedType(input.witnessScriptType)) {
throw new Error('Impossible to sign this type')
case SCRIPT_TYPES.MULTISIG: {
if (allowIncomplete) {
signatures = signatures.map(x => x || ops.OP_0)
} else {
signatures = signatures.filter(x => x)
}
if (supportedType(input.witnessScriptType)) {
witness = buildStack(input.witnessScriptType, input.signatures, input.pubKeys, allowIncomplete)
witness.push(input.witnessScript)
scriptType = input.witnessScriptType
}
return payments.p2ms({ signatures }, { allowIncomplete })
}
case SCRIPT_TYPES.P2SH: {
const redeem = build(input.redeemScriptType, input, allowIncomplete)
if (!redeem) return
break
}
return payments.p2sh({
redeem: {
output: redeem.output || input.redeemScript,
input: redeem.input,
witness: redeem.witness
}
})
}
case SCRIPT_TYPES.P2WSH: {
const redeem = build(input.witnessScriptType, input, allowIncomplete)
if (!redeem) return
// append redeemScript if necessary
if (p2sh) {
sig.push(input.redeemScript)
return payments.p2wsh({
redeem: {
output: input.witnessScript,
input: redeem.input,
witness: redeem.witness
}
})
}
}
return {
type: scriptType,
script: bscript.compile(sig),
witness: witness
}
}
function TransactionBuilder (network, maximumFeeRate) {
this.prevTxMap = {}
this.__prevTxSet = {}
this.network = network || networks.bitcoin

@@ -477,4 +441,5 @@

this.inputs = []
this.tx = new Transaction()
this.__inputs = []
this.__tx = new Transaction()
this.__tx.version = 2
}

@@ -486,3 +451,3 @@

// if any signatures exist, throw
if (this.inputs.some(function (input) {
if (this.__inputs.some(function (input) {
if (!input.signatures) return false

@@ -495,3 +460,3 @@

this.tx.locktime = locktime
this.__tx.locktime = locktime
}

@@ -503,7 +468,7 @@

// XXX: this might eventually become more complex depending on what the versions represent
this.tx.version = version
this.__tx.version = version
}
TransactionBuilder.fromTransaction = function (transaction, network) {
var txb = new TransactionBuilder(network)
const txb = new TransactionBuilder(network)

@@ -529,3 +494,3 @@ // Copy transaction fields

// fix some things not possible through the public API
txb.inputs.forEach(function (input, i) {
txb.__inputs.forEach(function (input, i) {
fixMultisigOrder(input, transaction, i)

@@ -542,3 +507,3 @@ })

var value
let value

@@ -552,3 +517,3 @@ // is it a hex string?

} else if (txHash instanceof Transaction) {
var txOut = txHash.outs[vout]
const txOut = txHash.outs[vout]
prevOutScript = txOut.script

@@ -572,6 +537,6 @@ value = txOut.value

var prevTxOut = txHash.toString('hex') + ':' + vout
if (this.prevTxMap[prevTxOut] !== undefined) throw new Error('Duplicate TxOut: ' + prevTxOut)
const prevTxOut = txHash.toString('hex') + ':' + vout
if (this.__prevTxSet[prevTxOut] !== undefined) throw new Error('Duplicate TxOut: ' + prevTxOut)
var input = {}
let input = {}

@@ -590,22 +555,21 @@ // derive what we can from the scriptSig

if (!input.prevOutScript && options.prevOutScript) {
var prevOutType
let prevOutType
if (!input.pubKeys && !input.signatures) {
var expanded = expandOutput(options.prevOutScript)
if (expanded.pubKeys) {
input.pubKeys = expanded.pubKeys
if (!input.pubkeys && !input.signatures) {
const expanded = expandOutput(options.prevOutScript)
if (expanded.pubkeys) {
input.pubkeys = expanded.pubkeys
input.signatures = expanded.signatures
}
prevOutType = expanded.scriptType
prevOutType = expanded.type
}
input.prevOutScript = options.prevOutScript
input.prevOutType = prevOutType || btemplates.classifyOutput(options.prevOutScript)
input.prevOutType = prevOutType || classify.output(options.prevOutScript)
}
var vin = this.tx.addInput(txHash, vout, options.sequence, options.scriptSig)
this.inputs[vin] = input
this.prevTxMap[prevTxOut] = vin
const vin = this.__tx.addInput(txHash, vout, options.sequence, options.scriptSig)
this.__inputs[vin] = input
this.__prevTxSet[prevTxOut] = true
return vin

@@ -619,3 +583,3 @@ }

// Attempt to get a script if it's a base58 address string
// Attempt to get a script if it's a base58 or bech32 address string
if (typeof scriptPubKey === 'string') {

@@ -625,3 +589,3 @@ scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network)

return this.tx.addOutput(scriptPubKey, value)
return this.__tx.addOutput(scriptPubKey, value)
}

@@ -638,21 +602,20 @@

if (!allowIncomplete) {
if (!this.tx.ins.length) throw new Error('Transaction has no inputs')
if (!this.tx.outs.length) throw new Error('Transaction has no outputs')
if (!this.__tx.ins.length) throw new Error('Transaction has no inputs')
if (!this.__tx.outs.length) throw new Error('Transaction has no outputs')
}
var tx = this.tx.clone()
// Create script signatures from inputs
this.inputs.forEach(function (input, i) {
var scriptType = input.witnessScriptType || input.redeemScriptType || input.prevOutType
if (!scriptType && !allowIncomplete) throw new Error('Transaction is not complete')
var result = buildInput(input, allowIncomplete)
const tx = this.__tx.clone()
// skip if no result
if (!allowIncomplete) {
if (!supportedType(result.type) && result.type !== btemplates.types.P2WPKH) {
throw new Error(result.type + ' not supported')
}
// create script signatures from inputs
this.__inputs.forEach(function (input, i) {
if (!input.prevOutType && !allowIncomplete) throw new Error('Transaction is not complete')
const result = build(input.prevOutType, input, allowIncomplete)
if (!result) {
if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) throw new Error('Unknown input type')
if (!allowIncomplete) throw new Error('Not enough information')
return
}
tx.setInputScript(i, result.script)
tx.setInputScript(i, result.input)
tx.setWitness(i, result.witness)

@@ -672,11 +635,11 @@ })

function canSign (input) {
return input.prevOutScript !== undefined &&
input.signScript !== undefined &&
input.pubKeys !== undefined &&
return input.signScript !== undefined &&
input.signType !== undefined &&
input.pubkeys !== undefined &&
input.signatures !== undefined &&
input.signatures.length === input.pubKeys.length &&
input.pubKeys.length > 0 &&
input.signatures.length === input.pubkeys.length &&
input.pubkeys.length > 0 &&
(
input.witness === false ||
(input.witness === true && input.value !== undefined)
input.hasWitness === false ||
input.value !== undefined
)

@@ -688,6 +651,6 @@ }

if (keyPair.network && keyPair.network !== this.network) throw new TypeError('Inconsistent network')
if (!this.inputs[vin]) throw new Error('No input at index: ' + vin)
if (!this.__inputs[vin]) throw new Error('No input at index: ' + vin)
hashType = hashType || Transaction.SIGHASH_ALL
var input = this.inputs[vin]
const input = this.__inputs[vin]

@@ -701,3 +664,3 @@ // if redeemScript was previously provided, enforce consistency

var kpPubKey = keyPair.publicKey || keyPair.getPublicKeyBuffer()
const ourPubKey = keyPair.publicKey || keyPair.getPublicKey()
if (!canSign(input)) {

@@ -710,3 +673,9 @@ if (witnessValue !== undefined) {

if (!canSign(input)) prepareInput(input, kpPubKey, redeemScript, witnessValue, witnessScript)
if (!canSign(input)) {
const prepared = prepareInput(input, ourPubKey, redeemScript, witnessValue, witnessScript)
// updates inline
Object.assign(input, prepared)
}
if (!canSign(input)) throw Error(input.prevOutType + ' not supported')

@@ -716,20 +685,21 @@ }

// ready to sign
var signatureHash
if (input.witness) {
signatureHash = this.tx.hashForWitnessV0(vin, input.signScript, input.value, hashType)
let signatureHash
if (input.hasWitness) {
signatureHash = this.__tx.hashForWitnessV0(vin, input.signScript, input.value, hashType)
} else {
signatureHash = this.tx.hashForSignature(vin, input.signScript, hashType)
signatureHash = this.__tx.hashForSignature(vin, input.signScript, hashType)
}
// enforce in order signing of public keys
var signed = input.pubKeys.some(function (pubKey, i) {
if (!kpPubKey.equals(pubKey)) return false
const signed = input.pubkeys.some(function (pubKey, i) {
if (!ourPubKey.equals(pubKey)) return false
if (input.signatures[i]) throw new Error('Signature already exists')
if (kpPubKey.length !== 33 &&
input.signType === scriptTypes.P2WPKH) throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH')
var signature = keyPair.sign(signatureHash)
if (Buffer.isBuffer(signature)) signature = ECSignature.fromRSBuffer(signature)
// TODO: add tests
if (ourPubKey.length !== 33 && input.hasWitness) {
throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH')
}
input.signatures[i] = signature.toScriptSignature(hashType)
const signature = keyPair.sign(signatureHash)
input.signatures[i] = bscript.signature.encode(signature, hashType)
return true

@@ -746,3 +716,3 @@ })

TransactionBuilder.prototype.__canModifyInputs = function () {
return this.inputs.every(function (input) {
return this.__inputs.every(function (input) {
// any signatures?

@@ -753,3 +723,3 @@ if (input.signatures === undefined) return true

if (!signature) return true
var hashType = signatureHashType(signature)
const hashType = signatureHashType(signature)

@@ -764,6 +734,6 @@ // if SIGHASH_ANYONECANPAY is set, signatures would not

TransactionBuilder.prototype.__canModifyOutputs = function () {
var nInputs = this.tx.ins.length
var nOutputs = this.tx.outs.length
const nInputs = this.__tx.ins.length
const nOutputs = this.__tx.outs.length
return this.inputs.every(function (input) {
return this.__inputs.every(function (input) {
if (input.signatures === undefined) return true

@@ -773,5 +743,5 @@

if (!signature) return true
var hashType = signatureHashType(signature)
const hashType = signatureHashType(signature)
var hashTypeMod = hashType & 0x1f
const hashTypeMod = hashType & 0x1f
if (hashTypeMod === Transaction.SIGHASH_NONE) return true

@@ -790,9 +760,9 @@ if (hashTypeMod === Transaction.SIGHASH_SINGLE) {

// not all inputs will have .value defined
var incoming = this.inputs.reduce(function (a, x) { return a + (x.value >>> 0) }, 0)
const incoming = this.__inputs.reduce(function (a, x) { return a + (x.value >>> 0) }, 0)
// but all outputs do, and if we have any input value
// we can immediately determine if the outputs are too small
var outgoing = this.tx.outs.reduce(function (a, x) { return a + x.value }, 0)
var fee = incoming - outgoing
var feeRate = fee / bytes
const outgoing = this.__tx.outs.reduce(function (a, x) { return a + x.value }, 0)
const fee = incoming - outgoing
const feeRate = fee / bytes

@@ -799,0 +769,0 @@ return feeRate > this.maximumFeeRate

@@ -1,12 +0,12 @@

var Buffer = require('safe-buffer').Buffer
var bcrypto = require('./crypto')
var bscript = require('./script')
var bufferutils = require('./bufferutils')
var opcodes = require('bitcoin-ops')
var typeforce = require('typeforce')
var types = require('./types')
var varuint = require('varuint-bitcoin')
const Buffer = require('safe-buffer').Buffer
const bcrypto = require('./crypto')
const bscript = require('./script')
const bufferutils = require('./bufferutils')
const opcodes = require('bitcoin-ops')
const typeforce = require('typeforce')
const types = require('./types')
const varuint = require('varuint-bitcoin')
function varSliceSize (someScript) {
var length = someScript.length
const length = someScript.length

@@ -17,3 +17,3 @@ return varuint.encodingLength(length) + length

function vectorSize (someVector) {
var length = someVector.length
const length = someVector.length

@@ -40,8 +40,8 @@ return varuint.encodingLength(length) + someVector.reduce(function (sum, witness) {

var EMPTY_SCRIPT = Buffer.allocUnsafe(0)
var EMPTY_WITNESS = []
var ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
var ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
var VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex')
var BLANK_OUTPUT = {
const EMPTY_SCRIPT = Buffer.allocUnsafe(0)
const EMPTY_WITNESS = []
const ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
const VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex')
const BLANK_OUTPUT = {
script: EMPTY_SCRIPT,

@@ -52,3 +52,3 @@ valueBuffer: VALUE_UINT64_MAX

Transaction.fromBuffer = function (buffer, __noStrict) {
var offset = 0
let offset = 0
function readSlice (n) {

@@ -60,3 +60,3 @@ offset += n

function readUInt32 () {
var i = buffer.readUInt32LE(offset)
const i = buffer.readUInt32LE(offset)
offset += 4

@@ -67,3 +67,3 @@ return i

function readInt32 () {
var i = buffer.readInt32LE(offset)
const i = buffer.readInt32LE(offset)
offset += 4

@@ -74,3 +74,3 @@ return i

function readUInt64 () {
var i = bufferutils.readUInt64LE(buffer, offset)
const i = bufferutils.readUInt64LE(buffer, offset)
offset += 8

@@ -81,3 +81,3 @@ return i

function readVarInt () {
var vi = varuint.decode(buffer, offset)
const vi = varuint.decode(buffer, offset)
offset += varuint.decode.bytes

@@ -92,4 +92,4 @@ return vi

function readVector () {
var count = readVarInt()
var vector = []
const count = readVarInt()
const vector = []
for (var i = 0; i < count; i++) vector.push(readVarSlice())

@@ -99,9 +99,9 @@ return vector

var tx = new Transaction()
const tx = new Transaction()
tx.version = readInt32()
var marker = buffer.readUInt8(offset)
var flag = buffer.readUInt8(offset + 1)
const marker = buffer.readUInt8(offset)
const flag = buffer.readUInt8(offset + 1)
var hasWitnesses = false
let hasWitnesses = false
if (marker === Transaction.ADVANCED_TRANSACTION_MARKER &&

@@ -113,3 +113,3 @@ flag === Transaction.ADVANCED_TRANSACTION_FLAG) {

var vinLen = readVarInt()
const vinLen = readVarInt()
for (var i = 0; i < vinLen; ++i) {

@@ -125,3 +125,3 @@ tx.ins.push({

var voutLen = readVarInt()
const voutLen = readVarInt()
for (i = 0; i < voutLen; ++i) {

@@ -206,4 +206,4 @@ tx.outs.push({

Transaction.prototype.weight = function () {
var base = this.__byteLength(false)
var total = this.__byteLength(true)
const base = this.__byteLength(false)
const total = this.__byteLength(true)
return base * 3 + total

@@ -221,3 +221,3 @@ }

Transaction.prototype.__byteLength = function (__allowWitness) {
var hasWitnesses = __allowWitness && this.hasWitnesses()
const hasWitnesses = __allowWitness && this.hasWitnesses()

@@ -235,3 +235,3 @@ return (

Transaction.prototype.clone = function () {
var newTx = new Transaction()
const newTx = new Transaction()
newTx.version = this.version

@@ -275,7 +275,7 @@ newTx.locktime = this.locktime

// ignore OP_CODESEPARATOR
var ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(function (x) {
const ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(function (x) {
return x !== opcodes.OP_CODESEPARATOR
}))
var txTmp = this.clone()
const txTmp = this.clone()

@@ -327,3 +327,3 @@ // SIGHASH_NONE: ignore all outputs? (wildcard payee)

// serialize and hash
var buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4)
const buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4)
buffer.writeInt32LE(hashType, buffer.length - 4)

@@ -338,3 +338,3 @@ txTmp.__toBuffer(buffer, 0, false)

var tbuffer, toffset
let tbuffer, toffset
function writeSlice (slice) { toffset += slice.copy(tbuffer, toffset) }

@@ -349,5 +349,5 @@ function writeUInt32 (i) { toffset = tbuffer.writeUInt32LE(i, toffset) }

var hashOutputs = ZERO
var hashPrevouts = ZERO
var hashSequence = ZERO
let hashOutputs = ZERO
let hashPrevouts = ZERO
let hashSequence = ZERO

@@ -381,3 +381,3 @@ if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) {

(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
var txOutsSize = this.outs.reduce(function (sum, output) {
const txOutsSize = this.outs.reduce(function (sum, output) {
return sum + 8 + varSliceSize(output.script)

@@ -396,3 +396,3 @@ }, 0)

} else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) {
var output = this.outs[inIndex]
const output = this.outs[inIndex]

@@ -410,3 +410,3 @@ tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script))

var input = this.ins[inIndex]
const input = this.ins[inIndex]
writeUInt32(this.version)

@@ -442,3 +442,3 @@ writeSlice(hashPrevouts)

var offset = initialOffset || 0
let offset = initialOffset || 0
function writeSlice (slice) { offset += slice.copy(buffer, offset) }

@@ -458,3 +458,3 @@ function writeUInt8 (i) { offset = buffer.writeUInt8(i, offset) }

var hasWitnesses = __allowWitness && this.hasWitnesses()
const hasWitnesses = __allowWitness && this.hasWitnesses()

@@ -461,0 +461,0 @@ if (hasWitnesses) {

@@ -1,4 +0,4 @@

var typeforce = require('typeforce')
const typeforce = require('typeforce')
var UINT31_MAX = Math.pow(2, 31) - 1
const UINT31_MAX = Math.pow(2, 31) - 1
function UInt31 (value) {

@@ -13,3 +13,3 @@ return typeforce.UInt32(value) && value <= UINT31_MAX

var SATOSHI_MAX = 21 * 1e14
const SATOSHI_MAX = 21 * 1e14
function Satoshi (value) {

@@ -20,8 +20,6 @@ return typeforce.UInt53(value) && value <= SATOSHI_MAX

// external dependent types
var BigInt = typeforce.quacksLike('BigInteger')
var ECPoint = typeforce.quacksLike('Point')
const ECPoint = typeforce.quacksLike('Point')
// exposed, external API
var ECSignature = typeforce.compile({ r: BigInt, s: BigInt })
var Network = typeforce.compile({
const Network = typeforce.compile({
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),

@@ -38,8 +36,6 @@ bip32: {

// extend typeforce types with ours
var types = {
BigInt: BigInt,
const types = {
BIP32Path: BIP32Path,
Buffer256bit: typeforce.BufferN(32),
ECPoint: ECPoint,
ECSignature: ECSignature,
Hash160bit: typeforce.BufferN(20),

@@ -46,0 +42,0 @@ Hash256bit: typeforce.BufferN(32),

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc