diff --git a/package-lock.json b/package-lock.json
index 3e5bd51b5..7528202bd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,8 +1,3399 @@
{
"name": "bitcoinjs-lib",
"version": "6.0.1",
- "lockfileVersion": 1,
+ "lockfileVersion": 2,
"requires": true,
+ "packages": {
+ "": {
+ "version": "6.0.1",
+ "license": "MIT",
+ "dependencies": {
+ "bech32": "^2.0.0",
+ "bip174": "^2.0.1",
+ "bs58check": "^2.1.2",
+ "create-hash": "^1.1.0",
+ "tiny-secp256k1": "^2.2.0",
+ "typeforce": "^1.11.3",
+ "varuint-bitcoin": "^1.1.2",
+ "wif": "^2.0.1"
+ },
+ "devDependencies": {
+ "@types/bs58": "^4.0.0",
+ "@types/bs58check": "^2.1.0",
+ "@types/create-hash": "^1.2.2",
+ "@types/mocha": "^5.2.7",
+ "@types/node": "^16.11.7",
+ "@types/proxyquire": "^1.3.28",
+ "@types/randombytes": "^2.0.0",
+ "@types/wif": "^2.0.2",
+ "bip32": "^3.0.1",
+ "bip39": "^3.0.2",
+ "bip65": "^1.0.1",
+ "bip68": "^1.0.3",
+ "bs58": "^4.0.0",
+ "dhttp": "^3.0.0",
+ "ecpair": "^2.0.1",
+ "hoodwink": "^2.0.0",
+ "minimaldata": "^1.0.2",
+ "mocha": "^7.1.1",
+ "npm-audit-whitelister": "^1.0.2",
+ "nyc": "^15.1.0",
+ "prettier": "1.16.4",
+ "proxyquire": "^2.0.1",
+ "randombytes": "^2.1.0",
+ "regtest-client": "0.2.0",
+ "rimraf": "^2.6.3",
+ "ts-node": "^8.3.0",
+ "tslint": "^6.1.3",
+ "typescript": "^4.4.4"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.15.8",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
+ "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.13.tgz",
+ "integrity": "sha512-BQKE9kXkPlXHPeqissfxo0lySWJcYdEP0hdtJOH/iJfDdhOCcgtNCjftCJg3qqauB4h+lz2N6ixM++b9DN1Tcw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@babel/generator": "^7.12.13",
+ "@babel/helper-module-transforms": "^7.12.13",
+ "@babel/helpers": "^7.12.13",
+ "@babel/parser": "^7.12.13",
+ "@babel/template": "^7.12.13",
+ "@babel/traverse": "^7.12.13",
+ "@babel/types": "^7.12.13",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.19",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/code-frame": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
+ "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/core/node_modules/@babel/highlight": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz",
+ "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "node_modules/@babel/core/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/core/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.12.15",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.15.tgz",
+ "integrity": "sha512-6F2xHxBiFXWNSGb7vyCUTBF8RCLY66rS0zEPcP8t/nQyXjha5EuK4z7H5o7fWG8B4M7y6mqVWq1J+1PuwRhecQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13",
+ "jsesc": "^2.5.1",
+ "source-map": "^0.5.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz",
+ "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-get-function-arity": "^7.12.13",
+ "@babel/template": "^7.12.13",
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-get-function-arity": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz",
+ "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.13.tgz",
+ "integrity": "sha512-B+7nN0gIL8FZ8SvMcF+EPyB21KnCcZHQZFczCxbiNGV/O0rsrSBlWGLzmtBJ3GMjSVMIm4lpFhR+VdVBuIsUcQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz",
+ "integrity": "sha512-NGmfvRp9Rqxy0uHSSVP+SRIW1q31a7Ji10cLBcqSDUngGentY4FRiHOFZFE1CLU5eiL0oE8reH7Tg1y99TDM/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.13.tgz",
+ "integrity": "sha512-acKF7EjqOR67ASIlDTupwkKM1eUisNAjaSduo5Cz+793ikfnpe7p4Q7B7EWU2PCoSTPWsQkR7hRUWEIZPiVLGA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.12.13",
+ "@babel/helper-replace-supers": "^7.12.13",
+ "@babel/helper-simple-access": "^7.12.13",
+ "@babel/helper-split-export-declaration": "^7.12.13",
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "@babel/template": "^7.12.13",
+ "@babel/traverse": "^7.12.13",
+ "@babel/types": "^7.12.13",
+ "lodash": "^4.17.19"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz",
+ "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.13.tgz",
+ "integrity": "sha512-pctAOIAMVStI2TMLhozPKbf5yTEXc0OJa0eENheb4w09SrgOWEs+P4nTOZYJQCqs8JlErGLDPDJTiGIp3ygbLg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.12.13",
+ "@babel/helper-optimise-call-expression": "^7.12.13",
+ "@babel/traverse": "^7.12.13",
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.13.tgz",
+ "integrity": "sha512-0ski5dyYIHEfwpWGx5GPWhH35j342JaflmCeQmsPWcrOQDtCN6C1zKAVRFVbK53lPW2c9TsuLLSUDf0tIGJ5hA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz",
+ "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+ "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
+ "dev": true
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.13.tgz",
+ "integrity": "sha512-oohVzLRZ3GQEk4Cjhfs9YkJA4TdIDTObdBEZGrd6F/T0GPSnuV6l22eMcxlvcvzVIPH3VTtxbseudM1zIE+rPQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.12.13",
+ "@babel/traverse": "^7.12.13",
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz",
+ "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.14.5",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/@babel/helper-validator-identifier": {
+ "version": "7.15.7",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz",
+ "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.12.15",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.15.tgz",
+ "integrity": "sha512-AQBOU2Z9kWwSZMd6lNjCX0GUgFonL1wAM1db8L8PMk9UDaGsRCArBkU4Sc+UCM3AE4hjbXx+h58Lb3QT4oRmrA==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz",
+ "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@babel/parser": "^7.12.13",
+ "@babel/types": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/template/node_modules/@babel/code-frame": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
+ "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/template/node_modules/@babel/highlight": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz",
+ "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.13.tgz",
+ "integrity": "sha512-3Zb4w7eE/OslI0fTp8c7b286/cQps3+vdLW3UcwC8VSJC6GbKn55aeVVu2QJNuCDoeKyptLOFrPq8WqZZBodyA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@babel/generator": "^7.12.13",
+ "@babel/helper-function-name": "^7.12.13",
+ "@babel/helper-split-export-declaration": "^7.12.13",
+ "@babel/parser": "^7.12.13",
+ "@babel/types": "^7.12.13",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.19"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/code-frame": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz",
+ "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.12.13"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/@babel/highlight": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.12.13.tgz",
+ "integrity": "sha512-kocDQvIbgMKlWxXe9fof3TQ+gkIPOUSEYhJjqUjvKMez3krV7vbzYCDq39Oj11UAVK7JqPVGQPlgE85dPNlQww==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "chalk": "^2.0.0",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/@babel/types": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.13.tgz",
+ "integrity": "sha512-oKrdZTld2im1z8bDwTOQvUbxKwE+854zc16qWZQlcTqMN00pWxHQ4ZeOq0yDMnisOpRykH2/5Qqcrk/OlbAjiQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
+ "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@types/base-x": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/base-x/-/base-x-3.0.0.tgz",
+ "integrity": "sha512-vnqSlpsv9uFX5/z8GyKWAfWHhLGJDBkrgRRsnxlsX23DHOlNyqP/eHQiv4TwnYcZULzQIxaWA/xRWU9Dyy4qzw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/bs58": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@types/bs58/-/bs58-4.0.0.tgz",
+ "integrity": "sha512-gYX+MHD4G/R+YGYwdhG5gbJj4LsEQGr3Vg6gVDAbe7xC5Bn8dNNG2Lpo6uDX/rT5dE7VBj0rGEFuV8L0AEx4Rg==",
+ "dev": true,
+ "dependencies": {
+ "@types/base-x": "*"
+ }
+ },
+ "node_modules/@types/bs58check": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/bs58check/-/bs58check-2.1.0.tgz",
+ "integrity": "sha512-OxsysnJQh82vy9DRbOcw9m2j/WiyqZLn0YBhKxdQ+aCwoHj+tWzyCgpwAkr79IfDXZKxc6h7k89T9pwS78CqTQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/create-hash": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@types/create-hash/-/create-hash-1.2.2.tgz",
+ "integrity": "sha512-Fg8/kfMJObbETFU/Tn+Y0jieYewryLrbKwLCEIwPyklZZVY2qB+64KFjhplGSw+cseZosfFXctXO+PyIYD8iZQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/mocha": {
+ "version": "5.2.7",
+ "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
+ "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "16.11.7",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.7.tgz",
+ "integrity": "sha512-QB5D2sqfSjCmTuWcBWyJ+/44bcjO7VbjSbOE0ucoVbAsSNQc4Lt6QkgkVXkTDwkL4z/beecZNDvVX15D4P8Jbw==",
+ "dev": true
+ },
+ "node_modules/@types/proxyquire": {
+ "version": "1.3.28",
+ "resolved": "https://registry.npmjs.org/@types/proxyquire/-/proxyquire-1.3.28.tgz",
+ "integrity": "sha512-SQaNzWQ2YZSr7FqAyPPiA3FYpux2Lqh3HWMZQk47x3xbMCqgC/w0dY3dw9rGqlweDDkrySQBcaScXWeR+Yb11Q==",
+ "dev": true
+ },
+ "node_modules/@types/randombytes": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/randombytes/-/randombytes-2.0.0.tgz",
+ "integrity": "sha512-bz8PhAVlwN72vqefzxa14DKNT8jK/mV66CSjwdVQM/k3Th3EPKfUtdMniwZgMedQTFuywAsfjnZsg+pEnltaMA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/wif": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@types/wif/-/wif-2.0.2.tgz",
+ "integrity": "sha512-IiIuBeJzlh4LWJ7kVTrX0nwB60OG0vvGTaWC/SgSbVFw7uYUTF6gEuvDZ1goWkeirekJDD58Y8g7NljQh2fNkA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-colors": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz",
+ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz",
+ "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==",
+ "dev": true,
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/append-transform": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
+ "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
+ "dev": true,
+ "dependencies": {
+ "default-require-extensions": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+ "dev": true
+ },
+ "node_modules/arg": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz",
+ "integrity": "sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw==",
+ "dev": true
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "node_modules/base-x": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz",
+ "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/bech32": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz",
+ "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg=="
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz",
+ "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bip174": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.0.1.tgz",
+ "integrity": "sha512-i3X26uKJOkDTAalYAp0Er+qGMDhrbbh2o93/xiPyAN2s25KrClSpe3VXo/7mNJoqA5qfko8rLS2l3RWZgYmjKQ==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/bip32": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/bip32/-/bip32-3.0.1.tgz",
+ "integrity": "sha512-Uhpp9aEx3iyiO7CpbNGFxv9WcMIVdGoHG04doQ5Ln0u60uwDah7jUSc3QMV/fSZGm/Oo01/OeAmYevXV+Gz5jQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "10.12.18",
+ "bs58check": "^2.1.1",
+ "create-hash": "^1.2.0",
+ "create-hmac": "^1.1.7",
+ "typeforce": "^1.11.5",
+ "wif": "^2.0.6"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/bip32/node_modules/@types/node": {
+ "version": "10.12.18",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz",
+ "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==",
+ "dev": true
+ },
+ "node_modules/bip39": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz",
+ "integrity": "sha512-J4E1r2N0tUylTKt07ibXvhpT2c5pyAFgvuA5q1H9uDy6dEGpjV8jmymh3MTYJDLCNbIVClSB9FbND49I6N24MQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "11.11.6",
+ "create-hash": "^1.1.0",
+ "pbkdf2": "^3.0.9",
+ "randombytes": "^2.0.1"
+ }
+ },
+ "node_modules/bip39/node_modules/@types/node": {
+ "version": "11.11.6",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz",
+ "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==",
+ "dev": true
+ },
+ "node_modules/bip65": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/bip65/-/bip65-1.0.3.tgz",
+ "integrity": "sha512-RQ1nc7xtnLa5XltnCqkoR2zmhuz498RjMJwrLKQzOE049D1HUqnYfon7cVSbwS5UGm0/EQlC2CH+NY3MyITA4Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.5.0"
+ }
+ },
+ "node_modules/bip68": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bip68/-/bip68-1.0.4.tgz",
+ "integrity": "sha512-O1htyufFTYy3EO0JkHg2CLykdXEtV2ssqw47Gq9A0WByp662xpJnMEB9m43LZjsSDjIAOozWRExlFQk2hlV1XQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.5.0"
+ }
+ },
+ "node_modules/bitcoin-ops": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz",
+ "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "node_modules/bs58": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
+ "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
+ "dependencies": {
+ "base-x": "^3.0.2"
+ }
+ },
+ "node_modules/bs58check": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
+ "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
+ "dependencies": {
+ "bs58": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "node_modules/builtin-modules": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/caching-transform": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
+ "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
+ "dev": true,
+ "dependencies": {
+ "hasha": "^5.0.0",
+ "make-dir": "^3.0.0",
+ "package-hash": "^4.0.0",
+ "write-file-atomic": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz",
+ "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==",
+ "dev": true,
+ "dependencies": {
+ "anymatch": "~3.1.1",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.0",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.2.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.1.1"
+ }
+ },
+ "node_modules/cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+ "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^3.1.0",
+ "strip-ansi": "^5.2.0",
+ "wrap-ansi": "^5.1.0"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cliui/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "node_modules/commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "node_modules/convert-source-map": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
+ "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "node_modules/create-hash": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+ "dependencies": {
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
+ }
+ },
+ "node_modules/create-hmac": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+ "dev": true,
+ "dependencies": {
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cross-spawn/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)",
+ "dev": true,
+ "dependencies": {
+ "ms": "^2.1.1"
+ }
+ },
+ "node_modules/decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/default-require-extensions": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
+ "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
+ "dev": true,
+ "dependencies": {
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/define-properties": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+ "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "dev": true,
+ "dependencies": {
+ "object-keys": "^1.0.12"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/dhttp": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/dhttp/-/dhttp-3.0.3.tgz",
+ "integrity": "sha512-map1b8iyvxSv0uEw3DUDDK5XvH3aYA7QU9DcXy8e3FBIXSwHPHTZWVrOot7Iu9mieWq5XcrZemEJlob6IdCBmg==",
+ "deprecated": "Not maintained, don't use this",
+ "dev": true,
+ "dependencies": {
+ "statuses": "^1.5.0"
+ }
+ },
+ "node_modules/diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/ecpair": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ecpair/-/ecpair-2.0.1.tgz",
+ "integrity": "sha512-iT3wztQMeE/nDTlfnAg8dAFUfBS7Tq2BXzq3ae6L+pWgFU0fQ3l0woTzdTBrJV3OxBjxbzjq8EQhAbEmJNWFSw==",
+ "dev": true,
+ "dependencies": {
+ "randombytes": "^2.1.0",
+ "typeforce": "^1.18.0",
+ "wif": "^2.0.6"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "node_modules/es-abstract": {
+ "version": "1.17.4",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz",
+ "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==",
+ "dev": true,
+ "dependencies": {
+ "es-to-primitive": "^1.2.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.1",
+ "is-callable": "^1.1.5",
+ "is-regex": "^1.0.5",
+ "object-inspect": "^1.7.0",
+ "object-keys": "^1.1.1",
+ "object.assign": "^4.1.0",
+ "string.prototype.trimleft": "^2.1.1",
+ "string.prototype.trimright": "^2.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es-to-primitive": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
+ "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/es6-error": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
+ "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
+ "dev": true
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/fill-keys": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz",
+ "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=",
+ "dev": true,
+ "dependencies": {
+ "is-object": "~1.0.1",
+ "merge-descriptors": "~1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-cache-dir": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
+ "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
+ "dev": true,
+ "dependencies": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.2",
+ "pkg-dir": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/avajs/find-cache-dir?sponsor=1"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/flat": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz",
+ "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==",
+ "deprecated": "Fixed a prototype pollution security issue in 4.1.0, please upgrade to ^4.1.1 or ^5.0.1.",
+ "dev": true,
+ "dependencies": {
+ "is-buffer": "~2.0.3"
+ },
+ "bin": {
+ "flat": "cli.js"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
+ "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/fromentries": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz",
+ "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "node_modules/fsevents": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz",
+ "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
+ "deprecated": "\"Please update to latest v2.3 or v2.2\"",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+ "dev": true
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
+ "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
+ "dev": true
+ },
+ "node_modules/growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.x"
+ }
+ },
+ "node_modules/has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
+ "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/hasha": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
+ "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==",
+ "dev": true,
+ "dependencies": {
+ "is-stream": "^2.0.0",
+ "type-fest": "^0.8.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/he": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
+ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
+ "dev": true,
+ "bin": {
+ "he": "bin/he"
+ }
+ },
+ "node_modules/hoodwink": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hoodwink/-/hoodwink-2.0.0.tgz",
+ "integrity": "sha512-j1jog3tDfhpWlqbVbh29qc7FG7w+NT4ed+QQFGqvww83+50AzzretB7wykZGOe28mBdvCYH3GdHaVWJQ2lJ/4w==",
+ "dev": true
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
+ "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-callable": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
+ "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-date-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
+ "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-object": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+ "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=",
+ "dev": true
+ },
+ "node_modules/is-regex": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
+ "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
+ "dev": true,
+ "dependencies": {
+ "has": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
+ "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-symbol": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
+ "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
+ "dev": true,
+ "dependencies": {
+ "has-symbols": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
+ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-hook": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
+ "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
+ "dev": true,
+ "dependencies": {
+ "append-transform": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz",
+ "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.7.5",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.0.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz",
+ "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==",
+ "dev": true,
+ "dependencies": {
+ "archy": "^1.0.0",
+ "cross-spawn": "^7.0.0",
+ "istanbul-lib-coverage": "^3.0.0-alpha.1",
+ "make-dir": "^3.0.0",
+ "p-map": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "uuid": "^3.3.3"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-processinfo/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
+ "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
+ "dev": true,
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^3.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
+ "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/debug": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+ "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
+ "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
+ "dev": true,
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^3.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.flattendeep": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
+ "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
+ "dev": true
+ },
+ "node_modules/log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
+ "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/make-error": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
+ "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==",
+ "dev": true
+ },
+ "node_modules/md5.js": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+ "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.1.2"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+ "dev": true
+ },
+ "node_modules/minimaldata": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minimaldata/-/minimaldata-1.0.2.tgz",
+ "integrity": "sha1-AfOywB2LJzmEP9hT1AY2xaLrdms=",
+ "dev": true,
+ "dependencies": {
+ "bitcoin-ops": "^1.3.0",
+ "pushdata-bitcoin": "^1.0.1"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz",
+ "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==",
+ "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/mocha": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.1.tgz",
+ "integrity": "sha512-3qQsu3ijNS3GkWcccT5Zw0hf/rWvu1fTN9sPvEd81hlwsr30GX2GcDSSoBxo24IR8FelmrAydGC6/1J5QQP4WA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-colors": "3.2.3",
+ "browser-stdout": "1.3.1",
+ "chokidar": "3.3.0",
+ "debug": "3.2.6",
+ "diff": "3.5.0",
+ "escape-string-regexp": "1.0.5",
+ "find-up": "3.0.0",
+ "glob": "7.1.3",
+ "growl": "1.10.5",
+ "he": "1.2.0",
+ "js-yaml": "3.13.1",
+ "log-symbols": "3.0.0",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.3",
+ "ms": "2.1.1",
+ "node-environment-flags": "1.0.6",
+ "object.assign": "4.1.0",
+ "strip-json-comments": "2.0.1",
+ "supports-color": "6.0.0",
+ "which": "1.3.1",
+ "wide-align": "1.1.3",
+ "yargs": "13.3.2",
+ "yargs-parser": "13.1.2",
+ "yargs-unparser": "1.6.0"
+ },
+ "bin": {
+ "_mocha": "bin/_mocha",
+ "mocha": "bin/mocha"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/mochajs"
+ }
+ },
+ "node_modules/module-not-found-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz",
+ "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=",
+ "dev": true
+ },
+ "node_modules/ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ },
+ "node_modules/node-environment-flags": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz",
+ "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==",
+ "dev": true,
+ "dependencies": {
+ "object.getownpropertydescriptors": "^2.0.3",
+ "semver": "^5.7.0"
+ }
+ },
+ "node_modules/node-preload": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
+ "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
+ "dev": true,
+ "dependencies": {
+ "process-on-spawn": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-audit-whitelister": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/npm-audit-whitelister/-/npm-audit-whitelister-1.0.2.tgz",
+ "integrity": "sha512-MNaYMUPI4P1cGcnLNvMv0XW4F5NkVEJv2aAfLqXXKY4cgo5lXCHl1h9eUIQnWLKM3WHVOqKzUipMzfunzQZXUg==",
+ "dev": true,
+ "bin": {
+ "npm-audit-whitelister": "bin/npm-audit-whitelister.js"
+ }
+ },
+ "node_modules/nyc": {
+ "version": "15.1.0",
+ "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
+ "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "caching-transform": "^4.0.0",
+ "convert-source-map": "^1.7.0",
+ "decamelize": "^1.2.0",
+ "find-cache-dir": "^3.2.0",
+ "find-up": "^4.1.0",
+ "foreground-child": "^2.0.0",
+ "get-package-type": "^0.1.0",
+ "glob": "^7.1.6",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-hook": "^3.0.0",
+ "istanbul-lib-instrument": "^4.0.0",
+ "istanbul-lib-processinfo": "^2.0.2",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.0.2",
+ "make-dir": "^3.0.0",
+ "node-preload": "^0.2.1",
+ "p-map": "^3.0.0",
+ "process-on-spawn": "^1.0.0",
+ "resolve-from": "^5.0.0",
+ "rimraf": "^3.0.0",
+ "signal-exit": "^3.0.2",
+ "spawn-wrap": "^2.0.0",
+ "test-exclude": "^6.0.0",
+ "yargs": "^15.0.2"
+ },
+ "bin": {
+ "nyc": "bin/nyc.js"
+ },
+ "engines": {
+ "node": ">=8.9"
+ }
+ },
+ "node_modules/nyc/node_modules/ansi-regex": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+ "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/nyc/node_modules/cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "node_modules/nyc/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/nyc/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/nyc/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/nyc/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/nyc/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/nyc/node_modules/string-width": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+ "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/strip-ansi": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+ "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nyc/node_modules/yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
+ "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.assign": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/object.getownpropertydescriptors": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
+ "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.17.0-next.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
+ "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+ "dev": true,
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/package-hash": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
+ "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.15",
+ "hasha": "^5.0.0",
+ "lodash.flattendeep": "^4.4.0",
+ "release-zalgo": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/pbkdf2": {
+ "version": "3.0.17",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+ "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+ "dev": true,
+ "dependencies": {
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
+ "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/pkg-dir/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "1.16.4",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz",
+ "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/process-on-spawn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
+ "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
+ "dev": true,
+ "dependencies": {
+ "fromentries": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/proxyquire": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.1.0.tgz",
+ "integrity": "sha512-kptdFArCfGRtQFv3Qwjr10lwbEV0TBJYvfqzhwucyfEXqVgmnAkyEw/S3FYzR5HI9i5QOq4rcqQjZ6AlknlCDQ==",
+ "dev": true,
+ "dependencies": {
+ "fill-keys": "^1.0.2",
+ "module-not-found-error": "^1.0.0",
+ "resolve": "~1.8.1"
+ }
+ },
+ "node_modules/pushdata-bitcoin": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz",
+ "integrity": "sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc=",
+ "dev": true,
+ "dependencies": {
+ "bitcoin-ops": "^1.3.0"
+ }
+ },
+ "node_modules/randombytes": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+ "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz",
+ "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==",
+ "dev": true,
+ "dependencies": {
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/regtest-client": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/regtest-client/-/regtest-client-0.2.0.tgz",
+ "integrity": "sha512-eIcC8Kle/wjS47pRlw7nJpstrJDWp0bkvVPl2KJpJcK3JDNW0fMxJgE/CGpMEUSjhhFXW1rtJMN6kyKw5NIzqg==",
+ "dev": true,
+ "dependencies": {
+ "bs58check": "^2.1.2",
+ "dhttp": "^3.0.3",
+ "randombytes": "^2.1.0"
+ }
+ },
+ "node_modules/release-zalgo": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
+ "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
+ "dev": true,
+ "dependencies": {
+ "es6-error": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+ "dev": true
+ },
+ "node_modules/resolve": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+ "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+ "dev": true,
+ "dependencies": {
+ "path-parse": "^1.0.5"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/rimraf/node_modules/glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+ "dependencies": {
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "node_modules/sha.js": {
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ },
+ "bin": {
+ "sha.js": "bin.js"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
+ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
+ "dev": true
+ },
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-support/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/spawn-wrap": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
+ "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^2.0.0",
+ "is-windows": "^1.0.2",
+ "make-dir": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "signal-exit": "^3.0.2",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dev": true,
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/spawn-wrap/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/string.prototype.trimleft": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
+ "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/string.prototype.trimright": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
+ "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3",
+ "function-bind": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz",
+ "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "7.1.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
+ "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/tiny-secp256k1": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.0.tgz",
+ "integrity": "sha512-2hPuUGCroLrxh6xxwoe+1RgPpOOK1w2uTnhgiHBpvoutBR+krNuT4hOXQyOaaYnZgoXBB6hBYkuAJHxyeBOPzQ==",
+ "dependencies": {
+ "uint8array-tools": "0.0.6"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/ts-node": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz",
+ "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==",
+ "dev": true,
+ "dependencies": {
+ "arg": "^4.1.0",
+ "diff": "^4.0.1",
+ "make-error": "^1.1.1",
+ "source-map-support": "^0.5.6",
+ "yn": "^3.0.0"
+ },
+ "bin": {
+ "ts-node": "dist/bin.js"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.0"
+ }
+ },
+ "node_modules/ts-node/node_modules/diff": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz",
+ "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
+ "dev": true
+ },
+ "node_modules/tslint": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz",
+ "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==",
+ "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "builtin-modules": "^1.1.1",
+ "chalk": "^2.3.0",
+ "commander": "^2.12.1",
+ "diff": "^4.0.1",
+ "glob": "^7.1.1",
+ "js-yaml": "^3.13.1",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.3",
+ "resolve": "^1.3.2",
+ "semver": "^5.3.0",
+ "tslib": "^1.13.0",
+ "tsutils": "^2.29.0"
+ },
+ "bin": {
+ "tslint": "bin/tslint"
+ },
+ "engines": {
+ "node": ">=4.8.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev"
+ }
+ },
+ "node_modules/tslint/node_modules/diff": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
+ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/tsutils": {
+ "version": "2.29.0",
+ "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
+ "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^1.8.1"
+ },
+ "peerDependencies": {
+ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
+ "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/typedarray-to-buffer": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
+ "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
+ "dev": true,
+ "dependencies": {
+ "is-typedarray": "^1.0.0"
+ }
+ },
+ "node_modules/typeforce": {
+ "version": "1.18.0",
+ "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
+ "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g=="
+ },
+ "node_modules/typescript": {
+ "version": "4.4.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
+ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/uint8array-tools": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.6.tgz",
+ "integrity": "sha512-aIvEHNRX1AlOYAr6qSUjQBn4mCduxx6MtC967aRDTb2UUBPj0Ix2ZFQDcmXUUO/UxRPHcw1f5a5nVbCSKDSOqA==",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "dev": true,
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/varuint-bitcoin": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz",
+ "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==",
+ "dependencies": {
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "node_modules/wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "node_modules/wif": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
+ "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=",
+ "dependencies": {
+ "bs58check": "<3.0.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+ "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.0",
+ "string-width": "^3.0.0",
+ "strip-ansi": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/write-file-atomic": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
+ "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
+ "dev": true,
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "is-typedarray": "^1.0.0",
+ "signal-exit": "^3.0.2",
+ "typedarray-to-buffer": "^3.1.5"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
+ "dev": true
+ },
+ "node_modules/yargs": {
+ "version": "13.3.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
+ "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^5.0.0",
+ "find-up": "^3.0.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^3.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^13.1.2"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "13.1.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
+ "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
+ "dev": true,
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ },
+ "node_modules/yargs-unparser": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
+ "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
+ "dev": true,
+ "dependencies": {
+ "flat": "^4.1.0",
+ "lodash": "^4.17.15",
+ "yargs": "^13.3.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yargs/node_modules/ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yargs/node_modules/string-width": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yargs/node_modules/strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/yn": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
+ "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ }
+ },
"dependencies": {
"@babel/code-frame": {
"version": "7.15.8",
@@ -606,12 +3997,6 @@
"integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==",
"dev": true
},
- "bn.js": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
- "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
- "dev": true
- },
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2374,10 +5759,9 @@
}
},
"tiny-secp256k1": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.1.2.tgz",
- "integrity": "sha512-8qPw7zDK6Hco2tVGYGQeOmOPp/hZnREwy2iIkcq0ygAuqc9WHo29vKN94lNymh1QbB3nthtAMF6KTIrdbsIotA==",
- "dev": true,
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-2.2.0.tgz",
+ "integrity": "sha512-2hPuUGCroLrxh6xxwoe+1RgPpOOK1w2uTnhgiHBpvoutBR+krNuT4hOXQyOaaYnZgoXBB6hBYkuAJHxyeBOPzQ==",
"requires": {
"uint8array-tools": "0.0.6"
}
@@ -2491,8 +5875,7 @@
"uint8array-tools": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.6.tgz",
- "integrity": "sha512-aIvEHNRX1AlOYAr6qSUjQBn4mCduxx6MtC967aRDTb2UUBPj0Ix2ZFQDcmXUUO/UxRPHcw1f5a5nVbCSKDSOqA==",
- "dev": true
+ "integrity": "sha512-aIvEHNRX1AlOYAr6qSUjQBn4mCduxx6MtC967aRDTb2UUBPj0Ix2ZFQDcmXUUO/UxRPHcw1f5a5nVbCSKDSOqA=="
},
"uuid": {
"version": "3.4.0",
diff --git a/package.json b/package.json
index c5553d57c..57c1b4d6e 100644
--- a/package.json
+++ b/package.json
@@ -53,6 +53,7 @@
"bip174": "^2.0.1",
"bs58check": "^2.1.2",
"create-hash": "^1.1.0",
+ "tiny-secp256k1": "^2.2.0",
"typeforce": "^1.11.3",
"varuint-bitcoin": "^1.1.2",
"wif": "^2.0.1"
@@ -70,7 +71,6 @@
"bip39": "^3.0.2",
"bip65": "^1.0.1",
"bip68": "^1.0.3",
- "bn.js": "^4.11.8",
"bs58": "^4.0.0",
"dhttp": "^3.0.0",
"ecpair": "^2.0.1",
@@ -84,7 +84,6 @@
"randombytes": "^2.1.0",
"regtest-client": "0.2.0",
"rimraf": "^2.6.3",
- "tiny-secp256k1": "^2.1.2",
"ts-node": "^8.3.0",
"tslint": "^6.1.3",
"typescript": "^4.4.4"
diff --git a/play.mjs b/play.mjs
new file mode 100644
index 000000000..75840951f
--- /dev/null
+++ b/play.mjs
@@ -0,0 +1,105 @@
+import * as ecc from 'tiny-secp256k1';
+import { ECPairFactory } from 'ecpair'
+
+import { Psbt } from './src/psbt.js'
+import { p2pkh, p2wpkh, p2tr } from './src/payments/index.js'
+import { testnet as network } from './src/networks.js'
+
+console.log(''.padEnd(100, '#'))
+const ECPair = ECPairFactory(ecc);
+const hex = (s) => Buffer.from(s, 'hex')
+
+const inP2pkhKey = ECPair.fromPrivateKey(hex('82fd530c9eb33570c7e05ca5e80b740bcf1118e8f4c73d44a801fa9dd60f6449'))
+const inP2wpkhKey = ECPair.fromPrivateKey(hex('35dfb4dc373860005d6f74d37064e328bc772343c354c95e31b654d0c5e22f58'))
+const inP2trKey = ECPair.fromPrivateKey(hex('accaf12e04e11b08fc28f5fe75b47ea663843b698981e31f1cafa2224d6e28c0'))
+
+const outP2trKey = ECPair.fromPrivateKey(hex('900afde76badc8914c9940379c74857d70b4d7da590097285572df6b88ad2975'))
+const outP2wpkhKey = ECPair.fromPrivateKey(hex('65ba77c6052f41325d13df8c740b5e33a26d6612e1923bf3afd67ad8081227ee'))
+
+
+
+const inP2wpkh = p2wpkh({ pubkey: inP2wpkhKey.publicKey, network })
+const inP2tr = p2tr({ internalPubkey: inP2trKey.publicKey.slice(1), network }, { eccLib: ecc })
+const outP2tr = p2tr({ internalPubkey: outP2trKey.publicKey.slice(1), network }, { eccLib: ecc })
+const outP2wpkh = p2wpkh({ pubkey: outP2wpkhKey.publicKey, network })
+
+const inTweakedP2trKey = Psbt.tweakSigner(inP2trKey, { network })
+
+console.log('### inP2trKey.privateKey ', inP2trKey.privateKey.toString('hex'))
+console.log('### inP2trKey.publicKey ', inP2trKey.publicKey.toString('hex'))
+console.log('### inP2trKey.toWIF() ', inP2trKey.toWIF())
+console.log('### inTweakedP2trKey.privateKey ', inTweakedP2trKey.privateKey.toString('hex'))
+console.log('### inTweakedP2trKey.publicKey ', inTweakedP2trKey.publicKey.toString('hex'))
+console.log(''.padEnd(100, '#'))
+
+
+console.log('### inP2tr.script ', inP2tr.output.toString('hex'))
+console.log('### inP2tr.address ', inP2tr.address)
+console.log('### inP2tr.pubkey ', inP2tr.pubkey.toString('hex'))
+console.log(''.padEnd(100, '#'))
+
+console.log('### p2pkh.address ', p2pkh({ pubkey: inP2pkhKey.publicKey, network }).address)
+console.log('### p2wpkh.address ', inP2wpkh.address)
+console.log('### inP2tr.address ', inP2tr.address)
+console.log('### outP2tr.address ', outP2tr.address)
+console.log(''.padEnd(100, '#'))
+
+
+const psbt = new Psbt({ network })
+// spend p2pkh
+psbt.addInput({
+ hash: hex('32833f8502f64f85674d2b637ec3ff0032d5585cd305b8d68db4b83ed977f303').reverse(),
+ index: 0,
+}).updateInput(0, { nonWitnessUtxo: hex('0200000000010147d8d83d6dd1dc8c7841f7f42d7239d2318a0a6a9bb5c936a1d54f72dcf859220000000000feffffff02122c1b00000000001976a9149e7ef1767764ff34a0595dbc4c2b70db017ed06688ac9874aeb10000000017a914b0c19f9f547df19b5fbbbfa25c850c6d1e1b550987024730440220301ddecd390bad5f957545a8eb68bf43681d11abf0a15c3a91fa47ff35178e8402206dfa3f611f2bd3da1604c9ff1f758b0cf4881b9f26ed3d5fa44531c36ba463d001210269997f09a81ec9829043a7f407d14e1fbceb799445e96613c852a8be0c1b5132749c2000') })
+
+// spend p2tr
+psbt.addInput({
+ hash: hex('8b9fd7f222dfa16191a15485e241d2e94baa1bef3e6a989cf2d584bda800d066').reverse(),
+ index: 0,
+}).updateInput(1, { witnessUtxo: { script: inP2tr.output, value: 67000 } })
+
+// spend pwpkh
+psbt.addInput({
+ hash: hex('2258ccf6dcb061db928b8f74c6bb74596b43935eb04f03c5d431020ba5e4877e').reverse(),
+ index: 0,
+}).updateInput(2, { witnessUtxo: { script: inP2wpkh.output, value: 10000 } })
+
+psbt.addOutput({
+ address: outP2tr.address,
+ value: 1780000
+})
+psbt.addOutput({
+ address: outP2wpkh.address,
+ value: 67000
+})
+
+console.log('### psbt 1', psbt.toBase64())
+// psbt.signInput(0, inP2pkhKey)
+psbt.signInput(1, inTweakedP2trKey)
+// psbt.signInput(2, inP2wpkhKey)
+console.log('### psbt 2', psbt.toBase64())
+
+const validator = (
+ pubkey,
+ msghash,
+ signature,
+) => {
+ console.log('### verifySchnorr', pubkey.toString('hex'))
+ // msghash[0]=0
+ return ECPair.fromPublicKey(pubkey).verifySchnorr(msghash, signature)
+};
+
+const isValid = psbt.validateSignaturesOfInput(1, validator)
+console.log('### isValid', isValid)
+
+// Serialize tx
+psbt.finalizeAllInputs()
+const tx = psbt.extractTransaction()
+const rawTx = tx.toBuffer()
+
+console.log('### rawTx', rawTx.toString('hex'))
+/// 1b9e7e80288a059adb9da6fd7c30e7383a5a924f78d3a0b6b047e07345990f48
+/// b2138ee2639c569fe7f2666635399caaa7a435b3763c079f069e194116840892
+/// e7a79cc65d17bebfc4cf03d26d6d879b754afe9cdc56ce98d2f1fac29cc7f1e2
+/// 8b9fd7f222dfa16191a15485e241d2e94baa1bef3e6a989cf2d584bda800d066
+/// 735321667cf43ded23dc935f355c4b1b1e77d9a47d11c77d384af5094e1ad171 -> 3 inputs, 2 outputs
\ No newline at end of file
diff --git a/play2.mjs b/play2.mjs
new file mode 100644
index 000000000..10a432d59
--- /dev/null
+++ b/play2.mjs
@@ -0,0 +1,110 @@
+import { BIP32Factory } from 'bip32';
+import { ECPairFactory } from 'ecpair'
+import * as ecc from 'tiny-secp256k1';
+
+import * as bitcoin from './src/index.js';
+import { testnet as network } from './src/networks.js'
+
+const ECPair = ECPairFactory(ecc);
+const bip32 = BIP32Factory(ecc);
+const hex = (s) => Buffer.from(s, 'hex')
+
+// Order of the curve (N) - 1
+const N_LESS_1 = Buffer.from(
+ 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
+ 'hex',
+);
+// 1 represented as 32 bytes BE
+const ONE = Buffer.from(
+ '0000000000000000000000000000000000000000000000000000000000000001',
+ 'hex',
+);
+
+
+const myKey = ECPair.fromPrivateKey(hex('accaf12e04e11b08fc28f5fe75b47ea663843b698981e31f1cafa2224d6e28c0'))
+const output = createKeySpendOutput(myKey.publicKey);
+const address = bitcoin.address.fromOutputScript(output, network);
+const amount = 100000;
+const sendAmount = 75000
+console.log('### output', output.toString('hex'))
+console.log('### address', address)
+
+const unspent = { txId: '8162b0310f37182049429e147b0ba7ac17eb4dd5c6d3016927e4c993b63edc2b', vout: 0}
+
+const tx = createSigned(
+ myKey,
+ unspent.txId,
+ unspent.vout,
+ sendAmount,
+ [output], // public key
+ [amount],
+);
+
+const txHex = tx.toHex();
+console.log('### txHex', txHex)
+// txId: a618fdb361a6cfbc345d2b030ab7533dc88b3c097af58df6979b4d9aa4472379
+
+
+function createKeySpendOutput(publicKey) {
+ // x-only pubkey (remove 1 byte y parity)
+ const myXOnlyPubkey = publicKey.slice(1, 33);
+ const commitHash = bitcoin.crypto.taggedHash('TapTweak', myXOnlyPubkey);
+ console.log('### commitHash ', commitHash.toString('hex'))
+ const tweakResult = ecc.xOnlyPointAddTweak(myXOnlyPubkey, commitHash);
+ console.log('### tweakResult xOnlyPubkey', Buffer.from(tweakResult.xOnlyPubkey).toString('hex'))
+ if (tweakResult === null) throw new Error('Invalid Tweak');
+ const { xOnlyPubkey: tweaked } = tweakResult;
+ // scriptPubkey
+ return Buffer.concat([
+ // witness v1, PUSH_DATA 32 bytes
+ Buffer.from([0x51, 0x20]),
+ // x-only tweaked pubkey
+ tweaked,
+ ]);
+}
+
+function signTweaked(messageHash, key) {
+ const privateKey =
+ key.publicKey[0] === 2
+ ? key.privateKey
+ : ecc.privateAdd(ecc.privateSub(N_LESS_1, key.privateKey), ONE);
+ const tweakHash = bitcoin.crypto.taggedHash(
+ 'TapTweak',
+ key.publicKey.slice(1, 33),
+ );
+ const newPrivateKey = ecc.privateAdd(privateKey, tweakHash);
+ if (newPrivateKey === null) throw new Error('Invalid Tweak');
+ return ecc.signSchnorr(messageHash, newPrivateKey, Buffer.alloc(32));
+}
+
+// Function for creating signed tx
+function createSigned(
+ key,
+ txid,
+ vout,
+ amountToSend,
+ scriptPubkeys,
+ values,
+ ) {
+ console.log('### scriptPubkeys', scriptPubkeys.map(s => s.toString('hex')))
+ console.log('### values', values)
+ const tx = new bitcoin.Transaction();
+ tx.version = 2;
+ // Add input
+ tx.addInput(Buffer.from(txid, 'hex').reverse(), vout);
+ // Add output
+ tx.addOutput(scriptPubkeys[0], amountToSend);
+ const sighash = tx.hashForWitnessV1(
+ 0, // which input
+ scriptPubkeys, // All previous outputs of all inputs
+ values, // All previous values of all inputs
+ bitcoin.Transaction.SIGHASH_DEFAULT, // sighash flag, DEFAULT is schnorr-only (DEFAULT == ALL)
+ );
+ console.log('### sighash', sighash.toString('hex'))
+ console.log('### unsignedTx', tx.toHex())
+ const signature = Buffer.from(signTweaked(sighash, key));
+ // witness stack for keypath spend is just the signature.
+ // If sighash is not SIGHASH_DEFAULT (ALL) then you must add 1 byte with sighash value
+ tx.ins[0].witness = [signature];
+ return tx;
+ }
\ No newline at end of file
diff --git a/play3.mjs b/play3.mjs
new file mode 100644
index 000000000..fdff92091
--- /dev/null
+++ b/play3.mjs
@@ -0,0 +1,11 @@
+import * as ecc from 'tiny-secp256k1';
+import { ECPairFactory } from 'ecpair'
+
+import { p2tr } from './src/payments/index.js'
+import { testnet as network } from './src/networks.js'
+
+console.log(''.padEnd(100, '#'))
+
+const inP2tr = p2tr({ output: Buffer.from('51209421e734b0f9d2c467ea7dd197c61acb4467cdcbc9f4cb0c571f8b63a5c40cae', 'hex'), network }, { eccLib: ecc })
+
+console.log('### inP2tr',inP2tr.address)
\ No newline at end of file
diff --git a/play4.mjs b/play4.mjs
new file mode 100644
index 000000000..1b61431c6
--- /dev/null
+++ b/play4.mjs
@@ -0,0 +1,11 @@
+import * as ecc from 'tiny-secp256k1';
+import { ECPairFactory } from 'ecpair'
+import NETWORKS from './src/networks.js'
+
+const ECPair = ECPairFactory(ecc);
+const hex = (s) => Buffer.from(s, 'hex')
+
+const key = ECPair.fromPrivateKey(hex('82fd530c9eb33570c7e05ca5e80b740bcf1118e8f4c73d44a801fa9dd60f6449'), { network: NETWORKS.testnet })
+console.log('### key.toWIF()', key.toWIF())
+
+ECPair.fromWIF('cRyKzLXVgTReWe7wgfEiXktTa9tf4e5DK1STha274d7BBbnucTaR', NETWORKS.testnet);
\ No newline at end of file
diff --git a/play5.mjs b/play5.mjs
new file mode 100644
index 000000000..bae7a7d3e
--- /dev/null
+++ b/play5.mjs
@@ -0,0 +1,112 @@
+import * as ecc from 'tiny-secp256k1';
+import { ECPairFactory } from 'ecpair'
+
+import { Psbt } from './src/psbt.js'
+import { p2pkh, p2wpkh, p2tr } from './src/payments/index.js'
+import { testnet as network } from './src/networks.js'
+console.log(''.padEnd(100, '#'))
+const ECPair = ECPairFactory(ecc);
+const hex = (s) => Buffer.from(s, 'hex')
+
+const inP2pkhKey = ECPair.fromPrivateKey(hex('82fd530c9eb33570c7e05ca5e80b740bcf1118e8f4c73d44a801fa9dd60f6449'), { network })
+const inP2wpkhKey = ECPair.fromPrivateKey(hex('35dfb4dc373860005d6f74d37064e328bc772343c354c95e31b654d0c5e22f58'), { network })
+const inP2trKey = ECPair.fromPrivateKey(hex('accaf12e04e11b08fc28f5fe75b47ea663843b698981e31f1cafa2224d6e28c0'), { network })
+
+const outP2trKey = ECPair.fromPrivateKey(hex('900afde76badc8914c9940379c74857d70b4d7da590097285572df6b88ad2975'), { network })
+const outP2wpkhKey = ECPair.fromPrivateKey(hex('65ba77c6052f41325d13df8c740b5e33a26d6612e1923bf3afd67ad8081227ee'), { network })
+
+console.log('### inP2pkhKey.toWIF()', inP2pkhKey.toWIF())
+console.log('### inP2trKey.toWIF()', inP2trKey.toWIF())
+console.log('### inP2wpkhKey.toWIF()', inP2wpkhKey.toWIF())
+console.log('### outP2trKey.toWIF()', outP2trKey.toWIF())
+// 02982a2876765bb37b53a12418b9e72b8afa8d54e344a1bd585299a211fbe625f3
+
+
+
+const inP2wpkh = p2wpkh({ pubkey: inP2wpkhKey.publicKey, network })
+const inP2tr = p2tr({ internalPubkey: inP2trKey.publicKey.slice(1), network }, { eccLib: ecc })
+const outP2tr = p2tr({ internalPubkey: outP2trKey.publicKey.slice(1), network }, { eccLib: ecc })
+const outP2wpkh = p2wpkh({ pubkey: outP2wpkhKey.publicKey, network })
+
+
+// const inTweakedP2trKey = inP2trKeyPsbt.prepareTaprootSigner(outP2trKey, { network })
+// console.log('### inTweakedP2trKey.toWIF()', inTweakedP2trKey.toWIF())
+
+
+console.log('### inP2trKey.privateKey ', inP2trKey.privateKey.toString('hex'))
+console.log('### inP2trKey.publicKey ', inP2trKey.publicKey.toString('hex'))
+console.log('### outP2trKey.publicKey ', outP2trKey.publicKey.toString('hex'))
+console.log('### inP2pkhKey.publicKey ', inP2pkhKey.publicKey.toString('hex'))
+console.log('### inP2wpkhKey.publicKey ', inP2wpkhKey.publicKey.toString('hex'))
+// console.log('### inTweakedP2trKey.privateKey ', inTweakedP2trKey.privateKey.toString('hex'))
+// console.log('### inTweakedP2trKey.publicKey ', inTweakedP2trKey.publicKey.toString('hex'))
+console.log(''.padEnd(100, '#'))
+
+
+console.log('### inP2tr.script ', inP2tr.output.toString('hex'))
+console.log('### inP2tr.address ', inP2tr.address)
+console.log('### inP2tr.pubkey ', inP2tr.pubkey.toString('hex'))
+console.log(''.padEnd(100, '#'))
+
+console.log('### p2pkh.address ', p2pkh({ pubkey: inP2pkhKey.publicKey, network }).address)
+console.log('### p2wpkh.address ', inP2wpkh.address)
+console.log('### inP2tr.address ', inP2tr.address)
+console.log('### outP2tr.address ', outP2tr.address)
+
+console.log(''.padEnd(100, '#'))
+
+
+const psbt = new Psbt({ network })
+// spend p2pkh
+psbt.addInput({
+ hash: hex('32833f8502f64f85674d2b637ec3ff0032d5585cd305b8d68db4b83ed977f303').reverse(),
+ index: 0,
+}).updateInput(0, { nonWitnessUtxo: hex('0200000000010147d8d83d6dd1dc8c7841f7f42d7239d2318a0a6a9bb5c936a1d54f72dcf859220000000000feffffff02122c1b00000000001976a9149e7ef1767764ff34a0595dbc4c2b70db017ed06688ac9874aeb10000000017a914b0c19f9f547df19b5fbbbfa25c850c6d1e1b550987024730440220301ddecd390bad5f957545a8eb68bf43681d11abf0a15c3a91fa47ff35178e8402206dfa3f611f2bd3da1604c9ff1f758b0cf4881b9f26ed3d5fa44531c36ba463d001210269997f09a81ec9829043a7f407d14e1fbceb799445e96613c852a8be0c1b5132749c2000') })
+
+// spend p2tr
+psbt.addInput({
+ hash: hex('8b9fd7f222dfa16191a15485e241d2e94baa1bef3e6a989cf2d584bda800d066').reverse(),
+ index: 0,
+}).updateInput(1, { witnessUtxo: { script: outP2tr.output, value: 67000 } })
+
+// spend pwpkh
+psbt.addInput({
+ hash: hex('2258ccf6dcb061db928b8f74c6bb74596b43935eb04f03c5d431020ba5e4877e').reverse(),
+ index: 0,
+}).updateInput(2, { witnessUtxo: { script: inP2wpkh.output, value: 10000 } })
+
+psbt.addOutput({
+ address: inP2tr.address,
+ value: 1780000
+})
+psbt.addOutput({
+ address: outP2wpkh.address,
+ value: 67000
+})
+
+console.log('### psbt 1', psbt.toBase64())
+
+psbt.signInput(0, inP2pkhKey)
+psbt.signInput(1, outP2trKey)
+psbt.signInput(2, inP2wpkhKey)
+
+console.log('### psbt 2', psbt.toBase64())
+
+// const validator = (
+// pubkey,
+// msghash,
+// signature,
+// ) => ECPair.fromPublicKey(pubkey).verify(msghash, signature);
+// psbt.validateSignaturesOfAllInputs(validator)
+
+// Serialize tx
+psbt.finalizeAllInputs()
+const tx = psbt.extractTransaction()
+const rawTx = tx.toBuffer()
+
+console.log('### rawTx', rawTx.toString('hex'))
+/// 1b9e7e80288a059adb9da6fd7c30e7383a5a924f78d3a0b6b047e07345990f48
+/// b2138ee2639c569fe7f2666635399caaa7a435b3763c079f069e194116840892
+/// e7a79cc65d17bebfc4cf03d26d6d879b754afe9cdc56ce98d2f1fac29cc7f1e2
+/// 8b9fd7f222dfa16191a15485e241d2e94baa1bef3e6a989cf2d584bda800d066
+/// 735321667cf43ded23dc935f355c4b1b1e77d9a47d11c77d384af5094e1ad171 -> 3 inputs, 2 outputs
\ No newline at end of file
diff --git a/published tx b/published tx
new file mode 100644
index 000000000..958922a53
--- /dev/null
+++ b/published tx
@@ -0,0 +1,4 @@
+published tx
+### hash 990576cefd2f30f46709a14cf0eff8fe94c9d004229b9e0ff7fca7a526e9cfea
+### rawTx 0200000000010303f377d93eb8b48dd6b805d35c58d53200ffc37e632b4d67854ff602853f8332000000006a473044022069582941c9bb47bde5e4840813884f1049cccc26cf0c1ae1f82ce48d440eacfc02205a56c1df124eb4922cb338f5a99ff0840e632bdc274f3799cc3955b3f8afab670121022e68bc11f5c4ba06c4faad161e3cc141299ccf92b7549b3f34703bb90134a390ffffffff66d000a8bd84d5f29c986a3eef1baa4be9d241e28554a19161a1df22f2d79f8b0000000000ffffffff7e87e4a50b0231d4c5034fb05e93436b5974bbc6748f8b92db61b0dcf6cc58220000000000ffffffff0220291b000000000022512046f6497cb2f19d50c3e9e982a950dcc86214b01fcce437a42061c7bdb1230d33b805010000000000160014c98a3134bf8f33e599a67c40000d774205c1b41400014003694b9b7e9145af36d4faf2fca82cd913f14efbdba7cf295fa488106781d3cb6a8f52d2ef6f21f9f46029773d1289464697c2ba0abbedf5821f23fe45c5b38b02483045022100a02224b6084be798ae3009a4cf0609cdbfa1faa98d7b0657c40c7fd3a39bc484022042c2b01cffc1ddb03e59c96f6ece96ec4c9133e70b21c0d82f92c47897fc5bcf012103a54ea4405b3c933fc58b2a3b67aeb6d605a6079cf6f731820c93ca89252baeb400000000
+
diff --git a/r1.txt b/r1.txt
new file mode 100644
index 000000000..36beb16c4
--- /dev/null
+++ b/r1.txt
@@ -0,0 +1,5 @@
+### rawTx 0200000000010303f377d93eb8b48dd6b805d35c58d53200ffc37e632b4d67854ff602853f8332000000006a473044022069582941c9bb47bde5e4840813884f1049cccc26cf0c1ae1f82ce48d440eacfc02205a56c1df124eb4922cb338f5a99ff0840e632bdc274f3799cc3955b3f8afab670121022e68bc11f5c4ba06c4faad161e3cc141299ccf92b7549b3f34703bb90134a390ffffffff66d000a8bd84d5f29c986a3eef1baa4be9d241e28554a19161a1df22f2d79f8b0000000000ffffffff7e87e4a50b0231d4c5034fb05e93436b5974bbc6748f8b92db61b0dcf6cc58220000000000ffffffff0220291b000000000022512046f6497cb2f19d50c3e9e982a950dcc86214b01fcce437a42061c7bdb1230d33b805010000000000160014c98a3134bf8f33e599a67c40000d774205c1b41400014003694b9b7e9145af36d4faf2fca82cd913f14efbdba7cf295fa488106781d3cb6a8f52d2ef6f21f9f46029773d1289464697c2ba0abbedf5821f23fe45c5b38b02483045022100a02224b6084be798ae3009a4cf0609cdbfa1faa98d7b0657c40c7fd3a39bc484022042c2b01cffc1ddb03e59c96f6ece96ec4c9133e70b21c0d82f92c47897fc5bcf012103a54ea4405b3c933fc58b2a3b67aeb6d605a6079cf6f731820c93ca89252baeb400000000
+
+### rawTx 0200000000010303f377d93eb8b48dd6b805d35c58d53200ffc37e632b4d67854ff602853f8332000000006a473044022069582941c9bb47bde5e4840813884f1049cccc26cf0c1ae1f82ce48d440eacfc02205a56c1df124eb4922cb338f5a99ff0840e632bdc274f3799cc3955b3f8afab670121022e68bc11f5c4ba06c4faad161e3cc141299ccf92b7549b3f34703bb90134a390ffffffff66d000a8bd84d5f29c986a3eef1baa4be9d241e28554a19161a1df22f2d79f8b0000000000ffffffff7e87e4a50b0231d4c5034fb05e93436b5974bbc6748f8b92db61b0dcf6cc58220000000000ffffffff0220291b000000000022512046f6497cb2f19d50c3e9e982a950dcc86214b01fcce437a42061c7bdb1230d33b805010000000000160014c98a3134bf8f33e599a67c40000d774205c1b41400014003694b9b7e9145af36d4faf2fca82cd913f14efbdba7cf295fa488106781d3cb6a8f52d2ef6f21f9f46029773d1289464697c2ba0abbedf5821f23fe45c5b38b02483045022100a02224b6084be798ae3009a4cf0609cdbfa1faa98d7b0657c40c7fd3a39bc484022042c2b01cffc1ddb03e59c96f6ece96ec4c9133e70b21c0d82f92c47897fc5bcf012103a54ea4405b3c933fc58b2a3b67aeb6d605a6079cf6f731820c93ca89252baeb400000000
+
+mempool: 0200000000010303f377d93eb8b48dd6b805d35c58d53200ffc37e632b4d67854ff602853f8332000000006a473044022069582941c9bb47bde5e4840813884f1049cccc26cf0c1ae1f82ce48d440eacfc02205a56c1df124eb4922cb338f5a99ff0840e632bdc274f3799cc3955b3f8afab670121022e68bc11f5c4ba06c4faad161e3cc141299ccf92b7549b3f34703bb90134a390ffffffff66d000a8bd84d5f29c986a3eef1baa4be9d241e28554a19161a1df22f2d79f8b0000000000ffffffff7e87e4a50b0231d4c5034fb05e93436b5974bbc6748f8b92db61b0dcf6cc58220000000000ffffffff0220291b000000000022512046f6497cb2f19d50c3e9e982a950dcc86214b01fcce437a42061c7bdb1230d33b805010000000000160014c98a3134bf8f33e599a67c40000d774205c1b41400014003694b9b7e9145af36d4faf2fca82cd913f14efbdba7cf295fa488106781d3cb6a8f52d2ef6f21f9f46029773d1289464697c2ba0abbedf5821f23fe45c5b38b02483045022100a02224b6084be798ae3009a4cf0609cdbfa1faa98d7b0657c40c7fd3a39bc484022042c2b01cffc1ddb03e59c96f6ece96ec4c9133e70b21c0d82f92c47897fc5bcf012103a54ea4405b3c933fc58b2a3b67aeb6d605a6079cf6f731820c93ca89252baeb400000000
\ No newline at end of file
diff --git a/src/payments/index.d.ts b/src/payments/index.d.ts
index 1edf07167..6b186c4d1 100644
--- a/src/payments/index.d.ts
+++ b/src/payments/index.d.ts
@@ -1,5 +1,6 @@
///
import { Network } from '../networks';
+import { TaprootLeaf, TinySecp256k1Interface } from '../types';
import { p2data as embed } from './embed';
import { p2ms } from './p2ms';
import { p2pk } from './p2pk';
@@ -7,6 +8,7 @@ import { p2pkh } from './p2pkh';
import { p2sh } from './p2sh';
import { p2wpkh } from './p2wpkh';
import { p2wsh } from './p2wsh';
+import { p2tr } from './p2tr';
export interface Payment {
name?: string;
network?: Network;
@@ -17,11 +19,14 @@ export interface Payment {
pubkeys?: Buffer[];
input?: Buffer;
signatures?: Buffer[];
+ internalPubkey?: Buffer;
pubkey?: Buffer;
signature?: Buffer;
address?: string;
hash?: Buffer;
redeem?: Payment;
+ scriptsTree?: any;
+ scriptLeaf?: TaprootLeaf;
witness?: Buffer[];
}
export declare type PaymentCreator = (a: Payment, opts?: PaymentOpts) => Payment;
@@ -29,8 +34,9 @@ export declare type PaymentFunction = () => Payment;
export interface PaymentOpts {
validate?: boolean;
allowIncomplete?: boolean;
+ eccLib?: TinySecp256k1Interface;
}
export declare type StackElement = Buffer | number;
export declare type Stack = StackElement[];
export declare type StackFunction = () => Stack;
-export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh };
+export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh, p2tr };
diff --git a/src/payments/index.js b/src/payments/index.js
index c23c529c6..9ce55f859 100644
--- a/src/payments/index.js
+++ b/src/payments/index.js
@@ -1,6 +1,6 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
-exports.p2wsh = exports.p2wpkh = exports.p2sh = exports.p2pkh = exports.p2pk = exports.p2ms = exports.embed = void 0;
+exports.p2tr = exports.p2wsh = exports.p2wpkh = exports.p2sh = exports.p2pkh = exports.p2pk = exports.p2ms = exports.embed = void 0;
const embed_1 = require('./embed');
Object.defineProperty(exports, 'embed', {
enumerable: true,
@@ -50,5 +50,12 @@ Object.defineProperty(exports, 'p2wsh', {
return p2wsh_1.p2wsh;
},
});
+const p2tr_1 = require('./p2tr');
+Object.defineProperty(exports, 'p2tr', {
+ enumerable: true,
+ get: function() {
+ return p2tr_1.p2tr;
+ },
+});
// TODO
// witness commitment
diff --git a/src/payments/p2tr.d.ts b/src/payments/p2tr.d.ts
new file mode 100644
index 000000000..350ed0ffc
--- /dev/null
+++ b/src/payments/p2tr.d.ts
@@ -0,0 +1,2 @@
+import { Payment, PaymentOpts } from './index';
+export declare function p2tr(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2tr.js b/src/payments/p2tr.js
new file mode 100644
index 000000000..d03d7980d
--- /dev/null
+++ b/src/payments/p2tr.js
@@ -0,0 +1,253 @@
+'use strict';
+Object.defineProperty(exports, '__esModule', { value: true });
+exports.p2tr = void 0;
+const buffer_1 = require('buffer');
+const networks_1 = require('../networks');
+const bscript = require('../script');
+const types_1 = require('../types');
+const taprootutils_1 = require('./taprootutils');
+const lazy = require('./lazy');
+const bech32_1 = require('bech32');
+const testecc_1 = require('./testecc');
+const OPS = bscript.OPS;
+const TAPROOT_VERSION = 0x01;
+const ANNEX_PREFIX = 0x50;
+function p2tr(a, opts) {
+ if (
+ !a.address &&
+ !a.output &&
+ !a.pubkey &&
+ !a.output &&
+ !a.internalPubkey &&
+ !(a.witness && a.witness.length > 1)
+ )
+ throw new TypeError('Not enough data');
+ opts = Object.assign({ validate: true }, opts || {});
+ const _ecc = lazy.value(() => {
+ if (!opts.eccLib) throw new Error('ECC Library is missing for p2tr.');
+ (0, testecc_1.testEcc)(opts.eccLib);
+ return opts.eccLib;
+ });
+ (0, types_1.typeforce)(
+ {
+ address: types_1.typeforce.maybe(types_1.typeforce.String),
+ input: types_1.typeforce.maybe(types_1.typeforce.BufferN(0)),
+ network: types_1.typeforce.maybe(types_1.typeforce.Object),
+ output: types_1.typeforce.maybe(types_1.typeforce.BufferN(34)),
+ internalPubkey: types_1.typeforce.maybe(types_1.typeforce.BufferN(32)),
+ hash: types_1.typeforce.maybe(types_1.typeforce.BufferN(32)),
+ pubkey: types_1.typeforce.maybe(types_1.typeforce.BufferN(32)),
+ signature: types_1.typeforce.maybe(types_1.typeforce.BufferN(64)),
+ witness: types_1.typeforce.maybe(
+ types_1.typeforce.arrayOf(types_1.typeforce.Buffer),
+ ),
+ // scriptsTree: typef.maybe(typef.TaprootNode), // use merkel.isMast ?
+ scriptLeaf: types_1.typeforce.maybe({
+ version: types_1.typeforce.maybe(types_1.typeforce.Number),
+ output: types_1.typeforce.maybe(types_1.typeforce.Buffer),
+ }),
+ },
+ a,
+ );
+ const _address = lazy.value(() => {
+ const result = bech32_1.bech32m.decode(a.address);
+ const version = result.words.shift();
+ const data = bech32_1.bech32m.fromWords(result.words);
+ return {
+ version,
+ prefix: result.prefix,
+ data: buffer_1.Buffer.from(data),
+ };
+ });
+ const _witness = lazy.value(() => {
+ if (!a.witness || !a.witness.length) return;
+ if (
+ a.witness.length >= 2 &&
+ a.witness[a.witness.length - 1][0] === ANNEX_PREFIX
+ ) {
+ // remove annex, ignored by taproot
+ return a.witness.slice(0, -1);
+ }
+ return a.witness.slice();
+ });
+ const network = a.network || networks_1.bitcoin;
+ const o = { name: 'p2tr', network };
+ lazy.prop(o, 'address', () => {
+ if (!o.pubkey) return;
+ const words = bech32_1.bech32m.toWords(o.pubkey);
+ words.unshift(TAPROOT_VERSION);
+ return bech32_1.bech32m.encode(network.bech32, words);
+ });
+ lazy.prop(o, 'hash', () => {
+ if (a.hash) return a.hash;
+ if (a.scriptsTree)
+ return (0, taprootutils_1.toHashTree)(a.scriptsTree).hash;
+ const w = _witness();
+ if (w && w.length > 1) {
+ const controlBlock = w[w.length - 1];
+ const leafVersion = controlBlock[0] & 0b11111110;
+ const script = w[w.length - 2];
+ const leafHash = (0, taprootutils_1.tapLeafHash)(script, leafVersion);
+ return (0, taprootutils_1.rootHashFromPath)(controlBlock, leafHash);
+ }
+ return null;
+ });
+ lazy.prop(o, 'output', () => {
+ if (!o.pubkey) return;
+ return bscript.compile([OPS.OP_1, o.pubkey]);
+ });
+ lazy.prop(o, 'scriptLeaf', () => {
+ if (a.scriptLeaf) return a.scriptLeaf;
+ });
+ lazy.prop(o, 'pubkey', () => {
+ if (a.pubkey) return a.pubkey;
+ if (a.output) return a.output.slice(2);
+ if (a.address) return _address().data;
+ if (o.internalPubkey) {
+ const tweakedKey = tweakKey(o.internalPubkey, o.hash, _ecc());
+ if (tweakedKey) return tweakedKey.x;
+ }
+ });
+ lazy.prop(o, 'internalPubkey', () => {
+ if (a.internalPubkey) return a.internalPubkey;
+ const witness = _witness();
+ if (witness && witness.length > 1)
+ return witness[witness.length - 1].slice(1, 33);
+ });
+ lazy.prop(o, 'signature', () => {
+ if (!a.witness || a.witness.length !== 1) return;
+ return a.witness[0];
+ });
+ lazy.prop(o, 'input', () => {
+ // todo
+ });
+ lazy.prop(o, 'witness', () => {
+ if (a.witness) return a.witness;
+ if (a.scriptsTree && a.scriptLeaf && a.internalPubkey) {
+ // todo: optimize/cache
+ const hashTree = (0, taprootutils_1.toHashTree)(a.scriptsTree);
+ const leafHash = (0, taprootutils_1.tapLeafHash)(
+ a.scriptLeaf.output,
+ a.scriptLeaf.version,
+ );
+ const path = (0, taprootutils_1.findScriptPath)(hashTree, leafHash);
+ const outputKey = tweakKey(a.internalPubkey, hashTree.hash, _ecc());
+ if (!outputKey) return;
+ const version = a.scriptLeaf.version || 0xc0;
+ const controlBock = buffer_1.Buffer.concat(
+ [
+ buffer_1.Buffer.from([version | outputKey.parity]),
+ a.internalPubkey,
+ ].concat(path.reverse()),
+ );
+ return [a.scriptLeaf.output, controlBock];
+ }
+ if (a.signature) return [a.signature];
+ });
+ // extended validation
+ if (opts.validate) {
+ let pubkey = buffer_1.Buffer.from([]);
+ if (a.address) {
+ if (network && network.bech32 !== _address().prefix)
+ throw new TypeError('Invalid prefix or Network mismatch');
+ if (_address().version !== TAPROOT_VERSION)
+ throw new TypeError('Invalid address version');
+ if (_address().data.length !== 32)
+ throw new TypeError('Invalid address data');
+ pubkey = _address().data;
+ }
+ if (a.pubkey) {
+ if (pubkey.length > 0 && !pubkey.equals(a.pubkey))
+ throw new TypeError('Pubkey mismatch');
+ else pubkey = a.pubkey;
+ }
+ if (a.output) {
+ if (
+ a.output.length !== 34 ||
+ a.output[0] !== OPS.OP_1 ||
+ a.output[1] !== 0x20
+ )
+ throw new TypeError('Output is invalid');
+ if (pubkey.length > 0 && !pubkey.equals(a.output.slice(2)))
+ throw new TypeError('Pubkey mismatch');
+ else pubkey = a.output.slice(2);
+ }
+ if (a.internalPubkey) {
+ const tweakedKey = tweakKey(a.internalPubkey, o.hash, _ecc());
+ if (pubkey.length > 0 && !pubkey.equals(tweakedKey.x))
+ throw new TypeError('Pubkey mismatch');
+ else pubkey = tweakedKey.x;
+ }
+ if (pubkey && pubkey.length) {
+ if (!_ecc().isXOnlyPoint(pubkey))
+ throw new TypeError('Invalid pubkey for p2tr');
+ }
+ if (a.hash && a.scriptsTree) {
+ const hash = (0, taprootutils_1.toHashTree)(a.scriptsTree).hash;
+ if (!a.hash.equals(hash)) throw new TypeError('Hash mismatch');
+ }
+ const witness = _witness();
+ if (witness && witness.length) {
+ if (witness.length === 1) {
+ // key spending
+ if (a.signature && !a.signature.equals(witness[0]))
+ throw new TypeError('Signature mismatch');
+ // todo: recheck
+ // if (!bscript.isSchnorSignature(a.pubkey, a.witness[0]))
+ // throw new TypeError('Witness has invalid signature');
+ } else {
+ // script path spending
+ const controlBlock = witness[witness.length - 1];
+ if (controlBlock.length < 33)
+ throw new TypeError(
+ `The control-block length is too small. Got ${
+ controlBlock.length
+ }, expected min 33.`,
+ );
+ if ((controlBlock.length - 33) % 32 !== 0)
+ throw new TypeError(
+ `The control-block length of ${controlBlock.length} is incorrect!`,
+ );
+ const m = (controlBlock.length - 33) / 32;
+ if (m > 128)
+ throw new TypeError(
+ `The script path is too long. Got ${m}, expected max 128.`,
+ );
+ const internalPubkey = controlBlock.slice(1, 33);
+ if (a.internalPubkey && !a.internalPubkey.equals(internalPubkey))
+ throw new TypeError('Internal pubkey mismatch');
+ if (!_ecc().isXOnlyPoint(internalPubkey))
+ throw new TypeError('Invalid internalPubkey for p2tr witness');
+ const leafVersion = controlBlock[0] & 0b11111110;
+ const script = witness[witness.length - 2];
+ const leafHash = (0, taprootutils_1.tapLeafHash)(script, leafVersion);
+ const hash = (0, taprootutils_1.rootHashFromPath)(
+ controlBlock,
+ leafHash,
+ );
+ const outputKey = tweakKey(internalPubkey, hash, _ecc());
+ if (!outputKey)
+ // todo: needs test data
+ throw new TypeError('Invalid outputKey for p2tr witness');
+ if (pubkey.length && !pubkey.equals(outputKey.x))
+ throw new TypeError('Pubkey mismatch for p2tr witness');
+ if (outputKey.parity !== (controlBlock[0] & 1))
+ throw new Error('Incorrect parity');
+ }
+ }
+ }
+ return Object.assign(o, a);
+}
+exports.p2tr = p2tr;
+function tweakKey(pubKey, h, eccLib) {
+ if (!buffer_1.Buffer.isBuffer(pubKey)) return null;
+ if (pubKey.length !== 32) return null;
+ if (h && h.length !== 32) return null;
+ const tweakHash = (0, taprootutils_1.tapTweakHash)(pubKey, h);
+ const res = eccLib.xOnlyPointAddTweak(pubKey, tweakHash);
+ if (!res || res.xOnlyPubkey === null) return null;
+ return {
+ parity: res.parity,
+ x: buffer_1.Buffer.from(res.xOnlyPubkey),
+ };
+}
diff --git a/src/payments/taprootutils.d.ts b/src/payments/taprootutils.d.ts
new file mode 100644
index 000000000..f68a37495
--- /dev/null
+++ b/src/payments/taprootutils.d.ts
@@ -0,0 +1,26 @@
+///
+import { TaprootLeaf } from '../types';
+export declare function rootHashFromPath(controlBlock: Buffer, tapLeafMsg: Buffer): Buffer;
+export interface HashTree {
+ hash: Buffer;
+ left?: HashTree;
+ right?: HashTree;
+}
+/**
+ * Build the hash tree from the scripts binary tree.
+ * The binary tree can be balanced or not.
+ * @param scriptsTree - is a list representing a binary tree where an element can be:
+ * - a taproot leaf [(output, version)], or
+ * - a pair of two taproot leafs [(output, version), (output, version)], or
+ * - one taproot leaf and a list of elements
+ */
+export declare function toHashTree(scriptsTree: TaprootLeaf[]): HashTree;
+/**
+ * Given a MAST tree, it finds the path of a particular hash.
+ * @param node - the root of the tree
+ * @param hash - the hash to search for
+ * @returns - and array of hashes representing the path, or an empty array if no pat is found
+ */
+export declare function findScriptPath(node: HashTree, hash: Buffer): Buffer[];
+export declare function tapLeafHash(script: Buffer, version?: number): Buffer;
+export declare function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer;
diff --git a/src/payments/taprootutils.js b/src/payments/taprootutils.js
new file mode 100644
index 000000000..2da6a4b7d
--- /dev/null
+++ b/src/payments/taprootutils.js
@@ -0,0 +1,108 @@
+'use strict';
+Object.defineProperty(exports, '__esModule', { value: true });
+exports.tapTweakHash = exports.tapLeafHash = exports.findScriptPath = exports.toHashTree = exports.rootHashFromPath = void 0;
+const buffer_1 = require('buffer');
+const bcrypto = require('../crypto');
+const bufferutils_1 = require('../bufferutils');
+const LEAF_VERSION_TAPSCRIPT = 0xc0;
+const TAP_LEAF_TAG = 'TapLeaf';
+const TAP_BRANCH_TAG = 'TapBranch';
+const TAP_TWEAK_TAG = 'TapTweak';
+function rootHashFromPath(controlBlock, tapLeafMsg) {
+ const k = [tapLeafMsg];
+ const e = [];
+ const m = (controlBlock.length - 33) / 32;
+ for (let j = 0; j < m; j++) {
+ e[j] = controlBlock.slice(33 + 32 * j, 65 + 32 * j);
+ if (k[j].compare(e[j]) < 0) {
+ k[j + 1] = tapBranchHash(k[j], e[j]);
+ } else {
+ k[j + 1] = tapBranchHash(e[j], k[j]);
+ }
+ }
+ return k[m];
+}
+exports.rootHashFromPath = rootHashFromPath;
+/**
+ * Build the hash tree from the scripts binary tree.
+ * The binary tree can be balanced or not.
+ * @param scriptsTree - is a list representing a binary tree where an element can be:
+ * - a taproot leaf [(output, version)], or
+ * - a pair of two taproot leafs [(output, version), (output, version)], or
+ * - one taproot leaf and a list of elements
+ */
+function toHashTree(scriptsTree) {
+ if (scriptsTree.length === 1) {
+ const script = scriptsTree[0];
+ if (Array.isArray(script)) {
+ return toHashTree(script);
+ }
+ script.version = script.version || LEAF_VERSION_TAPSCRIPT;
+ if ((script.version & 1) !== 0)
+ throw new TypeError('Invalid script version');
+ return {
+ hash: tapLeafHash(script.output, script.version),
+ };
+ }
+ const left = toHashTree([scriptsTree[0]]);
+ const right = toHashTree([scriptsTree[1]]);
+ let leftHash = left.hash;
+ let rightHash = right.hash;
+ if (leftHash.compare(rightHash) === 1)
+ [leftHash, rightHash] = [rightHash, leftHash];
+ return {
+ hash: tapBranchHash(leftHash, rightHash),
+ left,
+ right,
+ };
+}
+exports.toHashTree = toHashTree;
+/**
+ * Given a MAST tree, it finds the path of a particular hash.
+ * @param node - the root of the tree
+ * @param hash - the hash to search for
+ * @returns - and array of hashes representing the path, or an empty array if no pat is found
+ */
+function findScriptPath(node, hash) {
+ if (node.left) {
+ if (node.left.hash.equals(hash)) return node.right ? [node.right.hash] : [];
+ const leftPath = findScriptPath(node.left, hash);
+ if (leftPath.length)
+ return node.right ? [node.right.hash].concat(leftPath) : leftPath;
+ }
+ if (node.right) {
+ if (node.right.hash.equals(hash)) return node.left ? [node.left.hash] : [];
+ const rightPath = findScriptPath(node.right, hash);
+ if (rightPath.length)
+ return node.left ? [node.left.hash].concat(rightPath) : rightPath;
+ }
+ return [];
+}
+exports.findScriptPath = findScriptPath;
+function tapLeafHash(script, version) {
+ version = version || LEAF_VERSION_TAPSCRIPT;
+ return bcrypto.taggedHash(
+ TAP_LEAF_TAG,
+ buffer_1.Buffer.concat([
+ buffer_1.Buffer.from([version]),
+ serializeScript(script),
+ ]),
+ );
+}
+exports.tapLeafHash = tapLeafHash;
+function tapTweakHash(pubKey, h) {
+ return bcrypto.taggedHash(
+ TAP_TWEAK_TAG,
+ buffer_1.Buffer.concat(h ? [pubKey, h] : [pubKey]),
+ );
+}
+exports.tapTweakHash = tapTweakHash;
+function tapBranchHash(a, b) {
+ return bcrypto.taggedHash(TAP_BRANCH_TAG, buffer_1.Buffer.concat([a, b]));
+}
+function serializeScript(s) {
+ const varintLen = bufferutils_1.varuint.encodingLength(s.length);
+ const buffer = buffer_1.Buffer.allocUnsafe(varintLen); // better
+ bufferutils_1.varuint.encode(s.length, buffer);
+ return buffer_1.Buffer.concat([buffer, s]);
+}
diff --git a/src/payments/testecc.d.ts b/src/payments/testecc.d.ts
new file mode 100644
index 000000000..59d0de2b2
--- /dev/null
+++ b/src/payments/testecc.d.ts
@@ -0,0 +1,2 @@
+import { TinySecp256k1Interface } from '../types';
+export declare function testEcc(ecc: TinySecp256k1Interface): void;
diff --git a/src/payments/testecc.js b/src/payments/testecc.js
new file mode 100644
index 000000000..44e19c887
--- /dev/null
+++ b/src/payments/testecc.js
@@ -0,0 +1,72 @@
+'use strict';
+Object.defineProperty(exports, '__esModule', { value: true });
+exports.testEcc = void 0;
+const h = hex => Buffer.from(hex, 'hex');
+function testEcc(ecc) {
+ assert(typeof ecc.isXOnlyPoint === 'function');
+ assert(
+ ecc.isXOnlyPoint(
+ h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
+ ),
+ );
+ assert(
+ ecc.isXOnlyPoint(
+ h('fffffffffffffffffffffffffffffffffffffffffffffffffffffffeeffffc2e'),
+ ),
+ );
+ assert(
+ ecc.isXOnlyPoint(
+ h('f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9'),
+ ),
+ );
+ assert(
+ ecc.isXOnlyPoint(
+ h('0000000000000000000000000000000000000000000000000000000000000001'),
+ ),
+ );
+ assert(
+ !ecc.isXOnlyPoint(
+ h('0000000000000000000000000000000000000000000000000000000000000000'),
+ ),
+ );
+ assert(
+ !ecc.isXOnlyPoint(
+ h('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),
+ ),
+ );
+ assert(typeof ecc.xOnlyPointAddTweak === 'function');
+ tweakAddVectors.forEach(t => {
+ const r = ecc.xOnlyPointAddTweak(h(t.pubkey), h(t.tweak));
+ if (t.result === null) {
+ assert(r === null);
+ } else {
+ assert(r !== null);
+ assert(r.parity === t.parity);
+ assert(Buffer.from(r.xOnlyPubkey).equals(h(t.result)));
+ }
+ });
+}
+exports.testEcc = testEcc;
+function assert(bool) {
+ if (!bool) throw new Error('ecc library invalid');
+}
+const tweakAddVectors = [
+ {
+ pubkey: '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
+ tweak: 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
+ parity: -1,
+ result: null,
+ },
+ {
+ pubkey: '1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b',
+ tweak: 'a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac',
+ parity: 1,
+ result: 'e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf',
+ },
+ {
+ pubkey: '2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991',
+ tweak: '823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47',
+ parity: 0,
+ result: '9534f8dc8c6deda2dc007655981c78b49c5d96c778fbf363462a11ec9dfd948c',
+ },
+];
diff --git a/src/psbt.d.ts b/src/psbt.d.ts
index 8603a6955..43ce706f9 100644
--- a/src/psbt.d.ts
+++ b/src/psbt.d.ts
@@ -56,6 +56,17 @@ export declare class Psbt {
static fromBase64(data: string, opts?: PsbtOptsOptional): Psbt;
static fromHex(data: string, opts?: PsbtOptsOptional): Psbt;
static fromBuffer(buffer: Buffer, opts?: PsbtOptsOptional): Psbt;
+ /**
+ * This is a helper method for converting a normal Signer into a Taproot Signer.
+ * Note that this helper method required for the Private Key of the Signer to be present.
+ * Steps:
+ * - if the Y coordinate of the Signer Public Key is odd then negate the Private Key
+ * - tweak the private key with the provided hash (should be empty for key-path spending)
+ * @param signer a taproot signer object, the Private Key must be present
+ * @param opts
+ * @returns a Signer having the Private and Public keys tweaked
+ */
+ static tweakSigner(signer: Signer, opts?: TaprootSignerOpts): Signer;
private __CACHE;
private opts;
constructor(opts?: PsbtOptsOptional, data?: PsbtBase);
@@ -143,6 +154,7 @@ export interface HDSigner extends HDSignerBase {
* Return a 64 byte signature (32 byte r and 32 byte s in that order)
*/
sign(hash: Buffer): Buffer;
+ signSchnorr?(hash: Buffer): Buffer;
}
/**
* Same as above but with async sign method
@@ -150,17 +162,31 @@ export interface HDSigner extends HDSignerBase {
export interface HDSignerAsync extends HDSignerBase {
derivePath(path: string): HDSignerAsync;
sign(hash: Buffer): Promise;
+ signSchnorr?(hash: Buffer): Promise;
}
export interface Signer {
publicKey: Buffer;
+ /**
+ * Private Key is optional, it is required only if the signer must be tweaked.
+ * See the `tweakSigner()` method.
+ */
+ privateKey?: Buffer;
network?: any;
sign(hash: Buffer, lowR?: boolean): Buffer;
+ signSchnorr?(hash: Buffer): Buffer;
getPublicKey?(): Buffer;
}
+export interface TaprootSignerOpts {
+ network?: Network;
+ eccLib?: any;
+ /** The hash used to tweak the Signer */
+ tweakHash?: Buffer;
+}
export interface SignerAsync {
publicKey: Buffer;
network?: any;
sign(hash: Buffer, lowR?: boolean): Promise;
+ signSchnorr?(hash: Buffer): Promise;
getPublicKey?(): Buffer;
}
/**
@@ -178,5 +204,5 @@ isP2WSH: boolean) => {
finalScriptSig: Buffer | undefined;
finalScriptWitness: Buffer | undefined;
};
-declare type AllScriptType = 'witnesspubkeyhash' | 'pubkeyhash' | 'multisig' | 'pubkey' | 'nonstandard' | 'p2sh-witnesspubkeyhash' | 'p2sh-pubkeyhash' | 'p2sh-multisig' | 'p2sh-pubkey' | 'p2sh-nonstandard' | 'p2wsh-pubkeyhash' | 'p2wsh-multisig' | 'p2wsh-pubkey' | 'p2wsh-nonstandard' | 'p2sh-p2wsh-pubkeyhash' | 'p2sh-p2wsh-multisig' | 'p2sh-p2wsh-pubkey' | 'p2sh-p2wsh-nonstandard';
+declare type AllScriptType = 'witnesspubkeyhash' | 'pubkeyhash' | 'multisig' | 'pubkey' | 'taproot' | 'nonstandard' | 'p2sh-witnesspubkeyhash' | 'p2sh-pubkeyhash' | 'p2sh-multisig' | 'p2sh-pubkey' | 'p2sh-nonstandard' | 'p2wsh-pubkeyhash' | 'p2wsh-multisig' | 'p2wsh-pubkey' | 'p2wsh-nonstandard' | 'p2sh-p2wsh-pubkeyhash' | 'p2sh-p2wsh-multisig' | 'p2sh-p2wsh-pubkey' | 'p2sh-p2wsh-nonstandard';
export {};
diff --git a/src/psbt.js b/src/psbt.js
index 616219580..4dce4643a 100644
--- a/src/psbt.js
+++ b/src/psbt.js
@@ -1,6 +1,8 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
exports.Psbt = void 0;
+const ecc = require('tiny-secp256k1'); // TODO: extract
+const ecpair_1 = require('ecpair');
const bip174_1 = require('bip174');
const varuint = require('bip174/src/lib/converter/varint');
const utils_1 = require('bip174/src/lib/utils');
@@ -11,6 +13,7 @@ const networks_1 = require('./networks');
const payments = require('./payments');
const bscript = require('./script');
const transaction_1 = require('./transaction');
+const taprootutils_1 = require('./payments/taprootutils');
/**
* These are the default arguments for a Psbt instance.
*/
@@ -103,6 +106,39 @@ class Psbt {
checkTxForDupeIns(psbt.__CACHE.__TX, psbt.__CACHE);
return psbt;
}
+ /**
+ * This is a helper method for converting a normal Signer into a Taproot Signer.
+ * Note that this helper method required for the Private Key of the Signer to be present.
+ * Steps:
+ * - if the Y coordinate of the Signer Public Key is odd then negate the Private Key
+ * - tweak the private key with the provided hash (should be empty for key-path spending)
+ * @param signer a taproot signer object, the Private Key must be present
+ * @param opts
+ * @returns a Signer having the Private and Public keys tweaked
+ */
+ static tweakSigner(signer, opts = {}) {
+ let privateKey = signer.privateKey;
+ if (!privateKey) {
+ throw new Error('Private key is required for tweaking signer!');
+ }
+ if (signer.publicKey[0] === 3) {
+ privateKey = ecc.privateNegate(privateKey);
+ }
+ const tweakedPrivateKey = ecc.privateAdd(
+ privateKey,
+ (0, taprootutils_1.tapTweakHash)(
+ signer.publicKey.slice(1, 33),
+ opts.tweakHash,
+ ),
+ );
+ if (!tweakedPrivateKey) {
+ throw new Error('Invalid tweaked private key!');
+ }
+ const ECPair = (0, ecpair_1.ECPairFactory)(ecc);
+ return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {
+ network: opts.network,
+ });
+ }
get inputCount() {
return this.data.inputs.length;
}
@@ -298,7 +334,11 @@ class Psbt {
}
getInputType(inputIndex) {
const input = (0, utils_1.checkForInput)(this.data.inputs, inputIndex);
- const script = getScriptFromUtxo(inputIndex, input, this.__CACHE);
+ const { script } = getScriptAndAmountFromUtxo(
+ inputIndex,
+ input,
+ this.__CACHE,
+ );
const result = getMeaningfulScript(
script,
inputIndex,
@@ -355,13 +395,21 @@ class Psbt {
let hashCache;
let scriptCache;
let sighashCache;
+ const scriptType = this.getInputType(inputIndex);
for (const pSig of mySigs) {
- const sig = bscript.signature.decode(pSig.signature);
+ const sig =
+ scriptType === 'taproot'
+ ? {
+ signature: pSig.signature,
+ hashType: transaction_1.Transaction.SIGHASH_DEFAULT,
+ }
+ : bscript.signature.decode(pSig.signature);
const { hash, script } =
sighashCache !== sig.hashType
? getHashForSig(
inputIndex,
Object.assign({}, input, { sighashType: sig.hashType }),
+ this.data.inputs,
this.__CACHE,
true,
)
@@ -526,13 +574,30 @@ class Psbt {
this.__CACHE,
sighashTypes,
);
- const partialSig = [
- {
- pubkey: keyPair.publicKey,
- signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
- },
- ];
- this.data.updateInput(inputIndex, { partialSig });
+ const scriptType = this.getInputType(inputIndex);
+ if (scriptType === 'taproot') {
+ if (!keyPair.signSchnorr) {
+ throw new Error(
+ `Need Schnorr Signer to sign taproot input #${inputIndex}.`,
+ );
+ }
+ const partialSig = [
+ {
+ pubkey: keyPair.publicKey,
+ signature: keyPair.signSchnorr(hash),
+ },
+ ];
+ // must be changed to use the `updateInput()` public API
+ this.data.inputs[inputIndex].partialSig = partialSig;
+ } else {
+ const partialSig = [
+ {
+ pubkey: keyPair.publicKey,
+ signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
+ },
+ ];
+ this.data.updateInput(inputIndex, { partialSig });
+ }
return this;
}
signInputAsync(
@@ -671,6 +736,7 @@ function canFinalize(input, script, scriptType) {
case 'pubkey':
case 'pubkeyhash':
case 'witnesspubkeyhash':
+ case 'taproot':
return hasSigs(1, input.partialSig);
case 'multisig':
const p2ms = payments.p2ms({ output: script });
@@ -704,9 +770,9 @@ function isFinalized(input) {
return !!input.finalScriptSig || !!input.finalScriptWitness;
}
function isPaymentFactory(payment) {
- return script => {
+ return (script, eccLib) => {
try {
- payment({ output: script });
+ payment({ output: script }, { eccLib });
return true;
} catch (err) {
return false;
@@ -719,6 +785,7 @@ const isP2PKH = isPaymentFactory(payments.p2pkh);
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
const isP2SHScript = isPaymentFactory(payments.p2sh);
+const isP2TR = isPaymentFactory(payments.p2tr);
function bip32DerivationIsMine(root) {
return d => {
if (!d.masterFingerprint.equals(root.fingerprint)) return false;
@@ -920,6 +987,7 @@ function getHashAndSighashType(
const { hash, sighashType, script } = getHashForSig(
inputIndex,
input,
+ inputs,
cache,
false,
sighashTypes,
@@ -930,7 +998,14 @@ function getHashAndSighashType(
sighashType,
};
}
-function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
+function getHashForSig(
+ inputIndex,
+ input,
+ inputs,
+ cache,
+ forValidate,
+ sighashTypes,
+) {
const unsignedTx = cache.__TX;
const sighashType =
input.sighashType || transaction_1.Transaction.SIGHASH_ALL;
@@ -988,6 +1063,18 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
prevout.value,
sighashType,
);
+ } else if (isP2TR(meaningfulScript, ecc)) {
+ const prevOuts = inputs.map((i, index) =>
+ getScriptAndAmountFromUtxo(index, i, cache),
+ );
+ const signingScripts = prevOuts.map(o => o.script);
+ const values = prevOuts.map(o => o.value);
+ hash = unsignedTx.hashForWitnessV1(
+ inputIndex,
+ signingScripts,
+ values,
+ transaction_1.Transaction.SIGHASH_DEFAULT,
+ );
} else {
// non-segwit
if (
@@ -1050,6 +1137,15 @@ function getPayment(script, scriptType, partialSig) {
signature: partialSig[0].signature,
});
break;
+ case 'taproot':
+ payment = payments.p2tr(
+ {
+ output: script,
+ signature: partialSig[0].signature,
+ },
+ { eccLib: ecc },
+ );
+ break;
}
return payment;
}
@@ -1094,7 +1190,7 @@ function getScriptFromInput(inputIndex, input, cache) {
res.script = input.witnessUtxo.script;
}
}
- if (input.witnessScript || isP2WPKH(res.script)) {
+ if (input.witnessScript || isP2WPKH(res.script) || isP2TR(res.script, ecc)) {
res.isSegwit = true;
}
return res;
@@ -1267,22 +1363,26 @@ function nonWitnessUtxoTxFromCache(cache, input, inputIndex) {
}
return c[inputIndex];
}
-function getScriptFromUtxo(inputIndex, input, cache) {
+function getScriptAndAmountFromUtxo(inputIndex, input, cache) {
if (input.witnessUtxo !== undefined) {
- return input.witnessUtxo.script;
+ return {
+ script: input.witnessUtxo.script,
+ value: input.witnessUtxo.value,
+ };
} else if (input.nonWitnessUtxo !== undefined) {
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
cache,
input,
inputIndex,
);
- return nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index].script;
+ const o = nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index];
+ return { script: o.script, value: o.value };
} else {
throw new Error("Can't find pubkey in input without Utxo data");
}
}
function pubkeyInInput(pubkey, input, inputIndex, cache) {
- const script = getScriptFromUtxo(inputIndex, input, cache);
+ const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache);
const { meaningfulScript } = getMeaningfulScript(
script,
inputIndex,
@@ -1392,11 +1492,16 @@ function checkInvalidP2WSH(script) {
}
function pubkeyInScript(pubkey, script) {
const pubkeyHash = (0, crypto_1.hash160)(pubkey);
+ const pubkeyXOnly = pubkey.slice(1, 33);
const decompiled = bscript.decompile(script);
if (decompiled === null) throw new Error('Unknown script error');
return decompiled.some(element => {
if (typeof element === 'number') return false;
- return element.equals(pubkey) || element.equals(pubkeyHash);
+ return (
+ element.equals(pubkey) ||
+ element.equals(pubkeyHash) ||
+ element.equals(pubkeyXOnly)
+ );
});
}
function classifyScript(script) {
@@ -1404,6 +1509,7 @@ function classifyScript(script) {
if (isP2PKH(script)) return 'pubkeyhash';
if (isP2MS(script)) return 'multisig';
if (isP2PK(script)) return 'pubkey';
+ if (isP2TR(script, ecc)) return 'taproot';
return 'nonstandard';
}
function range(n) {
diff --git a/src/types.d.ts b/src/types.d.ts
index 5a8505d34..aefc6bed7 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -10,6 +10,18 @@ export declare function Signer(obj: any): boolean;
export declare function Satoshi(value: number): boolean;
export declare const ECPoint: any;
export declare const Network: any;
+export interface XOnlyPointAddTweakResult {
+ parity: 1 | 0;
+ xOnlyPubkey: Uint8Array;
+}
+export interface TaprootLeaf {
+ output: Buffer;
+ version?: number;
+}
+export interface TinySecp256k1Interface {
+ isXOnlyPoint(p: Uint8Array): boolean;
+ xOnlyPointAddTweak(p: Uint8Array, tweak: Uint8Array): XOnlyPointAddTweakResult | null;
+}
export declare const Buffer256bit: any;
export declare const Hash160bit: any;
export declare const Hash256bit: any;
diff --git a/test/fixtures/p2tr.json b/test/fixtures/p2tr.json
new file mode 100644
index 000000000..4c7174fc0
--- /dev/null
+++ b/test/fixtures/p2tr.json
@@ -0,0 +1,1026 @@
+{
+ "valid": [
+ {
+ "description": "output and pubkey from address",
+ "arguments": {
+ "address": "bc1p4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82r6sj7lcqx"
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address and pubkey from output",
+ "arguments": {
+ "output": "OP_1 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5"
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1p4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82r6sj7lcqx",
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address and output from pubkey",
+ "arguments": {
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5"
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1p4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82r6sj7lcqx",
+ "output": "OP_1 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, output and witness from pubkey and signature",
+ "arguments": {
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "signature": "a251221c339a7129dd0b769698aca40d8d9da9570ab796a1820b91ab7dbf5acbea21c88ba8f1e9308a21729baf080734beaf97023882d972f75e380d480fd704"
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1p4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82r6sj7lcqx",
+ "output": "OP_1 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "input": null,
+ "witness": [
+ "a251221c339a7129dd0b769698aca40d8d9da9570ab796a1820b91ab7dbf5acbea21c88ba8f1e9308a21729baf080734beaf97023882d972f75e380d480fd704"
+ ]
+ }
+ },
+ {
+ "description": "address, output and signature from pubkey and witness",
+ "arguments": {
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "witness": [
+ "300602010002010001"
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1p4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82r6sj7lcqx",
+ "output": "OP_1 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "input": null,
+ "signature": "300602010002010001",
+ "witness": [
+ "300602010002010001"
+ ]
+ }
+ },
+ {
+ "description": "address, pubkey and output from internalPubkey",
+ "arguments": {
+ "internalPubkey": "9fa5ffb68821cf559001caa0577eeea4978b29416def328a707b15e91701a2f7"
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1prs7pxymu7jhsptzjlwlqnk8jyg5qmq4sdlc3rwcy7pd3ydz92xjq5ap2sg",
+ "pubkey": "1c3c13137cf4af00ac52fbbe09d8f222280d82b06ff111bb04f05b12344551a4",
+ "output": "OP_1 1c3c13137cf4af00ac52fbbe09d8f222280d82b06ff111bb04f05b12344551a4",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, pubkey, internalPubkey and output from witness",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "internalPubkey": "a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a36",
+ "pubkey": "1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
+ "hash": "c5c62d7fc595ba5fbe61602eb1a29e2e4763408fe1e2b161beb7cb3c71ebcad9",
+ "address": "bc1pr6lghypk80gf025lx5kgkgv3fcvgd0qfl608psylx0hj624a7j7qay80rv",
+ "output": "OP_1 1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
+ "signature": null,
+ "input": null,
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ }
+ },
+ {
+ "description": "address, pubkey, internalPubkey and output from witness with annex",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c",
+ "5000000000000000001111111111111111"
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "internalPubkey": "a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a36",
+ "pubkey": "1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
+ "hash": "c5c62d7fc595ba5fbe61602eb1a29e2e4763408fe1e2b161beb7cb3c71ebcad9",
+ "address": "bc1pr6lghypk80gf025lx5kgkgv3fcvgd0qfl608psylx0hj624a7j7qay80rv",
+ "output": "OP_1 1ebe8b90363bd097aa9f352c8b21914e1886bc09fe9e70c09f33ef2d2abdf4bc",
+ "signature": null,
+ "input": null,
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c",
+ "5000000000000000001111111111111111"
+ ]
+ }
+ },
+ {
+ "description": "address, pubkey, output and hash from internalPubkey and a script tree with one leaf",
+ "arguments": {
+ "internalPubkey": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0",
+ "scriptsTree": [
+ {
+ "output": "83d8ee77a0f3a32a5cea96fd1624d623b836c1e5d1ac2dcde46814b619320c18 OP_CHECKSIG"
+ }
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1pjegs09vkeder9m4sw3ycjf2rnpa8nljdqmuleunk9eshu8cq3xysvhgp2u",
+ "pubkey": "9651079596cb7232eeb07449892543987a79fe4d06f9fcf2762e617e1f008989",
+ "output": "OP_1 9651079596cb7232eeb07449892543987a79fe4d06f9fcf2762e617e1f008989",
+ "hash": "16e3f3b8b9c1e453c56b547785cdd25259d65823a2064f30783acc58ef012633",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, pubkey, output and hash from internalPubkey and a script tree with two leafs",
+ "arguments": {
+ "internalPubkey": "2258b1c3160be0864a541854eec9164a572f094f7562628281a8073bb89173a7",
+ "scriptsTree": [
+ {
+ "output": "d826a0a53abb6ffc60df25b9c152870578faef4b2eb5a09bdd672bbe32cdd79b OP_CHECKSIG"
+ },
+ {
+ "output": "d826a0a53abb6ffc60df25b9c152870578faef4b2eb5a09bdd672bbe32cdd79b OP_CHECKSIG"
+ }
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1ptj0v8rwcj6s36p4r26ws6htx0fct43n0mxdvdeh9043whlxlq3kq9965ke",
+ "pubkey": "5c9ec38dd896a11d06a3569d0d5d667a70bac66fd99ac6e6e57d62ebfcdf046c",
+ "output": "OP_1 5c9ec38dd896a11d06a3569d0d5d667a70bac66fd99ac6e6e57d62ebfcdf046c",
+ "hash": "ce00198cd4667abae1f94aa5862d089e2967af5aec20715c692db74e3d66bb73",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, pubkey, output and hash from internalPubkey and a script tree with three leafs",
+ "arguments": {
+ "internalPubkey": "7631cacec3343052d87ef4d0065f61dde82d7d2db0c1cc02ef61ef3c982ea763",
+ "scriptsTree": [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ {
+ "output": "9b4d495b74887815a1ff623c055c6eac6b6b2e07d2a016d6526ebac71dd99744 OP_CHECKSIG"
+ }
+ ]
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1pkq0t8nkmqswn3qjg9uy6ux2hsyyz4as25v8unfjc9s8q2e4c00sqku9lxh",
+ "pubkey": "b01eb3cedb041d3882482f09ae195781082af60aa30fc9a6582c0e0566b87be0",
+ "output": "OP_1 b01eb3cedb041d3882482f09ae195781082af60aa30fc9a6582c0e0566b87be0",
+ "hash": "7ae0cc2057b1a7bf0e09c787e1d7b6b2355ac112a7b80380a5c1e942155b0c0f",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, pubkey, output and hash from internalPubkey and a script tree with four leafs",
+ "arguments": {
+ "internalPubkey": "d0c19def28bb1b39451c1a814737615983967780d223b79969ba692182c6006b",
+ "scriptsTree": [
+ [
+ {
+ "output": "9b4d495b74887815a1ff623c055c6eac6b6b2e07d2a016d6526ebac71dd99744 OP_CHECKSIG"
+ },
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ }
+ ],
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ {
+ "output": "9b4d495b74887815a1ff623c055c6eac6b6b2e07d2a016d6526ebac71dd99744 OP_CHECKSIG"
+ }
+ ]
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1pstdzevc40j059s0473rghhv9e05l9f5xv7l6dtlavvq22rzfna3syjvjut",
+ "pubkey": "82da2cb3157c9f42c1f5f4468bdd85cbe9f2a68667bfa6affd6300a50c499f63",
+ "output": "OP_1 82da2cb3157c9f42c1f5f4468bdd85cbe9f2a68667bfa6affd6300a50c499f63",
+ "hash": "d673e784eac9b70289130a0bd359023a0fbdde51dc069b9efb4157c2cdce3ea5",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, pubkey, output and hash from internalPubkey and a script tree with seven leafs",
+ "arguments": {
+ "internalPubkey": "f95886b02a84928c5c15bdca32784993105f73de27fa6ad8c1a60389b999267c",
+ "scriptsTree": [
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ {
+ "output": "2258b1c3160be0864a541854eec9164a572f094f7562628281a8073bb89173a7 OP_CHECKSIG"
+ }
+ ]
+ ],
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ {
+ "output": "03a669ea926f381582ec4a000b9472ba8a17347f5fb159eddd4a07036a6718eb OP_CHECKSIG"
+ }
+ ]
+ ]
+ ]
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1pfas4r5s5208puwzj20hvwg2dw2kanc06yxczzdd66729z63pk43q7zwlu6",
+ "pubkey": "4f6151d21453ce1e385253eec7214d72add9e1fa21b02135bad794516a21b562",
+ "output": "OP_1 4f6151d21453ce1e385253eec7214d72add9e1fa21b02135bad794516a21b562",
+ "hash": "16fb2e99bdf86f67ee6980d0418658f15df7e19476053b58f45a89df2e219b1b",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "address, pubkey, output and hash from internalPubkey and a script tree with seven leafs (2)",
+ "arguments": {
+ "internalPubkey": "aba457d16a8d59151c387f24d1eb887efbe24644c1ee64b261282e7baebdb247",
+ "scriptsTree": [
+ {
+ "output": "00a9da96087a72258f83b338ef7f0ea8cbbe05da5f18f091eb397d1ecbf7c3d3 OP_CHECKSIG"
+ },
+ [
+ [
+ {
+ "output": "00a9da96087a72258f83b338ef7f0ea8cbbe05da5f18f091eb397d1ecbf7c3d3 OP_CHECKSIG"
+ },
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ }
+ ]
+ ],
+ [
+ [
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ },
+ {
+ "output": "50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0 OP_CHECKSIG"
+ }
+ ],
+ {
+ "output": "00a9da96087a72258f83b338ef7f0ea8cbbe05da5f18f091eb397d1ecbf7c3d3 OP_CHECKSIG"
+ }
+ ]
+ ]
+ ]
+ },
+ "expected": {
+ "name": "p2tr",
+ "address": "bc1pmu8qwr9zljs9anger0d6q3uyr43yzjetmjmzf8p93ltycrwj28lsee3e0n",
+ "pubkey": "df0e070ca2fca05ecd191bdba047841d62414b2bdcb6249c258fd64c0dd251ff",
+ "output": "OP_1 df0e070ca2fca05ecd191bdba047841d62414b2bdcb6249c258fd64c0dd251ff",
+ "hash": "027391d0aac8d94725e4fcec4b07214d7c8a14bcdca2b1c08e4bc786308bdae5",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 1",
+ "arguments": {
+ "internalPubkey": "d6889cb081036e0faefa3a35157ad71086b123b2b144b649798b494c300a961d"
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 53a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343",
+ "pubkey": "53a1f6e454df1aa2776a2814a721372d6258050de330b3c6d10ee8f4e0dda343",
+ "address": "bc1p2wsldez5mud2yam29q22wgfh9439spgduvct83k3pm50fcxa5dps59h4z5",
+ "signature": null,
+ "input": null,
+ "witness": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 2",
+ "arguments": {
+ "internalPubkey": "187791b6f712a8ea41c8ecdd0ee77fab3e85263b37e1ec18a3651926b3a6cf27",
+ "scriptLeaf": {
+ "output": "d85a959b0290bf19bb89ed43c916be835475d013da4b362117393e25a48229b8 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "d85a959b0290bf19bb89ed43c916be835475d013da4b362117393e25a48229b8 OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3",
+ "pubkey": "147c9c57132f6e7ecddba9800bb0c4449251c92a1e60371ee77557b6620f3ea3",
+ "address": "bc1pz37fc4cn9ah8anwm4xqqhvxygjf9rjf2resrw8h8w4tmvcs0863sa2e586",
+ "hash": "5b75adecf53548f3ec6ad7d78383bf84cc57b55a3127c72b9a2481752dd88b21",
+ "witness": [
+ "20d85a959b0290bf19bb89ed43c916be835475d013da4b362117393e25a48229b8ac",
+ "c1187791b6f712a8ea41c8ecdd0ee77fab3e85263b37e1ec18a3651926b3a6cf27"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 3",
+ "arguments": {
+ "internalPubkey": "93478e9488f956df2396be2ce6c5cced75f900dfa18e7dabd2428aae78451820",
+ "scriptLeaf": {
+ "output": "b617298552a72ade070667e86ca63b8f5789a9fe8731ef91202a91c9f3459007 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "b617298552a72ade070667e86ca63b8f5789a9fe8731ef91202a91c9f3459007 OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 e4d810fd50586274face62b8a807eb9719cef49c04177cc6b76a9a4251d5450e",
+ "pubkey": "e4d810fd50586274face62b8a807eb9719cef49c04177cc6b76a9a4251d5450e",
+ "address": "bc1punvppl2stp38f7kwv2u2spltjuvuaayuqsthe34hd2dyy5w4g58qqfuag5",
+ "hash": "c525714a7f49c28aedbbba78c005931a81c234b2f6c99a73e4d06082adc8bf2b",
+ "witness": [
+ "20b617298552a72ade070667e86ca63b8f5789a9fe8731ef91202a91c9f3459007ac",
+ "c093478e9488f956df2396be2ce6c5cced75f900dfa18e7dabd2428aae78451820"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 4 - spend leaf 0",
+ "arguments": {
+ "internalPubkey": "ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf3786592",
+ "scriptLeaf": {
+ "output": "387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "424950333431",
+ "version": 152
+ }
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 0f63ca2c7639b9bb4be0465cc0aa3ee78a0761ba5f5f7d6ff8eab340f09da561",
+ "pubkey": "0f63ca2c7639b9bb4be0465cc0aa3ee78a0761ba5f5f7d6ff8eab340f09da561",
+ "address": "bc1ppa3u5trk8xumkjlqgewvp237u79qwcd6ta0h6mlca2e5puya54ssw9zq0y",
+ "hash": "f3004d6c183e038105d436db1424f321613366cbb7b05939bf05d763a9ebb962",
+ "witness": [
+ "20387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48ac",
+ "c0ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf37865927b2c2af8aa3e8b7bfe2f62a155f91427489c5c3b32be47e0b3fac755fc780e0e"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 4 - spend leaf 1",
+ "arguments": {
+ "internalPubkey": "ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf3786592",
+ "scriptLeaf": {
+ "output": "424950333431",
+ "version": 152
+ },
+ "scriptsTree": [
+ {
+ "output": "387671353e273264c495656e27e39ba899ea8fee3bb69fb2a680e22093447d48 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "424950333431",
+ "version": 152
+ }
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 0f63ca2c7639b9bb4be0465cc0aa3ee78a0761ba5f5f7d6ff8eab340f09da561",
+ "pubkey": "0f63ca2c7639b9bb4be0465cc0aa3ee78a0761ba5f5f7d6ff8eab340f09da561",
+ "address": "bc1ppa3u5trk8xumkjlqgewvp237u79qwcd6ta0h6mlca2e5puya54ssw9zq0y",
+ "hash": "f3004d6c183e038105d436db1424f321613366cbb7b05939bf05d763a9ebb962",
+ "witness": [
+ "06424950333431",
+ "98ee4fe085983462a184015d1f782d6a5f8b9c2b60130aff050ce221ecf37865928ad69ec7cf41c2a4001fd1f738bf1e505ce2277acdcaa63fe4765192497f47a7"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 5 - spend leaf 0",
+ "arguments": {
+ "internalPubkey": "f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd8",
+ "scriptLeaf": {
+ "output": "44b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fd OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "44b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fd OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "546170726f6f74",
+ "version": 82
+ }
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 053690babeabbb7850c32eead0acf8df990ced79f7a31e358fabf2658b4bc587",
+ "pubkey": "053690babeabbb7850c32eead0acf8df990ced79f7a31e358fabf2658b4bc587",
+ "address": "bc1pq5mfpw474wahs5xr9m4dpt8cm7vsemte7733udv040extz6tckrs29g04c",
+ "hash": "d9c2c32808b41c0301d876d49c0af72e1d98e84b99ca9b4bb67fea1a7424b755",
+ "witness": [
+ "2044b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fdac",
+ "c1f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd8e44d5f8fa5892c8b6d4d09a08d36edd0b08636e30311302e2448ad8172fb3433"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 5 - spend leaf 1",
+ "arguments": {
+ "internalPubkey": "f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd8",
+ "scriptLeaf": {
+ "output": "546170726f6f74",
+ "version": 82
+ },
+ "scriptsTree": [
+ {
+ "output": "44b178d64c32c4a05cc4f4d1407268f764c940d20ce97abfd44db5c3592b72fd OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "546170726f6f74",
+ "version": 82
+ }
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 053690babeabbb7850c32eead0acf8df990ced79f7a31e358fabf2658b4bc587",
+ "pubkey": "053690babeabbb7850c32eead0acf8df990ced79f7a31e358fabf2658b4bc587",
+ "address": "bc1pq5mfpw474wahs5xr9m4dpt8cm7vsemte7733udv040extz6tckrs29g04c",
+ "hash": "d9c2c32808b41c0301d876d49c0af72e1d98e84b99ca9b4bb67fea1a7424b755",
+ "witness": [
+ "07546170726f6f74",
+ "53f9f400803e683727b14f463836e1e78e1c64417638aa066919291a225f0e8dd864512fecdb5afa04f98839b50e6f0cb7b1e539bf6f205f67934083cdcc3c8d89"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 6 - spend leaf 0",
+ "arguments": {
+ "internalPubkey": "e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f",
+ "scriptLeaf": {
+ "output": "72ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "72ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69 OP_CHECKSIG",
+ "version": 192
+ },
+ [
+ {
+ "output": "2352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "7337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186a OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "pubkey": "91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "address": "bc1pjxmy65eywgafs5tsunw95ruycpqcqnev6ynxp7jaasylcgtcxczs6n332e",
+ "hash": "ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2",
+ "witness": [
+ "2072ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69ac",
+ "c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6fffe578e9ea769027e4f5a3de40732f75a88a6353a09d767ddeb66accef85e553"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 6 - spend leaf 1",
+ "arguments": {
+ "internalPubkey": "e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f",
+ "scriptLeaf": {
+ "output": "2352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "72ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69 OP_CHECKSIG",
+ "version": 192
+ },
+ [
+ {
+ "output": "2352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "7337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186a OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "pubkey": "91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "address": "bc1pjxmy65eywgafs5tsunw95ruycpqcqnev6ynxp7jaasylcgtcxczs6n332e",
+ "hash": "ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2",
+ "witness": [
+ "202352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8ac",
+ "c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f9e31407bffa15fefbf5090b149d53959ecdf3f62b1246780238c24501d5ceaf62645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 6 - spend leaf 2",
+ "arguments": {
+ "internalPubkey": "e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6f",
+ "scriptLeaf": {
+ "output": "7337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186a OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "72ea6adcf1d371dea8fba1035a09f3d24ed5a059799bae114084130ee5898e69 OP_CHECKSIG",
+ "version": 192
+ },
+ [
+ {
+ "output": "2352d137f2f3ab38d1eaa976758873377fa5ebb817372c71e2c542313d4abda8 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "7337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186a OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "pubkey": "91b64d5324723a985170e4dc5a0f84c041804f2cd12660fa5dec09fc21783605",
+ "address": "bc1pjxmy65eywgafs5tsunw95ruycpqcqnev6ynxp7jaasylcgtcxczs6n332e",
+ "hash": "ccbd66c6f7e8fdab47b3a486f59d28262be857f30d4773f2d5ea47f7761ce0e2",
+ "witness": [
+ "207337c0dd4253cb86f2c43a2351aadd82cccb12a172cd120452b9bb8324f2186aac",
+ "c0e0dfe2300b0dd746a3f8674dfd4525623639042569d829c7f0eed9602d263e6fba982a91d4fc552163cb1c0da03676102d5b7a014304c01f0c77b2b8e888de1c2645a02e0aac1fe69d69755733a9b7621b694bb5b5cde2bbfc94066ed62b9817"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 7 - spend leaf 0",
+ "arguments": {
+ "internalPubkey": "55adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d",
+ "scriptLeaf": {
+ "output": "71981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "71981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2 OP_CHECKSIG",
+ "version": 192
+ },
+ [
+ {
+ "output": "d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4c OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "pubkey": "75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "address": "bc1pw5tf7sqp4f50zka7629jrr036znzew70zxyvvej3zrpf8jg8hqcssyuewe",
+ "hash": "2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def",
+ "witness": [
+ "2071981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2ac",
+ "c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d3cd369a528b326bc9d2133cbd2ac21451acb31681a410434672c8e34fe757e91"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 7 - spend leaf 1",
+ "arguments": {
+ "internalPubkey": "55adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d",
+ "scriptLeaf": {
+ "output": "d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748 OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "71981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2 OP_CHECKSIG",
+ "version": 192
+ },
+ [
+ {
+ "output": "d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4c OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "pubkey": "75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "address": "bc1pw5tf7sqp4f50zka7629jrr036znzew70zxyvvej3zrpf8jg8hqcssyuewe",
+ "hash": "2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def",
+ "witness": [
+ "20d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748ac",
+ "c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312dd7485025fceb78b9ed667db36ed8b8dc7b1f0b307ac167fa516fe4352b9f4ef7f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d"
+ ],
+ "signature": null,
+ "input": null
+ }
+ },
+ {
+ "description": "BIP341 Test case 7 - spend leaf 2",
+ "arguments": {
+ "internalPubkey": "55adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d",
+ "scriptLeaf": {
+ "output": "c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4c OP_CHECKSIG",
+ "version": 192
+ },
+ "scriptsTree": [
+ {
+ "output": "71981521ad9fc9036687364118fb6ccd2035b96a423c59c5430e98310a11abe2 OP_CHECKSIG",
+ "version": 192
+ },
+ [
+ {
+ "output": "d5094d2dbe9b76e2c245a2b89b6006888952e2faa6a149ae318d69e520617748 OP_CHECKSIG",
+ "version": 192
+ },
+ {
+ "output": "c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4c OP_CHECKSIG",
+ "version": 192
+ }
+ ]
+ ]
+ },
+ "options": {},
+ "expected": {
+ "name": "p2tr",
+ "output": "OP_1 75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "pubkey": "75169f4001aa68f15bbed28b218df1d0a62cbbcf1188c6665110c293c907b831",
+ "address": "bc1pw5tf7sqp4f50zka7629jrr036znzew70zxyvvej3zrpf8jg8hqcssyuewe",
+ "hash": "2f6b2c5397b6d68ca18e09a3f05161668ffe93a988582d55c6f07bd5b3329def",
+ "witness": [
+ "20c440b462ad48c7a77f94cd4532d8f2119dcebbd7c9764557e62726419b08ad4cac",
+ "c155adf4e8967fbd2e29f20ac896e60c3b0f1d5b0efa9d34941b5958c7b0a0312d737ed1fe30bc42b8022d717b44f0d93516617af64a64753b7a06bf16b26cd711f154e8e8e17c31d3462d7132589ed29353c6fafdb884c5a6e04ea938834f0d9d"
+ ],
+ "signature": null,
+ "input": null
+ }
+ }
+ ],
+ "invalid": [
+ {
+ "exception": "Not enough data",
+ "arguments": {}
+ },
+ {
+ "exception": "Not enough data",
+ "arguments": {
+ "signature": "300602010002010001"
+ }
+ },
+ {
+ "description": "Incorrect Witness Version",
+ "exception": "Output is invalid",
+ "arguments": {
+ "output": "OP_0 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5"
+ }
+ },
+ {
+ "description": "Invalid x coordinate for pubkey in pubkey",
+ "exception": "Invalid pubkey for p2tr",
+ "arguments": {
+ "pubkey": "f136e956540197c21ff3c075d32a6e3c82f1ee1e646cc0f08f51b0b5edafa762"
+ }
+ },
+ {
+ "description": "Invalid x coordinate for pubkey in output",
+ "exception": "Invalid pubkey for p2tr",
+ "arguments": {
+ "output": "OP_1 f136e956540197c21ff3c075d32a6e3c82f1ee1e646cc0f08f51b0b5edafa762"
+ }
+ },
+ {
+ "description": "Invalid x coordinate for pubkey in address",
+ "exception": "Invalid pubkey for p2tr",
+ "arguments": {
+ "address": "bc1p7ymwj4j5qxtuy8lncp6ax2nw8jp0rms7v3kvpuy02xcttmd05a3qmwlnez"
+ }
+ },
+ {
+ "description": "Pubkey mismatch between pubkey and output",
+ "exception": "Pubkey mismatch",
+ "options": {},
+ "arguments": {
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "output": "OP_1 12d7dac98d69a086a50b30959a3537950f356ffc6f50a263ab75c8a3ec9d44c1"
+ }
+ },
+ {
+ "description": "Pubkey mismatch between pubkey and address",
+ "exception": "Pubkey mismatch",
+ "options": {},
+ "arguments": {
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "address": "bc1pztta4jvddxsgdfgtxz2e5dfhj58n2mludag2ycatwhy28myagnqsnl7mv7"
+ }
+ },
+ {
+ "description": "Pubkey mismatch between output and address",
+ "exception": "Pubkey mismatch",
+ "options": {},
+ "arguments": {
+ "output": "OP_1 ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "address": "bc1pztta4jvddxsgdfgtxz2e5dfhj58n2mludag2ycatwhy28myagnqsnl7mv7"
+ }
+ },
+ {
+ "description": "Pubkey mismatch between internalPubkey and pubkey",
+ "exception": "Pubkey mismatch",
+ "options": {},
+ "arguments": {
+ "internalPubkey": "9fa5ffb68821cf559001caa0577eeea4978b29416def328a707b15e91701a2f7",
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5"
+ }
+ },
+ {
+ "description": "Hash mismatch between scriptsTree and hash",
+ "exception": "Hash mismatch",
+ "options": {},
+ "arguments": {
+ "internalPubkey": "9fa5ffb68821cf559001caa0577eeea4978b29416def328a707b15e91701a2f7",
+ "scriptsTree": [
+ {
+ "output": "83d8ee77a0f3a32a5cea96fd1624d623b836c1e5d1ac2dcde46814b619320c18 OP_CHECKSIG"
+ }
+ ],
+ "hash": "b76077013c8e303085e300000000000000000000000000000000000000000000"
+ }
+ },
+ {
+ "exception": "Expected Point",
+ "options": {},
+ "arguments": {
+ "internalPubkey": "9fa5ffb68821cf559001caa0577eeea4978b29416def328a707b15e91701a2f8"
+ }
+ },
+ {
+ "exception": "Signature mismatch",
+ "arguments": {
+ "pubkey": "ab610d22c801def8a1e02368d1b92018970eb52a729919705e8a1a2f60c750f5",
+ "signature": "a251221c339a7129dd0b769698aca40d8d9da9570ab796a1820b91ab7dbf5acbea21c88ba8f1e9308a21729baf080734beaf97023882d972f75e380d480fd704",
+ "witness": [
+ "607b8b5b5c8614757736e3d5811790636d2a8e2ea14418f8cff66b2e898b3b7536a49b7c4bc8b3227953194bf5d0548e13e3526fdb36beeefadda1ec834a0db2"
+ ]
+ }
+ },
+ {
+ "exception": "Invalid prefix or Network mismatch",
+ "arguments": {
+ "address": "bcrt1prhepe49mpmhclwcqmkzpaz43revunykc7fc0f9az6pq08sn4qe7sxtrd8y"
+ }
+ },
+ {
+ "exception": "Invalid address version",
+ "arguments": {
+ "address": "bc1z4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82r6s6rxhwd"
+ }
+ },
+ {
+ "exception": "Invalid address data",
+ "arguments": {
+ "address": "bc1p4dss6gkgq8003g0qyd5drwfqrztsadf2w2v3juz73gdz7cx82qh3d2w3"
+ }
+ },
+ {
+ "description": "Control block length too small",
+ "exception": "The control-block length is too small. Got 16, expected min 33.",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8"
+ ]
+ }
+ },
+ {
+ "description": "Control block must have a length of 33 + 32m (0 <= m <= 128)",
+ "exception": "The control-block length of 40 is incorrect!",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf77"
+ ]
+ }
+ },
+ {
+ "description": "Control block length too large",
+ "exception": "The script path is too long. Got 129, expected max 128.",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c50cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ }
+ },
+ {
+ "description": "Invalid internalPubkey in control block",
+ "exception": "Invalid internalPubkey for p2tr witness",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c14444444444444444453d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ }
+ },
+ {
+ "description": "internalPubkey mismatch between control block and internalKey",
+ "exception": "Internal pubkey mismatch",
+ "arguments": {
+ "internalPubkey": "9fa5ffb68821cf559001caa0577eeea4978b29416def328a707b15e91701a2f7",
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ }
+ },
+ {
+ "description": "pubkey mismatch between outputKey and pubkey",
+ "exception": "Pubkey mismatch for p2tr witness",
+ "arguments": {
+ "pubkey": "df0e070ca2fca05ecd191bdba047841d62414b2bdcb6249c258fd64c0dd251ff",
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c1a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ }
+ },
+ {
+ "description": "parity",
+ "exception": "Incorrect parity",
+ "arguments": {
+ "witness": [
+ "9675a9982c6398ea9d441cb7a943bcd6ff033cc3a2e01a0178a7d3be4575be863871c6bf3eef5ecd34721c784259385ca9101c3a313e010ac942c99de05aaaa602",
+ "5799cf4b193b730fb99580b186f7477c2cca4d28957326f6f1a5d14116438530e7ec0ce1cd465ad96968ae8a6a09d4d37a060a115919f56fcfebe7b2277cc2df5cc08fb6cda9105ee2512b2e22635aba",
+ "7520c7b5db9562078049719228db2ac80cb9643ec96c8055aa3b29c2c03d4d99edb0ac",
+ "c0a7957acbaaf7b444c53d9e0c9436e8a8a3247fd515095d66ddf6201918b40a3668f9a4ccdffcf778da624dca2dda0b08e763ec52fd4ad403ec7563a3504d0cc168b9a77a410029e01dac89567c9b2e6cd726e840351df3f2f58fefe976200a19244150d04153909f660184d656ee95fa7bf8e1d4ec83da1fca34f64bc279b76d257ec623e08baba2cfa4ea9e99646e88f1eb1668c00c0f15b7443c8ab83481611cc3ae85eb89a7bfc40067eb1d2e6354a32426d0ce710e88bc4cc0718b99c325509c9d02a6a980d675a8969be10ee9bef82cafee2fc913475667ccda37b1bc7f13f64e56c449c532658ba8481631c02ead979754c809584a875951619cec8fb040c33f06468ae0266cd8693d6a64cea5912be32d8de95a6da6300b0c50fdcd6001ea41126e7b7e5280d455054a816560028f5ca53c9a50ee52f10e15c5337315bad1f5277acb109a1418649dc6ead2fe14699742fee7182f2f15e54279c7d932ed2799d01d73c97e68bbc94d6f7f56ee0a80efd7c76e3169e10d1a1ba3b5f1eb02369dc43af687461c7a2a3344d13eb5485dca29a67f16b4cb988923060fd3b65d0f0352bb634bcc44f2fe668836dcd0f604150049835135dc4b4fbf90fb334b3938a1f137eb32f047c65b85e6c1173b890b6d0162b48b186d1f1af8521945924ac8ac8efec321bf34f1d4b3d4a304a10313052c652d53f6ecb8a55586614e8950cde9ab6fe8e22802e93b3b9139112250b80ebc589aba231af535bb20f7eeec2e412f698c17f3fdc0a2e20924a5e38b21a628a9e3b2a61e35958e60c7f5087c"
+ ]
+ }
+ }
+ ],
+ "dynamic": {
+ "depends": {},
+ "details": []
+ }
+}
\ No newline at end of file
diff --git a/test/fixtures/psbt.json b/test/fixtures/psbt.json
index 0e51d57cf..b113d75b6 100644
--- a/test/fixtures/psbt.json
+++ b/test/fixtures/psbt.json
@@ -116,6 +116,10 @@
{
"description": "PSBT with unknown types in the inputs.",
"psbt": "cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA="
+ },
+ {
+ "description": "PSBT with one P2TR input and one P2TR output.",
+ "psbt": "cHNidP8BAF4CAAAAAWbQAKi9hNXynJhqPu8bqkvp0kHihVShkWGh3yLy15+LAAAAAAD/////Aej9AAAAAAAAIlEgRvZJfLLxnVDD6emCqVDcyGIUsB/M5DekIGHHvbEjDTMAAAAAAAEBK7gFAQAAAAAAIlEglCHnNLD50sRn6n3Rl8Yay0RnzcvJ9MsMVx+LY6XEDK4AAA=="
}
],
"failSignChecks": [
@@ -273,6 +277,25 @@
}
],
"result": "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU210gwRQIhAPYQOLMI3B2oZaNIUnRvAVdyk0IIxtJEVDk82ZvfIhd3AiAFbmdaZ1ptCgK4WxTl4pB02KJam1dgvqKBb2YZEKAG6gEBAwQBAAAAAQRHUiEClYO/Oa4KYJdHrRma3dY0+mEIVZ1sXNObTCGD8auW4H8hAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXUq4iBgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfxDZDGpPAAAAgAAAAIAAAACAIgYC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtcQ2QxqTwAAAIAAAACAAQAAgAABASAAwusLAAAAABepFLf1+vQOPUClpFmx2zU18rcvqSHohyICAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zRzBEAiBl9FulmYtZon/+GnvtAWrx8fkNVLOqj3RQql9WolEDvQIgf3JHA60e25ZoCyhLVtT/y4j3+3Weq74IqjDym4UTg9IBAQMEAQAAAAEEIgAgjCNTFzdDtZXftKB7crqOQuN5fadOh/59nXSX47ICiQMBBUdSIQMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3CECOt2QTz1tz1nduQaw3uI1Kbf/ue1Q5ehhUZJoYCIfDnNSriIGAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zENkMak8AAACAAAAAgAMAAIAiBgMIncEMesbbVPkTKa9hczPbOIzq0MIx9yM3nRuZAwsC3BDZDGpPAAAAgAAAAIACAACAACICA6mkw39ZltOqJdusa1cK8GUDlEkpQkYLNUdT7Z7spYdxENkMak8AAACAAAAAgAQAAIAAIgICf2OZdX0u/1WhNq0CxoSxg4tlVuXxtrNCgqlLa1AFEJYQ2QxqTwAAAIAAAACABQAAgAA="
+ },
+ {
+ "description": "Sign PSBT with 3 inputs [P2PKH, P2TR, P2WPKH] and two outputs [P2TR, P2WPKH]",
+ "psbt": "cHNidP8BAM8CAAAAAwPzd9k+uLSN1rgF01xY1TIA/8N+YytNZ4VP9gKFP4MyAAAAAAD/////ZtAAqL2E1fKcmGo+7xuqS+nSQeKFVKGRYaHfIvLXn4sAAAAAAP////9+h+SlCwIx1MUDT7Bek0NrWXS7xnSPi5LbYbDc9sxYIgAAAAAA/////wIgKRsAAAAAACJRIEb2SXyy8Z1Qw+npgqlQ3MhiFLAfzOQ3pCBhx72xIw0zuAUBAAAAAAAWABTJijE0v48z5ZmmfEAADXdCBcG0FAAAAAAAAQDiAgAAAAABAUfY2D1t0dyMeEH39C1yOdIxigpqm7XJNqHVT3Lc+FkiAAAAAAD+////AhIsGwAAAAAAGXapFJ5+8XZ3ZP80oFldvEwrcNsBftBmiKyYdK6xAAAAABepFLDBn59UffGbX7u/olyFDG0eG1UJhwJHMEQCIDAd3s05C61flXVFqOtov0NoHRGr8KFcOpH6R/81F46EAiBt+j9hHyvT2hYEyf8fdYsM9IgbnybtPV+kRTHDa6Rj0AEhAmmZfwmoHsmCkEOn9AfRTh+863mURelmE8hSqL4MG1EydJwgAAABASu4BQEAAAAAACJRIJQh5zSw+dLEZ+p90ZfGGstEZ83LyfTLDFcfi2OlxAyuAAEBHxAnAAAAAAAAFgAUT6KsoSi2+d7lMJxPcAUeScZf1zIAAAA=",
+ "keys": [
+ {
+ "inputToSign": 0,
+ "WIF": "cRyKzLXVgTReWe7wgfEiXktTa9tf4e5DK1STha274d7BBbnucTaR"
+ },
+ {
+ "inputToSign": 1,
+ "WIF": "cNPzVNoVCAfNEadTExqN2HzfC4dX42RtduE39D2i7cxuVEKY3DM3"
+ },
+ {
+ "inputToSign": 2,
+ "WIF": "cPPRdCmAMZMjPdHfRmTCmzYVruZHJ8GbM1FqN2W6DnmEPWDg29aL"
+ }
+ ],
+ "result": "cHNidP8BAM8CAAAAAwPzd9k+uLSN1rgF01xY1TIA/8N+YytNZ4VP9gKFP4MyAAAAAAD/////ZtAAqL2E1fKcmGo+7xuqS+nSQeKFVKGRYaHfIvLXn4sAAAAAAP////9+h+SlCwIx1MUDT7Bek0NrWXS7xnSPi5LbYbDc9sxYIgAAAAAA/////wIgKRsAAAAAACJRIEb2SXyy8Z1Qw+npgqlQ3MhiFLAfzOQ3pCBhx72xIw0zuAUBAAAAAAAWABTJijE0v48z5ZmmfEAADXdCBcG0FAAAAAAAAQDiAgAAAAABAUfY2D1t0dyMeEH39C1yOdIxigpqm7XJNqHVT3Lc+FkiAAAAAAD+////AhIsGwAAAAAAGXapFJ5+8XZ3ZP80oFldvEwrcNsBftBmiKyYdK6xAAAAABepFLDBn59UffGbX7u/olyFDG0eG1UJhwJHMEQCIDAd3s05C61flXVFqOtov0NoHRGr8KFcOpH6R/81F46EAiBt+j9hHyvT2hYEyf8fdYsM9IgbnybtPV+kRTHDa6Rj0AEhAmmZfwmoHsmCkEOn9AfRTh+863mURelmE8hSqL4MG1EydJwgACICAi5ovBH1xLoGxPqtFh48wUEpnM+St1SbPzRwO7kBNKOQRzBEAiBpWClBybtHveXkhAgTiE8QSczMJs8MGuH4LOSNRA6s/AIgWlbB3xJOtJIsszj1qZ/whA5jK9wnTzeZzDlVs/ivq2cBAAEBK7gFAQAAAAAAIlEglCHnNLD50sRn6n3Rl8Yay0RnzcvJ9MsMVx+LY6XEDK4iAgKUIec0sPnSxGfqfdGXxhrLRGfNy8n0ywxXH4tjpcQMrkADaUubfpFFrzbU+vL8qCzZE/FO+9unzylfpIgQZ4HTy2qPUtLvbyH59GApdz0SiUZGl8K6Crvt9YIfI/5FxbOLAAEBHxAnAAAAAAAAFgAUT6KsoSi2+d7lMJxPcAUeScZf1zIiAgOlTqRAWzyTP8WLKjtnrrbWBaYHnPb3MYIMk8qJJSuutEgwRQIhAKAiJLYIS+eYrjAJpM8GCc2/ofqpjXsGV8QMf9Ojm8SEAiBCwrAc/8HdsD5ZyW9uzpbsTJEz5wshwNgvksR4l/xbzwEAAAA="
}
],
"combiner": [
@@ -551,6 +574,13 @@
"incorrectPubkey": "Buffer.from('029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e02a', 'hex')",
"nonExistantIndex": 42
},
+ "validateSignaturesOfTaprootInput": {
+ "psbt": "cHNidP8BAM8CAAAAAwPzd9k+uLSN1rgF01xY1TIA/8N+YytNZ4VP9gKFP4MyAAAAAAD/////ZtAAqL2E1fKcmGo+7xuqS+nSQeKFVKGRYaHfIvLXn4sAAAAAAP////9+h+SlCwIx1MUDT7Bek0NrWXS7xnSPi5LbYbDc9sxYIgAAAAAA/////wIgKRsAAAAAACJRIEb2SXyy8Z1Qw+npgqlQ3MhiFLAfzOQ3pCBhx72xIw0zuAUBAAAAAAAWABTJijE0v48z5ZmmfEAADXdCBcG0FAAAAAAAAQDiAgAAAAABAUfY2D1t0dyMeEH39C1yOdIxigpqm7XJNqHVT3Lc+FkiAAAAAAD+////AhIsGwAAAAAAGXapFJ5+8XZ3ZP80oFldvEwrcNsBftBmiKyYdK6xAAAAABepFLDBn59UffGbX7u/olyFDG0eG1UJhwJHMEQCIDAd3s05C61flXVFqOtov0NoHRGr8KFcOpH6R/81F46EAiBt+j9hHyvT2hYEyf8fdYsM9IgbnybtPV+kRTHDa6Rj0AEhAmmZfwmoHsmCkEOn9AfRTh+863mURelmE8hSqL4MG1EydJwgAAABASu4BQEAAAAAACJRIJQh5zSw+dLEZ+p90ZfGGstEZ83LyfTLDFcfi2OlxAyuIgIClCHnNLD50sRn6n3Rl8Yay0RnzcvJ9MsMVx+LY6XEDK5AA2lLm36RRa821Pry/Kgs2RPxTvvbp88pX6SIEGeB08tqj1LS728h+fRgKXc9EolGRpfCugq77fWCHyP+RcWziwABAR8QJwAAAAAAABYAFE+irKEotvne5TCcT3AFHknGX9cyAAAA",
+ "index": 1,
+ "pubkey": "Buffer.from('029421e734b0f9d2c467ea7dd197c61acb4467cdcbc9f4cb0c571f8b63a5c40cae', 'hex')",
+ "incorrectPubkey": "Buffer.from('029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e02a', 'hex')",
+ "nonExistantIndex": 42
+ },
"getFeeRate": {
"psbt": "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAEAuwIAAAABqtc5MQGL0l+ErkALaISL4J23BurCrBgpi6vucatlb4sAAAAASEcwRAIgWPb8fGoz4bMVSNSByCbAFb0wE1qtQs1neQ2rZtKtJDsCIEoc7SYExnNbY5PltBaR3XiwDwxZQvufdRhW+qk4FX26Af7///8CgPD6AgAAAAAXqRQPuUY0IWlrgsgzryQceMF9295JNIfQ8gonAQAAABepFCnKdPigj4GZlCgYXJe12FLkBj9hh2UAAAAiAgKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgf0cwRAIgdAGK1BgAl7hzMjwAFXILNoTMgSOJEEjn282bVa1nnJkCIHPTabdA4+tT3O+jOCPIBwUUylWn3ZVE8VfBZ5EyYRGMASICAtq2H/SaFNtqfQKwzR+7ePxLGDErW05U2uTbovv+9TbXSDBFAiEA9hA4swjcHahlo0hSdG8BV3KTQgjG0kRUOTzZm98iF3cCIAVuZ1pnWm0KArhbFOXikHTYolqbV2C+ooFvZhkQoAbqAQEDBAEAAAABBEdSIQKVg785rgpgl0etGZrd1jT6YQhVnWxc05tMIYPxq5bgfyEC2rYf9JoU22p9ArDNH7t4/EsYMStbTlTa5Nui+/71NtdSriIGApWDvzmuCmCXR60Zmt3WNPphCFWdbFzTm0whg/GrluB/ENkMak8AAACAAAAAgAAAAIAiBgLath/0mhTban0CsM0fu3j8SxgxK1tOVNrk26L7/vU21xDZDGpPAAAAgAAAAIABAACAAAEBIADC6wsAAAAAF6kUt/X69A49QKWkWbHbNTXyty+pIeiHIgIDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtxHMEQCIGLrelVhB6fHP0WsSrWh3d9vcHX7EnWWmn84Pv/3hLyyAiAMBdu3Rw2/LwhVfdNWxzJcHtMJE+mWzThAlF2xIijaXwEiAgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8Oc0cwRAIgZfRbpZmLWaJ//hp77QFq8fH5DVSzqo90UKpfVqJRA70CIH9yRwOtHtuWaAsoS1bU/8uI9/t1nqu+CKow8puFE4PSAQEDBAEAAAABBCIAIIwjUxc3Q7WV37Sge3K6jkLjeX2nTof+fZ10l+OyAokDAQVHUiEDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwhAjrdkE89bc9Z3bkGsN7iNSm3/7ntUOXoYVGSaGAiHw5zUq4iBgI63ZBPPW3PWd25BrDe4jUpt/+57VDl6GFRkmhgIh8OcxDZDGpPAAAAgAAAAIADAACAIgYDCJ3BDHrG21T5EymvYXMz2ziM6tDCMfcjN50bmQMLAtwQ2QxqTwAAAIAAAACAAgAAgAAiAgOppMN/WZbTqiXbrGtXCvBlA5RJKUJGCzVHU+2e7KWHcRDZDGpPAAAAgAAAAIAEAACAACICAn9jmXV9Lv9VoTatAsaEsYOLZVbl8bazQoKpS2tQBRCWENkMak8AAACAAAAAgAUAAIAA",
"fee": 21
diff --git a/test/payments.spec.ts b/test/payments.spec.ts
index bc123cba3..e89834d3b 100644
--- a/test/payments.spec.ts
+++ b/test/payments.spec.ts
@@ -1,113 +1,125 @@
import * as assert from 'assert';
+import * as ecc from 'tiny-secp256k1';
import { describe, it } from 'mocha';
import { PaymentCreator } from '../src/payments';
import * as u from './payments.utils';
-['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh'].forEach(p => {
- describe(p, () => {
- let fn: PaymentCreator;
- const payment = require('../src/payments/' + p);
- if (p === 'embed') {
- fn = payment.p2data;
- } else {
- fn = payment[p];
- }
- const fixtures = require('./fixtures/' + p);
+import { TinySecp256k1Interface } from '../src/types';
- fixtures.valid.forEach((f: any) => {
- it(f.description + ' as expected', () => {
- const args = u.preform(f.arguments);
- const actual = fn(args, f.options);
-
- u.equate(actual, f.expected, f.arguments);
- });
-
- it(f.description + ' as expected (no validation)', () => {
- const args = u.preform(f.arguments);
- const actual = fn(
- args,
- Object.assign({}, f.options, {
- validate: false,
- }),
- );
+['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh', 'p2tr'].forEach(
+ p => {
+ describe(p, () => {
+ let fn: PaymentCreator;
+ const eccLib: TinySecp256k1Interface | undefined =
+ p === 'p2tr' ? ecc : undefined;
+ const payment = require('../src/payments/' + p);
+ if (p === 'embed') {
+ fn = payment.p2data;
+ } else {
+ fn = payment[p];
+ }
- u.equate(actual, f.expected, f.arguments);
- });
- });
+ const fixtures = require('./fixtures/' + p);
- fixtures.invalid.forEach((f: any) => {
- it(
- 'throws ' + f.exception + (f.description ? 'for ' + f.description : ''),
- () => {
+ fixtures.valid.forEach((f: any) => {
+ const options = Object.assign({ eccLib }, f.options || {});
+ it(f.description + ' as expected', () => {
const args = u.preform(f.arguments);
+ const actual = fn(args, options);
- assert.throws(() => {
- fn(args, f.options);
- }, new RegExp(f.exception));
- },
- );
- });
-
- if (p === 'p2sh') {
- const p2wsh = require('../src/payments/p2wsh').p2wsh;
- const p2pk = require('../src/payments/p2pk').p2pk;
- it('properly assembles nested p2wsh with names', () => {
- const actual = fn({
- redeem: p2wsh({
- redeem: p2pk({
- pubkey: Buffer.from(
- '03e15819590382a9dd878f01e2f0cbce541564eb415e43b440472d883ecd283058',
- 'hex',
- ),
- }),
- }),
+ u.equate(actual, f.expected, f.arguments);
});
- assert.strictEqual(
- actual.address,
- '3MGbrbye4ttNUXM8WAvBFRKry4fkS9fjuw',
- );
- assert.strictEqual(actual.name, 'p2sh-p2wsh-p2pk');
- assert.strictEqual(actual.redeem!.name, 'p2wsh-p2pk');
- assert.strictEqual(actual.redeem!.redeem!.name, 'p2pk');
- });
- }
- // cross-verify dynamically too
- if (!fixtures.dynamic) return;
- const { depends, details } = fixtures.dynamic;
+ it(f.description + ' as expected (no validation)', () => {
+ const args = u.preform(f.arguments);
+ const actual = fn(
+ args,
+ Object.assign({}, options, {
+ validate: false,
+ }),
+ );
- details.forEach((f: any) => {
- const detail = u.preform(f);
- const disabled: any = {};
- if (f.disabled)
- f.disabled.forEach((k: string) => {
- disabled[k] = true;
+ u.equate(actual, f.expected, f.arguments);
});
+ });
- for (const key in depends) {
- if (key in disabled) continue;
- const dependencies = depends[key];
+ fixtures.invalid.forEach((f: any) => {
+ const options = Object.assign({ eccLib }, f.options || {});
+ it(
+ 'throws ' +
+ f.exception +
+ (f.description ? 'for ' + f.description : ''),
+ () => {
+ const args = u.preform(f.arguments);
- dependencies.forEach((dependency: any) => {
- if (!Array.isArray(dependency)) dependency = [dependency];
+ assert.throws(() => {
+ fn(args, options);
+ }, new RegExp(f.exception));
+ },
+ );
+ });
- const args = {};
- dependency.forEach((d: any) => {
- u.from(d, detail, args);
+ if (p === 'p2sh') {
+ const p2wsh = require('../src/payments/p2wsh').p2wsh;
+ const p2pk = require('../src/payments/p2pk').p2pk;
+ it('properly assembles nested p2wsh with names', () => {
+ const actual = fn({
+ redeem: p2wsh({
+ redeem: p2pk({
+ pubkey: Buffer.from(
+ '03e15819590382a9dd878f01e2f0cbce541564eb415e43b440472d883ecd283058',
+ 'hex',
+ ),
+ }),
+ }),
});
- const expected = u.from(key, detail);
-
- it(
- f.description +
- ', ' +
- key +
- ' derives from ' +
- JSON.stringify(dependency),
- () => {
- u.equate(fn(args), expected);
- },
+ assert.strictEqual(
+ actual.address,
+ '3MGbrbye4ttNUXM8WAvBFRKry4fkS9fjuw',
);
+ assert.strictEqual(actual.name, 'p2sh-p2wsh-p2pk');
+ assert.strictEqual(actual.redeem!.name, 'p2wsh-p2pk');
+ assert.strictEqual(actual.redeem!.redeem!.name, 'p2pk');
});
}
+
+ // cross-verify dynamically too
+ if (!fixtures.dynamic) return;
+ const { depends, details } = fixtures.dynamic;
+
+ details.forEach((f: any) => {
+ const detail = u.preform(f);
+ const disabled: any = {};
+ if (f.disabled)
+ f.disabled.forEach((k: string) => {
+ disabled[k] = true;
+ });
+
+ for (const key in depends) {
+ if (key in disabled) continue;
+ const dependencies = depends[key];
+
+ dependencies.forEach((dependency: any) => {
+ if (!Array.isArray(dependency)) dependency = [dependency];
+
+ const args = {};
+ dependency.forEach((d: any) => {
+ u.from(d, detail, args);
+ });
+ const expected = u.from(key, detail);
+
+ it(
+ f.description +
+ ', ' +
+ key +
+ ' derives from ' +
+ JSON.stringify(dependency),
+ () => {
+ u.equate(fn(args), expected);
+ },
+ );
+ });
+ }
+ });
});
- });
-});
+ },
+);
diff --git a/test/payments.utils.ts b/test/payments.utils.ts
index c0635f3cf..d4aee8374 100644
--- a/test/payments.utils.ts
+++ b/test/payments.utils.ts
@@ -86,6 +86,12 @@ export function equate(a: any, b: any, args?: any): void {
t.strictEqual(tryHex(a.hash), tryHex(b.hash), 'Inequal *.hash');
if ('pubkey' in b)
t.strictEqual(tryHex(a.pubkey), tryHex(b.pubkey), 'Inequal *.pubkey');
+ if ('internalPubkey' in b)
+ t.strictEqual(
+ tryHex(a.internalPubkey),
+ tryHex(b.internalPubkey),
+ 'Inequal *.internalPubkey',
+ );
if ('signature' in b)
t.strictEqual(
tryHex(a.signature),
@@ -129,6 +135,7 @@ export function preform(x: any): any {
if (x.data) x.data = x.data.map(fromHex);
if (x.hash) x.hash = Buffer.from(x.hash, 'hex');
if (x.pubkey) x.pubkey = Buffer.from(x.pubkey, 'hex');
+ if (x.internalPubkey) x.internalPubkey = Buffer.from(x.internalPubkey, 'hex');
if (x.signature) x.signature = Buffer.from(x.signature, 'hex');
if (x.pubkeys) x.pubkeys = x.pubkeys.map(fromHex);
if (x.signatures)
@@ -146,7 +153,12 @@ export function preform(x: any): any {
if (x.redeem.network)
x.redeem.network = (BNETWORKS as any)[x.redeem.network];
}
-
+ if (x.scriptLeaf) {
+ x.scriptLeaf = Object.assign({}, x.scriptLeaf);
+ if (typeof x.scriptLeaf.output === 'string')
+ x.scriptLeaf.output = asmToBuffer(x.scriptLeaf.output);
+ }
+ if (x.scriptsTree) x.scriptsTree = convertScriptsTree(x.scriptsTree);
return x;
}
@@ -169,3 +181,13 @@ export function from(path: string, object: any, result?: any): any {
return result;
}
+
+// todo: solve any type
+function convertScriptsTree(scriptsTree: any): any {
+ if (Array.isArray(scriptsTree)) return scriptsTree.map(convertScriptsTree);
+
+ const script = Object.assign({}, scriptsTree);
+ if (typeof script.output === 'string')
+ script.output = asmToBuffer(scriptsTree.output);
+ return script;
+}
diff --git a/test/psbt.spec.ts b/test/psbt.spec.ts
index f583e8068..3f4cf93b8 100644
--- a/test/psbt.spec.ts
+++ b/test/psbt.spec.ts
@@ -18,6 +18,12 @@ const validator = (
signature: Buffer,
): boolean => ECPair.fromPublicKey(pubkey).verify(msghash, signature);
+const schnorrValidator = (
+ pubkey: Buffer,
+ msghash: Buffer,
+ signature: Buffer,
+): boolean => ECPair.fromPublicKey(pubkey).verifySchnorr(msghash, signature);
+
const initBuffers = (object: any): typeof preFixtures =>
JSON.parse(JSON.stringify(object), (_, value) => {
const regex = new RegExp(/^Buffer.from\(['"](.*)['"], ['"](.*)['"]\)$/);
@@ -952,6 +958,36 @@ describe(`Psbt`, () => {
});
});
+ describe('validateSignaturesOfTaprootInput', () => {
+ const f = fixtures.validateSignaturesOfTaprootInput;
+ it('Correctly validates a signature', () => {
+ const psbt = Psbt.fromBase64(f.psbt);
+ assert.strictEqual(
+ psbt.validateSignaturesOfInput(f.index, schnorrValidator),
+ true,
+ );
+ });
+
+ it('Correctly validates a signature against a pubkey', () => {
+ const psbt = Psbt.fromBase64(f.psbt);
+ assert.strictEqual(
+ psbt.validateSignaturesOfInput(
+ f.index,
+ schnorrValidator,
+ f.pubkey as any,
+ ),
+ true,
+ );
+ assert.throws(() => {
+ psbt.validateSignaturesOfInput(
+ f.index,
+ schnorrValidator,
+ f.incorrectPubkey as any,
+ );
+ }, new RegExp('No signatures for this pubkey'));
+ });
+ });
+
describe('getFeeRate', () => {
it('Throws error if called before inputs are finalized', () => {
const f = fixtures.getFeeRate;
@@ -969,6 +1005,35 @@ describe(`Psbt`, () => {
});
});
+ describe('tweakSigner', () => {
+ it('Throws error if signer is missing private key', () => {
+ const keyPair = Object.assign({}, ECPair.makeRandom(), {
+ privateKey: null,
+ });
+ assert.throws(() => {
+ Psbt.tweakSigner(keyPair);
+ }, new RegExp('Private key is required for tweaking signer!'));
+ });
+
+ it('Correctly creates tweaked signer', () => {
+ const keyPair = ECPair.fromPrivateKey(
+ Buffer.from(
+ 'accaf12e04e11b08fc28f5fe75b47ea663843b698981e31f1cafa2224d6e28c0',
+ 'hex',
+ ),
+ );
+ const tweakedSigner: Signer = Psbt.tweakSigner(keyPair);
+ assert.strictEqual(
+ '029421e734b0f9d2c467ea7dd197c61acb4467cdcbc9f4cb0c571f8b63a5c40cae',
+ tweakedSigner.publicKey.toString('hex'),
+ );
+ assert.strictEqual(
+ '1853f5034982ec659e015873a0a958a73eac785850f425fd3444b12430d58692',
+ tweakedSigner.privateKey!.toString('hex'),
+ );
+ });
+ });
+
describe('create 1-to-1 transaction', () => {
const alice = ECPair.fromWIF(
'L2uPYXe17xSTqbCjZvL2DsyXPCbXspvcu5mHLDYUgzdUbZGSKrSr',
diff --git a/ts_src/payments/index.ts b/ts_src/payments/index.ts
index 4b7f1117e..7bb77b6ac 100644
--- a/ts_src/payments/index.ts
+++ b/ts_src/payments/index.ts
@@ -1,4 +1,5 @@
import { Network } from '../networks';
+import { TaprootLeaf, TinySecp256k1Interface } from '../types';
import { p2data as embed } from './embed';
import { p2ms } from './p2ms';
import { p2pk } from './p2pk';
@@ -6,6 +7,7 @@ import { p2pkh } from './p2pkh';
import { p2sh } from './p2sh';
import { p2wpkh } from './p2wpkh';
import { p2wsh } from './p2wsh';
+import { p2tr } from './p2tr';
export interface Payment {
name?: string;
@@ -17,11 +19,14 @@ export interface Payment {
pubkeys?: Buffer[];
input?: Buffer;
signatures?: Buffer[];
+ internalPubkey?: Buffer;
pubkey?: Buffer;
signature?: Buffer;
address?: string;
hash?: Buffer;
redeem?: Payment;
+ scriptsTree?: any; // todo: solve
+ scriptLeaf?: TaprootLeaf;
witness?: Buffer[];
}
@@ -32,13 +37,14 @@ export type PaymentFunction = () => Payment;
export interface PaymentOpts {
validate?: boolean;
allowIncomplete?: boolean;
+ eccLib?: TinySecp256k1Interface;
}
export type StackElement = Buffer | number;
export type Stack = StackElement[];
export type StackFunction = () => Stack;
-export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh };
+export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh, p2tr };
// TODO
// witness commitment
diff --git a/ts_src/payments/p2tr.ts b/ts_src/payments/p2tr.ts
new file mode 100644
index 000000000..fa6598dc3
--- /dev/null
+++ b/ts_src/payments/p2tr.ts
@@ -0,0 +1,289 @@
+import { Buffer as NBuffer } from 'buffer';
+import { bitcoin as BITCOIN_NETWORK } from '../networks';
+import * as bscript from '../script';
+import { typeforce as typef, TinySecp256k1Interface } from '../types';
+import {
+ toHashTree,
+ rootHashFromPath,
+ findScriptPath,
+ tapLeafHash,
+ tapTweakHash,
+} from './taprootutils';
+import { Payment, PaymentOpts } from './index';
+import * as lazy from './lazy';
+import { bech32m } from 'bech32';
+import { testEcc } from './testecc';
+
+const OPS = bscript.OPS;
+const TAPROOT_VERSION = 0x01;
+const ANNEX_PREFIX = 0x50;
+
+export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
+ if (
+ !a.address &&
+ !a.output &&
+ !a.pubkey &&
+ !a.output &&
+ !a.internalPubkey &&
+ !(a.witness && a.witness.length > 1)
+ )
+ throw new TypeError('Not enough data');
+
+ opts = Object.assign({ validate: true }, opts || {});
+
+ const _ecc = lazy.value(() => {
+ if (!opts!.eccLib) throw new Error('ECC Library is missing for p2tr.');
+
+ testEcc(opts!.eccLib);
+ return opts!.eccLib;
+ });
+
+ typef(
+ {
+ address: typef.maybe(typef.String),
+ input: typef.maybe(typef.BufferN(0)),
+ network: typef.maybe(typef.Object),
+ output: typef.maybe(typef.BufferN(34)),
+ internalPubkey: typef.maybe(typef.BufferN(32)),
+ hash: typef.maybe(typef.BufferN(32)),
+ pubkey: typef.maybe(typef.BufferN(32)),
+ signature: typef.maybe(typef.BufferN(64)),
+ witness: typef.maybe(typef.arrayOf(typef.Buffer)),
+ // scriptsTree: typef.maybe(typef.TaprootNode), // use merkel.isMast ?
+ scriptLeaf: typef.maybe({
+ version: typef.maybe(typef.Number),
+ output: typef.maybe(typef.Buffer),
+ }),
+ },
+ a,
+ );
+
+ const _address = lazy.value(() => {
+ const result = bech32m.decode(a.address!);
+ const version = result.words.shift();
+ const data = bech32m.fromWords(result.words);
+ return {
+ version,
+ prefix: result.prefix,
+ data: NBuffer.from(data),
+ };
+ });
+
+ const _witness = lazy.value(() => {
+ if (!a.witness || !a.witness.length) return;
+ if (
+ a.witness.length >= 2 &&
+ a.witness[a.witness.length - 1][0] === ANNEX_PREFIX
+ ) {
+ // remove annex, ignored by taproot
+ return a.witness.slice(0, -1);
+ }
+ return a.witness.slice();
+ });
+
+ const network = a.network || BITCOIN_NETWORK;
+ const o: Payment = { name: 'p2tr', network };
+
+ lazy.prop(o, 'address', () => {
+ if (!o.pubkey) return;
+
+ const words = bech32m.toWords(o.pubkey);
+ words.unshift(TAPROOT_VERSION);
+ return bech32m.encode(network.bech32, words);
+ });
+
+ lazy.prop(o, 'hash', () => {
+ if (a.hash) return a.hash;
+ if (a.scriptsTree) return toHashTree(a.scriptsTree).hash;
+ const w = _witness();
+ if (w && w.length > 1) {
+ const controlBlock = w[w.length - 1];
+ const leafVersion = controlBlock[0] & 0b11111110;
+ const script = w[w.length - 2];
+ const leafHash = tapLeafHash(script, leafVersion);
+ return rootHashFromPath(controlBlock, leafHash);
+ }
+ return null;
+ });
+ lazy.prop(o, 'output', () => {
+ if (!o.pubkey) return;
+ return bscript.compile([OPS.OP_1, o.pubkey]);
+ });
+ lazy.prop(o, 'scriptLeaf', () => {
+ if (a.scriptLeaf) return a.scriptLeaf;
+ });
+ lazy.prop(o, 'pubkey', () => {
+ if (a.pubkey) return a.pubkey;
+ if (a.output) return a.output.slice(2);
+ if (a.address) return _address().data;
+ if (o.internalPubkey) {
+ const tweakedKey = tweakKey(o.internalPubkey, o.hash, _ecc());
+ if (tweakedKey) return tweakedKey.x;
+ }
+ });
+ lazy.prop(o, 'internalPubkey', () => {
+ if (a.internalPubkey) return a.internalPubkey;
+ const witness = _witness();
+ if (witness && witness.length > 1)
+ return witness[witness.length - 1].slice(1, 33);
+ });
+ lazy.prop(o, 'signature', () => {
+ if (!a.witness || a.witness.length !== 1) return;
+ return a.witness[0];
+ });
+ lazy.prop(o, 'input', () => {
+ // todo
+ });
+ lazy.prop(o, 'witness', () => {
+ if (a.witness) return a.witness;
+ if (a.scriptsTree && a.scriptLeaf && a.internalPubkey) {
+ // todo: optimize/cache
+ const hashTree = toHashTree(a.scriptsTree);
+ const leafHash = tapLeafHash(a.scriptLeaf.output, a.scriptLeaf.version);
+ const path = findScriptPath(hashTree, leafHash);
+ const outputKey = tweakKey(a.internalPubkey, hashTree.hash, _ecc());
+ if (!outputKey) return;
+ const version = a.scriptLeaf.version || 0xc0;
+ const controlBock = NBuffer.concat(
+ [NBuffer.from([version | outputKey.parity]), a.internalPubkey].concat(
+ path.reverse(),
+ ),
+ );
+ return [a.scriptLeaf.output, controlBock];
+ }
+ if (a.signature) return [a.signature];
+ });
+
+ // extended validation
+ if (opts.validate) {
+ let pubkey: Buffer = NBuffer.from([]);
+ if (a.address) {
+ if (network && network.bech32 !== _address().prefix)
+ throw new TypeError('Invalid prefix or Network mismatch');
+ if (_address().version !== TAPROOT_VERSION)
+ throw new TypeError('Invalid address version');
+ if (_address().data.length !== 32)
+ throw new TypeError('Invalid address data');
+ pubkey = _address().data;
+ }
+
+ if (a.pubkey) {
+ if (pubkey.length > 0 && !pubkey.equals(a.pubkey))
+ throw new TypeError('Pubkey mismatch');
+ else pubkey = a.pubkey;
+ }
+
+ if (a.output) {
+ if (
+ a.output.length !== 34 ||
+ a.output[0] !== OPS.OP_1 ||
+ a.output[1] !== 0x20
+ )
+ throw new TypeError('Output is invalid');
+ if (pubkey.length > 0 && !pubkey.equals(a.output.slice(2)))
+ throw new TypeError('Pubkey mismatch');
+ else pubkey = a.output.slice(2);
+ }
+
+ if (a.internalPubkey) {
+ const tweakedKey = tweakKey(a.internalPubkey, o.hash, _ecc());
+ if (pubkey.length > 0 && !pubkey.equals(tweakedKey!.x))
+ throw new TypeError('Pubkey mismatch');
+ else pubkey = tweakedKey!.x;
+ }
+
+ if (pubkey && pubkey.length) {
+ if (!_ecc().isXOnlyPoint(pubkey))
+ throw new TypeError('Invalid pubkey for p2tr');
+ }
+
+ if (a.hash && a.scriptsTree) {
+ const hash = toHashTree(a.scriptsTree).hash;
+ if (!a.hash.equals(hash)) throw new TypeError('Hash mismatch');
+ }
+
+ const witness = _witness();
+
+ if (witness && witness.length) {
+ if (witness.length === 1) {
+ // key spending
+ if (a.signature && !a.signature.equals(witness[0]))
+ throw new TypeError('Signature mismatch');
+ // todo: recheck
+ // if (!bscript.isSchnorSignature(a.pubkey, a.witness[0]))
+ // throw new TypeError('Witness has invalid signature');
+ } else {
+ // script path spending
+ const controlBlock = witness[witness.length - 1];
+ if (controlBlock.length < 33)
+ throw new TypeError(
+ `The control-block length is too small. Got ${
+ controlBlock.length
+ }, expected min 33.`,
+ );
+
+ if ((controlBlock.length - 33) % 32 !== 0)
+ throw new TypeError(
+ `The control-block length of ${controlBlock.length} is incorrect!`,
+ );
+
+ const m = (controlBlock.length - 33) / 32;
+ if (m > 128)
+ throw new TypeError(
+ `The script path is too long. Got ${m}, expected max 128.`,
+ );
+
+ const internalPubkey = controlBlock.slice(1, 33);
+ if (a.internalPubkey && !a.internalPubkey.equals(internalPubkey))
+ throw new TypeError('Internal pubkey mismatch');
+
+ if (!_ecc().isXOnlyPoint(internalPubkey))
+ throw new TypeError('Invalid internalPubkey for p2tr witness');
+
+ const leafVersion = controlBlock[0] & 0b11111110;
+ const script = witness[witness.length - 2];
+
+ const leafHash = tapLeafHash(script, leafVersion);
+ const hash = rootHashFromPath(controlBlock, leafHash);
+
+ const outputKey = tweakKey(internalPubkey, hash, _ecc());
+ if (!outputKey)
+ // todo: needs test data
+ throw new TypeError('Invalid outputKey for p2tr witness');
+
+ if (pubkey.length && !pubkey.equals(outputKey.x))
+ throw new TypeError('Pubkey mismatch for p2tr witness');
+
+ if (outputKey.parity !== (controlBlock[0] & 1))
+ throw new Error('Incorrect parity');
+ }
+ }
+ }
+
+ return Object.assign(o, a);
+}
+
+interface TweakedPublicKey {
+ parity: number;
+ x: Buffer;
+}
+
+function tweakKey(
+ pubKey: Buffer,
+ h: Buffer | undefined,
+ eccLib: TinySecp256k1Interface,
+): TweakedPublicKey | null {
+ if (!NBuffer.isBuffer(pubKey)) return null;
+ if (pubKey.length !== 32) return null;
+ if (h && h.length !== 32) return null;
+
+ const tweakHash = tapTweakHash(pubKey, h);
+
+ const res = eccLib.xOnlyPointAddTweak(pubKey, tweakHash);
+ if (!res || res.xOnlyPubkey === null) return null;
+
+ return {
+ parity: res.parity,
+ x: NBuffer.from(res.xOnlyPubkey),
+ };
+}
diff --git a/ts_src/payments/taprootutils.ts b/ts_src/payments/taprootutils.ts
new file mode 100644
index 000000000..83ed9b14c
--- /dev/null
+++ b/ts_src/payments/taprootutils.ts
@@ -0,0 +1,125 @@
+import { Buffer as NBuffer } from 'buffer';
+import * as bcrypto from '../crypto';
+
+import { varuint } from '../bufferutils';
+import { TaprootLeaf } from '../types';
+
+const LEAF_VERSION_TAPSCRIPT = 0xc0;
+const TAP_LEAF_TAG = 'TapLeaf';
+const TAP_BRANCH_TAG = 'TapBranch';
+const TAP_TWEAK_TAG = 'TapTweak';
+
+export function rootHashFromPath(
+ controlBlock: Buffer,
+ tapLeafMsg: Buffer,
+): Buffer {
+ const k = [tapLeafMsg];
+ const e = [];
+
+ const m = (controlBlock.length - 33) / 32;
+
+ for (let j = 0; j < m; j++) {
+ e[j] = controlBlock.slice(33 + 32 * j, 65 + 32 * j);
+ if (k[j].compare(e[j]) < 0) {
+ k[j + 1] = tapBranchHash(k[j], e[j]);
+ } else {
+ k[j + 1] = tapBranchHash(e[j], k[j]);
+ }
+ }
+
+ return k[m];
+}
+
+export interface HashTree {
+ hash: Buffer;
+ left?: HashTree;
+ right?: HashTree;
+}
+
+/**
+ * Build the hash tree from the scripts binary tree.
+ * The binary tree can be balanced or not.
+ * @param scriptsTree - is a list representing a binary tree where an element can be:
+ * - a taproot leaf [(output, version)], or
+ * - a pair of two taproot leafs [(output, version), (output, version)], or
+ * - one taproot leaf and a list of elements
+ */
+export function toHashTree(scriptsTree: TaprootLeaf[]): HashTree {
+ if (scriptsTree.length === 1) {
+ const script = scriptsTree[0];
+ if (Array.isArray(script)) {
+ return toHashTree(script);
+ }
+ script.version = script.version || LEAF_VERSION_TAPSCRIPT;
+ if ((script.version & 1) !== 0)
+ throw new TypeError('Invalid script version');
+
+ return {
+ hash: tapLeafHash(script.output, script.version),
+ };
+ }
+
+ const left = toHashTree([scriptsTree[0]]);
+ const right = toHashTree([scriptsTree[1]]);
+
+ let leftHash = left.hash;
+ let rightHash = right.hash;
+
+ if (leftHash.compare(rightHash) === 1)
+ [leftHash, rightHash] = [rightHash, leftHash];
+ return {
+ hash: tapBranchHash(leftHash, rightHash),
+ left,
+ right,
+ };
+}
+
+/**
+ * Given a MAST tree, it finds the path of a particular hash.
+ * @param node - the root of the tree
+ * @param hash - the hash to search for
+ * @returns - and array of hashes representing the path, or an empty array if no pat is found
+ */
+export function findScriptPath(node: HashTree, hash: Buffer): Buffer[] {
+ if (node.left) {
+ if (node.left.hash.equals(hash)) return node.right ? [node.right.hash] : [];
+ const leftPath = findScriptPath(node.left, hash);
+ if (leftPath.length)
+ return node.right ? [node.right.hash].concat(leftPath) : leftPath;
+ }
+
+ if (node.right) {
+ if (node.right.hash.equals(hash)) return node.left ? [node.left.hash] : [];
+ const rightPath = findScriptPath(node.right, hash);
+ if (rightPath.length)
+ return node.left ? [node.left.hash].concat(rightPath) : rightPath;
+ }
+
+ return [];
+}
+
+export function tapLeafHash(script: Buffer, version?: number): Buffer {
+ version = version || LEAF_VERSION_TAPSCRIPT;
+ return bcrypto.taggedHash(
+ TAP_LEAF_TAG,
+ NBuffer.concat([NBuffer.from([version]), serializeScript(script)]),
+ );
+}
+
+export function tapTweakHash(pubKey: Buffer, h: Buffer | undefined): Buffer {
+ return bcrypto.taggedHash(
+ TAP_TWEAK_TAG,
+ NBuffer.concat(h ? [pubKey, h] : [pubKey]),
+ );
+}
+
+function tapBranchHash(a: Buffer, b: Buffer): Buffer {
+ return bcrypto.taggedHash(TAP_BRANCH_TAG, NBuffer.concat([a, b]));
+}
+
+function serializeScript(s: Buffer): Buffer {
+ const varintLen = varuint.encodingLength(s.length);
+ const buffer = NBuffer.allocUnsafe(varintLen); // better
+ varuint.encode(s.length, buffer);
+ return NBuffer.concat([buffer, s]);
+}
diff --git a/ts_src/payments/testecc.ts b/ts_src/payments/testecc.ts
new file mode 100644
index 000000000..382d6149a
--- /dev/null
+++ b/ts_src/payments/testecc.ts
@@ -0,0 +1,74 @@
+import { TinySecp256k1Interface } from '../types';
+
+const h = (hex: string): Buffer => Buffer.from(hex, 'hex');
+
+export function testEcc(ecc: TinySecp256k1Interface): void {
+ assert(typeof ecc.isXOnlyPoint === 'function');
+ assert(
+ ecc.isXOnlyPoint(
+ h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'),
+ ),
+ );
+ assert(
+ ecc.isXOnlyPoint(
+ h('fffffffffffffffffffffffffffffffffffffffffffffffffffffffeeffffc2e'),
+ ),
+ );
+ assert(
+ ecc.isXOnlyPoint(
+ h('f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9'),
+ ),
+ );
+ assert(
+ ecc.isXOnlyPoint(
+ h('0000000000000000000000000000000000000000000000000000000000000001'),
+ ),
+ );
+ assert(
+ !ecc.isXOnlyPoint(
+ h('0000000000000000000000000000000000000000000000000000000000000000'),
+ ),
+ );
+ assert(
+ !ecc.isXOnlyPoint(
+ h('fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'),
+ ),
+ );
+
+ assert(typeof ecc.xOnlyPointAddTweak === 'function');
+ tweakAddVectors.forEach(t => {
+ const r = ecc.xOnlyPointAddTweak(h(t.pubkey), h(t.tweak));
+ if (t.result === null) {
+ assert(r === null);
+ } else {
+ assert(r !== null);
+ assert(r!.parity === t.parity);
+ assert(Buffer.from(r!.xOnlyPubkey).equals(h(t.result)));
+ }
+ });
+}
+
+function assert(bool: boolean): void {
+ if (!bool) throw new Error('ecc library invalid');
+}
+
+const tweakAddVectors = [
+ {
+ pubkey: '79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
+ tweak: 'fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140',
+ parity: -1,
+ result: null,
+ },
+ {
+ pubkey: '1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b',
+ tweak: 'a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac',
+ parity: 1,
+ result: 'e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf',
+ },
+ {
+ pubkey: '2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991',
+ tweak: '823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47',
+ parity: 0,
+ result: '9534f8dc8c6deda2dc007655981c78b49c5d96c778fbf363462a11ec9dfd948c',
+ },
+];
diff --git a/ts_src/psbt.ts b/ts_src/psbt.ts
index b9af10fcf..467d8fc58 100644
--- a/ts_src/psbt.ts
+++ b/ts_src/psbt.ts
@@ -1,3 +1,6 @@
+import * as ecc from 'tiny-secp256k1'; // TODO: extract
+import { ECPairFactory } from 'ecpair';
+
import { Psbt as PsbtBase } from 'bip174';
import * as varuint from 'bip174/src/lib/converter/varint';
import {
@@ -20,6 +23,7 @@ import { bitcoin as btcNetwork, Network } from './networks';
import * as payments from './payments';
import * as bscript from './script';
import { Output, Transaction } from './transaction';
+import { tapTweakHash } from './payments/taprootutils';
export interface TransactionInput {
hash: string | Buffer;
@@ -114,6 +118,39 @@ export class Psbt {
return psbt;
}
+ /**
+ * This is a helper method for converting a normal Signer into a Taproot Signer.
+ * Note that this helper method required for the Private Key of the Signer to be present.
+ * Steps:
+ * - if the Y coordinate of the Signer Public Key is odd then negate the Private Key
+ * - tweak the private key with the provided hash (should be empty for key-path spending)
+ * @param signer a taproot signer object, the Private Key must be present
+ * @param opts
+ * @returns a Signer having the Private and Public keys tweaked
+ */
+ static tweakSigner(signer: Signer, opts: TaprootSignerOpts = {}): Signer {
+ let privateKey: Uint8Array | undefined = signer.privateKey;
+ if (!privateKey) {
+ throw new Error('Private key is required for tweaking signer!');
+ }
+ if (signer.publicKey[0] === 3) {
+ privateKey = ecc.privateNegate(privateKey!);
+ }
+
+ const tweakedPrivateKey = ecc.privateAdd(
+ privateKey,
+ tapTweakHash(signer.publicKey.slice(1, 33), opts.tweakHash),
+ );
+ if (!tweakedPrivateKey) {
+ throw new Error('Invalid tweaked private key!');
+ }
+
+ const ECPair = ECPairFactory(ecc);
+ return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {
+ network: opts.network,
+ });
+ }
+
private __CACHE: PsbtCache;
private opts: PsbtOpts;
@@ -378,7 +415,11 @@ export class Psbt {
getInputType(inputIndex: number): AllScriptType {
const input = checkForInput(this.data.inputs, inputIndex);
- const script = getScriptFromUtxo(inputIndex, input, this.__CACHE);
+ const { script } = getScriptAndAmountFromUtxo(
+ inputIndex,
+ input,
+ this.__CACHE,
+ );
const result = getMeaningfulScript(
script,
inputIndex,
@@ -445,13 +486,23 @@ export class Psbt {
let hashCache: Buffer;
let scriptCache: Buffer;
let sighashCache: number;
+ const scriptType = this.getInputType(inputIndex);
+
for (const pSig of mySigs) {
- const sig = bscript.signature.decode(pSig.signature);
+ const sig =
+ scriptType === 'taproot'
+ ? {
+ signature: pSig.signature,
+ hashType: Transaction.SIGHASH_DEFAULT,
+ }
+ : bscript.signature.decode(pSig.signature);
+
const { hash, script } =
sighashCache! !== sig.hashType
? getHashForSig(
inputIndex,
Object.assign({}, input, { sighashType: sig.hashType }),
+ this.data.inputs,
this.__CACHE,
true,
)
@@ -572,7 +623,6 @@ export class Psbt {
): this {
if (!keyPair || !keyPair.publicKey)
throw new Error('Need Signer to sign input');
-
// TODO: Add a pubkey/pubkeyhash cache to each input
// as input information is added, then eventually
// optimize this method.
@@ -634,6 +684,7 @@ export class Psbt {
): this {
if (!keyPair || !keyPair.publicKey)
throw new Error('Need Signer to sign input');
+
const { hash, sighashType } = getHashAndSighashType(
this.data.inputs,
inputIndex,
@@ -642,14 +693,32 @@ export class Psbt {
sighashTypes,
);
- const partialSig = [
- {
- pubkey: keyPair.publicKey,
- signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
- },
- ];
+ const scriptType = this.getInputType(inputIndex);
+
+ if (scriptType === 'taproot') {
+ if (!keyPair.signSchnorr) {
+ throw new Error(
+ `Need Schnorr Signer to sign taproot input #${inputIndex}.`,
+ );
+ }
+ const partialSig = [
+ {
+ pubkey: keyPair.publicKey,
+ signature: keyPair.signSchnorr!(hash),
+ },
+ ];
+ // must be changed to use the `updateInput()` public API
+ this.data.inputs[inputIndex].partialSig = partialSig;
+ } else {
+ const partialSig = [
+ {
+ pubkey: keyPair.publicKey,
+ signature: bscript.signature.encode(keyPair.sign(hash), sighashType),
+ },
+ ];
+ this.data.updateInput(inputIndex, { partialSig });
+ }
- this.data.updateInput(inputIndex, { partialSig });
return this;
}
@@ -798,6 +867,7 @@ export interface HDSigner extends HDSignerBase {
* Return a 64 byte signature (32 byte r and 32 byte s in that order)
*/
sign(hash: Buffer): Buffer;
+ signSchnorr?(hash: Buffer): Buffer;
}
/**
@@ -806,19 +876,35 @@ export interface HDSigner extends HDSignerBase {
export interface HDSignerAsync extends HDSignerBase {
derivePath(path: string): HDSignerAsync;
sign(hash: Buffer): Promise;
+ signSchnorr?(hash: Buffer): Promise;
}
export interface Signer {
publicKey: Buffer;
+ /**
+ * Private Key is optional, it is required only if the signer must be tweaked.
+ * See the `tweakSigner()` method.
+ */
+ privateKey?: Buffer;
network?: any;
sign(hash: Buffer, lowR?: boolean): Buffer;
+ signSchnorr?(hash: Buffer): Buffer;
getPublicKey?(): Buffer;
}
+export interface TaprootSignerOpts {
+ network?: Network;
+ // TODO: revisit.
+ eccLib?: any;
+ /** The hash used to tweak the Signer */
+ tweakHash?: Buffer;
+}
+
export interface SignerAsync {
publicKey: Buffer;
network?: any;
sign(hash: Buffer, lowR?: boolean): Promise;
+ signSchnorr?(hash: Buffer): Promise;
getPublicKey?(): Buffer;
}
@@ -899,6 +985,7 @@ function canFinalize(
case 'pubkey':
case 'pubkeyhash':
case 'witnesspubkeyhash':
+ case 'taproot':
return hasSigs(1, input.partialSig);
case 'multisig':
const p2ms = payments.p2ms({ output: script });
@@ -939,10 +1026,12 @@ function isFinalized(input: PsbtInput): boolean {
return !!input.finalScriptSig || !!input.finalScriptWitness;
}
-function isPaymentFactory(payment: any): (script: Buffer) => boolean {
- return (script: Buffer): boolean => {
+function isPaymentFactory(
+ payment: any,
+): (script: Buffer, eccLib?: any) => boolean {
+ return (script: Buffer, eccLib?: any): boolean => {
try {
- payment({ output: script });
+ payment({ output: script }, { eccLib });
return true;
} catch (err) {
return false;
@@ -955,6 +1044,7 @@ const isP2PKH = isPaymentFactory(payments.p2pkh);
const isP2WPKH = isPaymentFactory(payments.p2wpkh);
const isP2WSHScript = isPaymentFactory(payments.p2wsh);
const isP2SHScript = isPaymentFactory(payments.p2sh);
+const isP2TR = isPaymentFactory(payments.p2tr);
function bip32DerivationIsMine(
root: HDSigner,
@@ -1227,6 +1317,7 @@ function getHashAndSighashType(
const { hash, sighashType, script } = getHashForSig(
inputIndex,
input,
+ inputs,
cache,
false,
sighashTypes,
@@ -1241,6 +1332,7 @@ function getHashAndSighashType(
function getHashForSig(
inputIndex: number,
input: PsbtInput,
+ inputs: PsbtInput[],
cache: PsbtCache,
forValidate: boolean,
sighashTypes?: number[],
@@ -1311,6 +1403,19 @@ function getHashForSig(
prevout.value,
sighashType,
);
+ } else if (isP2TR(meaningfulScript, ecc)) {
+ const prevOuts: Output[] = inputs.map((i, index) =>
+ getScriptAndAmountFromUtxo(index, i, cache),
+ );
+ const signingScripts: any = prevOuts.map(o => o.script);
+ const values: any = prevOuts.map(o => o.value);
+
+ hash = unsignedTx.hashForWitnessV1(
+ inputIndex,
+ signingScripts,
+ values,
+ Transaction.SIGHASH_DEFAULT,
+ );
} else {
// non-segwit
if (
@@ -1379,6 +1484,15 @@ function getPayment(
signature: partialSig[0].signature,
});
break;
+ case 'taproot':
+ payment = payments.p2tr(
+ {
+ output: script,
+ signature: partialSig[0].signature,
+ },
+ { eccLib: ecc },
+ );
+ break;
}
return payment!;
}
@@ -1435,7 +1549,12 @@ function getScriptFromInput(
res.script = input.witnessUtxo.script;
}
}
- if (input.witnessScript || isP2WPKH(res.script!)) {
+
+ if (
+ input.witnessScript ||
+ isP2WPKH(res.script!) ||
+ isP2TR(res.script!, ecc)
+ ) {
res.isSegwit = true;
}
return res;
@@ -1651,20 +1770,24 @@ function nonWitnessUtxoTxFromCache(
return c[inputIndex];
}
-function getScriptFromUtxo(
+function getScriptAndAmountFromUtxo(
inputIndex: number,
input: PsbtInput,
cache: PsbtCache,
-): Buffer {
+): { script: Buffer; value: number } {
if (input.witnessUtxo !== undefined) {
- return input.witnessUtxo.script;
+ return {
+ script: input.witnessUtxo.script,
+ value: input.witnessUtxo.value,
+ };
} else if (input.nonWitnessUtxo !== undefined) {
const nonWitnessUtxoTx = nonWitnessUtxoTxFromCache(
cache,
input,
inputIndex,
);
- return nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index].script;
+ const o = nonWitnessUtxoTx.outs[cache.__TX.ins[inputIndex].index];
+ return { script: o.script, value: o.value };
} else {
throw new Error("Can't find pubkey in input without Utxo data");
}
@@ -1676,7 +1799,7 @@ function pubkeyInInput(
inputIndex: number,
cache: PsbtCache,
): boolean {
- const script = getScriptFromUtxo(inputIndex, input, cache);
+ const { script } = getScriptAndAmountFromUtxo(inputIndex, input, cache);
const { meaningfulScript } = getMeaningfulScript(
script,
inputIndex,
@@ -1810,13 +1933,18 @@ function checkInvalidP2WSH(script: Buffer): void {
function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
const pubkeyHash = hash160(pubkey);
+ const pubkeyXOnly = pubkey.slice(1, 33);
const decompiled = bscript.decompile(script);
if (decompiled === null) throw new Error('Unknown script error');
return decompiled.some(element => {
if (typeof element === 'number') return false;
- return element.equals(pubkey) || element.equals(pubkeyHash);
+ return (
+ element.equals(pubkey) ||
+ element.equals(pubkeyHash) ||
+ element.equals(pubkeyXOnly)
+ );
});
}
@@ -1825,6 +1953,7 @@ type AllScriptType =
| 'pubkeyhash'
| 'multisig'
| 'pubkey'
+ | 'taproot'
| 'nonstandard'
| 'p2sh-witnesspubkeyhash'
| 'p2sh-pubkeyhash'
@@ -1844,12 +1973,14 @@ type ScriptType =
| 'pubkeyhash'
| 'multisig'
| 'pubkey'
+ | 'taproot'
| 'nonstandard';
function classifyScript(script: Buffer): ScriptType {
if (isP2WPKH(script)) return 'witnesspubkeyhash';
if (isP2PKH(script)) return 'pubkeyhash';
if (isP2MS(script)) return 'multisig';
if (isP2PK(script)) return 'pubkey';
+ if (isP2TR(script, ecc)) return 'taproot';
return 'nonstandard';
}
diff --git a/ts_src/types.ts b/ts_src/types.ts
index c035b4008..840ab9be2 100644
--- a/ts_src/types.ts
+++ b/ts_src/types.ts
@@ -1,4 +1,5 @@
import { Buffer as NBuffer } from 'buffer';
+
export const typeforce = require('typeforce');
const ZERO32 = NBuffer.alloc(32, 0);
@@ -6,6 +7,7 @@ const EC_P = NBuffer.from(
'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f',
'hex',
);
+
export function isPoint(p: Buffer | number | undefined | null): boolean {
if (!NBuffer.isBuffer(p)) return false;
if (p.length < 33) return false;
@@ -65,6 +67,23 @@ export const Network = typeforce.compile({
wif: typeforce.UInt8,
});
+export interface XOnlyPointAddTweakResult {
+ parity: 1 | 0;
+ xOnlyPubkey: Uint8Array;
+}
+
+export interface TaprootLeaf {
+ output: Buffer;
+ version?: number;
+}
+export interface TinySecp256k1Interface {
+ isXOnlyPoint(p: Uint8Array): boolean;
+ xOnlyPointAddTweak(
+ p: Uint8Array,
+ tweak: Uint8Array,
+ ): XOnlyPointAddTweakResult | null;
+}
+
export const Buffer256bit = typeforce.BufferN(32);
export const Hash160bit = typeforce.BufferN(20);
export const Hash256bit = typeforce.BufferN(32);