diff --git a/.github/workflows/main_ci.yml b/.github/workflows/main_ci.yml
index e9ba67bb2..2e197b4e6 100644
--- a/.github/workflows/main_ci.yml
+++ b/.github/workflows/main_ci.yml
@@ -8,6 +8,9 @@ on:
permissions:
contents: read
+ pages: write
+ id-token: write
+
jobs:
##################
@@ -124,3 +127,31 @@ jobs:
cache: 'npm'
- run: npm ci
- run: npm run lint:tests
+
+ build-doc:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@ec3a7ce113134d7a93b817d10a8272cb61118579 # v2
+ - uses: actions/setup-node@eeb10cff27034e7acf239c5d29f62154018672fd # v3
+ with:
+ node-version: 'lts/*'
+ registry-url: https://registry.npmjs.org/
+ cache: 'npm'
+ - run: npm ci
+ - run: npm run doc
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v2
+ with:
+ path: ./docs
+
+ deploy-doc:
+ if: github.ref == 'refs/heads/master'
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ needs: build-doc
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
diff --git a/.gitignore b/.gitignore
index d6ceb6b58..c1733a6e0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ npm-debug.log
test/*.js
test/integration/*.js
!test/ts-node-register.js
+docs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d0485f0e8..91ed0dae5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -331,8 +331,8 @@ Ideally you shoud not have to directly access `HDNode` internals for general usa
__added__
- `ECPair.prototype.getNetwork`
-- `HDNode.prototype.getNetwork`, wraps the underyling keyPair's `getNetwork` method
-- `HDNode.prototype.getPublicKeyBuffer`, wraps the underyling keyPair's `getPublicKeyBuffer` method
+- `HDNode.prototype.getNetwork`, wraps the underlying keyPair's `getNetwork` method
+- `HDNode.prototype.getPublicKeyBuffer`, wraps the underlying keyPair's `getPublicKeyBuffer` method
- `HDNode.prototype.sign`, wraps the underlying keyPair's `sign` method
- `HDNode.prototype.verify`, wraps the underlying keyPair's `verify` method
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c1df5e090..7797c92d2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -14,8 +14,8 @@ We are always accepting of pull requests, but we do adhere to specific standards
GitHub is the preferred method of communication between members.
Otherwise, in order of preference:
-* bitcoinjs.slack.com
-* #bitcoinjs-dev on Freenode IRC
+* #bitcoinjs-dev:matrix.org on Matrix (A part of the #bitcoinjs-space:matrix.org "Space")
+* #bitcoinjs on libera.chat IRC
## Workflow
diff --git a/README.md b/README.md
index 01a45733b..ba3700948 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Mistakes and bugs happen, but with your help in resolving and reporting [issues]
- Friendly, with a strong and helpful community, ready to answer questions.
## Documentation
-Presently, we do not have any formal documentation other than our [examples](#examples), please [ask for help](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new) if our examples aren't enough to guide you.
+Visit our [documentation](https://bitcoinjs.github.io/bitcoinjs-lib/) to explore the available resources. We're continually enhancing our documentation with additional features for an enriched experience. If you need further guidance beyond what our [examples](#examples) offer, don't hesitate to [ask for help](https://github.com/bitcoinjs/bitcoinjs-lib/issues/new). We're here to assist you.
You can find a [Web UI](https://bitcoincore.tech/apps/bitcoinjs-ui/index.html) that covers most of the `psbt.ts`, `transaction.ts` and `p2*.ts` APIs [here](https://bitcoincore.tech/apps/bitcoinjs-ui/index.html).
diff --git a/package-lock.json b/package-lock.json
index cb00c5608..c02f958ed 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -47,6 +47,8 @@
"rimraf": "^2.6.3",
"tiny-secp256k1": "^2.2.0",
"ts-node": "^8.3.0",
+ "typedoc": "^0.25.1",
+ "typedoc-plugin-bitcoinjs-runcase": "^1.0.1",
"typescript": "^4.4.4"
},
"engines": {
@@ -67,17 +69,89 @@
}
},
"node_modules/@babel/code-frame": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
- "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dev": true,
"dependencies": {
- "@babel/highlight": "^7.18.6"
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
},
"engines": {
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/code-frame/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/@babel/code-frame/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/@babel/code-frame/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/@babel/code-frame/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/code-frame/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": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/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/@babel/compat-data": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz",
@@ -127,13 +201,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz",
- "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.20.5",
+ "@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
},
"engines": {
@@ -182,34 +257,34 @@
}
},
"node_modules/@babel/helper-environment-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
- "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-function-name": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
- "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"dependencies": {
- "@babel/template": "^7.18.10",
- "@babel/types": "^7.19.0"
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-hoist-variables": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
- "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.18.6"
+ "@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
@@ -259,30 +334,30 @@
}
},
"node_modules/@babel/helper-split-export-declaration": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
- "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.18.6"
+ "@babel/types": "^7.22.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-string-parser": {
- "version": "7.19.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
- "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
"dev": true,
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
- "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true,
"engines": {
"node": ">=6.9.0"
@@ -312,13 +387,13 @@
}
},
"node_modules/@babel/highlight": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
- "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"dependencies": {
- "@babel/helper-validator-identifier": "^7.18.6",
- "chalk": "^2.0.0",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"engines": {
@@ -397,9 +472,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz",
- "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -409,33 +484,33 @@
}
},
"node_modules/@babel/template": {
- "version": "7.18.10",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
- "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"dependencies": {
- "@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.18.10",
- "@babel/types": "^7.18.10"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz",
- "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.20.5",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.20.5",
- "@babel/types": "^7.20.5",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -453,13 +528,13 @@
}
},
"node_modules/@babel/types": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz",
- "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dev": true,
"dependencies": {
- "@babel/helper-string-parser": "^7.19.4",
- "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
},
"engines": {
@@ -1047,6 +1122,12 @@
"node": ">=8"
}
},
+ "node_modules/ansi-sequence-parser": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+ "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
+ "dev": true
+ },
"node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -2720,6 +2801,12 @@
"node": ">=6"
}
},
+ "node_modules/jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "dev": true
+ },
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -2788,6 +2875,18 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
"node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -2800,6 +2899,12 @@
"node": ">=10"
}
},
+ "node_modules/lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmmirror.com/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true
+ },
"node_modules/make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -2830,6 +2935,18 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
+ "node_modules/marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 12"
+ }
+ },
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -3553,6 +3670,31 @@
"safe-buffer": "^5.1.0"
}
},
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
"node_modules/readable-stream": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
@@ -3749,6 +3891,15 @@
}
]
},
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
"node_modules/semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -3813,6 +3964,18 @@
"node": ">=8"
}
},
+ "node_modules/shiki": {
+ "version": "0.14.4",
+ "resolved": "https://registry.npmmirror.com/shiki/-/shiki-0.14.4.tgz",
+ "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-sequence-parser": "^1.1.0",
+ "jsonc-parser": "^3.2.0",
+ "vscode-oniguruma": "^1.7.0",
+ "vscode-textmate": "^8.0.0"
+ }
+ },
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -4170,6 +4333,58 @@
"is-typedarray": "^1.0.0"
}
},
+ "node_modules/typedoc": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.1.tgz",
+ "integrity": "sha512-c2ye3YUtGIadxN2O6YwPEXgrZcvhlZ6HlhWZ8jQRNzwLPn2ylhdGqdR8HbyDRyALP8J6lmSANILCkkIdNPFxqA==",
+ "dev": true,
+ "dependencies": {
+ "lunr": "^2.3.9",
+ "marked": "^4.3.0",
+ "minimatch": "^9.0.3",
+ "shiki": "^0.14.1"
+ },
+ "bin": {
+ "typedoc": "bin/typedoc"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "peerDependencies": {
+ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x"
+ }
+ },
+ "node_modules/typedoc-plugin-bitcoinjs-runcase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typedoc-plugin-bitcoinjs-runcase/-/typedoc-plugin-bitcoinjs-runcase-1.0.1.tgz",
+ "integrity": "sha512-tqbnCCP2ku2egGjwn0G0bRNeSH/lh3FT7khrpyYdx1kDu8rjKlyqJX7yPgEj4biBHJATJnQGxp3cKmYG0wv5uw==",
+ "dev": true,
+ "dependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ }
+ },
+ "node_modules/typedoc/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/typedoc/node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
"node_modules/typeforce": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
@@ -4255,6 +4470,18 @@
"safe-buffer": "^5.1.1"
}
},
+ "node_modules/vscode-oniguruma": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmmirror.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+ "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
+ "dev": true
+ },
+ "node_modules/vscode-textmate": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmmirror.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+ "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
+ "dev": true
+ },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -4461,12 +4688,71 @@
}
},
"@babel/code-frame": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
- "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==",
+ "version": "7.22.13",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
+ "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
"dev": true,
"requires": {
- "@babel/highlight": "^7.18.6"
+ "@babel/highlight": "^7.22.13",
+ "chalk": "^2.4.2"
+ },
+ "dependencies": {
+ "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,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "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,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "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,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true
+ },
+ "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,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"@babel/compat-data": {
@@ -4507,13 +4793,14 @@
}
},
"@babel/generator": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz",
- "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
+ "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
"dev": true,
"requires": {
- "@babel/types": "^7.20.5",
+ "@babel/types": "^7.23.0",
"@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
"jsesc": "^2.5.1"
},
"dependencies": {
@@ -4551,28 +4838,28 @@
}
},
"@babel/helper-environment-visitor": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
- "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
"dev": true
},
"@babel/helper-function-name": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz",
- "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
"dev": true,
"requires": {
- "@babel/template": "^7.18.10",
- "@babel/types": "^7.19.0"
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
}
},
"@babel/helper-hoist-variables": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz",
- "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==",
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
"dev": true,
"requires": {
- "@babel/types": "^7.18.6"
+ "@babel/types": "^7.22.5"
}
},
"@babel/helper-module-imports": {
@@ -4610,24 +4897,24 @@
}
},
"@babel/helper-split-export-declaration": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
- "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==",
+ "version": "7.22.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dev": true,
"requires": {
- "@babel/types": "^7.18.6"
+ "@babel/types": "^7.22.5"
}
},
"@babel/helper-string-parser": {
- "version": "7.19.4",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz",
- "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==",
+ "version": "7.22.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
+ "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
"dev": true
},
"@babel/helper-validator-identifier": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
- "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"dev": true
},
"@babel/helper-validator-option": {
@@ -4648,13 +4935,13 @@
}
},
"@babel/highlight": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
- "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
+ "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
"dev": true,
"requires": {
- "@babel/helper-validator-identifier": "^7.18.6",
- "chalk": "^2.0.0",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
"js-tokens": "^4.0.0"
},
"dependencies": {
@@ -4717,36 +5004,36 @@
}
},
"@babel/parser": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz",
- "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
+ "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
"dev": true
},
"@babel/template": {
- "version": "7.18.10",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
- "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
+ "version": "7.22.15",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"dev": true,
"requires": {
- "@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.18.10",
- "@babel/types": "^7.18.10"
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
}
},
"@babel/traverse": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz",
- "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.20.5",
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-function-name": "^7.19.0",
- "@babel/helper-hoist-variables": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.20.5",
- "@babel/types": "^7.20.5",
+ "version": "7.23.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
+ "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/generator": "^7.23.0",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.0",
+ "@babel/types": "^7.23.0",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -4760,13 +5047,13 @@
}
},
"@babel/types": {
- "version": "7.20.5",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz",
- "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==",
+ "version": "7.23.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
+ "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
"dev": true,
"requires": {
- "@babel/helper-string-parser": "^7.19.4",
- "@babel/helper-validator-identifier": "^7.19.1",
+ "@babel/helper-string-parser": "^7.22.5",
+ "@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
}
},
@@ -5170,6 +5457,12 @@
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
+ "ansi-sequence-parser": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
+ "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
+ "dev": true
+ },
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@@ -6416,6 +6709,12 @@
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
+ "jsonc-parser": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
+ "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
+ "dev": true
+ },
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@@ -6469,6 +6768,15 @@
"is-unicode-supported": "^0.1.0"
}
},
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@@ -6478,6 +6786,12 @@
"yallist": "^4.0.0"
}
},
+ "lunr": {
+ "version": "2.3.9",
+ "resolved": "https://registry.npmmirror.com/lunr/-/lunr-2.3.9.tgz",
+ "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
+ "dev": true
+ },
"make-dir": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
@@ -6501,6 +6815,12 @@
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
"dev": true
},
+ "marked": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/marked/-/marked-4.3.0.tgz",
+ "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
+ "dev": true
+ },
"md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@@ -7052,6 +7372,25 @@
"safe-buffer": "^5.1.0"
}
},
+ "react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ }
+ },
"readable-stream": {
"version": "3.6.1",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz",
@@ -7185,6 +7524,15 @@
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
+ "scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.1.0"
+ }
+ },
"semver": {
"version": "7.3.8",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
@@ -7234,6 +7582,18 @@
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
+ "shiki": {
+ "version": "0.14.4",
+ "resolved": "https://registry.npmmirror.com/shiki/-/shiki-0.14.4.tgz",
+ "integrity": "sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==",
+ "dev": true,
+ "requires": {
+ "ansi-sequence-parser": "^1.1.0",
+ "jsonc-parser": "^3.2.0",
+ "vscode-oniguruma": "^1.7.0",
+ "vscode-textmate": "^8.0.0"
+ }
+ },
"signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -7500,6 +7860,48 @@
"is-typedarray": "^1.0.0"
}
},
+ "typedoc": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.1.tgz",
+ "integrity": "sha512-c2ye3YUtGIadxN2O6YwPEXgrZcvhlZ6HlhWZ8jQRNzwLPn2ylhdGqdR8HbyDRyALP8J6lmSANILCkkIdNPFxqA==",
+ "dev": true,
+ "requires": {
+ "lunr": "^2.3.9",
+ "marked": "^4.3.0",
+ "minimatch": "^9.0.3",
+ "shiki": "^0.14.1"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ }
+ }
+ },
+ "typedoc-plugin-bitcoinjs-runcase": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/typedoc-plugin-bitcoinjs-runcase/-/typedoc-plugin-bitcoinjs-runcase-1.0.1.tgz",
+ "integrity": "sha512-tqbnCCP2ku2egGjwn0G0bRNeSH/lh3FT7khrpyYdx1kDu8rjKlyqJX7yPgEj4biBHJATJnQGxp3cKmYG0wv5uw==",
+ "dev": true,
+ "requires": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ }
+ },
"typeforce": {
"version": "1.18.0",
"resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz",
@@ -7556,6 +7958,18 @@
"safe-buffer": "^5.1.1"
}
},
+ "vscode-oniguruma": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmmirror.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
+ "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
+ "dev": true
+ },
+ "vscode-textmate": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmmirror.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
+ "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
+ "dev": true
+ },
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
diff --git a/package.json b/package.json
index 485afdbf8..13c845713 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"coverage-report": "npm run build && npm run nobuild:coverage-report",
"coverage-html": "npm run build && npm run nobuild:coverage-html",
"coverage": "npm run build && npm run nobuild:coverage",
+ "doc": "typedoc",
"format": "npm run prettier -- --write",
"formatjs": "npm run prettierjs -- --write",
"format:ci": "npm run prettier -- --check && npm run prettierjs -- --check",
@@ -87,6 +88,7 @@
"rimraf": "^2.6.3",
"tiny-secp256k1": "^2.2.0",
"ts-node": "^8.3.0",
+ "typedoc": "^0.25.1",
"typescript": "^4.4.4"
},
"license": "MIT"
diff --git a/src/address.d.ts b/src/address.d.ts
index be0e00a61..6b5bc9c2a 100644
--- a/src/address.d.ts
+++ b/src/address.d.ts
@@ -1,17 +1,51 @@
///
+/**
+ * bitcoin address decode and encode tools, include base58、bech32 and output script
+ *
+ * networks support bitcoin、bitcoin testnet and bitcoin regtest
+ *
+ * addresses support P2PKH、P2SH、P2WPKH、P2WSH、P2TR and so on
+ *
+ * @packageDocumentation
+ */
import { Network } from './networks';
+/** base58check decode result */
export interface Base58CheckResult {
+ /** address hash */
hash: Buffer;
+ /** address version: 0x00 for P2PKH, 0x05 for P2SH */
version: number;
}
+/** bech32 decode result */
export interface Bech32Result {
+ /** address version: 0x00 for P2WPKH、P2WSH, 0x01 for P2TR*/
version: number;
+ /** address prefix: bc for P2WPKH、P2WSH、P2TR */
prefix: string;
+ /** address data:20 bytes for P2WPKH, 32 bytes for P2WSH、P2TR */
data: Buffer;
}
+/**
+ * decode address with base58 specification, return address version and address hash if valid
+ */
export declare function fromBase58Check(address: string): Base58CheckResult;
+/**
+ * decode address with bech32 specification, return address version、address prefix and address data if valid
+ */
export declare function fromBech32(address: string): Bech32Result;
+/**
+ * encode address hash to base58 address with version
+ */
export declare function toBase58Check(hash: Buffer, version: number): string;
+/**
+ * encode address hash to bech32 address with version and prefix
+ */
export declare function toBech32(data: Buffer, version: number, prefix: string): string;
+/**
+ * decode address from output script with network, return address if matched
+ */
export declare function fromOutputScript(output: Buffer, network?: Network): string;
+/**
+ * encodes address to output script with network, return output script if address matched
+ */
export declare function toOutputScript(address: string, network?: Network): Buffer;
diff --git a/src/address.js b/src/address.js
index ada8042af..ad3ceeb1a 100644
--- a/src/address.js
+++ b/src/address.js
@@ -41,6 +41,9 @@ function _toFutureSegwitAddress(output, network) {
console.warn(FUTURE_SEGWIT_VERSION_WARNING);
return toBech32(data, version, network.bech32);
}
+/**
+ * decode address with base58 specification, return address version and address hash if valid
+ */
function fromBase58Check(address) {
const payload = Buffer.from(bs58check.decode(address));
// TODO: 4.0.0, move to "toOutputScript"
@@ -51,6 +54,9 @@ function fromBase58Check(address) {
return { version, hash };
}
exports.fromBase58Check = fromBase58Check;
+/**
+ * decode address with bech32 specification, return address version、address prefix and address data if valid
+ */
function fromBech32(address) {
let result;
let version;
@@ -73,6 +79,9 @@ function fromBech32(address) {
};
}
exports.fromBech32 = fromBech32;
+/**
+ * encode address hash to base58 address with version
+ */
function toBase58Check(hash, version) {
(0, types_1.typeforce)(
(0, types_1.tuple)(types_1.Hash160bit, types_1.UInt8),
@@ -84,6 +93,9 @@ function toBase58Check(hash, version) {
return bs58check.encode(payload);
}
exports.toBase58Check = toBase58Check;
+/**
+ * encode address hash to bech32 address with version and prefix
+ */
function toBech32(data, version, prefix) {
const words = bech32_1.bech32.toWords(data);
words.unshift(version);
@@ -92,6 +104,9 @@ function toBech32(data, version, prefix) {
: bech32_1.bech32m.encode(prefix, words);
}
exports.toBech32 = toBech32;
+/**
+ * decode address from output script with network, return address if matched
+ */
function fromOutputScript(output, network) {
// TODO: Network
network = network || networks.bitcoin;
@@ -116,6 +131,9 @@ function fromOutputScript(output, network) {
throw new Error(bscript.toASM(output) + ' has no matching Address');
}
exports.fromOutputScript = fromOutputScript;
+/**
+ * encodes address to output script with network, return output script if address matched
+ */
function toOutputScript(address, network) {
network = network || networks.bitcoin;
let decodeBase58;
diff --git a/src/bufferutils.d.ts b/src/bufferutils.d.ts
index b1d89665b..b76bae0e3 100644
--- a/src/bufferutils.d.ts
+++ b/src/bufferutils.d.ts
@@ -2,7 +2,20 @@
import * as varuint from 'varuint-bitcoin';
export { varuint };
export declare function readUInt64LE(buffer: Buffer, offset: number): number;
+/**
+ * Writes a 64-bit unsigned integer in little-endian format to the specified buffer at the given offset.
+ *
+ * @param buffer - The buffer to write the value to.
+ * @param value - The 64-bit unsigned integer value to write.
+ * @param offset - The offset in the buffer where the value should be written.
+ * @returns The new offset after writing the value.
+ */
export declare function writeUInt64LE(buffer: Buffer, value: number, offset: number): number;
+/**
+ * Reverses the order of bytes in a buffer.
+ * @param buffer - The buffer to reverse.
+ * @returns A new buffer with the bytes reversed.
+ */
export declare function reverseBuffer(buffer: Buffer): Buffer;
export declare function cloneBuffer(buffer: Buffer): Buffer;
/**
diff --git a/src/bufferutils.js b/src/bufferutils.js
index 0f7fd10f4..cf11f02b4 100644
--- a/src/bufferutils.js
+++ b/src/bufferutils.js
@@ -30,6 +30,14 @@ function readUInt64LE(buffer, offset) {
return b + a;
}
exports.readUInt64LE = readUInt64LE;
+/**
+ * Writes a 64-bit unsigned integer in little-endian format to the specified buffer at the given offset.
+ *
+ * @param buffer - The buffer to write the value to.
+ * @param value - The 64-bit unsigned integer value to write.
+ * @param offset - The offset in the buffer where the value should be written.
+ * @returns The new offset after writing the value.
+ */
function writeUInt64LE(buffer, value, offset) {
verifuint(value, 0x001fffffffffffff);
buffer.writeInt32LE(value & -1, offset);
@@ -37,6 +45,11 @@ function writeUInt64LE(buffer, value, offset) {
return offset + 8;
}
exports.writeUInt64LE = writeUInt64LE;
+/**
+ * Reverses the order of bytes in a buffer.
+ * @param buffer - The buffer to reverse.
+ * @returns A new buffer with the bytes reversed.
+ */
function reverseBuffer(buffer) {
if (buffer.length < 1) return buffer;
let j = buffer.length - 1;
diff --git a/src/crypto.d.ts b/src/crypto.d.ts
index 1a465dad1..6692df1ee 100644
--- a/src/crypto.d.ts
+++ b/src/crypto.d.ts
@@ -10,6 +10,9 @@ type TaggedHashPrefixes = {
[key in TaggedHashPrefix]: Buffer;
};
/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
+/**
+ * Defines the tagged hash prefixes used in the crypto module.
+ */
export declare const TAGGED_HASH_PREFIXES: TaggedHashPrefixes;
export declare function taggedHash(prefix: TaggedHashPrefix, data: Buffer): Buffer;
export {};
diff --git a/src/crypto.js b/src/crypto.js
index af1224d25..a7a5936d9 100644
--- a/src/crypto.js
+++ b/src/crypto.js
@@ -9,6 +9,12 @@ exports.taggedHash =
exports.sha1 =
exports.ripemd160 =
void 0;
+/**
+ * A module for hashing functions.
+ * include ripemd160、sha1、sha256、hash160、hash256、taggedHash
+ *
+ * @packageDocumentation
+ */
const ripemd160_1 = require('@noble/hashes/ripemd160');
const sha1_1 = require('@noble/hashes/sha1');
const sha256_1 = require('@noble/hashes/sha256');
@@ -48,6 +54,9 @@ exports.TAGS = [
'KeyAgg coefficient',
];
/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
+/**
+ * Defines the tagged hash prefixes used in the crypto module.
+ */
exports.TAGGED_HASH_PREFIXES = {
'BIP0340/challenge': Buffer.from([
123, 181, 45, 122, 159, 239, 88, 50, 62, 177, 191, 122, 64, 125, 179, 130,
diff --git a/src/ecc_lib.d.ts b/src/ecc_lib.d.ts
index 201ebb5cf..abb750a32 100644
--- a/src/ecc_lib.d.ts
+++ b/src/ecc_lib.d.ts
@@ -1,3 +1,17 @@
import { TinySecp256k1Interface } from './types';
+/**
+ * Initializes the ECC library with the provided instance.
+ * If `eccLib` is `undefined`, the library will be cleared.
+ * If `eccLib` is a new instance, it will be verified before setting it as the active library.
+ *
+ * @param eccLib The instance of the ECC library to initialize.
+ */
export declare function initEccLib(eccLib: TinySecp256k1Interface | undefined): void;
+/**
+ * Retrieves the ECC Library instance.
+ * Throws an error if the ECC Library is not provided.
+ * You must call initEccLib() with a valid TinySecp256k1Interface instance before calling this function.
+ * @returns The ECC Library instance.
+ * @throws Error if the ECC Library is not provided.
+ */
export declare function getEccLib(): TinySecp256k1Interface;
diff --git a/src/ecc_lib.js b/src/ecc_lib.js
index eaa8a5327..22202da98 100644
--- a/src/ecc_lib.js
+++ b/src/ecc_lib.js
@@ -2,6 +2,13 @@
Object.defineProperty(exports, '__esModule', { value: true });
exports.getEccLib = exports.initEccLib = void 0;
const _ECCLIB_CACHE = {};
+/**
+ * Initializes the ECC library with the provided instance.
+ * If `eccLib` is `undefined`, the library will be cleared.
+ * If `eccLib` is a new instance, it will be verified before setting it as the active library.
+ *
+ * @param eccLib The instance of the ECC library to initialize.
+ */
function initEccLib(eccLib) {
if (!eccLib) {
// allow clearing the library
@@ -13,6 +20,13 @@ function initEccLib(eccLib) {
}
}
exports.initEccLib = initEccLib;
+/**
+ * Retrieves the ECC Library instance.
+ * Throws an error if the ECC Library is not provided.
+ * You must call initEccLib() with a valid TinySecp256k1Interface instance before calling this function.
+ * @returns The ECC Library instance.
+ * @throws Error if the ECC Library is not provided.
+ */
function getEccLib() {
if (!_ECCLIB_CACHE.eccLib)
throw new Error(
@@ -22,6 +36,11 @@ function getEccLib() {
}
exports.getEccLib = getEccLib;
const h = hex => Buffer.from(hex, 'hex');
+/**
+ * Verifies the ECC functionality.
+ *
+ * @param ecc - The TinySecp256k1Interface object.
+ */
function verifyEcc(ecc) {
assert(typeof ecc.isXOnlyPoint === 'function');
assert(
diff --git a/src/index.d.ts b/src/index.d.ts
index 420979ffe..3655f4560 100644
--- a/src/index.d.ts
+++ b/src/index.d.ts
@@ -5,11 +5,15 @@ import * as payments from './payments';
import * as script from './script';
export { address, crypto, networks, payments, script };
export { Block } from './block';
+/** @hidden */
export { TaggedHashPrefix } from './crypto';
export { Psbt, PsbtTxInput, PsbtTxOutput, Signer, SignerAsync, HDSigner, HDSignerAsync, } from './psbt';
+/** @hidden */
export { OPS as opcodes } from './ops';
export { Transaction } from './transaction';
+/** @hidden */
export { Network } from './networks';
+/** @hidden */
export { Payment, PaymentCreator, PaymentOpts, Stack, StackElement, } from './payments';
export { Input as TxInput, Output as TxOutput } from './transaction';
export { initEccLib } from './ecc_lib';
diff --git a/src/index.js b/src/index.js
index 4159064bd..c742ceef6 100644
--- a/src/index.js
+++ b/src/index.js
@@ -35,6 +35,7 @@ Object.defineProperty(exports, 'Psbt', {
return psbt_1.Psbt;
},
});
+/** @hidden */
var ops_1 = require('./ops');
Object.defineProperty(exports, 'opcodes', {
enumerable: true,
diff --git a/src/merkle.d.ts b/src/merkle.d.ts
index d602201b9..a911ca525 100644
--- a/src/merkle.d.ts
+++ b/src/merkle.d.ts
@@ -1,2 +1,10 @@
///
+/**
+ * Calculates the Merkle root of an array of buffers using a specified digest function.
+ *
+ * @param values - The array of buffers.
+ * @param digestFn - The digest function used to calculate the hash of the concatenated buffers.
+ * @returns The Merkle root as a buffer.
+ * @throws {TypeError} If the values parameter is not an array or the digestFn parameter is not a function.
+ */
export declare function fastMerkleRoot(values: Buffer[], digestFn: (b: Buffer) => Buffer): Buffer;
diff --git a/src/merkle.js b/src/merkle.js
index e93f9cab6..c326c53af 100644
--- a/src/merkle.js
+++ b/src/merkle.js
@@ -1,6 +1,14 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
exports.fastMerkleRoot = void 0;
+/**
+ * Calculates the Merkle root of an array of buffers using a specified digest function.
+ *
+ * @param values - The array of buffers.
+ * @param digestFn - The digest function used to calculate the hash of the concatenated buffers.
+ * @returns The Merkle root as a buffer.
+ * @throws {TypeError} If the values parameter is not an array or the digestFn parameter is not a function.
+ */
function fastMerkleRoot(values, digestFn) {
if (!Array.isArray(values)) throw TypeError('Expected values Array');
if (typeof digestFn !== 'function')
diff --git a/src/networks.d.ts b/src/networks.d.ts
index d5590fd1b..f9b020d9e 100644
--- a/src/networks.d.ts
+++ b/src/networks.d.ts
@@ -1,3 +1,8 @@
+/**
+ * Represents a Bitcoin network configuration,including messagePrefix, bech32, bip32, pubKeyHash, scriptHash, wif.
+ * Support bitcoin、bitcoin testnet and bitcoin regtest.
+ * @packageDocumentation
+ */
export interface Network {
messagePrefix: string;
bech32: string;
@@ -10,7 +15,16 @@ interface Bip32 {
public: number;
private: number;
}
+/**
+ * Represents the Bitcoin network configuration.
+ */
export declare const bitcoin: Network;
+/**
+ * Represents the regtest network configuration.
+ */
export declare const regtest: Network;
+/**
+ * Represents the testnet network configuration.
+ */
export declare const testnet: Network;
export {};
diff --git a/src/networks.js b/src/networks.js
index ea710f8a2..75cdf30cc 100644
--- a/src/networks.js
+++ b/src/networks.js
@@ -1,17 +1,49 @@
'use strict';
+// https://en.bitcoin.it/wiki/List_of_address_prefixes
+// Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731
Object.defineProperty(exports, '__esModule', { value: true });
exports.testnet = exports.regtest = exports.bitcoin = void 0;
+/**
+ * Represents the Bitcoin network configuration.
+ */
exports.bitcoin = {
+ /**
+ * The message prefix used for signing Bitcoin messages.
+ */
messagePrefix: '\x18Bitcoin Signed Message:\n',
+ /**
+ * The Bech32 prefix used for Bitcoin addresses.
+ */
bech32: 'bc',
+ /**
+ * The BIP32 key prefixes for Bitcoin.
+ */
bip32: {
+ /**
+ * The public key prefix for BIP32 extended public keys.
+ */
public: 0x0488b21e,
+ /**
+ * The private key prefix for BIP32 extended private keys.
+ */
private: 0x0488ade4,
},
+ /**
+ * The prefix for Bitcoin public key hashes.
+ */
pubKeyHash: 0x00,
+ /**
+ * The prefix for Bitcoin script hashes.
+ */
scriptHash: 0x05,
+ /**
+ * The prefix for Bitcoin Wallet Import Format (WIF) private keys.
+ */
wif: 0x80,
};
+/**
+ * Represents the regtest network configuration.
+ */
exports.regtest = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bcrt',
@@ -23,6 +55,9 @@ exports.regtest = {
scriptHash: 0xc4,
wif: 0xef,
};
+/**
+ * Represents the testnet network configuration.
+ */
exports.testnet = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'tb',
diff --git a/src/payments/bip341.d.ts b/src/payments/bip341.d.ts
index fe9ecf0d9..676021e4c 100644
--- a/src/payments/bip341.d.ts
+++ b/src/payments/bip341.d.ts
@@ -21,6 +21,13 @@ interface TweakedPublicKey {
* and calculating merkle inclusion proofs when constructing a control block.
*/
export type HashTree = HashLeaf | HashBranch;
+/**
+ * Calculates the root hash from a given control block and leaf hash.
+ * @param controlBlock - The control block buffer.
+ * @param leafHash - The leaf hash buffer.
+ * @returns The root hash buffer.
+ * @throws {TypeError} If the control block length is less than 33.
+ */
export declare function rootHashFromPath(controlBlock: Buffer, leafHash: Buffer): Buffer;
/**
* Build a hash tree of merkle nodes from the scripts binary tree.
diff --git a/src/payments/bip341.js b/src/payments/bip341.js
index 35609d788..926af6bf2 100644
--- a/src/payments/bip341.js
+++ b/src/payments/bip341.js
@@ -17,6 +17,13 @@ const types_1 = require('../types');
exports.LEAF_VERSION_TAPSCRIPT = 0xc0;
exports.MAX_TAPTREE_DEPTH = 128;
const isHashBranch = ht => 'left' in ht && 'right' in ht;
+/**
+ * Calculates the root hash from a given control block and leaf hash.
+ * @param controlBlock - The control block buffer.
+ * @param leafHash - The leaf hash buffer.
+ * @returns The root hash buffer.
+ * @throws {TypeError} If the control block length is less than 33.
+ */
function rootHashFromPath(controlBlock, leafHash) {
if (controlBlock.length < 33)
throw new TypeError(
diff --git a/src/payments/embed.d.ts b/src/payments/embed.d.ts
index 76a9ed28f..d5f5785e1 100644
--- a/src/payments/embed.d.ts
+++ b/src/payments/embed.d.ts
@@ -1,2 +1,9 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Embeds data in a Bitcoin payment.
+ * @param a - The payment object.
+ * @param opts - Optional payment options.
+ * @returns The modified payment object.
+ * @throws {TypeError} If there is not enough data or if the output is invalid.
+ */
export declare function p2data(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/embed.js b/src/payments/embed.js
index a465c0815..92bbb572f 100644
--- a/src/payments/embed.js
+++ b/src/payments/embed.js
@@ -7,6 +7,13 @@ const types_1 = require('../types');
const lazy = require('./lazy');
const OPS = bscript.OPS;
// output: OP_RETURN ...
+/**
+ * Embeds data in a Bitcoin payment.
+ * @param a - The payment object.
+ * @param opts - Optional payment options.
+ * @returns The modified payment object.
+ * @throws {TypeError} If there is not enough data or if the output is invalid.
+ */
function p2data(a, opts) {
if (!a.data && !a.output) throw new TypeError('Not enough data');
opts = Object.assign({ validate: true }, opts || {});
diff --git a/src/payments/index.d.ts b/src/payments/index.d.ts
index 57a0369b8..8eafc319e 100644
--- a/src/payments/index.d.ts
+++ b/src/payments/index.d.ts
@@ -1,4 +1,11 @@
///
+/**
+ * Represents a payment object, which is used to create a payment.
+ *
+ * Supports P2PKH、P2SH、P2WPKH、P2WSH、P2TR and so on
+ *
+ * @packageDocumentation
+ */
import { Network } from '../networks';
import { Taptree } from '../types';
import { p2data as embed } from './embed';
diff --git a/src/payments/p2ms.d.ts b/src/payments/p2ms.d.ts
index 199e02915..ff761c1fc 100644
--- a/src/payments/p2ms.d.ts
+++ b/src/payments/p2ms.d.ts
@@ -1,2 +1,9 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Represents a function that creates a Pay-to-Multisig (P2MS) payment object.
+ * @param a - The payment object.
+ * @param opts - Optional payment options.
+ * @returns The created payment object.
+ * @throws {TypeError} If the provided data is not valid.
+ */
export declare function p2ms(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2ms.js b/src/payments/p2ms.js
index 0fb57bb41..dfa0c8dd7 100644
--- a/src/payments/p2ms.js
+++ b/src/payments/p2ms.js
@@ -9,6 +9,13 @@ const OPS = bscript.OPS;
const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1
// input: OP_0 [signatures ...]
// output: m [pubKeys ...] n OP_CHECKMULTISIG
+/**
+ * Represents a function that creates a Pay-to-Multisig (P2MS) payment object.
+ * @param a - The payment object.
+ * @param opts - Optional payment options.
+ * @returns The created payment object.
+ * @throws {TypeError} If the provided data is not valid.
+ */
function p2ms(a, opts) {
if (
!a.input &&
diff --git a/src/payments/p2pk.d.ts b/src/payments/p2pk.d.ts
index d7e824d6c..862ea90df 100644
--- a/src/payments/p2pk.d.ts
+++ b/src/payments/p2pk.d.ts
@@ -1,2 +1,10 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Creates a pay-to-public-key (P2PK) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2PK payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
export declare function p2pk(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2pk.js b/src/payments/p2pk.js
index 284953045..cd6702f53 100644
--- a/src/payments/p2pk.js
+++ b/src/payments/p2pk.js
@@ -8,6 +8,14 @@ const lazy = require('./lazy');
const OPS = bscript.OPS;
// input: {signature}
// output: {pubKey} OP_CHECKSIG
+/**
+ * Creates a pay-to-public-key (P2PK) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2PK payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
function p2pk(a, opts) {
if (!a.input && !a.output && !a.pubkey && !a.input && !a.signature)
throw new TypeError('Not enough data');
diff --git a/src/payments/p2pkh.d.ts b/src/payments/p2pkh.d.ts
index a33eeb030..1c5b76b5b 100644
--- a/src/payments/p2pkh.d.ts
+++ b/src/payments/p2pkh.d.ts
@@ -1,2 +1,10 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Creates a Pay-to-Public-Key-Hash (P2PKH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2PKH payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
export declare function p2pkh(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2pkh.js b/src/payments/p2pkh.js
index 16e293d59..bc35e878e 100644
--- a/src/payments/p2pkh.js
+++ b/src/payments/p2pkh.js
@@ -10,6 +10,14 @@ const bs58check = require('bs58check');
const OPS = bscript.OPS;
// input: {signature} {pubkey}
// output: OP_DUP OP_HASH160 {hash160(pubkey)} OP_EQUALVERIFY OP_CHECKSIG
+/**
+ * Creates a Pay-to-Public-Key-Hash (P2PKH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2PKH payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
function p2pkh(a, opts) {
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.input)
throw new TypeError('Not enough data');
diff --git a/src/payments/p2sh.d.ts b/src/payments/p2sh.d.ts
index bb76772e7..c82d040cc 100644
--- a/src/payments/p2sh.d.ts
+++ b/src/payments/p2sh.d.ts
@@ -1,2 +1,10 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Creates a Pay-to-Script-Hash (P2SH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2SH payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
export declare function p2sh(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2sh.js b/src/payments/p2sh.js
index 66e56b6c8..1386966be 100644
--- a/src/payments/p2sh.js
+++ b/src/payments/p2sh.js
@@ -11,6 +11,14 @@ const OPS = bscript.OPS;
// input: [redeemScriptSig ...] {redeemScript}
// witness: >
// output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL
+/**
+ * Creates a Pay-to-Script-Hash (P2SH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2SH payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
function p2sh(a, opts) {
if (!a.address && !a.hash && !a.output && !a.redeem && !a.input)
throw new TypeError('Not enough data');
diff --git a/src/payments/p2tr.d.ts b/src/payments/p2tr.d.ts
index 350ed0ffc..97b2e0eb2 100644
--- a/src/payments/p2tr.d.ts
+++ b/src/payments/p2tr.d.ts
@@ -1,2 +1,10 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Creates a Pay-to-Taproot (P2TR) payment object.
+ *
+ * @param a - The payment object containing the necessary data for P2TR.
+ * @param opts - Optional payment options.
+ * @returns The P2TR payment object.
+ * @throws {TypeError} If the provided data is invalid or insufficient.
+ */
export declare function p2tr(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2tr.js b/src/payments/p2tr.js
index bc0ab45c7..33fedb464 100644
--- a/src/payments/p2tr.js
+++ b/src/payments/p2tr.js
@@ -13,6 +13,14 @@ const address_1 = require('../address');
const OPS = bscript.OPS;
const TAPROOT_WITNESS_VERSION = 0x01;
const ANNEX_PREFIX = 0x50;
+/**
+ * Creates a Pay-to-Taproot (P2TR) payment object.
+ *
+ * @param a - The payment object containing the necessary data for P2TR.
+ * @param opts - Optional payment options.
+ * @returns The P2TR payment object.
+ * @throws {TypeError} If the provided data is invalid or insufficient.
+ */
function p2tr(a, opts) {
if (
!a.address &&
diff --git a/src/payments/p2wpkh.d.ts b/src/payments/p2wpkh.d.ts
index 360939119..5108e2912 100644
--- a/src/payments/p2wpkh.d.ts
+++ b/src/payments/p2wpkh.d.ts
@@ -1,2 +1,10 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Creates a pay-to-witness-public-key-hash (p2wpkh) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The p2wpkh payment object.
+ * @throws {TypeError} If the required data is missing or invalid.
+ */
export declare function p2wpkh(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2wpkh.js b/src/payments/p2wpkh.js
index 168e08f19..1c6073e9b 100644
--- a/src/payments/p2wpkh.js
+++ b/src/payments/p2wpkh.js
@@ -12,6 +12,14 @@ const EMPTY_BUFFER = Buffer.alloc(0);
// witness: {signature} {pubKey}
// input: <>
// output: OP_0 {pubKeyHash}
+/**
+ * Creates a pay-to-witness-public-key-hash (p2wpkh) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The p2wpkh payment object.
+ * @throws {TypeError} If the required data is missing or invalid.
+ */
function p2wpkh(a, opts) {
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.witness)
throw new TypeError('Not enough data');
diff --git a/src/payments/p2wsh.d.ts b/src/payments/p2wsh.d.ts
index d9ae925e8..4169a30de 100644
--- a/src/payments/p2wsh.d.ts
+++ b/src/payments/p2wsh.d.ts
@@ -1,2 +1,10 @@
import { Payment, PaymentOpts } from './index';
+/**
+ * Creates a Pay-to-Witness-Script-Hash (P2WSH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2WSH payment object.
+ * @throws {TypeError} If the required data is missing or invalid.
+ */
export declare function p2wsh(a: Payment, opts?: PaymentOpts): Payment;
diff --git a/src/payments/p2wsh.js b/src/payments/p2wsh.js
index b4adebd8e..a3422e50a 100644
--- a/src/payments/p2wsh.js
+++ b/src/payments/p2wsh.js
@@ -24,6 +24,14 @@ function chunkHasUncompressedPubkey(chunk) {
// input: <>
// witness: [redeemScriptSig ...] {redeemScript}
// output: OP_0 {sha256(redeemScript)}
+/**
+ * Creates a Pay-to-Witness-Script-Hash (P2WSH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2WSH payment object.
+ * @throws {TypeError} If the required data is missing or invalid.
+ */
function p2wsh(a, opts) {
if (!a.address && !a.hash && !a.output && !a.redeem && !a.witness)
throw new TypeError('Not enough data');
diff --git a/src/psbt.d.ts b/src/psbt.d.ts
index de7bbb3d4..d350ca12b 100644
--- a/src/psbt.d.ts
+++ b/src/psbt.d.ts
@@ -24,6 +24,7 @@ export type ValidateSigFunction = (pubkey: Buffer, msghash: Buffer, signature: B
* There are 6 roles that this class fulfills. (Explained in BIP174)
*
* Creator: This can be done with `new Psbt()`
+ *
* Updater: This can be done with `psbt.addInput(input)`, `psbt.addInputs(inputs)`,
* `psbt.addOutput(output)`, `psbt.addOutputs(outputs)` when you are looking to
* add new inputs and outputs to the PSBT, and `psbt.updateGlobal(itemObject)`,
@@ -34,20 +35,24 @@ export type ValidateSigFunction = (pubkey: Buffer, msghash: Buffer, signature: B
* data for updateOutput.
* For a list of what attributes should be what types. Check the bip174 library.
* Also, check the integration tests for some examples of usage.
+ *
* Signer: There are a few methods. signAllInputs and signAllInputsAsync, which will search all input
* information for your pubkey or pubkeyhash, and only sign inputs where it finds
* your info. Or you can explicitly sign a specific input with signInput and
* signInputAsync. For the async methods you can create a SignerAsync object
* and use something like a hardware wallet to sign with. (You must implement this)
+ *
* Combiner: psbts can be combined easily with `psbt.combine(psbt2, psbt3, psbt4 ...)`
* the psbt calling combine will always have precedence when a conflict occurs.
* Combine checks if the internal bitcoin transaction is the same, so be sure that
* all sequences, version, locktime, etc. are the same before combining.
+ *
* Input Finalizer: This role is fairly important. Not only does it need to construct
* the input scriptSigs and witnesses, but it SHOULD verify the signatures etc.
* Before running `psbt.finalizeAllInputs()` please run `psbt.validateSignaturesOfAllInputs()`
* Running any finalize method will delete any data in the input(s) that are no longer
* needed due to the finalized scripts containing the information.
+ *
* Transaction Extractor: This role will perform some checks before returning a
* Transaction object. Such as fee rate not being larger than maximumFeeRate etc.
*/
diff --git a/src/psbt.js b/src/psbt.js
index 71c3589f0..227e29304 100644
--- a/src/psbt.js
+++ b/src/psbt.js
@@ -34,6 +34,7 @@ const DEFAULT_OPTS = {
* There are 6 roles that this class fulfills. (Explained in BIP174)
*
* Creator: This can be done with `new Psbt()`
+ *
* Updater: This can be done with `psbt.addInput(input)`, `psbt.addInputs(inputs)`,
* `psbt.addOutput(output)`, `psbt.addOutputs(outputs)` when you are looking to
* add new inputs and outputs to the PSBT, and `psbt.updateGlobal(itemObject)`,
@@ -44,20 +45,24 @@ const DEFAULT_OPTS = {
* data for updateOutput.
* For a list of what attributes should be what types. Check the bip174 library.
* Also, check the integration tests for some examples of usage.
+ *
* Signer: There are a few methods. signAllInputs and signAllInputsAsync, which will search all input
* information for your pubkey or pubkeyhash, and only sign inputs where it finds
* your info. Or you can explicitly sign a specific input with signInput and
* signInputAsync. For the async methods you can create a SignerAsync object
* and use something like a hardware wallet to sign with. (You must implement this)
+ *
* Combiner: psbts can be combined easily with `psbt.combine(psbt2, psbt3, psbt4 ...)`
* the psbt calling combine will always have precedence when a conflict occurs.
* Combine checks if the internal bitcoin transaction is the same, so be sure that
* all sequences, version, locktime, etc. are the same before combining.
+ *
* Input Finalizer: This role is fairly important. Not only does it need to construct
* the input scriptSigs and witnesses, but it SHOULD verify the signatures etc.
* Before running `psbt.finalizeAllInputs()` please run `psbt.validateSignaturesOfAllInputs()`
* Running any finalize method will delete any data in the input(s) that are no longer
* needed due to the finalized scripts containing the information.
+ *
* Transaction Extractor: This role will perform some checks before returning a
* Transaction object. Such as fee rate not being larger than maximumFeeRate etc.
*/
@@ -85,7 +90,7 @@ class Psbt {
__NON_WITNESS_UTXO_BUF_CACHE: [],
__TX_IN_CACHE: {},
__TX: this.data.globalMap.unsignedTx.tx,
- // Psbt's predecesor (TransactionBuilder - now removed) behavior
+ // Psbt's predecessor (TransactionBuilder - now removed) behavior
// was to not confirm input values before signing.
// Even though we highly encourage people to get
// the full parent transaction to verify values, the ability to
@@ -1262,7 +1267,7 @@ function getHashForSig(inputIndex, input, cache, forValidate, sighashTypes) {
console.warn(
'Warning: Signing non-segwit inputs without the full parent transaction ' +
'means there is a chance that a miner could feed you incorrect information ' +
- "to trick you into paying large fees. This behavior is the same as Psbt's predecesor " +
+ "to trick you into paying large fees. This behavior is the same as Psbt's predecessor " +
'(TransactionBuilder - now removed) when signing non-segwit scripts. You are not ' +
'able to export this Psbt with toBuffer|toBase64|toHex since it is not ' +
'BIP174 compliant.\n*********************\nPROCEED WITH CAUTION!\n' +
diff --git a/src/psbt/bip371.js b/src/psbt/bip371.js
index 61196ead2..2b53171e0 100644
--- a/src/psbt/bip371.js
+++ b/src/psbt/bip371.js
@@ -265,6 +265,14 @@ function checkMixedTaprootAndNonTaprootOutputFields(
`Cannot use both taproot and non-taproot fields.`,
);
}
+/**
+ * Checks if the tap leaf is part of the tap tree for the given input data.
+ * Throws an error if the tap leaf is not part of the tap tree.
+ * @param inputData - The original PsbtInput data.
+ * @param newInputData - The new PsbtInput data.
+ * @param action - The action being performed.
+ * @throws {Error} - If the tap leaf is not part of the tap tree.
+ */
function checkIfTapLeafInTree(inputData, newInputData, action) {
if (newInputData.tapMerkleRoot) {
const newLeafsInTree = (newInputData.tapLeafScript || []).every(l =>
@@ -287,6 +295,12 @@ function checkIfTapLeafInTree(inputData, newInputData, action) {
);
}
}
+/**
+ * Checks if a TapLeafScript is present in a Merkle tree.
+ * @param tapLeaf The TapLeafScript to check.
+ * @param merkleRoot The Merkle root of the tree. If not provided, the function assumes the TapLeafScript is present.
+ * @returns A boolean indicating whether the TapLeafScript is present in the tree.
+ */
function isTapLeafInTree(tapLeaf, merkleRoot) {
if (!merkleRoot) return true;
const leafHash = (0, bip341_1.tapleafHash)({
@@ -299,6 +313,13 @@ function isTapLeafInTree(tapLeaf, merkleRoot) {
);
return rootHash.equals(merkleRoot);
}
+/**
+ * Sorts the signatures in the input's tapScriptSig array based on their position in the tapLeaf script.
+ *
+ * @param input - The PsbtInput object.
+ * @param tapLeaf - The TapLeafScript object.
+ * @returns An array of sorted signatures as Buffers.
+ */
function sortSignatures(input, tapLeaf) {
const leafHash = (0, bip341_1.tapleafHash)({
output: tapLeaf.script,
@@ -310,6 +331,12 @@ function sortSignatures(input, tapLeaf) {
.sort((t1, t2) => t2.positionInScript - t1.positionInScript)
.map(t => t.signature);
}
+/**
+ * Adds the position of a public key in a script to a TapScriptSig object.
+ * @param script The script in which to find the position of the public key.
+ * @param tss The TapScriptSig object to add the position to.
+ * @returns A TapScriptSigWitPosition object with the added position.
+ */
function addPubkeyPositionInScript(script, tss) {
return Object.assign(
{
@@ -340,6 +367,14 @@ function findTapLeafToFinalize(input, inputIndex, leafHashToFinalize) {
);
return tapLeaf;
}
+/**
+ * Determines whether a TapLeafScript can be finalized.
+ *
+ * @param leaf - The TapLeafScript to check.
+ * @param tapScriptSig - The array of TapScriptSig objects.
+ * @param hash - The optional hash to compare with the leaf hash.
+ * @returns A boolean indicating whether the TapLeafScript can be finalized.
+ */
function canFinalizeLeaf(leaf, tapScriptSig, hash) {
const leafHash = (0, bip341_1.tapleafHash)({
output: leaf.script,
@@ -351,6 +386,12 @@ function canFinalizeLeaf(leaf, tapScriptSig, hash) {
tapScriptSig.find(tss => tss.leafHash.equals(leafHash)) !== undefined
);
}
+/**
+ * Checks if the given PsbtInput or PsbtOutput has non-taproot fields.
+ * Non-taproot fields include redeemScript, witnessScript, and bip32Derivation.
+ * @param io The PsbtInput or PsbtOutput to check.
+ * @returns A boolean indicating whether the given input or output has non-taproot fields.
+ */
function hasNonTaprootFields(io) {
return (
io &&
diff --git a/src/psbt/psbtutils.d.ts b/src/psbt/psbtutils.d.ts
index db5f0b516..3e7b2a393 100644
--- a/src/psbt/psbtutils.d.ts
+++ b/src/psbt/psbtutils.d.ts
@@ -7,13 +7,49 @@ export declare const isP2WPKH: (script: Buffer) => boolean;
export declare const isP2WSHScript: (script: Buffer) => boolean;
export declare const isP2SHScript: (script: Buffer) => boolean;
export declare const isP2TR: (script: Buffer) => boolean;
+/**
+ * Converts a witness stack to a script witness.
+ * @param witness The witness stack to convert.
+ * @returns The script witness as a Buffer.
+ */
+/**
+ * Converts a witness stack to a script witness.
+ * @param witness The witness stack to convert.
+ * @returns The converted script witness.
+ */
export declare function witnessStackToScriptWitness(witness: Buffer[]): Buffer;
+/**
+ * Finds the position of a public key in a script.
+ * @param pubkey The public key to search for.
+ * @param script The script to search in.
+ * @returns The index of the public key in the script, or -1 if not found.
+ * @throws {Error} If there is an unknown script error.
+ */
export declare function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number;
+/**
+ * Checks if a public key is present in a script.
+ * @param pubkey The public key to check.
+ * @param script The script to search in.
+ * @returns A boolean indicating whether the public key is present in the script.
+ */
export declare function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean;
+/**
+ * Checks if an input contains a signature for a specific action.
+ * @param input - The input to check.
+ * @param action - The action to check for.
+ * @returns A boolean indicating whether the input contains a signature for the specified action.
+ */
export declare function checkInputForSig(input: PsbtInput, action: string): boolean;
type SignatureDecodeFunc = (buffer: Buffer) => {
signature: Buffer;
hashType: number;
};
+/**
+ * Determines if a given action is allowed for a signature block.
+ * @param signature - The signature block.
+ * @param signatureDecodeFn - The function used to decode the signature.
+ * @param action - The action to be checked.
+ * @returns True if the action is allowed, false otherwise.
+ */
export declare function signatureBlocksAction(signature: Buffer, signatureDecodeFn: SignatureDecodeFunc, action: string): boolean;
export {};
diff --git a/src/psbt/psbtutils.js b/src/psbt/psbtutils.js
index 2e8bd435a..ea5f1d719 100644
--- a/src/psbt/psbtutils.js
+++ b/src/psbt/psbtutils.js
@@ -35,6 +35,16 @@ exports.isP2WPKH = isPaymentFactory(payments.p2wpkh);
exports.isP2WSHScript = isPaymentFactory(payments.p2wsh);
exports.isP2SHScript = isPaymentFactory(payments.p2sh);
exports.isP2TR = isPaymentFactory(payments.p2tr);
+/**
+ * Converts a witness stack to a script witness.
+ * @param witness The witness stack to convert.
+ * @returns The script witness as a Buffer.
+ */
+/**
+ * Converts a witness stack to a script witness.
+ * @param witness The witness stack to convert.
+ * @returns The converted script witness.
+ */
function witnessStackToScriptWitness(witness) {
let buffer = Buffer.allocUnsafe(0);
function writeSlice(slice) {
@@ -58,6 +68,13 @@ function witnessStackToScriptWitness(witness) {
return buffer;
}
exports.witnessStackToScriptWitness = witnessStackToScriptWitness;
+/**
+ * Finds the position of a public key in a script.
+ * @param pubkey The public key to search for.
+ * @param script The script to search in.
+ * @returns The index of the public key in the script, or -1 if not found.
+ * @throws {Error} If there is an unknown script error.
+ */
function pubkeyPositionInScript(pubkey, script) {
const pubkeyHash = (0, crypto_1.hash160)(pubkey);
const pubkeyXOnly = pubkey.slice(1, 33); // slice before calling?
@@ -73,10 +90,22 @@ function pubkeyPositionInScript(pubkey, script) {
});
}
exports.pubkeyPositionInScript = pubkeyPositionInScript;
+/**
+ * Checks if a public key is present in a script.
+ * @param pubkey The public key to check.
+ * @param script The script to search in.
+ * @returns A boolean indicating whether the public key is present in the script.
+ */
function pubkeyInScript(pubkey, script) {
return pubkeyPositionInScript(pubkey, script) !== -1;
}
exports.pubkeyInScript = pubkeyInScript;
+/**
+ * Checks if an input contains a signature for a specific action.
+ * @param input - The input to check.
+ * @param action - The action to check for.
+ * @returns A boolean indicating whether the input contains a signature for the specified action.
+ */
function checkInputForSig(input, action) {
const pSigs = extractPartialSigs(input);
return pSigs.some(pSig =>
@@ -84,6 +113,13 @@ function checkInputForSig(input, action) {
);
}
exports.checkInputForSig = checkInputForSig;
+/**
+ * Determines if a given action is allowed for a signature block.
+ * @param signature - The signature block.
+ * @param signatureDecodeFn - The function used to decode the signature.
+ * @param action - The action to be checked.
+ * @returns True if the action is allowed, false otherwise.
+ */
function signatureBlocksAction(signature, signatureDecodeFn, action) {
const { hashType } = signatureDecodeFn(signature);
const whitelist = [];
@@ -106,6 +142,16 @@ function signatureBlocksAction(signature, signatureDecodeFn, action) {
return false;
}
exports.signatureBlocksAction = signatureBlocksAction;
+/**
+ * Extracts the signatures from a PsbtInput object.
+ * If the input has partial signatures, it returns an array of the signatures.
+ * If the input does not have partial signatures, it checks if it has a finalScriptSig or finalScriptWitness.
+ * If it does, it extracts the signatures from the final scripts and returns them.
+ * If none of the above conditions are met, it returns an empty array.
+ *
+ * @param input - The PsbtInput object from which to extract the signatures.
+ * @returns An array of signatures extracted from the PsbtInput object.
+ */
function extractPartialSigs(input) {
let pSigs = [];
if ((input.partialSig || []).length === 0) {
@@ -116,6 +162,14 @@ function extractPartialSigs(input) {
}
return pSigs.map(p => p.signature);
}
+/**
+ * Retrieves the partial signatures (Psigs) from the input's final scripts.
+ * Psigs are extracted from both the final scriptSig and final scriptWitness of the input.
+ * Only canonical script signatures are considered.
+ *
+ * @param input - The PsbtInput object representing the input.
+ * @returns An array of PartialSig objects containing the extracted Psigs.
+ */
function getPsigsFromInputFinalScripts(input) {
const scriptItems = !input.finalScriptSig
? []
diff --git a/src/push_data.d.ts b/src/push_data.d.ts
index 07c2f918d..068456148 100644
--- a/src/push_data.d.ts
+++ b/src/push_data.d.ts
@@ -1,6 +1,27 @@
///
+/**
+ * Calculates the encoding length of a number used for push data in Bitcoin transactions.
+ * @param i The number to calculate the encoding length for.
+ * @returns The encoding length of the number.
+ */
export declare function encodingLength(i: number): number;
+/**
+ * Encodes a number into a buffer using a variable-length encoding scheme.
+ * The encoded buffer is written starting at the specified offset.
+ * Returns the size of the encoded buffer.
+ *
+ * @param buffer - The buffer to write the encoded data into.
+ * @param num - The number to encode.
+ * @param offset - The offset at which to start writing the encoded buffer.
+ * @returns The size of the encoded buffer.
+ */
export declare function encode(buffer: Buffer, num: number, offset: number): number;
+/**
+ * Decodes a buffer and returns information about the opcode, number, and size.
+ * @param buffer - The buffer to decode.
+ * @param offset - The offset within the buffer to start decoding.
+ * @returns An object containing the opcode, number, and size, or null if decoding fails.
+ */
export declare function decode(buffer: Buffer, offset: number): {
opcode: number;
number: number;
diff --git a/src/push_data.js b/src/push_data.js
index 16b6147b5..2d3683769 100644
--- a/src/push_data.js
+++ b/src/push_data.js
@@ -2,10 +2,25 @@
Object.defineProperty(exports, '__esModule', { value: true });
exports.decode = exports.encode = exports.encodingLength = void 0;
const ops_1 = require('./ops');
+/**
+ * Calculates the encoding length of a number used for push data in Bitcoin transactions.
+ * @param i The number to calculate the encoding length for.
+ * @returns The encoding length of the number.
+ */
function encodingLength(i) {
return i < ops_1.OPS.OP_PUSHDATA1 ? 1 : i <= 0xff ? 2 : i <= 0xffff ? 3 : 5;
}
exports.encodingLength = encodingLength;
+/**
+ * Encodes a number into a buffer using a variable-length encoding scheme.
+ * The encoded buffer is written starting at the specified offset.
+ * Returns the size of the encoded buffer.
+ *
+ * @param buffer - The buffer to write the encoded data into.
+ * @param num - The number to encode.
+ * @param offset - The offset at which to start writing the encoded buffer.
+ * @returns The size of the encoded buffer.
+ */
function encode(buffer, num, offset) {
const size = encodingLength(num);
// ~6 bit
@@ -27,6 +42,12 @@ function encode(buffer, num, offset) {
return size;
}
exports.encode = encode;
+/**
+ * Decodes a buffer and returns information about the opcode, number, and size.
+ * @param buffer - The buffer to decode.
+ * @param offset - The offset within the buffer to start decoding.
+ * @returns An object containing the opcode, number, and size, or null if decoding fails.
+ */
function decode(buffer, offset) {
const opcode = buffer.readUInt8(offset);
let num;
diff --git a/src/script.d.ts b/src/script.d.ts
index fd5964b89..ffc8c89bb 100644
--- a/src/script.d.ts
+++ b/src/script.d.ts
@@ -6,10 +6,34 @@ import * as scriptSignature from './script_signature';
export { OPS };
export declare function isPushOnly(value: Stack): boolean;
export declare function countNonPushOnlyOPs(value: Stack): number;
+/**
+ * Compiles an array of chunks into a Buffer.
+ *
+ * @param chunks - The array of chunks to compile.
+ * @returns The compiled Buffer.
+ * @throws Error if the compilation fails.
+ */
export declare function compile(chunks: Buffer | Stack): Buffer;
export declare function decompile(buffer: Buffer | Array): Array | null;
+/**
+ * Converts the given chunks into an ASM (Assembly) string representation.
+ * If the chunks parameter is a Buffer, it will be decompiled into a Stack before conversion.
+ * @param chunks - The chunks to convert into ASM.
+ * @returns The ASM string representation of the chunks.
+ */
export declare function toASM(chunks: Buffer | Array): string;
+/**
+ * Converts an ASM string to a Buffer.
+ * @param asm The ASM string to convert.
+ * @returns The converted Buffer.
+ */
export declare function fromASM(asm: string): Buffer;
+/**
+ * Converts the given chunks into a stack of buffers.
+ *
+ * @param chunks - The chunks to convert.
+ * @returns The stack of buffers.
+ */
export declare function toStack(chunks: Buffer | Array): Buffer[];
export declare function isCanonicalPubKey(buffer: Buffer): boolean;
export declare function isDefinedHashType(hashType: number): boolean;
diff --git a/src/script.js b/src/script.js
index 6ed7ba20a..be2805190 100644
--- a/src/script.js
+++ b/src/script.js
@@ -14,6 +14,10 @@ exports.signature =
exports.isPushOnly =
exports.OPS =
void 0;
+/**
+ * Script tools, including decompile, compile, toASM, fromASM, toStack, isCanonicalPubKey, isCanonicalScriptSignature
+ * @packageDocumentation
+ */
const bip66 = require('./bip66');
const ops_1 = require('./ops');
Object.defineProperty(exports, 'OPS', {
@@ -62,6 +66,13 @@ function chunksIsArray(buf) {
function singleChunkIsBuffer(buf) {
return Buffer.isBuffer(buf);
}
+/**
+ * Compiles an array of chunks into a Buffer.
+ *
+ * @param chunks - The array of chunks to compile.
+ * @returns The compiled Buffer.
+ * @throws Error if the compilation fails.
+ */
function compile(chunks) {
// TODO: remove me
if (chunksIsBuffer(chunks)) return chunks;
@@ -137,6 +148,12 @@ function decompile(buffer) {
return chunks;
}
exports.decompile = decompile;
+/**
+ * Converts the given chunks into an ASM (Assembly) string representation.
+ * If the chunks parameter is a Buffer, it will be decompiled into a Stack before conversion.
+ * @param chunks - The chunks to convert into ASM.
+ * @returns The ASM string representation of the chunks.
+ */
function toASM(chunks) {
if (chunksIsBuffer(chunks)) {
chunks = decompile(chunks);
@@ -155,6 +172,11 @@ function toASM(chunks) {
.join(' ');
}
exports.toASM = toASM;
+/**
+ * Converts an ASM string to a Buffer.
+ * @param asm The ASM string to convert.
+ * @returns The converted Buffer.
+ */
function fromASM(asm) {
typeforce(types.String, asm);
return compile(
@@ -168,6 +190,12 @@ function fromASM(asm) {
);
}
exports.fromASM = fromASM;
+/**
+ * Converts the given chunks into a stack of buffers.
+ *
+ * @param chunks - The chunks to convert.
+ * @returns The stack of buffers.
+ */
function toStack(chunks) {
chunks = decompile(chunks);
typeforce(isPushOnly, chunks);
diff --git a/src/script_number.d.ts b/src/script_number.d.ts
index 015bb8943..90f09c55a 100644
--- a/src/script_number.d.ts
+++ b/src/script_number.d.ts
@@ -1,3 +1,19 @@
///
+/**
+ * Decodes a script number from a buffer.
+ *
+ * @param buffer - The buffer containing the script number.
+ * @param maxLength - The maximum length of the script number. Defaults to 4.
+ * @param minimal - Whether the script number should be minimal. Defaults to true.
+ * @returns The decoded script number.
+ * @throws {TypeError} If the script number overflows the maximum length.
+ * @throws {Error} If the script number is not minimally encoded when minimal is true.
+ */
export declare function decode(buffer: Buffer, maxLength?: number, minimal?: boolean): number;
+/**
+ * Encodes a number into a Buffer using a specific format.
+ *
+ * @param _number - The number to encode.
+ * @returns The encoded number as a Buffer.
+ */
export declare function encode(_number: number): Buffer;
diff --git a/src/script_number.js b/src/script_number.js
index 8220a1043..2691b41e6 100644
--- a/src/script_number.js
+++ b/src/script_number.js
@@ -1,6 +1,16 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
exports.encode = exports.decode = void 0;
+/**
+ * Decodes a script number from a buffer.
+ *
+ * @param buffer - The buffer containing the script number.
+ * @param maxLength - The maximum length of the script number. Defaults to 4.
+ * @param minimal - Whether the script number should be minimal. Defaults to true.
+ * @returns The decoded script number.
+ * @throws {TypeError} If the script number overflows the maximum length.
+ * @throws {Error} If the script number is not minimally encoded when minimal is true.
+ */
function decode(buffer, maxLength, minimal) {
maxLength = maxLength || 4;
minimal = minimal === undefined ? true : minimal;
@@ -43,6 +53,12 @@ function scriptNumSize(i) {
? 1
: 0;
}
+/**
+ * Encodes a number into a Buffer using a specific format.
+ *
+ * @param _number - The number to encode.
+ * @returns The encoded number as a Buffer.
+ */
function encode(_number) {
let value = Math.abs(_number);
const size = scriptNumSize(value);
diff --git a/src/script_signature.d.ts b/src/script_signature.d.ts
index 2057dd99f..b9034a816 100644
--- a/src/script_signature.d.ts
+++ b/src/script_signature.d.ts
@@ -3,6 +3,19 @@ interface ScriptSignature {
signature: Buffer;
hashType: number;
}
+/**
+ * Decodes a buffer into a ScriptSignature object.
+ * @param buffer - The buffer to decode.
+ * @returns The decoded ScriptSignature object.
+ * @throws Error if the hashType is invalid.
+ */
export declare function decode(buffer: Buffer): ScriptSignature;
+/**
+ * Encodes a signature and hash type into a buffer.
+ * @param signature - The signature to encode.
+ * @param hashType - The hash type to encode.
+ * @returns The encoded buffer.
+ * @throws Error if the hashType is invalid.
+ */
export declare function encode(signature: Buffer, hashType: number): Buffer;
export {};
diff --git a/src/script_signature.js b/src/script_signature.js
index eb252ceb4..61624b630 100644
--- a/src/script_signature.js
+++ b/src/script_signature.js
@@ -6,6 +6,11 @@ const script_1 = require('./script');
const types = require('./types');
const { typeforce } = types;
const ZERO = Buffer.alloc(1, 0);
+/**
+ * Converts a buffer to a DER-encoded buffer.
+ * @param x - The buffer to be converted.
+ * @returns The DER-encoded buffer.
+ */
function toDER(x) {
let i = 0;
while (x[i] === 0) ++i;
@@ -14,6 +19,13 @@ function toDER(x) {
if (x[0] & 0x80) return Buffer.concat([ZERO, x], 1 + x.length);
return x;
}
+/**
+ * Converts a DER-encoded signature to a buffer.
+ * If the first byte of the input buffer is 0x00, it is skipped.
+ * The resulting buffer is 32 bytes long, filled with zeros if necessary.
+ * @param x - The DER-encoded signature.
+ * @returns The converted buffer.
+ */
function fromDER(x) {
if (x[0] === 0x00) x = x.slice(1);
const buffer = Buffer.alloc(32, 0);
@@ -22,6 +34,12 @@ function fromDER(x) {
return buffer;
}
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
+/**
+ * Decodes a buffer into a ScriptSignature object.
+ * @param buffer - The buffer to decode.
+ * @returns The decoded ScriptSignature object.
+ * @throws Error if the hashType is invalid.
+ */
function decode(buffer) {
const hashType = buffer.readUInt8(buffer.length - 1);
if (!(0, script_1.isDefinedHashType)(hashType)) {
@@ -34,6 +52,13 @@ function decode(buffer) {
return { signature, hashType };
}
exports.decode = decode;
+/**
+ * Encodes a signature and hash type into a buffer.
+ * @param signature - The signature to encode.
+ * @param hashType - The hash type to encode.
+ * @returns The encoded buffer.
+ * @throws Error if the hashType is invalid.
+ */
function encode(signature, hashType) {
typeforce(
{
diff --git a/src/transaction.d.ts b/src/transaction.d.ts
index 613706b67..118fa57f1 100644
--- a/src/transaction.d.ts
+++ b/src/transaction.d.ts
@@ -10,6 +10,9 @@ export interface Input {
sequence: number;
witness: Buffer[];
}
+/**
+ * Represents a Bitcoin transaction.
+ */
export declare class Transaction {
static readonly DEFAULT_SEQUENCE = 4294967295;
static readonly SIGHASH_DEFAULT = 0;
diff --git a/src/transaction.js b/src/transaction.js
index ade4582cf..2b74f3788 100644
--- a/src/transaction.js
+++ b/src/transaction.js
@@ -38,6 +38,9 @@ const BLANK_OUTPUT = {
function isOutput(out) {
return out.value !== undefined;
}
+/**
+ * Represents a Bitcoin transaction.
+ */
class Transaction {
constructor() {
this.version = 1;
diff --git a/src/types.d.ts b/src/types.d.ts
index 5b32ab9de..b08a1fb6f 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -1,6 +1,17 @@
///
export declare const typeforce: any;
+/**
+ * Checks if two arrays of Buffers are equal.
+ * @param a - The first array of Buffers.
+ * @param b - The second array of Buffers.
+ * @returns True if the arrays are equal, false otherwise.
+ */
export declare function stacksEqual(a: Buffer[], b: Buffer[]): boolean;
+/**
+ * Checks if the given value is a valid elliptic curve point.
+ * @param p - The value to check.
+ * @returns True if the value is a valid elliptic curve point, false otherwise.
+ */
export declare function isPoint(p: Buffer | number | undefined | null): boolean;
export declare function UInt31(value: number): boolean;
export declare function BIP32Path(value: string): boolean;
diff --git a/src/types.js b/src/types.js
index 337badd34..5bcd54c81 100644
--- a/src/types.js
+++ b/src/types.js
@@ -37,6 +37,12 @@ const EC_P = buffer_1.Buffer.from(
'fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f',
'hex',
);
+/**
+ * Checks if two arrays of Buffers are equal.
+ * @param a - The first array of Buffers.
+ * @param b - The second array of Buffers.
+ * @returns True if the arrays are equal, false otherwise.
+ */
function stacksEqual(a, b) {
if (a.length !== b.length) return false;
return a.every((x, i) => {
@@ -44,6 +50,11 @@ function stacksEqual(a, b) {
});
}
exports.stacksEqual = stacksEqual;
+/**
+ * Checks if the given value is a valid elliptic curve point.
+ * @param p - The value to check.
+ * @returns True if the value is a valid elliptic curve point, false otherwise.
+ */
function isPoint(p) {
if (!buffer_1.Buffer.isBuffer(p)) return false;
if (p.length < 33) return false;
diff --git a/test/integration/transactions.spec.ts b/test/integration/transactions.spec.ts
index 264d99a2f..2754ee226 100644
--- a/test/integration/transactions.spec.ts
+++ b/test/integration/transactions.spec.ts
@@ -126,7 +126,7 @@ describe('bitcoinjs-lib (transactions with psbt)', () => {
// (in)(5e4 + 7e4) - (out)(8e4 + 1e4) = (fee)3e4 = 30000, this is the miner fee
// Let's show a new feature with PSBT.
- // We can have multiple signers sign in parrallel and combine them.
+ // We can have multiple signers sign in parallel and combine them.
// (this is not necessary, but a nice feature)
// encode to send out to the signers
diff --git a/test/transaction.spec.ts b/test/transaction.spec.ts
index bf62acedf..991557ba3 100644
--- a/test/transaction.spec.ts
+++ b/test/transaction.spec.ts
@@ -350,7 +350,7 @@ describe('Transaction', () => {
});
describe('setWitness', () => {
- it('only accepts a a witness stack (Array of Buffers)', () => {
+ it('only accepts a witness stack (Array of Buffers)', () => {
assert.throws(() => {
(new Transaction().setWitness as any)(0, 'foobar');
}, /Expected property "1" of type \[Buffer], got String "foobar"/);
diff --git a/ts_src/address.ts b/ts_src/address.ts
index ce224fd11..cbd03da1f 100644
--- a/ts_src/address.ts
+++ b/ts_src/address.ts
@@ -1,3 +1,12 @@
+/**
+ * bitcoin address decode and encode tools, include base58、bech32 and output script
+ *
+ * networks support bitcoin、bitcoin testnet and bitcoin regtest
+ *
+ * addresses support P2PKH、P2SH、P2WPKH、P2WSH、P2TR and so on
+ *
+ * @packageDocumentation
+ */
import { Network } from './networks';
import * as networks from './networks';
import * as payments from './payments';
@@ -5,14 +14,22 @@ import * as bscript from './script';
import { typeforce, tuple, Hash160bit, UInt8 } from './types';
import { bech32, bech32m } from 'bech32';
import * as bs58check from 'bs58check';
+
+/** base58check decode result */
export interface Base58CheckResult {
+ /** address hash */
hash: Buffer;
+ /** address version: 0x00 for P2PKH, 0x05 for P2SH */
version: number;
}
+/** bech32 decode result */
export interface Bech32Result {
+ /** address version: 0x00 for P2WPKH、P2WSH, 0x01 for P2TR*/
version: number;
+ /** address prefix: bc for P2WPKH、P2WSH、P2TR */
prefix: string;
+ /** address data:20 bytes for P2WPKH, 32 bytes for P2WSH、P2TR */
data: Buffer;
}
@@ -52,6 +69,9 @@ function _toFutureSegwitAddress(output: Buffer, network: Network): string {
return toBech32(data, version, network.bech32);
}
+/**
+ * decode address with base58 specification, return address version and address hash if valid
+ */
export function fromBase58Check(address: string): Base58CheckResult {
const payload = Buffer.from(bs58check.decode(address));
@@ -65,6 +85,9 @@ export function fromBase58Check(address: string): Base58CheckResult {
return { version, hash };
}
+/**
+ * decode address with bech32 specification, return address version、address prefix and address data if valid
+ */
export function fromBech32(address: string): Bech32Result {
let result;
let version;
@@ -90,6 +113,9 @@ export function fromBech32(address: string): Bech32Result {
};
}
+/**
+ * encode address hash to base58 address with version
+ */
export function toBase58Check(hash: Buffer, version: number): string {
typeforce(tuple(Hash160bit, UInt8), arguments);
@@ -100,6 +126,9 @@ export function toBase58Check(hash: Buffer, version: number): string {
return bs58check.encode(payload);
}
+/**
+ * encode address hash to bech32 address with version and prefix
+ */
export function toBech32(
data: Buffer,
version: number,
@@ -113,6 +142,9 @@ export function toBech32(
: bech32m.encode(prefix, words);
}
+/**
+ * decode address from output script with network, return address if matched
+ */
export function fromOutputScript(output: Buffer, network?: Network): string {
// TODO: Network
network = network || networks.bitcoin;
@@ -139,6 +171,9 @@ export function fromOutputScript(output: Buffer, network?: Network): string {
throw new Error(bscript.toASM(output) + ' has no matching Address');
}
+/**
+ * encodes address to output script with network, return output script if address matched
+ */
export function toOutputScript(address: string, network?: Network): Buffer {
network = network || networks.bitcoin;
diff --git a/ts_src/bufferutils.ts b/ts_src/bufferutils.ts
index 901d72a48..b73ce1502 100644
--- a/ts_src/bufferutils.ts
+++ b/ts_src/bufferutils.ts
@@ -23,6 +23,14 @@ export function readUInt64LE(buffer: Buffer, offset: number): number {
return b + a;
}
+/**
+ * Writes a 64-bit unsigned integer in little-endian format to the specified buffer at the given offset.
+ *
+ * @param buffer - The buffer to write the value to.
+ * @param value - The 64-bit unsigned integer value to write.
+ * @param offset - The offset in the buffer where the value should be written.
+ * @returns The new offset after writing the value.
+ */
export function writeUInt64LE(
buffer: Buffer,
value: number,
@@ -35,6 +43,11 @@ export function writeUInt64LE(
return offset + 8;
}
+/**
+ * Reverses the order of bytes in a buffer.
+ * @param buffer - The buffer to reverse.
+ * @returns A new buffer with the bytes reversed.
+ */
export function reverseBuffer(buffer: Buffer): Buffer {
if (buffer.length < 1) return buffer;
let j = buffer.length - 1;
diff --git a/ts_src/crypto.ts b/ts_src/crypto.ts
index e3b876961..223305a11 100644
--- a/ts_src/crypto.ts
+++ b/ts_src/crypto.ts
@@ -1,3 +1,9 @@
+/**
+ * A module for hashing functions.
+ * include ripemd160、sha1、sha256、hash160、hash256、taggedHash
+ *
+ * @packageDocumentation
+ */
import { ripemd160 as _ripemd160 } from '@noble/hashes/ripemd160';
import { sha1 as _sha1 } from '@noble/hashes/sha1';
import { sha256 as _sha256 } from '@noble/hashes/sha256';
@@ -38,6 +44,9 @@ type TaggedHashPrefixes = {
[key in TaggedHashPrefix]: Buffer;
};
/** An object mapping tags to their tagged hash prefix of [SHA256(tag) | SHA256(tag)] */
+/**
+ * Defines the tagged hash prefixes used in the crypto module.
+ */
export const TAGGED_HASH_PREFIXES: TaggedHashPrefixes = {
'BIP0340/challenge': Buffer.from([
123, 181, 45, 122, 159, 239, 88, 50, 62, 177, 191, 122, 64, 125, 179, 130,
diff --git a/ts_src/ecc_lib.ts b/ts_src/ecc_lib.ts
index eb4c59eeb..fbd1fcdb8 100644
--- a/ts_src/ecc_lib.ts
+++ b/ts_src/ecc_lib.ts
@@ -2,6 +2,13 @@ import { TinySecp256k1Interface } from './types';
const _ECCLIB_CACHE: { eccLib?: TinySecp256k1Interface } = {};
+/**
+ * Initializes the ECC library with the provided instance.
+ * If `eccLib` is `undefined`, the library will be cleared.
+ * If `eccLib` is a new instance, it will be verified before setting it as the active library.
+ *
+ * @param eccLib The instance of the ECC library to initialize.
+ */
export function initEccLib(eccLib: TinySecp256k1Interface | undefined): void {
if (!eccLib) {
// allow clearing the library
@@ -13,6 +20,13 @@ export function initEccLib(eccLib: TinySecp256k1Interface | undefined): void {
}
}
+/**
+ * Retrieves the ECC Library instance.
+ * Throws an error if the ECC Library is not provided.
+ * You must call initEccLib() with a valid TinySecp256k1Interface instance before calling this function.
+ * @returns The ECC Library instance.
+ * @throws Error if the ECC Library is not provided.
+ */
export function getEccLib(): TinySecp256k1Interface {
if (!_ECCLIB_CACHE.eccLib)
throw new Error(
@@ -23,6 +37,11 @@ export function getEccLib(): TinySecp256k1Interface {
const h = (hex: string): Buffer => Buffer.from(hex, 'hex');
+/**
+ * Verifies the ECC functionality.
+ *
+ * @param ecc - The TinySecp256k1Interface object.
+ */
function verifyEcc(ecc: TinySecp256k1Interface): void {
assert(typeof ecc.isXOnlyPoint === 'function');
assert(
diff --git a/ts_src/index.ts b/ts_src/index.ts
index 64c4294c2..4b4041152 100644
--- a/ts_src/index.ts
+++ b/ts_src/index.ts
@@ -7,6 +7,7 @@ import * as script from './script';
export { address, crypto, networks, payments, script };
export { Block } from './block';
+/** @hidden */
export { TaggedHashPrefix } from './crypto';
export {
Psbt,
@@ -17,10 +18,12 @@ export {
HDSigner,
HDSignerAsync,
} from './psbt';
+/** @hidden */
export { OPS as opcodes } from './ops';
export { Transaction } from './transaction';
-
+/** @hidden */
export { Network } from './networks';
+/** @hidden */
export {
Payment,
PaymentCreator,
diff --git a/ts_src/merkle.ts b/ts_src/merkle.ts
index 8ff8c3f8c..206f8fcd0 100644
--- a/ts_src/merkle.ts
+++ b/ts_src/merkle.ts
@@ -1,3 +1,11 @@
+/**
+ * Calculates the Merkle root of an array of buffers using a specified digest function.
+ *
+ * @param values - The array of buffers.
+ * @param digestFn - The digest function used to calculate the hash of the concatenated buffers.
+ * @returns The Merkle root as a buffer.
+ * @throws {TypeError} If the values parameter is not an array or the digestFn parameter is not a function.
+ */
export function fastMerkleRoot(
values: Buffer[],
digestFn: (b: Buffer) => Buffer,
diff --git a/ts_src/networks.ts b/ts_src/networks.ts
index e66b08c30..9aa465d70 100644
--- a/ts_src/networks.ts
+++ b/ts_src/networks.ts
@@ -1,5 +1,11 @@
// https://en.bitcoin.it/wiki/List_of_address_prefixes
// Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731
+
+/**
+ * Represents a Bitcoin network configuration,including messagePrefix, bech32, bip32, pubKeyHash, scriptHash, wif.
+ * Support bitcoin、bitcoin testnet and bitcoin regtest.
+ * @packageDocumentation
+ */
export interface Network {
messagePrefix: string;
bech32: string;
@@ -14,17 +20,47 @@ interface Bip32 {
private: number;
}
+/**
+ * Represents the Bitcoin network configuration.
+ */
export const bitcoin: Network = {
+ /**
+ * The message prefix used for signing Bitcoin messages.
+ */
messagePrefix: '\x18Bitcoin Signed Message:\n',
+ /**
+ * The Bech32 prefix used for Bitcoin addresses.
+ */
bech32: 'bc',
+ /**
+ * The BIP32 key prefixes for Bitcoin.
+ */
bip32: {
+ /**
+ * The public key prefix for BIP32 extended public keys.
+ */
public: 0x0488b21e,
+ /**
+ * The private key prefix for BIP32 extended private keys.
+ */
private: 0x0488ade4,
},
+ /**
+ * The prefix for Bitcoin public key hashes.
+ */
pubKeyHash: 0x00,
+ /**
+ * The prefix for Bitcoin script hashes.
+ */
scriptHash: 0x05,
+ /**
+ * The prefix for Bitcoin Wallet Import Format (WIF) private keys.
+ */
wif: 0x80,
};
+/**
+ * Represents the regtest network configuration.
+ */
export const regtest: Network = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'bcrt',
@@ -36,6 +72,9 @@ export const regtest: Network = {
scriptHash: 0xc4,
wif: 0xef,
};
+/**
+ * Represents the testnet network configuration.
+ */
export const testnet: Network = {
messagePrefix: '\x18Bitcoin Signed Message:\n',
bech32: 'tb',
diff --git a/ts_src/payments/bip341.ts b/ts_src/payments/bip341.ts
index 40793779f..af9b1f171 100644
--- a/ts_src/payments/bip341.ts
+++ b/ts_src/payments/bip341.ts
@@ -34,6 +34,13 @@ const isHashBranch = (ht: HashTree): ht is HashBranch =>
*/
export type HashTree = HashLeaf | HashBranch;
+/**
+ * Calculates the root hash from a given control block and leaf hash.
+ * @param controlBlock - The control block buffer.
+ * @param leafHash - The leaf hash buffer.
+ * @returns The root hash buffer.
+ * @throws {TypeError} If the control block length is less than 33.
+ */
export function rootHashFromPath(
controlBlock: Buffer,
leafHash: Buffer,
diff --git a/ts_src/payments/embed.ts b/ts_src/payments/embed.ts
index 1d9a82807..aef14e1b7 100644
--- a/ts_src/payments/embed.ts
+++ b/ts_src/payments/embed.ts
@@ -7,6 +7,13 @@ import * as lazy from './lazy';
const OPS = bscript.OPS;
// output: OP_RETURN ...
+/**
+ * Embeds data in a Bitcoin payment.
+ * @param a - The payment object.
+ * @param opts - Optional payment options.
+ * @returns The modified payment object.
+ * @throws {TypeError} If there is not enough data or if the output is invalid.
+ */
export function p2data(a: Payment, opts?: PaymentOpts): Payment {
if (!a.data && !a.output) throw new TypeError('Not enough data');
opts = Object.assign({ validate: true }, opts || {});
diff --git a/ts_src/payments/index.ts b/ts_src/payments/index.ts
index ca72f72cb..bd1ac0d84 100644
--- a/ts_src/payments/index.ts
+++ b/ts_src/payments/index.ts
@@ -1,3 +1,10 @@
+/**
+ * Represents a payment object, which is used to create a payment.
+ *
+ * Supports P2PKH、P2SH、P2WPKH、P2WSH、P2TR and so on
+ *
+ * @packageDocumentation
+ */
import { Network } from '../networks';
import { Taptree } from '../types';
import { p2data as embed } from './embed';
diff --git a/ts_src/payments/p2ms.ts b/ts_src/payments/p2ms.ts
index 8ba33479c..ffbf0155b 100644
--- a/ts_src/payments/p2ms.ts
+++ b/ts_src/payments/p2ms.ts
@@ -9,6 +9,13 @@ const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1
// input: OP_0 [signatures ...]
// output: m [pubKeys ...] n OP_CHECKMULTISIG
+/**
+ * Represents a function that creates a Pay-to-Multisig (P2MS) payment object.
+ * @param a - The payment object.
+ * @param opts - Optional payment options.
+ * @returns The created payment object.
+ * @throws {TypeError} If the provided data is not valid.
+ */
export function p2ms(a: Payment, opts?: PaymentOpts): Payment {
if (
!a.input &&
diff --git a/ts_src/payments/p2pk.ts b/ts_src/payments/p2pk.ts
index 7273f53fb..c6c83b35d 100644
--- a/ts_src/payments/p2pk.ts
+++ b/ts_src/payments/p2pk.ts
@@ -7,6 +7,14 @@ const OPS = bscript.OPS;
// input: {signature}
// output: {pubKey} OP_CHECKSIG
+/**
+ * Creates a pay-to-public-key (P2PK) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2PK payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
export function p2pk(a: Payment, opts?: PaymentOpts): Payment {
if (!a.input && !a.output && !a.pubkey && !a.input && !a.signature)
throw new TypeError('Not enough data');
diff --git a/ts_src/payments/p2pkh.ts b/ts_src/payments/p2pkh.ts
index 4947c832a..2873a6ebe 100644
--- a/ts_src/payments/p2pkh.ts
+++ b/ts_src/payments/p2pkh.ts
@@ -9,6 +9,14 @@ const OPS = bscript.OPS;
// input: {signature} {pubkey}
// output: OP_DUP OP_HASH160 {hash160(pubkey)} OP_EQUALVERIFY OP_CHECKSIG
+/**
+ * Creates a Pay-to-Public-Key-Hash (P2PKH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2PKH payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
export function p2pkh(a: Payment, opts?: PaymentOpts): Payment {
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.input)
throw new TypeError('Not enough data');
diff --git a/ts_src/payments/p2sh.ts b/ts_src/payments/p2sh.ts
index f4a07c55d..2f5f936c6 100644
--- a/ts_src/payments/p2sh.ts
+++ b/ts_src/payments/p2sh.ts
@@ -16,6 +16,14 @@ const OPS = bscript.OPS;
// input: [redeemScriptSig ...] {redeemScript}
// witness: >
// output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL
+/**
+ * Creates a Pay-to-Script-Hash (P2SH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2SH payment object.
+ * @throws {TypeError} If the required data is not provided or if the data is invalid.
+ */
export function p2sh(a: Payment, opts?: PaymentOpts): Payment {
if (!a.address && !a.hash && !a.output && !a.redeem && !a.input)
throw new TypeError('Not enough data');
diff --git a/ts_src/payments/p2tr.ts b/ts_src/payments/p2tr.ts
index b92d76cc3..c1140b715 100644
--- a/ts_src/payments/p2tr.ts
+++ b/ts_src/payments/p2tr.ts
@@ -25,6 +25,14 @@ const OPS = bscript.OPS;
const TAPROOT_WITNESS_VERSION = 0x01;
const ANNEX_PREFIX = 0x50;
+/**
+ * Creates a Pay-to-Taproot (P2TR) payment object.
+ *
+ * @param a - The payment object containing the necessary data for P2TR.
+ * @param opts - Optional payment options.
+ * @returns The P2TR payment object.
+ * @throws {TypeError} If the provided data is invalid or insufficient.
+ */
export function p2tr(a: Payment, opts?: PaymentOpts): Payment {
if (
!a.address &&
diff --git a/ts_src/payments/p2wpkh.ts b/ts_src/payments/p2wpkh.ts
index a4497fece..997cb6292 100644
--- a/ts_src/payments/p2wpkh.ts
+++ b/ts_src/payments/p2wpkh.ts
@@ -12,6 +12,14 @@ const EMPTY_BUFFER = Buffer.alloc(0);
// witness: {signature} {pubKey}
// input: <>
// output: OP_0 {pubKeyHash}
+/**
+ * Creates a pay-to-witness-public-key-hash (p2wpkh) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The p2wpkh payment object.
+ * @throws {TypeError} If the required data is missing or invalid.
+ */
export function p2wpkh(a: Payment, opts?: PaymentOpts): Payment {
if (!a.address && !a.hash && !a.output && !a.pubkey && !a.witness)
throw new TypeError('Not enough data');
diff --git a/ts_src/payments/p2wsh.ts b/ts_src/payments/p2wsh.ts
index 41cefe686..bd9339277 100644
--- a/ts_src/payments/p2wsh.ts
+++ b/ts_src/payments/p2wsh.ts
@@ -25,6 +25,14 @@ function chunkHasUncompressedPubkey(chunk: StackElement): boolean {
// input: <>
// witness: [redeemScriptSig ...] {redeemScript}
// output: OP_0 {sha256(redeemScript)}
+/**
+ * Creates a Pay-to-Witness-Script-Hash (P2WSH) payment object.
+ *
+ * @param a - The payment object containing the necessary data.
+ * @param opts - Optional payment options.
+ * @returns The P2WSH payment object.
+ * @throws {TypeError} If the required data is missing or invalid.
+ */
export function p2wsh(a: Payment, opts?: PaymentOpts): Payment {
if (!a.address && !a.hash && !a.output && !a.redeem && !a.witness)
throw new TypeError('Not enough data');
diff --git a/ts_src/psbt.ts b/ts_src/psbt.ts
index a69dc1e08..a44646592 100644
--- a/ts_src/psbt.ts
+++ b/ts_src/psbt.ts
@@ -92,6 +92,7 @@ const DEFAULT_OPTS: PsbtOpts = {
* There are 6 roles that this class fulfills. (Explained in BIP174)
*
* Creator: This can be done with `new Psbt()`
+ *
* Updater: This can be done with `psbt.addInput(input)`, `psbt.addInputs(inputs)`,
* `psbt.addOutput(output)`, `psbt.addOutputs(outputs)` when you are looking to
* add new inputs and outputs to the PSBT, and `psbt.updateGlobal(itemObject)`,
@@ -102,20 +103,24 @@ const DEFAULT_OPTS: PsbtOpts = {
* data for updateOutput.
* For a list of what attributes should be what types. Check the bip174 library.
* Also, check the integration tests for some examples of usage.
+ *
* Signer: There are a few methods. signAllInputs and signAllInputsAsync, which will search all input
* information for your pubkey or pubkeyhash, and only sign inputs where it finds
* your info. Or you can explicitly sign a specific input with signInput and
* signInputAsync. For the async methods you can create a SignerAsync object
* and use something like a hardware wallet to sign with. (You must implement this)
+ *
* Combiner: psbts can be combined easily with `psbt.combine(psbt2, psbt3, psbt4 ...)`
* the psbt calling combine will always have precedence when a conflict occurs.
* Combine checks if the internal bitcoin transaction is the same, so be sure that
* all sequences, version, locktime, etc. are the same before combining.
+ *
* Input Finalizer: This role is fairly important. Not only does it need to construct
* the input scriptSigs and witnesses, but it SHOULD verify the signatures etc.
* Before running `psbt.finalizeAllInputs()` please run `psbt.validateSignaturesOfAllInputs()`
* Running any finalize method will delete any data in the input(s) that are no longer
* needed due to the finalized scripts containing the information.
+ *
* Transaction Extractor: This role will perform some checks before returning a
* Transaction object. Such as fee rate not being larger than maximumFeeRate etc.
*/
@@ -151,7 +156,7 @@ export class Psbt {
__NON_WITNESS_UTXO_BUF_CACHE: [],
__TX_IN_CACHE: {},
__TX: (this.data.globalMap.unsignedTx as PsbtTransaction).tx,
- // Psbt's predecesor (TransactionBuilder - now removed) behavior
+ // Psbt's predecessor (TransactionBuilder - now removed) behavior
// was to not confirm input values before signing.
// Even though we highly encourage people to get
// the full parent transaction to verify values, the ability to
@@ -1673,7 +1678,7 @@ function getHashForSig(
console.warn(
'Warning: Signing non-segwit inputs without the full parent transaction ' +
'means there is a chance that a miner could feed you incorrect information ' +
- "to trick you into paying large fees. This behavior is the same as Psbt's predecesor " +
+ "to trick you into paying large fees. This behavior is the same as Psbt's predecessor " +
'(TransactionBuilder - now removed) when signing non-segwit scripts. You are not ' +
'able to export this Psbt with toBuffer|toBase64|toHex since it is not ' +
'BIP174 compliant.\n*********************\nPROCEED WITH CAUTION!\n' +
diff --git a/ts_src/psbt/bip371.ts b/ts_src/psbt/bip371.ts
index 375d35cc6..752265b0b 100644
--- a/ts_src/psbt/bip371.ts
+++ b/ts_src/psbt/bip371.ts
@@ -337,6 +337,14 @@ function checkMixedTaprootAndNonTaprootOutputFields(
);
}
+/**
+ * Checks if the tap leaf is part of the tap tree for the given input data.
+ * Throws an error if the tap leaf is not part of the tap tree.
+ * @param inputData - The original PsbtInput data.
+ * @param newInputData - The new PsbtInput data.
+ * @param action - The action being performed.
+ * @throws {Error} - If the tap leaf is not part of the tap tree.
+ */
function checkIfTapLeafInTree(
inputData: PsbtInput,
newInputData: PsbtInput,
@@ -364,6 +372,12 @@ function checkIfTapLeafInTree(
}
}
+/**
+ * Checks if a TapLeafScript is present in a Merkle tree.
+ * @param tapLeaf The TapLeafScript to check.
+ * @param merkleRoot The Merkle root of the tree. If not provided, the function assumes the TapLeafScript is present.
+ * @returns A boolean indicating whether the TapLeafScript is present in the tree.
+ */
function isTapLeafInTree(tapLeaf: TapLeafScript, merkleRoot?: Buffer): boolean {
if (!merkleRoot) return true;
@@ -376,6 +390,13 @@ function isTapLeafInTree(tapLeaf: TapLeafScript, merkleRoot?: Buffer): boolean {
return rootHash.equals(merkleRoot);
}
+/**
+ * Sorts the signatures in the input's tapScriptSig array based on their position in the tapLeaf script.
+ *
+ * @param input - The PsbtInput object.
+ * @param tapLeaf - The TapLeafScript object.
+ * @returns An array of sorted signatures as Buffers.
+ */
function sortSignatures(input: PsbtInput, tapLeaf: TapLeafScript): Buffer[] {
const leafHash = tapleafHash({
output: tapLeaf.script,
@@ -389,6 +410,12 @@ function sortSignatures(input: PsbtInput, tapLeaf: TapLeafScript): Buffer[] {
.map(t => t.signature) as Buffer[];
}
+/**
+ * Adds the position of a public key in a script to a TapScriptSig object.
+ * @param script The script in which to find the position of the public key.
+ * @param tss The TapScriptSig object to add the position to.
+ * @returns A TapScriptSigWitPosition object with the added position.
+ */
function addPubkeyPositionInScript(
script: Buffer,
tss: TapScriptSig,
@@ -427,6 +454,14 @@ function findTapLeafToFinalize(
return tapLeaf;
}
+/**
+ * Determines whether a TapLeafScript can be finalized.
+ *
+ * @param leaf - The TapLeafScript to check.
+ * @param tapScriptSig - The array of TapScriptSig objects.
+ * @param hash - The optional hash to compare with the leaf hash.
+ * @returns A boolean indicating whether the TapLeafScript can be finalized.
+ */
function canFinalizeLeaf(
leaf: TapLeafScript,
tapScriptSig: TapScriptSig[],
@@ -443,6 +478,12 @@ function canFinalizeLeaf(
);
}
+/**
+ * Checks if the given PsbtInput or PsbtOutput has non-taproot fields.
+ * Non-taproot fields include redeemScript, witnessScript, and bip32Derivation.
+ * @param io The PsbtInput or PsbtOutput to check.
+ * @returns A boolean indicating whether the given input or output has non-taproot fields.
+ */
function hasNonTaprootFields(io: PsbtInput | PsbtOutput): boolean {
return (
io &&
diff --git a/ts_src/psbt/psbtutils.ts b/ts_src/psbt/psbtutils.ts
index 173e0215c..19cf33e5b 100644
--- a/ts_src/psbt/psbtutils.ts
+++ b/ts_src/psbt/psbtutils.ts
@@ -23,6 +23,16 @@ export const isP2WSHScript = isPaymentFactory(payments.p2wsh);
export const isP2SHScript = isPaymentFactory(payments.p2sh);
export const isP2TR = isPaymentFactory(payments.p2tr);
+/**
+ * Converts a witness stack to a script witness.
+ * @param witness The witness stack to convert.
+ * @returns The script witness as a Buffer.
+ */
+/**
+ * Converts a witness stack to a script witness.
+ * @param witness The witness stack to convert.
+ * @returns The converted script witness.
+ */
export function witnessStackToScriptWitness(witness: Buffer[]): Buffer {
let buffer = Buffer.allocUnsafe(0);
@@ -53,6 +63,13 @@ export function witnessStackToScriptWitness(witness: Buffer[]): Buffer {
return buffer;
}
+/**
+ * Finds the position of a public key in a script.
+ * @param pubkey The public key to search for.
+ * @param script The script to search in.
+ * @returns The index of the public key in the script, or -1 if not found.
+ * @throws {Error} If there is an unknown script error.
+ */
export function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
const pubkeyHash = hash160(pubkey);
const pubkeyXOnly = pubkey.slice(1, 33); // slice before calling?
@@ -70,10 +87,22 @@ export function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
});
}
+/**
+ * Checks if a public key is present in a script.
+ * @param pubkey The public key to check.
+ * @param script The script to search in.
+ * @returns A boolean indicating whether the public key is present in the script.
+ */
export function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
return pubkeyPositionInScript(pubkey, script) !== -1;
}
+/**
+ * Checks if an input contains a signature for a specific action.
+ * @param input - The input to check.
+ * @param action - The action to check for.
+ * @returns A boolean indicating whether the input contains a signature for the specified action.
+ */
export function checkInputForSig(input: PsbtInput, action: string): boolean {
const pSigs = extractPartialSigs(input);
return pSigs.some(pSig =>
@@ -85,6 +114,13 @@ type SignatureDecodeFunc = (buffer: Buffer) => {
signature: Buffer;
hashType: number;
};
+/**
+ * Determines if a given action is allowed for a signature block.
+ * @param signature - The signature block.
+ * @param signatureDecodeFn - The function used to decode the signature.
+ * @param action - The action to be checked.
+ * @returns True if the action is allowed, false otherwise.
+ */
export function signatureBlocksAction(
signature: Buffer,
signatureDecodeFn: SignatureDecodeFunc,
@@ -110,6 +146,16 @@ export function signatureBlocksAction(
return false;
}
+/**
+ * Extracts the signatures from a PsbtInput object.
+ * If the input has partial signatures, it returns an array of the signatures.
+ * If the input does not have partial signatures, it checks if it has a finalScriptSig or finalScriptWitness.
+ * If it does, it extracts the signatures from the final scripts and returns them.
+ * If none of the above conditions are met, it returns an empty array.
+ *
+ * @param input - The PsbtInput object from which to extract the signatures.
+ * @returns An array of signatures extracted from the PsbtInput object.
+ */
function extractPartialSigs(input: PsbtInput): Buffer[] {
let pSigs: PartialSig[] = [];
if ((input.partialSig || []).length === 0) {
@@ -121,6 +167,14 @@ function extractPartialSigs(input: PsbtInput): Buffer[] {
return pSigs.map(p => p.signature);
}
+/**
+ * Retrieves the partial signatures (Psigs) from the input's final scripts.
+ * Psigs are extracted from both the final scriptSig and final scriptWitness of the input.
+ * Only canonical script signatures are considered.
+ *
+ * @param input - The PsbtInput object representing the input.
+ * @returns An array of PartialSig objects containing the extracted Psigs.
+ */
function getPsigsFromInputFinalScripts(input: PsbtInput): PartialSig[] {
const scriptItems = !input.finalScriptSig
? []
diff --git a/ts_src/push_data.ts b/ts_src/push_data.ts
index 56bb02ab2..ade5f82f9 100644
--- a/ts_src/push_data.ts
+++ b/ts_src/push_data.ts
@@ -1,9 +1,24 @@
import { OPS } from './ops';
+/**
+ * Calculates the encoding length of a number used for push data in Bitcoin transactions.
+ * @param i The number to calculate the encoding length for.
+ * @returns The encoding length of the number.
+ */
export function encodingLength(i: number): number {
return i < OPS.OP_PUSHDATA1 ? 1 : i <= 0xff ? 2 : i <= 0xffff ? 3 : 5;
}
+/**
+ * Encodes a number into a buffer using a variable-length encoding scheme.
+ * The encoded buffer is written starting at the specified offset.
+ * Returns the size of the encoded buffer.
+ *
+ * @param buffer - The buffer to write the encoded data into.
+ * @param num - The number to encode.
+ * @param offset - The offset at which to start writing the encoded buffer.
+ * @returns The size of the encoded buffer.
+ */
export function encode(buffer: Buffer, num: number, offset: number): number {
const size = encodingLength(num);
@@ -30,6 +45,12 @@ export function encode(buffer: Buffer, num: number, offset: number): number {
return size;
}
+/**
+ * Decodes a buffer and returns information about the opcode, number, and size.
+ * @param buffer - The buffer to decode.
+ * @param offset - The offset within the buffer to start decoding.
+ * @returns An object containing the opcode, number, and size, or null if decoding fails.
+ */
export function decode(
buffer: Buffer,
offset: number,
diff --git a/ts_src/script.ts b/ts_src/script.ts
index 4f246fe7a..54ee98fde 100644
--- a/ts_src/script.ts
+++ b/ts_src/script.ts
@@ -1,3 +1,7 @@
+/**
+ * Script tools, including decompile, compile, toASM, fromASM, toStack, isCanonicalPubKey, isCanonicalScriptSignature
+ * @packageDocumentation
+ */
import * as bip66 from './bip66';
import { OPS, REVERSE_OPS } from './ops';
import { Stack } from './payments';
@@ -50,6 +54,13 @@ function singleChunkIsBuffer(buf: number | Buffer): buf is Buffer {
return Buffer.isBuffer(buf);
}
+/**
+ * Compiles an array of chunks into a Buffer.
+ *
+ * @param chunks - The array of chunks to compile.
+ * @returns The compiled Buffer.
+ * @throws Error if the compilation fails.
+ */
export function compile(chunks: Buffer | Stack): Buffer {
// TODO: remove me
if (chunksIsBuffer(chunks)) return chunks;
@@ -147,6 +158,12 @@ export function decompile(
return chunks;
}
+/**
+ * Converts the given chunks into an ASM (Assembly) string representation.
+ * If the chunks parameter is a Buffer, it will be decompiled into a Stack before conversion.
+ * @param chunks - The chunks to convert into ASM.
+ * @returns The ASM string representation of the chunks.
+ */
export function toASM(chunks: Buffer | Array): string {
if (chunksIsBuffer(chunks)) {
chunks = decompile(chunks) as Stack;
@@ -167,6 +184,11 @@ export function toASM(chunks: Buffer | Array): string {
.join(' ');
}
+/**
+ * Converts an ASM string to a Buffer.
+ * @param asm The ASM string to convert.
+ * @returns The converted Buffer.
+ */
export function fromASM(asm: string): Buffer {
typeforce(types.String, asm);
@@ -182,6 +204,12 @@ export function fromASM(asm: string): Buffer {
);
}
+/**
+ * Converts the given chunks into a stack of buffers.
+ *
+ * @param chunks - The chunks to convert.
+ * @returns The stack of buffers.
+ */
export function toStack(chunks: Buffer | Array): Buffer[] {
chunks = decompile(chunks) as Stack;
typeforce(isPushOnly, chunks);
diff --git a/ts_src/script_number.ts b/ts_src/script_number.ts
index a4c502fc9..1ad20e2ff 100644
--- a/ts_src/script_number.ts
+++ b/ts_src/script_number.ts
@@ -1,3 +1,13 @@
+/**
+ * Decodes a script number from a buffer.
+ *
+ * @param buffer - The buffer containing the script number.
+ * @param maxLength - The maximum length of the script number. Defaults to 4.
+ * @param minimal - Whether the script number should be minimal. Defaults to true.
+ * @returns The decoded script number.
+ * @throws {TypeError} If the script number overflows the maximum length.
+ * @throws {Error} If the script number is not minimally encoded when minimal is true.
+ */
export function decode(
buffer: Buffer,
maxLength?: number,
@@ -50,6 +60,12 @@ function scriptNumSize(i: number): number {
: 0;
}
+/**
+ * Encodes a number into a Buffer using a specific format.
+ *
+ * @param _number - The number to encode.
+ * @returns The encoded number as a Buffer.
+ */
export function encode(_number: number): Buffer {
let value = Math.abs(_number);
const size = scriptNumSize(value);
diff --git a/ts_src/script_signature.ts b/ts_src/script_signature.ts
index f10ed86b7..571720607 100644
--- a/ts_src/script_signature.ts
+++ b/ts_src/script_signature.ts
@@ -4,6 +4,11 @@ import * as types from './types';
const { typeforce } = types;
const ZERO = Buffer.alloc(1, 0);
+/**
+ * Converts a buffer to a DER-encoded buffer.
+ * @param x - The buffer to be converted.
+ * @returns The DER-encoded buffer.
+ */
function toDER(x: Buffer): Buffer {
let i = 0;
while (x[i] === 0) ++i;
@@ -13,6 +18,13 @@ function toDER(x: Buffer): Buffer {
return x;
}
+/**
+ * Converts a DER-encoded signature to a buffer.
+ * If the first byte of the input buffer is 0x00, it is skipped.
+ * The resulting buffer is 32 bytes long, filled with zeros if necessary.
+ * @param x - The DER-encoded signature.
+ * @returns The converted buffer.
+ */
function fromDER(x: Buffer): Buffer {
if (x[0] === 0x00) x = x.slice(1);
const buffer = Buffer.alloc(32, 0);
@@ -27,6 +39,12 @@ interface ScriptSignature {
}
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
+/**
+ * Decodes a buffer into a ScriptSignature object.
+ * @param buffer - The buffer to decode.
+ * @returns The decoded ScriptSignature object.
+ * @throws Error if the hashType is invalid.
+ */
export function decode(buffer: Buffer): ScriptSignature {
const hashType = buffer.readUInt8(buffer.length - 1);
if (!isDefinedHashType(hashType)) {
@@ -41,6 +59,13 @@ export function decode(buffer: Buffer): ScriptSignature {
return { signature, hashType };
}
+/**
+ * Encodes a signature and hash type into a buffer.
+ * @param signature - The signature to encode.
+ * @param hashType - The hash type to encode.
+ * @returns The encoded buffer.
+ * @throws Error if the hashType is invalid.
+ */
export function encode(signature: Buffer, hashType: number): Buffer {
typeforce(
{
diff --git a/ts_src/transaction.ts b/ts_src/transaction.ts
index 39b975545..665583ec5 100644
--- a/ts_src/transaction.ts
+++ b/ts_src/transaction.ts
@@ -60,6 +60,9 @@ export interface Input {
witness: Buffer[];
}
+/**
+ * Represents a Bitcoin transaction.
+ */
export class Transaction {
static readonly DEFAULT_SEQUENCE = 0xffffffff;
static readonly SIGHASH_DEFAULT = 0x00;
diff --git a/ts_src/types.ts b/ts_src/types.ts
index 937805617..971b42363 100644
--- a/ts_src/types.ts
+++ b/ts_src/types.ts
@@ -8,6 +8,12 @@ const EC_P = NBuffer.from(
'hex',
);
+/**
+ * Checks if two arrays of Buffers are equal.
+ * @param a - The first array of Buffers.
+ * @param b - The second array of Buffers.
+ * @returns True if the arrays are equal, false otherwise.
+ */
export function stacksEqual(a: Buffer[], b: Buffer[]): boolean {
if (a.length !== b.length) return false;
@@ -16,6 +22,11 @@ export function stacksEqual(a: Buffer[], b: Buffer[]): boolean {
});
}
+/**
+ * Checks if the given value is a valid elliptic curve point.
+ * @param p - The value to check.
+ * @returns True if the value is a valid elliptic curve point, false otherwise.
+ */
export function isPoint(p: Buffer | number | undefined | null): boolean {
if (!NBuffer.isBuffer(p)) return false;
if (p.length < 33) return false;
diff --git a/typedoc.json b/typedoc.json
new file mode 100644
index 000000000..041e85042
--- /dev/null
+++ b/typedoc.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://typedoc.org/schema.json",
+ "name": "bitcoinjs-lib",
+ "entryPoints": ["./ts_src"],
+ "out": "docs",
+ "searchCategoryBoosts": {
+ "Component": 2,
+ "Model": 1.2
+ },
+ "searchGroupBoosts": {
+ "Classes": 1.5
+ },
+ "visibilityFilters": {},
+ "hideGenerator": true,
+ "excludePrivate": true,
+ "includeVersion": true
+}
\ No newline at end of file