├── .github └── workflows │ └── main_ci.yml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── fixup.cjs ├── package-lock.json ├── package.json ├── src ├── cjs │ ├── bip32.cjs │ ├── bip32.d.ts │ ├── crypto.cjs │ ├── crypto.d.ts │ ├── index.cjs │ ├── index.d.ts │ ├── testecc.cjs │ ├── testecc.d.ts │ ├── types.cjs │ └── types.d.ts └── esm │ ├── bip32.js │ ├── crypto.js │ ├── index.js │ ├── testecc.js │ └── types.js ├── test.cjs ├── test ├── fixtures │ └── index.json └── index.js ├── ts-src ├── bip32.ts ├── crypto.ts ├── index.ts ├── testecc.ts └── types.ts ├── tsconfig.base.json ├── tsconfig.cjs.json ├── tsconfig.json └── tslint.json /.github/workflows/main_ci.yml: -------------------------------------------------------------------------------- 1 | name: Run Tests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | 9 | jobs: 10 | unit: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-node@v4 15 | with: 16 | snode-version: 18 17 | registry-url: https://registry.npmjs.org/ 18 | - run: npm ci 19 | - run: npm run unit 20 | coverage: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - uses: actions/checkout@v3 24 | - uses: actions/setup-node@v4 25 | with: 26 | snode-version: 18 27 | registry-url: https://registry.npmjs.org/ 28 | - run: npm ci 29 | - run: npm run coverage 30 | format: 31 | runs-on: ubuntu-latest 32 | steps: 33 | - uses: actions/checkout@v3 34 | - uses: actions/setup-node@v4 35 | with: 36 | snode-version: 18 37 | registry-url: https://registry.npmjs.org/ 38 | - run: npm ci 39 | - run: npm run format:ci 40 | check-hybrid: 41 | runs-on: ubuntu-latest 42 | steps: 43 | - uses: actions/checkout@v3 44 | - uses: actions/setup-node@v4 45 | with: 46 | node-version: 18 47 | registry-url: https://registry.npmjs.org/ 48 | - run: npm ci 49 | - run: npm run checkHybrid 50 | gitdiff: 51 | runs-on: ubuntu-latest 52 | steps: 53 | - uses: actions/checkout@v3 54 | - uses: actions/setup-node@v4 55 | with: 56 | snode-version: 18 57 | registry-url: https://registry.npmjs.org/ 58 | - run: npm ci 59 | - run: npm run gitdiff:ci 60 | lint: 61 | runs-on: ubuntu-latest 62 | steps: 63 | - uses: actions/checkout@v3 64 | - uses: actions/setup-node@v4 65 | with: 66 | snode-version: 18 67 | registry-url: https://registry.npmjs.org/ 68 | - run: npm ci 69 | - run: npm run lint 70 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .nyc_output 3 | coverage 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bitcoinjs/bip32/1326d4ed940467285c74ca698c6f2a9d2f042871/.prettierignore -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "trailingComma": "all" 4 | } 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Refer to Bitcoinjs-lib 2 | 3 | [Please refer to bitcoinjs-lib CONTRIBUTING for a guide on how to contribute by clicking here.](https://github.com/bitcoinjs/bitcoinjs-lib/blob/master/CONTRIBUTING.md) 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2018 bitcoinjs-lib contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bip32 2 | [![Github CI](https://github.com/bitcoinjs/bip32/actions/workflows/main_ci.yml/badge.svg)](https://github.com/bitcoinjs/bip32/actions/workflows/main_ci.yml) [![NPM](https://img.shields.io/npm/v/bip32.svg)](https://www.npmjs.org/package/bip32) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) 3 | 4 | A [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) compatible library written in TypeScript with transpiled JavaScript committed to git. 5 | 6 | 7 | ## Example 8 | 9 | TypeScript 10 | 11 | ``` typescript 12 | import BIP32Factory from 'bip32'; 13 | import * as ecc from 'tiny-secp256k1'; 14 | import { BIP32Interface } from 'bip32'; 15 | // You must wrap a tiny-secp256k1 compatible implementation 16 | const bip32 = BIP32Factory(ecc); 17 | 18 | const node: BIP32Interface = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'); 19 | 20 | const child: BIP32Interface = node.derivePath('m/0/0'); 21 | // ... 22 | ``` 23 | 24 | NodeJS 25 | 26 | ``` javascript 27 | const ecc = require('tiny-secp256k1') 28 | const { BIP32Factory } = require('bip32') 29 | // You must wrap a tiny-secp256k1 compatible implementation 30 | const bip32 = BIP32Factory(ecc) 31 | 32 | const node = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi') 33 | 34 | const child = node.derivePath('m/0/0') 35 | ``` 36 | 37 | ## LICENSE [MIT](LICENSE) 38 | A derivation (and extraction for modularity) of the `HDWallet`/`HDNode` written and tested by [bitcoinjs-lib](https://github.com/bitcoinjs/bitcoinjs-lib) contributors since 2014. 39 | -------------------------------------------------------------------------------- /fixup.cjs: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const updateRequires = (filePath) => { 5 | let content = fs.readFileSync(filePath, 'utf8'); 6 | //replace local imports eg. require("./ecpair.js") to require("ecpair.cjs") 7 | content = content.replace(/require\("\.\/([^"]*)\.js"\)/g, 'require("./$1.cjs")'); 8 | 9 | fs.writeFileSync(filePath, content, 'utf8'); 10 | }; 11 | 12 | const processFiles = (dir) => { 13 | fs.readdirSync(dir).forEach((file) => { 14 | const filePath = path.join(dir, file); 15 | if (fs.lstatSync(filePath).isDirectory()) { 16 | processFiles(filePath); 17 | } else if (filePath.endsWith('.cjs')) { 18 | updateRequires(filePath); 19 | } 20 | }); 21 | }; 22 | 23 | const dir = path.join(__dirname, 'src', 'cjs'); 24 | processFiles(dir); 25 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bip32", 3 | "version": "5.0.0-rc.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "bip32", 9 | "version": "5.0.0-rc.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@noble/hashes": "^1.2.0", 13 | "@scure/base": "^1.1.1", 14 | "uint8array-tools": "^0.0.8", 15 | "valibot": "^0.37.0", 16 | "wif": "^5.0.0" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "18.x", 20 | "@types/tape": "^5.6.4", 21 | "c8": "^10.1.2", 22 | "prettier": "1.16.4", 23 | "tape": "^5.3.0", 24 | "tiny-secp256k1": "^2.2.1", 25 | "tslint": "^6.1.0", 26 | "typescript": "^5.0.4" 27 | }, 28 | "engines": { 29 | "node": ">=18.0.0" 30 | } 31 | }, 32 | "node_modules/@babel/code-frame": { 33 | "version": "7.8.3", 34 | "dev": true, 35 | "license": "MIT", 36 | "dependencies": { 37 | "@babel/highlight": "^7.8.3" 38 | } 39 | }, 40 | "node_modules/@babel/highlight": { 41 | "version": "7.8.3", 42 | "dev": true, 43 | "license": "MIT", 44 | "dependencies": { 45 | "chalk": "^2.0.0", 46 | "esutils": "^2.0.2", 47 | "js-tokens": "^4.0.0" 48 | } 49 | }, 50 | "node_modules/@bcoe/v8-coverage": { 51 | "version": "0.2.3", 52 | "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", 53 | "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", 54 | "dev": true 55 | }, 56 | "node_modules/@isaacs/cliui": { 57 | "version": "8.0.2", 58 | "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", 59 | "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", 60 | "dev": true, 61 | "dependencies": { 62 | "string-width": "^5.1.2", 63 | "string-width-cjs": "npm:string-width@^4.2.0", 64 | "strip-ansi": "^7.0.1", 65 | "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", 66 | "wrap-ansi": "^8.1.0", 67 | "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" 68 | }, 69 | "engines": { 70 | "node": ">=12" 71 | } 72 | }, 73 | "node_modules/@isaacs/cliui/node_modules/ansi-regex": { 74 | "version": "6.0.1", 75 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", 76 | "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", 77 | "dev": true, 78 | "engines": { 79 | "node": ">=12" 80 | }, 81 | "funding": { 82 | "url": "https://github.com/chalk/ansi-regex?sponsor=1" 83 | } 84 | }, 85 | "node_modules/@isaacs/cliui/node_modules/ansi-styles": { 86 | "version": "6.2.1", 87 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", 88 | "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", 89 | "dev": true, 90 | "engines": { 91 | "node": ">=12" 92 | }, 93 | "funding": { 94 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 95 | } 96 | }, 97 | "node_modules/@isaacs/cliui/node_modules/emoji-regex": { 98 | "version": "9.2.2", 99 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", 100 | "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", 101 | "dev": true 102 | }, 103 | "node_modules/@isaacs/cliui/node_modules/string-width": { 104 | "version": "5.1.2", 105 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", 106 | "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", 107 | "dev": true, 108 | "dependencies": { 109 | "eastasianwidth": "^0.2.0", 110 | "emoji-regex": "^9.2.2", 111 | "strip-ansi": "^7.0.1" 112 | }, 113 | "engines": { 114 | "node": ">=12" 115 | }, 116 | "funding": { 117 | "url": "https://github.com/sponsors/sindresorhus" 118 | } 119 | }, 120 | "node_modules/@isaacs/cliui/node_modules/strip-ansi": { 121 | "version": "7.1.0", 122 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", 123 | "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", 124 | "dev": true, 125 | "dependencies": { 126 | "ansi-regex": "^6.0.1" 127 | }, 128 | "engines": { 129 | "node": ">=12" 130 | }, 131 | "funding": { 132 | "url": "https://github.com/chalk/strip-ansi?sponsor=1" 133 | } 134 | }, 135 | "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { 136 | "version": "8.1.0", 137 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", 138 | "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", 139 | "dev": true, 140 | "dependencies": { 141 | "ansi-styles": "^6.1.0", 142 | "string-width": "^5.0.1", 143 | "strip-ansi": "^7.0.1" 144 | }, 145 | "engines": { 146 | "node": ">=12" 147 | }, 148 | "funding": { 149 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 150 | } 151 | }, 152 | "node_modules/@istanbuljs/schema": { 153 | "version": "0.1.3", 154 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", 155 | "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", 156 | "dev": true, 157 | "engines": { 158 | "node": ">=8" 159 | } 160 | }, 161 | "node_modules/@jridgewell/resolve-uri": { 162 | "version": "3.1.2", 163 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 164 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 165 | "dev": true, 166 | "engines": { 167 | "node": ">=6.0.0" 168 | } 169 | }, 170 | "node_modules/@jridgewell/sourcemap-codec": { 171 | "version": "1.5.0", 172 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", 173 | "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", 174 | "dev": true 175 | }, 176 | "node_modules/@jridgewell/trace-mapping": { 177 | "version": "0.3.25", 178 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", 179 | "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", 180 | "dev": true, 181 | "dependencies": { 182 | "@jridgewell/resolve-uri": "^3.1.0", 183 | "@jridgewell/sourcemap-codec": "^1.4.14" 184 | } 185 | }, 186 | "node_modules/@ljharb/resumer": { 187 | "version": "0.1.3", 188 | "resolved": "https://registry.npmjs.org/@ljharb/resumer/-/resumer-0.1.3.tgz", 189 | "integrity": "sha512-d+tsDgfkj9X5QTriqM4lKesCkMMJC3IrbPKHvayP00ELx2axdXvDfWkqjxrLXIzGcQzmj7VAUT1wopqARTvafw==", 190 | "dev": true, 191 | "dependencies": { 192 | "@ljharb/through": "^2.3.13", 193 | "call-bind": "^1.0.7" 194 | }, 195 | "engines": { 196 | "node": ">= 0.4" 197 | } 198 | }, 199 | "node_modules/@ljharb/through": { 200 | "version": "2.3.13", 201 | "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", 202 | "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", 203 | "dev": true, 204 | "dependencies": { 205 | "call-bind": "^1.0.7" 206 | }, 207 | "engines": { 208 | "node": ">= 0.4" 209 | } 210 | }, 211 | "node_modules/@noble/hashes": { 212 | "version": "1.5.0", 213 | "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.5.0.tgz", 214 | "integrity": "sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==", 215 | "engines": { 216 | "node": "^14.21.3 || >=16" 217 | }, 218 | "funding": { 219 | "url": "https://paulmillr.com/funding/" 220 | } 221 | }, 222 | "node_modules/@pkgjs/parseargs": { 223 | "version": "0.11.0", 224 | "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", 225 | "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", 226 | "dev": true, 227 | "optional": true, 228 | "engines": { 229 | "node": ">=14" 230 | } 231 | }, 232 | "node_modules/@scure/base": { 233 | "version": "1.1.8", 234 | "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.8.tgz", 235 | "integrity": "sha512-6CyAclxj3Nb0XT7GHK6K4zK6k2xJm6E4Ft0Ohjt4WgegiFUHEtFb2CGzmPmGBwoIhrLsqNLYfLr04Y1GePrzZg==", 236 | "funding": { 237 | "url": "https://paulmillr.com/funding/" 238 | } 239 | }, 240 | "node_modules/@types/istanbul-lib-coverage": { 241 | "version": "2.0.6", 242 | "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", 243 | "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", 244 | "dev": true 245 | }, 246 | "node_modules/@types/node": { 247 | "version": "18.19.50", 248 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.50.tgz", 249 | "integrity": "sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==", 250 | "dev": true, 251 | "dependencies": { 252 | "undici-types": "~5.26.4" 253 | } 254 | }, 255 | "node_modules/@types/tape": { 256 | "version": "5.6.4", 257 | "resolved": "https://registry.npmjs.org/@types/tape/-/tape-5.6.4.tgz", 258 | "integrity": "sha512-EmL4fJpZyByNCkupLLcJhneqcnT+rQUG5fWKNCsZyBK1x7nUuDTwwEerc4biEMZgvSK2+FXr775aLeXhKXK4Yw==", 259 | "dev": true, 260 | "dependencies": { 261 | "@types/node": "*", 262 | "@types/through": "*" 263 | } 264 | }, 265 | "node_modules/@types/through": { 266 | "version": "0.0.33", 267 | "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.33.tgz", 268 | "integrity": "sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==", 269 | "dev": true, 270 | "dependencies": { 271 | "@types/node": "*" 272 | } 273 | }, 274 | "node_modules/ansi-regex": { 275 | "version": "5.0.1", 276 | "dev": true, 277 | "license": "MIT", 278 | "engines": { 279 | "node": ">=8" 280 | } 281 | }, 282 | "node_modules/ansi-styles": { 283 | "version": "3.2.1", 284 | "dev": true, 285 | "license": "MIT", 286 | "dependencies": { 287 | "color-convert": "^1.9.0" 288 | }, 289 | "engines": { 290 | "node": ">=4" 291 | } 292 | }, 293 | "node_modules/argparse": { 294 | "version": "1.0.10", 295 | "dev": true, 296 | "license": "MIT", 297 | "dependencies": { 298 | "sprintf-js": "~1.0.2" 299 | } 300 | }, 301 | "node_modules/array-buffer-byte-length": { 302 | "version": "1.0.1", 303 | "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", 304 | "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", 305 | "dev": true, 306 | "dependencies": { 307 | "call-bind": "^1.0.5", 308 | "is-array-buffer": "^3.0.4" 309 | }, 310 | "engines": { 311 | "node": ">= 0.4" 312 | }, 313 | "funding": { 314 | "url": "https://github.com/sponsors/ljharb" 315 | } 316 | }, 317 | "node_modules/array.prototype.every": { 318 | "version": "1.1.6", 319 | "resolved": "https://registry.npmjs.org/array.prototype.every/-/array.prototype.every-1.1.6.tgz", 320 | "integrity": "sha512-gNEqZD97w6bfQRNmHkFv7rNnGM+VWyHZT+h/rf9C+22owcXuENr66Lfo0phItpU5KoXW6Owb34q2+8MnSIZ57w==", 321 | "dev": true, 322 | "dependencies": { 323 | "call-bind": "^1.0.7", 324 | "define-properties": "^1.2.1", 325 | "es-abstract": "^1.23.0", 326 | "es-object-atoms": "^1.0.0", 327 | "is-string": "^1.0.7" 328 | }, 329 | "engines": { 330 | "node": ">= 0.4" 331 | }, 332 | "funding": { 333 | "url": "https://github.com/sponsors/ljharb" 334 | } 335 | }, 336 | "node_modules/arraybuffer.prototype.slice": { 337 | "version": "1.0.3", 338 | "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", 339 | "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", 340 | "dev": true, 341 | "dependencies": { 342 | "array-buffer-byte-length": "^1.0.1", 343 | "call-bind": "^1.0.5", 344 | "define-properties": "^1.2.1", 345 | "es-abstract": "^1.22.3", 346 | "es-errors": "^1.2.1", 347 | "get-intrinsic": "^1.2.3", 348 | "is-array-buffer": "^3.0.4", 349 | "is-shared-array-buffer": "^1.0.2" 350 | }, 351 | "engines": { 352 | "node": ">= 0.4" 353 | }, 354 | "funding": { 355 | "url": "https://github.com/sponsors/ljharb" 356 | } 357 | }, 358 | "node_modules/available-typed-arrays": { 359 | "version": "1.0.7", 360 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", 361 | "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", 362 | "dev": true, 363 | "dependencies": { 364 | "possible-typed-array-names": "^1.0.0" 365 | }, 366 | "engines": { 367 | "node": ">= 0.4" 368 | }, 369 | "funding": { 370 | "url": "https://github.com/sponsors/ljharb" 371 | } 372 | }, 373 | "node_modules/balanced-match": { 374 | "version": "1.0.0", 375 | "dev": true, 376 | "license": "MIT" 377 | }, 378 | "node_modules/base-x": { 379 | "version": "5.0.1", 380 | "resolved": "https://registry.npmjs.org/base-x/-/base-x-5.0.1.tgz", 381 | "integrity": "sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==", 382 | "license": "MIT" 383 | }, 384 | "node_modules/brace-expansion": { 385 | "version": "1.1.11", 386 | "dev": true, 387 | "license": "MIT", 388 | "dependencies": { 389 | "balanced-match": "^1.0.0", 390 | "concat-map": "0.0.1" 391 | } 392 | }, 393 | "node_modules/bs58": { 394 | "version": "6.0.0", 395 | "resolved": "https://registry.npmjs.org/bs58/-/bs58-6.0.0.tgz", 396 | "integrity": "sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==", 397 | "dependencies": { 398 | "base-x": "^5.0.0" 399 | } 400 | }, 401 | "node_modules/bs58check": { 402 | "version": "4.0.0", 403 | "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-4.0.0.tgz", 404 | "integrity": "sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==", 405 | "dependencies": { 406 | "@noble/hashes": "^1.2.0", 407 | "bs58": "^6.0.0" 408 | } 409 | }, 410 | "node_modules/builtin-modules": { 411 | "version": "1.1.1", 412 | "dev": true, 413 | "license": "MIT", 414 | "engines": { 415 | "node": ">=0.10.0" 416 | } 417 | }, 418 | "node_modules/c8": { 419 | "version": "10.1.2", 420 | "resolved": "https://registry.npmjs.org/c8/-/c8-10.1.2.tgz", 421 | "integrity": "sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==", 422 | "dev": true, 423 | "dependencies": { 424 | "@bcoe/v8-coverage": "^0.2.3", 425 | "@istanbuljs/schema": "^0.1.3", 426 | "find-up": "^5.0.0", 427 | "foreground-child": "^3.1.1", 428 | "istanbul-lib-coverage": "^3.2.0", 429 | "istanbul-lib-report": "^3.0.1", 430 | "istanbul-reports": "^3.1.6", 431 | "test-exclude": "^7.0.1", 432 | "v8-to-istanbul": "^9.0.0", 433 | "yargs": "^17.7.2", 434 | "yargs-parser": "^21.1.1" 435 | }, 436 | "bin": { 437 | "c8": "bin/c8.js" 438 | }, 439 | "engines": { 440 | "node": ">=18" 441 | }, 442 | "peerDependencies": { 443 | "monocart-coverage-reports": "^2" 444 | }, 445 | "peerDependenciesMeta": { 446 | "monocart-coverage-reports": { 447 | "optional": true 448 | } 449 | } 450 | }, 451 | "node_modules/c8/node_modules/ansi-styles": { 452 | "version": "4.3.0", 453 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 454 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 455 | "dev": true, 456 | "dependencies": { 457 | "color-convert": "^2.0.1" 458 | }, 459 | "engines": { 460 | "node": ">=8" 461 | }, 462 | "funding": { 463 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 464 | } 465 | }, 466 | "node_modules/c8/node_modules/brace-expansion": { 467 | "version": "2.0.1", 468 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", 469 | "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", 470 | "dev": true, 471 | "dependencies": { 472 | "balanced-match": "^1.0.0" 473 | } 474 | }, 475 | "node_modules/c8/node_modules/cliui": { 476 | "version": "8.0.1", 477 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 478 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 479 | "dev": true, 480 | "dependencies": { 481 | "string-width": "^4.2.0", 482 | "strip-ansi": "^6.0.1", 483 | "wrap-ansi": "^7.0.0" 484 | }, 485 | "engines": { 486 | "node": ">=12" 487 | } 488 | }, 489 | "node_modules/c8/node_modules/color-convert": { 490 | "version": "2.0.1", 491 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 492 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 493 | "dev": true, 494 | "dependencies": { 495 | "color-name": "~1.1.4" 496 | }, 497 | "engines": { 498 | "node": ">=7.0.0" 499 | } 500 | }, 501 | "node_modules/c8/node_modules/color-name": { 502 | "version": "1.1.4", 503 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 504 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 505 | "dev": true 506 | }, 507 | "node_modules/c8/node_modules/find-up": { 508 | "version": "5.0.0", 509 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", 510 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", 511 | "dev": true, 512 | "dependencies": { 513 | "locate-path": "^6.0.0", 514 | "path-exists": "^4.0.0" 515 | }, 516 | "engines": { 517 | "node": ">=10" 518 | }, 519 | "funding": { 520 | "url": "https://github.com/sponsors/sindresorhus" 521 | } 522 | }, 523 | "node_modules/c8/node_modules/foreground-child": { 524 | "version": "3.3.0", 525 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", 526 | "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", 527 | "dev": true, 528 | "dependencies": { 529 | "cross-spawn": "^7.0.0", 530 | "signal-exit": "^4.0.1" 531 | }, 532 | "engines": { 533 | "node": ">=14" 534 | }, 535 | "funding": { 536 | "url": "https://github.com/sponsors/isaacs" 537 | } 538 | }, 539 | "node_modules/c8/node_modules/glob": { 540 | "version": "10.4.5", 541 | "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", 542 | "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", 543 | "dev": true, 544 | "dependencies": { 545 | "foreground-child": "^3.1.0", 546 | "jackspeak": "^3.1.2", 547 | "minimatch": "^9.0.4", 548 | "minipass": "^7.1.2", 549 | "package-json-from-dist": "^1.0.0", 550 | "path-scurry": "^1.11.1" 551 | }, 552 | "bin": { 553 | "glob": "dist/esm/bin.mjs" 554 | }, 555 | "funding": { 556 | "url": "https://github.com/sponsors/isaacs" 557 | } 558 | }, 559 | "node_modules/c8/node_modules/locate-path": { 560 | "version": "6.0.0", 561 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", 562 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", 563 | "dev": true, 564 | "dependencies": { 565 | "p-locate": "^5.0.0" 566 | }, 567 | "engines": { 568 | "node": ">=10" 569 | }, 570 | "funding": { 571 | "url": "https://github.com/sponsors/sindresorhus" 572 | } 573 | }, 574 | "node_modules/c8/node_modules/minimatch": { 575 | "version": "9.0.5", 576 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", 577 | "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", 578 | "dev": true, 579 | "dependencies": { 580 | "brace-expansion": "^2.0.1" 581 | }, 582 | "engines": { 583 | "node": ">=16 || 14 >=14.17" 584 | }, 585 | "funding": { 586 | "url": "https://github.com/sponsors/isaacs" 587 | } 588 | }, 589 | "node_modules/c8/node_modules/p-limit": { 590 | "version": "3.1.0", 591 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", 592 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", 593 | "dev": true, 594 | "dependencies": { 595 | "yocto-queue": "^0.1.0" 596 | }, 597 | "engines": { 598 | "node": ">=10" 599 | }, 600 | "funding": { 601 | "url": "https://github.com/sponsors/sindresorhus" 602 | } 603 | }, 604 | "node_modules/c8/node_modules/p-locate": { 605 | "version": "5.0.0", 606 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", 607 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", 608 | "dev": true, 609 | "dependencies": { 610 | "p-limit": "^3.0.2" 611 | }, 612 | "engines": { 613 | "node": ">=10" 614 | }, 615 | "funding": { 616 | "url": "https://github.com/sponsors/sindresorhus" 617 | } 618 | }, 619 | "node_modules/c8/node_modules/signal-exit": { 620 | "version": "4.1.0", 621 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 622 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 623 | "dev": true, 624 | "engines": { 625 | "node": ">=14" 626 | }, 627 | "funding": { 628 | "url": "https://github.com/sponsors/isaacs" 629 | } 630 | }, 631 | "node_modules/c8/node_modules/test-exclude": { 632 | "version": "7.0.1", 633 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz", 634 | "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==", 635 | "dev": true, 636 | "dependencies": { 637 | "@istanbuljs/schema": "^0.1.2", 638 | "glob": "^10.4.1", 639 | "minimatch": "^9.0.4" 640 | }, 641 | "engines": { 642 | "node": ">=18" 643 | } 644 | }, 645 | "node_modules/c8/node_modules/wrap-ansi": { 646 | "version": "7.0.0", 647 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 648 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 649 | "dev": true, 650 | "dependencies": { 651 | "ansi-styles": "^4.0.0", 652 | "string-width": "^4.1.0", 653 | "strip-ansi": "^6.0.0" 654 | }, 655 | "engines": { 656 | "node": ">=10" 657 | }, 658 | "funding": { 659 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 660 | } 661 | }, 662 | "node_modules/c8/node_modules/y18n": { 663 | "version": "5.0.8", 664 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 665 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 666 | "dev": true, 667 | "engines": { 668 | "node": ">=10" 669 | } 670 | }, 671 | "node_modules/c8/node_modules/yargs": { 672 | "version": "17.7.2", 673 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 674 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 675 | "dev": true, 676 | "dependencies": { 677 | "cliui": "^8.0.1", 678 | "escalade": "^3.1.1", 679 | "get-caller-file": "^2.0.5", 680 | "require-directory": "^2.1.1", 681 | "string-width": "^4.2.3", 682 | "y18n": "^5.0.5", 683 | "yargs-parser": "^21.1.1" 684 | }, 685 | "engines": { 686 | "node": ">=12" 687 | } 688 | }, 689 | "node_modules/c8/node_modules/yargs-parser": { 690 | "version": "21.1.1", 691 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 692 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 693 | "dev": true, 694 | "engines": { 695 | "node": ">=12" 696 | } 697 | }, 698 | "node_modules/call-bind": { 699 | "version": "1.0.7", 700 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", 701 | "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", 702 | "dev": true, 703 | "dependencies": { 704 | "es-define-property": "^1.0.0", 705 | "es-errors": "^1.3.0", 706 | "function-bind": "^1.1.2", 707 | "get-intrinsic": "^1.2.4", 708 | "set-function-length": "^1.2.1" 709 | }, 710 | "engines": { 711 | "node": ">= 0.4" 712 | }, 713 | "funding": { 714 | "url": "https://github.com/sponsors/ljharb" 715 | } 716 | }, 717 | "node_modules/chalk": { 718 | "version": "2.4.2", 719 | "dev": true, 720 | "license": "MIT", 721 | "dependencies": { 722 | "ansi-styles": "^3.2.1", 723 | "escape-string-regexp": "^1.0.5", 724 | "supports-color": "^5.3.0" 725 | }, 726 | "engines": { 727 | "node": ">=4" 728 | } 729 | }, 730 | "node_modules/color-convert": { 731 | "version": "1.9.3", 732 | "dev": true, 733 | "license": "MIT", 734 | "dependencies": { 735 | "color-name": "1.1.3" 736 | } 737 | }, 738 | "node_modules/color-name": { 739 | "version": "1.1.3", 740 | "dev": true, 741 | "license": "MIT" 742 | }, 743 | "node_modules/commander": { 744 | "version": "2.20.3", 745 | "dev": true, 746 | "license": "MIT" 747 | }, 748 | "node_modules/concat-map": { 749 | "version": "0.0.1", 750 | "dev": true, 751 | "license": "MIT" 752 | }, 753 | "node_modules/cross-spawn": { 754 | "version": "7.0.1", 755 | "dev": true, 756 | "license": "MIT", 757 | "dependencies": { 758 | "path-key": "^3.1.0", 759 | "shebang-command": "^2.0.0", 760 | "which": "^2.0.1" 761 | }, 762 | "engines": { 763 | "node": ">= 8" 764 | } 765 | }, 766 | "node_modules/data-view-buffer": { 767 | "version": "1.0.1", 768 | "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", 769 | "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", 770 | "dev": true, 771 | "dependencies": { 772 | "call-bind": "^1.0.6", 773 | "es-errors": "^1.3.0", 774 | "is-data-view": "^1.0.1" 775 | }, 776 | "engines": { 777 | "node": ">= 0.4" 778 | }, 779 | "funding": { 780 | "url": "https://github.com/sponsors/ljharb" 781 | } 782 | }, 783 | "node_modules/data-view-byte-length": { 784 | "version": "1.0.1", 785 | "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", 786 | "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", 787 | "dev": true, 788 | "dependencies": { 789 | "call-bind": "^1.0.7", 790 | "es-errors": "^1.3.0", 791 | "is-data-view": "^1.0.1" 792 | }, 793 | "engines": { 794 | "node": ">= 0.4" 795 | }, 796 | "funding": { 797 | "url": "https://github.com/sponsors/ljharb" 798 | } 799 | }, 800 | "node_modules/data-view-byte-offset": { 801 | "version": "1.0.0", 802 | "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", 803 | "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", 804 | "dev": true, 805 | "dependencies": { 806 | "call-bind": "^1.0.6", 807 | "es-errors": "^1.3.0", 808 | "is-data-view": "^1.0.1" 809 | }, 810 | "engines": { 811 | "node": ">= 0.4" 812 | }, 813 | "funding": { 814 | "url": "https://github.com/sponsors/ljharb" 815 | } 816 | }, 817 | "node_modules/deep-equal": { 818 | "version": "2.2.3", 819 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", 820 | "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", 821 | "dev": true, 822 | "dependencies": { 823 | "array-buffer-byte-length": "^1.0.0", 824 | "call-bind": "^1.0.5", 825 | "es-get-iterator": "^1.1.3", 826 | "get-intrinsic": "^1.2.2", 827 | "is-arguments": "^1.1.1", 828 | "is-array-buffer": "^3.0.2", 829 | "is-date-object": "^1.0.5", 830 | "is-regex": "^1.1.4", 831 | "is-shared-array-buffer": "^1.0.2", 832 | "isarray": "^2.0.5", 833 | "object-is": "^1.1.5", 834 | "object-keys": "^1.1.1", 835 | "object.assign": "^4.1.4", 836 | "regexp.prototype.flags": "^1.5.1", 837 | "side-channel": "^1.0.4", 838 | "which-boxed-primitive": "^1.0.2", 839 | "which-collection": "^1.0.1", 840 | "which-typed-array": "^1.1.13" 841 | }, 842 | "engines": { 843 | "node": ">= 0.4" 844 | }, 845 | "funding": { 846 | "url": "https://github.com/sponsors/ljharb" 847 | } 848 | }, 849 | "node_modules/define-data-property": { 850 | "version": "1.1.4", 851 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", 852 | "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", 853 | "dev": true, 854 | "dependencies": { 855 | "es-define-property": "^1.0.0", 856 | "es-errors": "^1.3.0", 857 | "gopd": "^1.0.1" 858 | }, 859 | "engines": { 860 | "node": ">= 0.4" 861 | }, 862 | "funding": { 863 | "url": "https://github.com/sponsors/ljharb" 864 | } 865 | }, 866 | "node_modules/define-properties": { 867 | "version": "1.2.1", 868 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", 869 | "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", 870 | "dev": true, 871 | "dependencies": { 872 | "define-data-property": "^1.0.1", 873 | "has-property-descriptors": "^1.0.0", 874 | "object-keys": "^1.1.1" 875 | }, 876 | "engines": { 877 | "node": ">= 0.4" 878 | }, 879 | "funding": { 880 | "url": "https://github.com/sponsors/ljharb" 881 | } 882 | }, 883 | "node_modules/defined": { 884 | "version": "1.0.1", 885 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", 886 | "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", 887 | "dev": true, 888 | "funding": { 889 | "url": "https://github.com/sponsors/ljharb" 890 | } 891 | }, 892 | "node_modules/diff": { 893 | "version": "4.0.2", 894 | "dev": true, 895 | "license": "BSD-3-Clause", 896 | "engines": { 897 | "node": ">=0.3.1" 898 | } 899 | }, 900 | "node_modules/dotignore": { 901 | "version": "0.1.2", 902 | "dev": true, 903 | "license": "MIT", 904 | "dependencies": { 905 | "minimatch": "^3.0.4" 906 | }, 907 | "bin": { 908 | "ignored": "bin/ignored" 909 | } 910 | }, 911 | "node_modules/eastasianwidth": { 912 | "version": "0.2.0", 913 | "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", 914 | "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", 915 | "dev": true 916 | }, 917 | "node_modules/emoji-regex": { 918 | "version": "8.0.0", 919 | "dev": true, 920 | "license": "MIT" 921 | }, 922 | "node_modules/es-abstract": { 923 | "version": "1.23.3", 924 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", 925 | "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", 926 | "dev": true, 927 | "dependencies": { 928 | "array-buffer-byte-length": "^1.0.1", 929 | "arraybuffer.prototype.slice": "^1.0.3", 930 | "available-typed-arrays": "^1.0.7", 931 | "call-bind": "^1.0.7", 932 | "data-view-buffer": "^1.0.1", 933 | "data-view-byte-length": "^1.0.1", 934 | "data-view-byte-offset": "^1.0.0", 935 | "es-define-property": "^1.0.0", 936 | "es-errors": "^1.3.0", 937 | "es-object-atoms": "^1.0.0", 938 | "es-set-tostringtag": "^2.0.3", 939 | "es-to-primitive": "^1.2.1", 940 | "function.prototype.name": "^1.1.6", 941 | "get-intrinsic": "^1.2.4", 942 | "get-symbol-description": "^1.0.2", 943 | "globalthis": "^1.0.3", 944 | "gopd": "^1.0.1", 945 | "has-property-descriptors": "^1.0.2", 946 | "has-proto": "^1.0.3", 947 | "has-symbols": "^1.0.3", 948 | "hasown": "^2.0.2", 949 | "internal-slot": "^1.0.7", 950 | "is-array-buffer": "^3.0.4", 951 | "is-callable": "^1.2.7", 952 | "is-data-view": "^1.0.1", 953 | "is-negative-zero": "^2.0.3", 954 | "is-regex": "^1.1.4", 955 | "is-shared-array-buffer": "^1.0.3", 956 | "is-string": "^1.0.7", 957 | "is-typed-array": "^1.1.13", 958 | "is-weakref": "^1.0.2", 959 | "object-inspect": "^1.13.1", 960 | "object-keys": "^1.1.1", 961 | "object.assign": "^4.1.5", 962 | "regexp.prototype.flags": "^1.5.2", 963 | "safe-array-concat": "^1.1.2", 964 | "safe-regex-test": "^1.0.3", 965 | "string.prototype.trim": "^1.2.9", 966 | "string.prototype.trimend": "^1.0.8", 967 | "string.prototype.trimstart": "^1.0.8", 968 | "typed-array-buffer": "^1.0.2", 969 | "typed-array-byte-length": "^1.0.1", 970 | "typed-array-byte-offset": "^1.0.2", 971 | "typed-array-length": "^1.0.6", 972 | "unbox-primitive": "^1.0.2", 973 | "which-typed-array": "^1.1.15" 974 | }, 975 | "engines": { 976 | "node": ">= 0.4" 977 | }, 978 | "funding": { 979 | "url": "https://github.com/sponsors/ljharb" 980 | } 981 | }, 982 | "node_modules/es-define-property": { 983 | "version": "1.0.0", 984 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", 985 | "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", 986 | "dev": true, 987 | "dependencies": { 988 | "get-intrinsic": "^1.2.4" 989 | }, 990 | "engines": { 991 | "node": ">= 0.4" 992 | } 993 | }, 994 | "node_modules/es-errors": { 995 | "version": "1.3.0", 996 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 997 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 998 | "dev": true, 999 | "engines": { 1000 | "node": ">= 0.4" 1001 | } 1002 | }, 1003 | "node_modules/es-get-iterator": { 1004 | "version": "1.1.3", 1005 | "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", 1006 | "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", 1007 | "dev": true, 1008 | "dependencies": { 1009 | "call-bind": "^1.0.2", 1010 | "get-intrinsic": "^1.1.3", 1011 | "has-symbols": "^1.0.3", 1012 | "is-arguments": "^1.1.1", 1013 | "is-map": "^2.0.2", 1014 | "is-set": "^2.0.2", 1015 | "is-string": "^1.0.7", 1016 | "isarray": "^2.0.5", 1017 | "stop-iteration-iterator": "^1.0.0" 1018 | }, 1019 | "funding": { 1020 | "url": "https://github.com/sponsors/ljharb" 1021 | } 1022 | }, 1023 | "node_modules/es-object-atoms": { 1024 | "version": "1.0.0", 1025 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", 1026 | "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", 1027 | "dev": true, 1028 | "dependencies": { 1029 | "es-errors": "^1.3.0" 1030 | }, 1031 | "engines": { 1032 | "node": ">= 0.4" 1033 | } 1034 | }, 1035 | "node_modules/es-set-tostringtag": { 1036 | "version": "2.0.3", 1037 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", 1038 | "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", 1039 | "dev": true, 1040 | "dependencies": { 1041 | "get-intrinsic": "^1.2.4", 1042 | "has-tostringtag": "^1.0.2", 1043 | "hasown": "^2.0.1" 1044 | }, 1045 | "engines": { 1046 | "node": ">= 0.4" 1047 | } 1048 | }, 1049 | "node_modules/es-to-primitive": { 1050 | "version": "1.2.1", 1051 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 1052 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 1053 | "dev": true, 1054 | "dependencies": { 1055 | "is-callable": "^1.1.4", 1056 | "is-date-object": "^1.0.1", 1057 | "is-symbol": "^1.0.2" 1058 | }, 1059 | "engines": { 1060 | "node": ">= 0.4" 1061 | }, 1062 | "funding": { 1063 | "url": "https://github.com/sponsors/ljharb" 1064 | } 1065 | }, 1066 | "node_modules/escalade": { 1067 | "version": "3.2.0", 1068 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 1069 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 1070 | "dev": true, 1071 | "engines": { 1072 | "node": ">=6" 1073 | } 1074 | }, 1075 | "node_modules/escape-string-regexp": { 1076 | "version": "1.0.5", 1077 | "dev": true, 1078 | "license": "MIT", 1079 | "engines": { 1080 | "node": ">=0.8.0" 1081 | } 1082 | }, 1083 | "node_modules/esprima": { 1084 | "version": "4.0.1", 1085 | "dev": true, 1086 | "license": "BSD-2-Clause", 1087 | "bin": { 1088 | "esparse": "bin/esparse.js", 1089 | "esvalidate": "bin/esvalidate.js" 1090 | }, 1091 | "engines": { 1092 | "node": ">=4" 1093 | } 1094 | }, 1095 | "node_modules/esutils": { 1096 | "version": "2.0.3", 1097 | "dev": true, 1098 | "license": "BSD-2-Clause", 1099 | "engines": { 1100 | "node": ">=0.10.0" 1101 | } 1102 | }, 1103 | "node_modules/for-each": { 1104 | "version": "0.3.3", 1105 | "dev": true, 1106 | "license": "MIT", 1107 | "dependencies": { 1108 | "is-callable": "^1.1.3" 1109 | } 1110 | }, 1111 | "node_modules/fs.realpath": { 1112 | "version": "1.0.0", 1113 | "dev": true, 1114 | "license": "ISC" 1115 | }, 1116 | "node_modules/function-bind": { 1117 | "version": "1.1.2", 1118 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1119 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1120 | "dev": true, 1121 | "funding": { 1122 | "url": "https://github.com/sponsors/ljharb" 1123 | } 1124 | }, 1125 | "node_modules/function.prototype.name": { 1126 | "version": "1.1.6", 1127 | "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", 1128 | "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", 1129 | "dev": true, 1130 | "dependencies": { 1131 | "call-bind": "^1.0.2", 1132 | "define-properties": "^1.2.0", 1133 | "es-abstract": "^1.22.1", 1134 | "functions-have-names": "^1.2.3" 1135 | }, 1136 | "engines": { 1137 | "node": ">= 0.4" 1138 | }, 1139 | "funding": { 1140 | "url": "https://github.com/sponsors/ljharb" 1141 | } 1142 | }, 1143 | "node_modules/functions-have-names": { 1144 | "version": "1.2.3", 1145 | "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", 1146 | "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", 1147 | "dev": true, 1148 | "funding": { 1149 | "url": "https://github.com/sponsors/ljharb" 1150 | } 1151 | }, 1152 | "node_modules/get-caller-file": { 1153 | "version": "2.0.5", 1154 | "dev": true, 1155 | "license": "ISC", 1156 | "engines": { 1157 | "node": "6.* || 8.* || >= 10.*" 1158 | } 1159 | }, 1160 | "node_modules/get-intrinsic": { 1161 | "version": "1.2.4", 1162 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", 1163 | "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", 1164 | "dev": true, 1165 | "dependencies": { 1166 | "es-errors": "^1.3.0", 1167 | "function-bind": "^1.1.2", 1168 | "has-proto": "^1.0.1", 1169 | "has-symbols": "^1.0.3", 1170 | "hasown": "^2.0.0" 1171 | }, 1172 | "engines": { 1173 | "node": ">= 0.4" 1174 | }, 1175 | "funding": { 1176 | "url": "https://github.com/sponsors/ljharb" 1177 | } 1178 | }, 1179 | "node_modules/get-package-type": { 1180 | "version": "0.1.0", 1181 | "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", 1182 | "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", 1183 | "dev": true, 1184 | "engines": { 1185 | "node": ">=8.0.0" 1186 | } 1187 | }, 1188 | "node_modules/get-symbol-description": { 1189 | "version": "1.0.2", 1190 | "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", 1191 | "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", 1192 | "dev": true, 1193 | "dependencies": { 1194 | "call-bind": "^1.0.5", 1195 | "es-errors": "^1.3.0", 1196 | "get-intrinsic": "^1.2.4" 1197 | }, 1198 | "engines": { 1199 | "node": ">= 0.4" 1200 | }, 1201 | "funding": { 1202 | "url": "https://github.com/sponsors/ljharb" 1203 | } 1204 | }, 1205 | "node_modules/glob": { 1206 | "version": "7.1.6", 1207 | "dev": true, 1208 | "license": "ISC", 1209 | "dependencies": { 1210 | "fs.realpath": "^1.0.0", 1211 | "inflight": "^1.0.4", 1212 | "inherits": "2", 1213 | "minimatch": "^3.0.4", 1214 | "once": "^1.3.0", 1215 | "path-is-absolute": "^1.0.0" 1216 | }, 1217 | "engines": { 1218 | "node": "*" 1219 | }, 1220 | "funding": { 1221 | "url": "https://github.com/sponsors/isaacs" 1222 | } 1223 | }, 1224 | "node_modules/globalthis": { 1225 | "version": "1.0.4", 1226 | "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", 1227 | "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", 1228 | "dev": true, 1229 | "dependencies": { 1230 | "define-properties": "^1.2.1", 1231 | "gopd": "^1.0.1" 1232 | }, 1233 | "engines": { 1234 | "node": ">= 0.4" 1235 | }, 1236 | "funding": { 1237 | "url": "https://github.com/sponsors/ljharb" 1238 | } 1239 | }, 1240 | "node_modules/gopd": { 1241 | "version": "1.0.1", 1242 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", 1243 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", 1244 | "dev": true, 1245 | "dependencies": { 1246 | "get-intrinsic": "^1.1.3" 1247 | }, 1248 | "funding": { 1249 | "url": "https://github.com/sponsors/ljharb" 1250 | } 1251 | }, 1252 | "node_modules/has-bigints": { 1253 | "version": "1.0.2", 1254 | "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", 1255 | "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", 1256 | "dev": true, 1257 | "funding": { 1258 | "url": "https://github.com/sponsors/ljharb" 1259 | } 1260 | }, 1261 | "node_modules/has-dynamic-import": { 1262 | "version": "2.1.0", 1263 | "resolved": "https://registry.npmjs.org/has-dynamic-import/-/has-dynamic-import-2.1.0.tgz", 1264 | "integrity": "sha512-su0anMkNEnJKZ/rB99jn3y6lV/J8Ro96hBJ28YAeVzj5rWxH+YL/AdCyiYYA1HDLV9YhmvqpWSJJj2KLo1MX6g==", 1265 | "dev": true, 1266 | "dependencies": { 1267 | "call-bind": "^1.0.5", 1268 | "get-intrinsic": "^1.2.2" 1269 | }, 1270 | "engines": { 1271 | "node": ">= 0.4" 1272 | }, 1273 | "funding": { 1274 | "url": "https://github.com/sponsors/ljharb" 1275 | } 1276 | }, 1277 | "node_modules/has-flag": { 1278 | "version": "3.0.0", 1279 | "dev": true, 1280 | "license": "MIT", 1281 | "engines": { 1282 | "node": ">=4" 1283 | } 1284 | }, 1285 | "node_modules/has-property-descriptors": { 1286 | "version": "1.0.2", 1287 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", 1288 | "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", 1289 | "dev": true, 1290 | "dependencies": { 1291 | "es-define-property": "^1.0.0" 1292 | }, 1293 | "funding": { 1294 | "url": "https://github.com/sponsors/ljharb" 1295 | } 1296 | }, 1297 | "node_modules/has-proto": { 1298 | "version": "1.0.3", 1299 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", 1300 | "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", 1301 | "dev": true, 1302 | "engines": { 1303 | "node": ">= 0.4" 1304 | }, 1305 | "funding": { 1306 | "url": "https://github.com/sponsors/ljharb" 1307 | } 1308 | }, 1309 | "node_modules/has-symbols": { 1310 | "version": "1.0.3", 1311 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", 1312 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", 1313 | "dev": true, 1314 | "engines": { 1315 | "node": ">= 0.4" 1316 | }, 1317 | "funding": { 1318 | "url": "https://github.com/sponsors/ljharb" 1319 | } 1320 | }, 1321 | "node_modules/has-tostringtag": { 1322 | "version": "1.0.2", 1323 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 1324 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 1325 | "dev": true, 1326 | "dependencies": { 1327 | "has-symbols": "^1.0.3" 1328 | }, 1329 | "engines": { 1330 | "node": ">= 0.4" 1331 | }, 1332 | "funding": { 1333 | "url": "https://github.com/sponsors/ljharb" 1334 | } 1335 | }, 1336 | "node_modules/hasown": { 1337 | "version": "2.0.2", 1338 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1339 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1340 | "dev": true, 1341 | "dependencies": { 1342 | "function-bind": "^1.1.2" 1343 | }, 1344 | "engines": { 1345 | "node": ">= 0.4" 1346 | } 1347 | }, 1348 | "node_modules/html-escaper": { 1349 | "version": "2.0.0", 1350 | "dev": true, 1351 | "license": "MIT" 1352 | }, 1353 | "node_modules/inflight": { 1354 | "version": "1.0.6", 1355 | "dev": true, 1356 | "license": "ISC", 1357 | "dependencies": { 1358 | "once": "^1.3.0", 1359 | "wrappy": "1" 1360 | } 1361 | }, 1362 | "node_modules/inherits": { 1363 | "version": "2.0.3", 1364 | "dev": true, 1365 | "license": "ISC" 1366 | }, 1367 | "node_modules/internal-slot": { 1368 | "version": "1.0.7", 1369 | "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", 1370 | "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", 1371 | "dev": true, 1372 | "dependencies": { 1373 | "es-errors": "^1.3.0", 1374 | "hasown": "^2.0.0", 1375 | "side-channel": "^1.0.4" 1376 | }, 1377 | "engines": { 1378 | "node": ">= 0.4" 1379 | } 1380 | }, 1381 | "node_modules/is-arguments": { 1382 | "version": "1.1.1", 1383 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", 1384 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", 1385 | "dev": true, 1386 | "dependencies": { 1387 | "call-bind": "^1.0.2", 1388 | "has-tostringtag": "^1.0.0" 1389 | }, 1390 | "engines": { 1391 | "node": ">= 0.4" 1392 | }, 1393 | "funding": { 1394 | "url": "https://github.com/sponsors/ljharb" 1395 | } 1396 | }, 1397 | "node_modules/is-array-buffer": { 1398 | "version": "3.0.4", 1399 | "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", 1400 | "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", 1401 | "dev": true, 1402 | "dependencies": { 1403 | "call-bind": "^1.0.2", 1404 | "get-intrinsic": "^1.2.1" 1405 | }, 1406 | "engines": { 1407 | "node": ">= 0.4" 1408 | }, 1409 | "funding": { 1410 | "url": "https://github.com/sponsors/ljharb" 1411 | } 1412 | }, 1413 | "node_modules/is-bigint": { 1414 | "version": "1.0.4", 1415 | "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", 1416 | "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", 1417 | "dev": true, 1418 | "dependencies": { 1419 | "has-bigints": "^1.0.1" 1420 | }, 1421 | "funding": { 1422 | "url": "https://github.com/sponsors/ljharb" 1423 | } 1424 | }, 1425 | "node_modules/is-boolean-object": { 1426 | "version": "1.1.2", 1427 | "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", 1428 | "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", 1429 | "dev": true, 1430 | "dependencies": { 1431 | "call-bind": "^1.0.2", 1432 | "has-tostringtag": "^1.0.0" 1433 | }, 1434 | "engines": { 1435 | "node": ">= 0.4" 1436 | }, 1437 | "funding": { 1438 | "url": "https://github.com/sponsors/ljharb" 1439 | } 1440 | }, 1441 | "node_modules/is-callable": { 1442 | "version": "1.2.7", 1443 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", 1444 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", 1445 | "dev": true, 1446 | "engines": { 1447 | "node": ">= 0.4" 1448 | }, 1449 | "funding": { 1450 | "url": "https://github.com/sponsors/ljharb" 1451 | } 1452 | }, 1453 | "node_modules/is-core-module": { 1454 | "version": "2.15.1", 1455 | "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", 1456 | "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", 1457 | "dev": true, 1458 | "dependencies": { 1459 | "hasown": "^2.0.2" 1460 | }, 1461 | "engines": { 1462 | "node": ">= 0.4" 1463 | }, 1464 | "funding": { 1465 | "url": "https://github.com/sponsors/ljharb" 1466 | } 1467 | }, 1468 | "node_modules/is-data-view": { 1469 | "version": "1.0.1", 1470 | "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", 1471 | "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", 1472 | "dev": true, 1473 | "dependencies": { 1474 | "is-typed-array": "^1.1.13" 1475 | }, 1476 | "engines": { 1477 | "node": ">= 0.4" 1478 | }, 1479 | "funding": { 1480 | "url": "https://github.com/sponsors/ljharb" 1481 | } 1482 | }, 1483 | "node_modules/is-date-object": { 1484 | "version": "1.0.5", 1485 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", 1486 | "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", 1487 | "dev": true, 1488 | "dependencies": { 1489 | "has-tostringtag": "^1.0.0" 1490 | }, 1491 | "engines": { 1492 | "node": ">= 0.4" 1493 | }, 1494 | "funding": { 1495 | "url": "https://github.com/sponsors/ljharb" 1496 | } 1497 | }, 1498 | "node_modules/is-fullwidth-code-point": { 1499 | "version": "3.0.0", 1500 | "dev": true, 1501 | "license": "MIT", 1502 | "engines": { 1503 | "node": ">=8" 1504 | } 1505 | }, 1506 | "node_modules/is-map": { 1507 | "version": "2.0.3", 1508 | "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", 1509 | "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", 1510 | "dev": true, 1511 | "engines": { 1512 | "node": ">= 0.4" 1513 | }, 1514 | "funding": { 1515 | "url": "https://github.com/sponsors/ljharb" 1516 | } 1517 | }, 1518 | "node_modules/is-negative-zero": { 1519 | "version": "2.0.3", 1520 | "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", 1521 | "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", 1522 | "dev": true, 1523 | "engines": { 1524 | "node": ">= 0.4" 1525 | }, 1526 | "funding": { 1527 | "url": "https://github.com/sponsors/ljharb" 1528 | } 1529 | }, 1530 | "node_modules/is-number-object": { 1531 | "version": "1.0.7", 1532 | "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", 1533 | "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", 1534 | "dev": true, 1535 | "dependencies": { 1536 | "has-tostringtag": "^1.0.0" 1537 | }, 1538 | "engines": { 1539 | "node": ">= 0.4" 1540 | }, 1541 | "funding": { 1542 | "url": "https://github.com/sponsors/ljharb" 1543 | } 1544 | }, 1545 | "node_modules/is-regex": { 1546 | "version": "1.1.4", 1547 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", 1548 | "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", 1549 | "dev": true, 1550 | "dependencies": { 1551 | "call-bind": "^1.0.2", 1552 | "has-tostringtag": "^1.0.0" 1553 | }, 1554 | "engines": { 1555 | "node": ">= 0.4" 1556 | }, 1557 | "funding": { 1558 | "url": "https://github.com/sponsors/ljharb" 1559 | } 1560 | }, 1561 | "node_modules/is-set": { 1562 | "version": "2.0.3", 1563 | "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", 1564 | "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", 1565 | "dev": true, 1566 | "engines": { 1567 | "node": ">= 0.4" 1568 | }, 1569 | "funding": { 1570 | "url": "https://github.com/sponsors/ljharb" 1571 | } 1572 | }, 1573 | "node_modules/is-shared-array-buffer": { 1574 | "version": "1.0.3", 1575 | "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", 1576 | "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", 1577 | "dev": true, 1578 | "dependencies": { 1579 | "call-bind": "^1.0.7" 1580 | }, 1581 | "engines": { 1582 | "node": ">= 0.4" 1583 | }, 1584 | "funding": { 1585 | "url": "https://github.com/sponsors/ljharb" 1586 | } 1587 | }, 1588 | "node_modules/is-string": { 1589 | "version": "1.0.7", 1590 | "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", 1591 | "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", 1592 | "dev": true, 1593 | "dependencies": { 1594 | "has-tostringtag": "^1.0.0" 1595 | }, 1596 | "engines": { 1597 | "node": ">= 0.4" 1598 | }, 1599 | "funding": { 1600 | "url": "https://github.com/sponsors/ljharb" 1601 | } 1602 | }, 1603 | "node_modules/is-symbol": { 1604 | "version": "1.0.4", 1605 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", 1606 | "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", 1607 | "dev": true, 1608 | "dependencies": { 1609 | "has-symbols": "^1.0.2" 1610 | }, 1611 | "engines": { 1612 | "node": ">= 0.4" 1613 | }, 1614 | "funding": { 1615 | "url": "https://github.com/sponsors/ljharb" 1616 | } 1617 | }, 1618 | "node_modules/is-typed-array": { 1619 | "version": "1.1.13", 1620 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", 1621 | "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", 1622 | "dev": true, 1623 | "dependencies": { 1624 | "which-typed-array": "^1.1.14" 1625 | }, 1626 | "engines": { 1627 | "node": ">= 0.4" 1628 | }, 1629 | "funding": { 1630 | "url": "https://github.com/sponsors/ljharb" 1631 | } 1632 | }, 1633 | "node_modules/is-weakmap": { 1634 | "version": "2.0.2", 1635 | "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", 1636 | "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", 1637 | "dev": true, 1638 | "engines": { 1639 | "node": ">= 0.4" 1640 | }, 1641 | "funding": { 1642 | "url": "https://github.com/sponsors/ljharb" 1643 | } 1644 | }, 1645 | "node_modules/is-weakref": { 1646 | "version": "1.0.2", 1647 | "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", 1648 | "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", 1649 | "dev": true, 1650 | "dependencies": { 1651 | "call-bind": "^1.0.2" 1652 | }, 1653 | "funding": { 1654 | "url": "https://github.com/sponsors/ljharb" 1655 | } 1656 | }, 1657 | "node_modules/is-weakset": { 1658 | "version": "2.0.3", 1659 | "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", 1660 | "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", 1661 | "dev": true, 1662 | "dependencies": { 1663 | "call-bind": "^1.0.7", 1664 | "get-intrinsic": "^1.2.4" 1665 | }, 1666 | "engines": { 1667 | "node": ">= 0.4" 1668 | }, 1669 | "funding": { 1670 | "url": "https://github.com/sponsors/ljharb" 1671 | } 1672 | }, 1673 | "node_modules/isarray": { 1674 | "version": "2.0.5", 1675 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", 1676 | "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", 1677 | "dev": true 1678 | }, 1679 | "node_modules/isexe": { 1680 | "version": "2.0.0", 1681 | "dev": true, 1682 | "license": "ISC" 1683 | }, 1684 | "node_modules/istanbul-lib-coverage": { 1685 | "version": "3.2.2", 1686 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", 1687 | "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", 1688 | "dev": true, 1689 | "engines": { 1690 | "node": ">=8" 1691 | } 1692 | }, 1693 | "node_modules/istanbul-lib-report": { 1694 | "version": "3.0.1", 1695 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", 1696 | "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", 1697 | "dev": true, 1698 | "dependencies": { 1699 | "istanbul-lib-coverage": "^3.0.0", 1700 | "make-dir": "^4.0.0", 1701 | "supports-color": "^7.1.0" 1702 | }, 1703 | "engines": { 1704 | "node": ">=10" 1705 | } 1706 | }, 1707 | "node_modules/istanbul-lib-report/node_modules/has-flag": { 1708 | "version": "4.0.0", 1709 | "dev": true, 1710 | "license": "MIT", 1711 | "engines": { 1712 | "node": ">=8" 1713 | } 1714 | }, 1715 | "node_modules/istanbul-lib-report/node_modules/make-dir": { 1716 | "version": "4.0.0", 1717 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", 1718 | "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", 1719 | "dev": true, 1720 | "dependencies": { 1721 | "semver": "^7.5.3" 1722 | }, 1723 | "engines": { 1724 | "node": ">=10" 1725 | }, 1726 | "funding": { 1727 | "url": "https://github.com/sponsors/sindresorhus" 1728 | } 1729 | }, 1730 | "node_modules/istanbul-lib-report/node_modules/semver": { 1731 | "version": "7.6.3", 1732 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", 1733 | "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", 1734 | "dev": true, 1735 | "bin": { 1736 | "semver": "bin/semver.js" 1737 | }, 1738 | "engines": { 1739 | "node": ">=10" 1740 | } 1741 | }, 1742 | "node_modules/istanbul-lib-report/node_modules/supports-color": { 1743 | "version": "7.1.0", 1744 | "dev": true, 1745 | "license": "MIT", 1746 | "dependencies": { 1747 | "has-flag": "^4.0.0" 1748 | }, 1749 | "engines": { 1750 | "node": ">=8" 1751 | } 1752 | }, 1753 | "node_modules/istanbul-reports": { 1754 | "version": "3.1.7", 1755 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", 1756 | "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", 1757 | "dev": true, 1758 | "dependencies": { 1759 | "html-escaper": "^2.0.0", 1760 | "istanbul-lib-report": "^3.0.0" 1761 | }, 1762 | "engines": { 1763 | "node": ">=8" 1764 | } 1765 | }, 1766 | "node_modules/jackspeak": { 1767 | "version": "3.4.3", 1768 | "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", 1769 | "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", 1770 | "dev": true, 1771 | "dependencies": { 1772 | "@isaacs/cliui": "^8.0.2" 1773 | }, 1774 | "funding": { 1775 | "url": "https://github.com/sponsors/isaacs" 1776 | }, 1777 | "optionalDependencies": { 1778 | "@pkgjs/parseargs": "^0.11.0" 1779 | } 1780 | }, 1781 | "node_modules/js-tokens": { 1782 | "version": "4.0.0", 1783 | "dev": true, 1784 | "license": "MIT" 1785 | }, 1786 | "node_modules/js-yaml": { 1787 | "version": "3.13.1", 1788 | "dev": true, 1789 | "license": "MIT", 1790 | "dependencies": { 1791 | "argparse": "^1.0.7", 1792 | "esprima": "^4.0.0" 1793 | }, 1794 | "bin": { 1795 | "js-yaml": "bin/js-yaml.js" 1796 | } 1797 | }, 1798 | "node_modules/lru-cache": { 1799 | "version": "10.4.3", 1800 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", 1801 | "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", 1802 | "dev": true 1803 | }, 1804 | "node_modules/minimatch": { 1805 | "version": "3.1.2", 1806 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1807 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1808 | "dev": true, 1809 | "dependencies": { 1810 | "brace-expansion": "^1.1.7" 1811 | }, 1812 | "engines": { 1813 | "node": "*" 1814 | } 1815 | }, 1816 | "node_modules/minimist": { 1817 | "version": "1.2.8", 1818 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1819 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1820 | "dev": true, 1821 | "funding": { 1822 | "url": "https://github.com/sponsors/ljharb" 1823 | } 1824 | }, 1825 | "node_modules/minipass": { 1826 | "version": "7.1.2", 1827 | "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", 1828 | "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", 1829 | "dev": true, 1830 | "engines": { 1831 | "node": ">=16 || 14 >=14.17" 1832 | } 1833 | }, 1834 | "node_modules/mkdirp": { 1835 | "version": "0.5.3", 1836 | "dev": true, 1837 | "license": "MIT", 1838 | "dependencies": { 1839 | "minimist": "^1.2.5" 1840 | }, 1841 | "bin": { 1842 | "mkdirp": "bin/cmd.js" 1843 | } 1844 | }, 1845 | "node_modules/mock-property": { 1846 | "version": "1.1.0", 1847 | "resolved": "https://registry.npmjs.org/mock-property/-/mock-property-1.1.0.tgz", 1848 | "integrity": "sha512-1/JjbLoGwv87xVsutkX0XJc0M0W4kb40cZl/K41xtTViBOD9JuFPKfyMNTrLJ/ivYAd0aPqu/vduamXO0emTFQ==", 1849 | "dev": true, 1850 | "dependencies": { 1851 | "define-data-property": "^1.1.4", 1852 | "functions-have-names": "^1.2.3", 1853 | "gopd": "^1.0.1", 1854 | "has-property-descriptors": "^1.0.2", 1855 | "hasown": "^2.0.2", 1856 | "isarray": "^2.0.5", 1857 | "object-inspect": "^1.13.2" 1858 | }, 1859 | "engines": { 1860 | "node": ">= 0.4" 1861 | }, 1862 | "funding": { 1863 | "url": "https://github.com/sponsors/ljharb" 1864 | } 1865 | }, 1866 | "node_modules/object-inspect": { 1867 | "version": "1.13.2", 1868 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", 1869 | "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", 1870 | "dev": true, 1871 | "engines": { 1872 | "node": ">= 0.4" 1873 | }, 1874 | "funding": { 1875 | "url": "https://github.com/sponsors/ljharb" 1876 | } 1877 | }, 1878 | "node_modules/object-is": { 1879 | "version": "1.1.6", 1880 | "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", 1881 | "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", 1882 | "dev": true, 1883 | "dependencies": { 1884 | "call-bind": "^1.0.7", 1885 | "define-properties": "^1.2.1" 1886 | }, 1887 | "engines": { 1888 | "node": ">= 0.4" 1889 | }, 1890 | "funding": { 1891 | "url": "https://github.com/sponsors/ljharb" 1892 | } 1893 | }, 1894 | "node_modules/object-keys": { 1895 | "version": "1.1.1", 1896 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1897 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1898 | "dev": true, 1899 | "engines": { 1900 | "node": ">= 0.4" 1901 | } 1902 | }, 1903 | "node_modules/object.assign": { 1904 | "version": "4.1.5", 1905 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", 1906 | "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", 1907 | "dev": true, 1908 | "dependencies": { 1909 | "call-bind": "^1.0.5", 1910 | "define-properties": "^1.2.1", 1911 | "has-symbols": "^1.0.3", 1912 | "object-keys": "^1.1.1" 1913 | }, 1914 | "engines": { 1915 | "node": ">= 0.4" 1916 | }, 1917 | "funding": { 1918 | "url": "https://github.com/sponsors/ljharb" 1919 | } 1920 | }, 1921 | "node_modules/once": { 1922 | "version": "1.4.0", 1923 | "dev": true, 1924 | "license": "ISC", 1925 | "dependencies": { 1926 | "wrappy": "1" 1927 | } 1928 | }, 1929 | "node_modules/package-json-from-dist": { 1930 | "version": "1.0.0", 1931 | "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", 1932 | "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", 1933 | "dev": true 1934 | }, 1935 | "node_modules/path-exists": { 1936 | "version": "4.0.0", 1937 | "dev": true, 1938 | "license": "MIT", 1939 | "engines": { 1940 | "node": ">=8" 1941 | } 1942 | }, 1943 | "node_modules/path-is-absolute": { 1944 | "version": "1.0.1", 1945 | "dev": true, 1946 | "license": "MIT", 1947 | "engines": { 1948 | "node": ">=0.10.0" 1949 | } 1950 | }, 1951 | "node_modules/path-key": { 1952 | "version": "3.1.1", 1953 | "dev": true, 1954 | "license": "MIT", 1955 | "engines": { 1956 | "node": ">=8" 1957 | } 1958 | }, 1959 | "node_modules/path-parse": { 1960 | "version": "1.0.7", 1961 | "dev": true, 1962 | "license": "MIT" 1963 | }, 1964 | "node_modules/path-scurry": { 1965 | "version": "1.11.1", 1966 | "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", 1967 | "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", 1968 | "dev": true, 1969 | "dependencies": { 1970 | "lru-cache": "^10.2.0", 1971 | "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" 1972 | }, 1973 | "engines": { 1974 | "node": ">=16 || 14 >=14.18" 1975 | }, 1976 | "funding": { 1977 | "url": "https://github.com/sponsors/isaacs" 1978 | } 1979 | }, 1980 | "node_modules/possible-typed-array-names": { 1981 | "version": "1.0.0", 1982 | "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", 1983 | "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", 1984 | "dev": true, 1985 | "engines": { 1986 | "node": ">= 0.4" 1987 | } 1988 | }, 1989 | "node_modules/prettier": { 1990 | "version": "1.16.4", 1991 | "dev": true, 1992 | "license": "MIT", 1993 | "bin": { 1994 | "prettier": "bin-prettier.js" 1995 | }, 1996 | "engines": { 1997 | "node": ">=4" 1998 | } 1999 | }, 2000 | "node_modules/regexp.prototype.flags": { 2001 | "version": "1.5.2", 2002 | "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", 2003 | "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", 2004 | "dev": true, 2005 | "dependencies": { 2006 | "call-bind": "^1.0.6", 2007 | "define-properties": "^1.2.1", 2008 | "es-errors": "^1.3.0", 2009 | "set-function-name": "^2.0.1" 2010 | }, 2011 | "engines": { 2012 | "node": ">= 0.4" 2013 | }, 2014 | "funding": { 2015 | "url": "https://github.com/sponsors/ljharb" 2016 | } 2017 | }, 2018 | "node_modules/require-directory": { 2019 | "version": "2.1.1", 2020 | "dev": true, 2021 | "license": "MIT", 2022 | "engines": { 2023 | "node": ">=0.10.0" 2024 | } 2025 | }, 2026 | "node_modules/resolve": { 2027 | "version": "1.15.1", 2028 | "dev": true, 2029 | "license": "MIT", 2030 | "dependencies": { 2031 | "path-parse": "^1.0.6" 2032 | }, 2033 | "funding": { 2034 | "url": "https://github.com/sponsors/ljharb" 2035 | } 2036 | }, 2037 | "node_modules/safe-array-concat": { 2038 | "version": "1.1.2", 2039 | "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", 2040 | "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", 2041 | "dev": true, 2042 | "dependencies": { 2043 | "call-bind": "^1.0.7", 2044 | "get-intrinsic": "^1.2.4", 2045 | "has-symbols": "^1.0.3", 2046 | "isarray": "^2.0.5" 2047 | }, 2048 | "engines": { 2049 | "node": ">=0.4" 2050 | }, 2051 | "funding": { 2052 | "url": "https://github.com/sponsors/ljharb" 2053 | } 2054 | }, 2055 | "node_modules/safe-regex-test": { 2056 | "version": "1.0.3", 2057 | "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", 2058 | "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", 2059 | "dev": true, 2060 | "dependencies": { 2061 | "call-bind": "^1.0.6", 2062 | "es-errors": "^1.3.0", 2063 | "is-regex": "^1.1.4" 2064 | }, 2065 | "engines": { 2066 | "node": ">= 0.4" 2067 | }, 2068 | "funding": { 2069 | "url": "https://github.com/sponsors/ljharb" 2070 | } 2071 | }, 2072 | "node_modules/set-function-length": { 2073 | "version": "1.2.2", 2074 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", 2075 | "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", 2076 | "dev": true, 2077 | "dependencies": { 2078 | "define-data-property": "^1.1.4", 2079 | "es-errors": "^1.3.0", 2080 | "function-bind": "^1.1.2", 2081 | "get-intrinsic": "^1.2.4", 2082 | "gopd": "^1.0.1", 2083 | "has-property-descriptors": "^1.0.2" 2084 | }, 2085 | "engines": { 2086 | "node": ">= 0.4" 2087 | } 2088 | }, 2089 | "node_modules/set-function-name": { 2090 | "version": "2.0.2", 2091 | "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", 2092 | "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", 2093 | "dev": true, 2094 | "dependencies": { 2095 | "define-data-property": "^1.1.4", 2096 | "es-errors": "^1.3.0", 2097 | "functions-have-names": "^1.2.3", 2098 | "has-property-descriptors": "^1.0.2" 2099 | }, 2100 | "engines": { 2101 | "node": ">= 0.4" 2102 | } 2103 | }, 2104 | "node_modules/shebang-command": { 2105 | "version": "2.0.0", 2106 | "dev": true, 2107 | "license": "MIT", 2108 | "dependencies": { 2109 | "shebang-regex": "^3.0.0" 2110 | }, 2111 | "engines": { 2112 | "node": ">=8" 2113 | } 2114 | }, 2115 | "node_modules/shebang-regex": { 2116 | "version": "3.0.0", 2117 | "dev": true, 2118 | "license": "MIT", 2119 | "engines": { 2120 | "node": ">=8" 2121 | } 2122 | }, 2123 | "node_modules/side-channel": { 2124 | "version": "1.0.6", 2125 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", 2126 | "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", 2127 | "dev": true, 2128 | "dependencies": { 2129 | "call-bind": "^1.0.7", 2130 | "es-errors": "^1.3.0", 2131 | "get-intrinsic": "^1.2.4", 2132 | "object-inspect": "^1.13.1" 2133 | }, 2134 | "engines": { 2135 | "node": ">= 0.4" 2136 | }, 2137 | "funding": { 2138 | "url": "https://github.com/sponsors/ljharb" 2139 | } 2140 | }, 2141 | "node_modules/sprintf-js": { 2142 | "version": "1.0.3", 2143 | "dev": true, 2144 | "license": "BSD-3-Clause" 2145 | }, 2146 | "node_modules/stop-iteration-iterator": { 2147 | "version": "1.0.0", 2148 | "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", 2149 | "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", 2150 | "dev": true, 2151 | "dependencies": { 2152 | "internal-slot": "^1.0.4" 2153 | }, 2154 | "engines": { 2155 | "node": ">= 0.4" 2156 | } 2157 | }, 2158 | "node_modules/string-width": { 2159 | "version": "4.2.3", 2160 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2161 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2162 | "dev": true, 2163 | "dependencies": { 2164 | "emoji-regex": "^8.0.0", 2165 | "is-fullwidth-code-point": "^3.0.0", 2166 | "strip-ansi": "^6.0.1" 2167 | }, 2168 | "engines": { 2169 | "node": ">=8" 2170 | } 2171 | }, 2172 | "node_modules/string-width-cjs": { 2173 | "name": "string-width", 2174 | "version": "4.2.3", 2175 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2176 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2177 | "dev": true, 2178 | "dependencies": { 2179 | "emoji-regex": "^8.0.0", 2180 | "is-fullwidth-code-point": "^3.0.0", 2181 | "strip-ansi": "^6.0.1" 2182 | }, 2183 | "engines": { 2184 | "node": ">=8" 2185 | } 2186 | }, 2187 | "node_modules/string.prototype.trim": { 2188 | "version": "1.2.9", 2189 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", 2190 | "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", 2191 | "dev": true, 2192 | "dependencies": { 2193 | "call-bind": "^1.0.7", 2194 | "define-properties": "^1.2.1", 2195 | "es-abstract": "^1.23.0", 2196 | "es-object-atoms": "^1.0.0" 2197 | }, 2198 | "engines": { 2199 | "node": ">= 0.4" 2200 | }, 2201 | "funding": { 2202 | "url": "https://github.com/sponsors/ljharb" 2203 | } 2204 | }, 2205 | "node_modules/string.prototype.trimend": { 2206 | "version": "1.0.8", 2207 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", 2208 | "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", 2209 | "dev": true, 2210 | "dependencies": { 2211 | "call-bind": "^1.0.7", 2212 | "define-properties": "^1.2.1", 2213 | "es-object-atoms": "^1.0.0" 2214 | }, 2215 | "funding": { 2216 | "url": "https://github.com/sponsors/ljharb" 2217 | } 2218 | }, 2219 | "node_modules/string.prototype.trimstart": { 2220 | "version": "1.0.8", 2221 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", 2222 | "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", 2223 | "dev": true, 2224 | "dependencies": { 2225 | "call-bind": "^1.0.7", 2226 | "define-properties": "^1.2.1", 2227 | "es-object-atoms": "^1.0.0" 2228 | }, 2229 | "engines": { 2230 | "node": ">= 0.4" 2231 | }, 2232 | "funding": { 2233 | "url": "https://github.com/sponsors/ljharb" 2234 | } 2235 | }, 2236 | "node_modules/strip-ansi": { 2237 | "version": "6.0.1", 2238 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2239 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2240 | "dev": true, 2241 | "dependencies": { 2242 | "ansi-regex": "^5.0.1" 2243 | }, 2244 | "engines": { 2245 | "node": ">=8" 2246 | } 2247 | }, 2248 | "node_modules/strip-ansi-cjs": { 2249 | "name": "strip-ansi", 2250 | "version": "6.0.1", 2251 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2252 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2253 | "dev": true, 2254 | "dependencies": { 2255 | "ansi-regex": "^5.0.1" 2256 | }, 2257 | "engines": { 2258 | "node": ">=8" 2259 | } 2260 | }, 2261 | "node_modules/supports-color": { 2262 | "version": "5.5.0", 2263 | "dev": true, 2264 | "license": "MIT", 2265 | "dependencies": { 2266 | "has-flag": "^3.0.0" 2267 | }, 2268 | "engines": { 2269 | "node": ">=4" 2270 | } 2271 | }, 2272 | "node_modules/supports-preserve-symlinks-flag": { 2273 | "version": "1.0.0", 2274 | "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", 2275 | "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", 2276 | "dev": true, 2277 | "engines": { 2278 | "node": ">= 0.4" 2279 | }, 2280 | "funding": { 2281 | "url": "https://github.com/sponsors/ljharb" 2282 | } 2283 | }, 2284 | "node_modules/tape": { 2285 | "version": "5.8.1", 2286 | "resolved": "https://registry.npmjs.org/tape/-/tape-5.8.1.tgz", 2287 | "integrity": "sha512-pUzADXBVYm5Jkneh9hfXnirADrzQrDA3vddKbPOc/ZLORj4dFQ6GR1KdGWX0/NvOLDcYkVgeMdw78Uf6BzO3KA==", 2288 | "dev": true, 2289 | "dependencies": { 2290 | "@ljharb/resumer": "^0.1.3", 2291 | "@ljharb/through": "^2.3.13", 2292 | "array.prototype.every": "^1.1.6", 2293 | "call-bind": "^1.0.7", 2294 | "deep-equal": "^2.2.3", 2295 | "defined": "^1.0.1", 2296 | "dotignore": "^0.1.2", 2297 | "for-each": "^0.3.3", 2298 | "get-package-type": "^0.1.0", 2299 | "glob": "^7.2.3", 2300 | "has-dynamic-import": "^2.1.0", 2301 | "hasown": "^2.0.2", 2302 | "inherits": "^2.0.4", 2303 | "is-regex": "^1.1.4", 2304 | "minimist": "^1.2.8", 2305 | "mock-property": "^1.0.3", 2306 | "object-inspect": "^1.13.1", 2307 | "object-is": "^1.1.6", 2308 | "object-keys": "^1.1.1", 2309 | "object.assign": "^4.1.5", 2310 | "resolve": "^2.0.0-next.5", 2311 | "string.prototype.trim": "^1.2.9" 2312 | }, 2313 | "bin": { 2314 | "tape": "bin/tape" 2315 | }, 2316 | "funding": { 2317 | "url": "https://github.com/sponsors/ljharb" 2318 | } 2319 | }, 2320 | "node_modules/tape/node_modules/glob": { 2321 | "version": "7.2.3", 2322 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 2323 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 2324 | "deprecated": "Glob versions prior to v9 are no longer supported", 2325 | "dev": true, 2326 | "dependencies": { 2327 | "fs.realpath": "^1.0.0", 2328 | "inflight": "^1.0.4", 2329 | "inherits": "2", 2330 | "minimatch": "^3.1.1", 2331 | "once": "^1.3.0", 2332 | "path-is-absolute": "^1.0.0" 2333 | }, 2334 | "engines": { 2335 | "node": "*" 2336 | }, 2337 | "funding": { 2338 | "url": "https://github.com/sponsors/isaacs" 2339 | } 2340 | }, 2341 | "node_modules/tape/node_modules/inherits": { 2342 | "version": "2.0.4", 2343 | "dev": true, 2344 | "license": "ISC" 2345 | }, 2346 | "node_modules/tape/node_modules/resolve": { 2347 | "version": "2.0.0-next.5", 2348 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", 2349 | "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", 2350 | "dev": true, 2351 | "dependencies": { 2352 | "is-core-module": "^2.13.0", 2353 | "path-parse": "^1.0.7", 2354 | "supports-preserve-symlinks-flag": "^1.0.0" 2355 | }, 2356 | "bin": { 2357 | "resolve": "bin/resolve" 2358 | }, 2359 | "funding": { 2360 | "url": "https://github.com/sponsors/ljharb" 2361 | } 2362 | }, 2363 | "node_modules/tiny-secp256k1": { 2364 | "version": "2.2.1", 2365 | "dev": true, 2366 | "license": "MIT", 2367 | "dependencies": { 2368 | "uint8array-tools": "0.0.7" 2369 | }, 2370 | "engines": { 2371 | "node": ">=14.0.0" 2372 | } 2373 | }, 2374 | "node_modules/tiny-secp256k1/node_modules/uint8array-tools": { 2375 | "version": "0.0.7", 2376 | "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.7.tgz", 2377 | "integrity": "sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ==", 2378 | "dev": true, 2379 | "engines": { 2380 | "node": ">=14.0.0" 2381 | } 2382 | }, 2383 | "node_modules/tslib": { 2384 | "version": "1.11.1", 2385 | "dev": true, 2386 | "license": "Apache-2.0" 2387 | }, 2388 | "node_modules/tslint": { 2389 | "version": "6.1.0", 2390 | "dev": true, 2391 | "license": "Apache-2.0", 2392 | "dependencies": { 2393 | "@babel/code-frame": "^7.0.0", 2394 | "builtin-modules": "^1.1.1", 2395 | "chalk": "^2.3.0", 2396 | "commander": "^2.12.1", 2397 | "diff": "^4.0.1", 2398 | "glob": "^7.1.1", 2399 | "js-yaml": "^3.13.1", 2400 | "minimatch": "^3.0.4", 2401 | "mkdirp": "^0.5.1", 2402 | "resolve": "^1.3.2", 2403 | "semver": "^5.3.0", 2404 | "tslib": "^1.10.0", 2405 | "tsutils": "^2.29.0" 2406 | }, 2407 | "bin": { 2408 | "tslint": "bin/tslint" 2409 | }, 2410 | "engines": { 2411 | "node": ">=4.8.0" 2412 | }, 2413 | "peerDependencies": { 2414 | "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" 2415 | } 2416 | }, 2417 | "node_modules/tslint/node_modules/semver": { 2418 | "version": "5.7.1", 2419 | "dev": true, 2420 | "license": "ISC", 2421 | "bin": { 2422 | "semver": "bin/semver" 2423 | } 2424 | }, 2425 | "node_modules/tsutils": { 2426 | "version": "2.29.0", 2427 | "dev": true, 2428 | "license": "MIT", 2429 | "dependencies": { 2430 | "tslib": "^1.8.1" 2431 | }, 2432 | "peerDependencies": { 2433 | "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" 2434 | } 2435 | }, 2436 | "node_modules/typed-array-buffer": { 2437 | "version": "1.0.2", 2438 | "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", 2439 | "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", 2440 | "dev": true, 2441 | "dependencies": { 2442 | "call-bind": "^1.0.7", 2443 | "es-errors": "^1.3.0", 2444 | "is-typed-array": "^1.1.13" 2445 | }, 2446 | "engines": { 2447 | "node": ">= 0.4" 2448 | } 2449 | }, 2450 | "node_modules/typed-array-byte-length": { 2451 | "version": "1.0.1", 2452 | "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", 2453 | "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", 2454 | "dev": true, 2455 | "dependencies": { 2456 | "call-bind": "^1.0.7", 2457 | "for-each": "^0.3.3", 2458 | "gopd": "^1.0.1", 2459 | "has-proto": "^1.0.3", 2460 | "is-typed-array": "^1.1.13" 2461 | }, 2462 | "engines": { 2463 | "node": ">= 0.4" 2464 | }, 2465 | "funding": { 2466 | "url": "https://github.com/sponsors/ljharb" 2467 | } 2468 | }, 2469 | "node_modules/typed-array-byte-offset": { 2470 | "version": "1.0.2", 2471 | "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", 2472 | "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", 2473 | "dev": true, 2474 | "dependencies": { 2475 | "available-typed-arrays": "^1.0.7", 2476 | "call-bind": "^1.0.7", 2477 | "for-each": "^0.3.3", 2478 | "gopd": "^1.0.1", 2479 | "has-proto": "^1.0.3", 2480 | "is-typed-array": "^1.1.13" 2481 | }, 2482 | "engines": { 2483 | "node": ">= 0.4" 2484 | }, 2485 | "funding": { 2486 | "url": "https://github.com/sponsors/ljharb" 2487 | } 2488 | }, 2489 | "node_modules/typed-array-length": { 2490 | "version": "1.0.6", 2491 | "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", 2492 | "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", 2493 | "dev": true, 2494 | "dependencies": { 2495 | "call-bind": "^1.0.7", 2496 | "for-each": "^0.3.3", 2497 | "gopd": "^1.0.1", 2498 | "has-proto": "^1.0.3", 2499 | "is-typed-array": "^1.1.13", 2500 | "possible-typed-array-names": "^1.0.0" 2501 | }, 2502 | "engines": { 2503 | "node": ">= 0.4" 2504 | }, 2505 | "funding": { 2506 | "url": "https://github.com/sponsors/ljharb" 2507 | } 2508 | }, 2509 | "node_modules/typescript": { 2510 | "version": "5.5.4", 2511 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", 2512 | "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", 2513 | "devOptional": true, 2514 | "bin": { 2515 | "tsc": "bin/tsc", 2516 | "tsserver": "bin/tsserver" 2517 | }, 2518 | "engines": { 2519 | "node": ">=14.17" 2520 | } 2521 | }, 2522 | "node_modules/uint8array-tools": { 2523 | "version": "0.0.8", 2524 | "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.8.tgz", 2525 | "integrity": "sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==", 2526 | "engines": { 2527 | "node": ">=14.0.0" 2528 | } 2529 | }, 2530 | "node_modules/unbox-primitive": { 2531 | "version": "1.0.2", 2532 | "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", 2533 | "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", 2534 | "dev": true, 2535 | "dependencies": { 2536 | "call-bind": "^1.0.2", 2537 | "has-bigints": "^1.0.2", 2538 | "has-symbols": "^1.0.3", 2539 | "which-boxed-primitive": "^1.0.2" 2540 | }, 2541 | "funding": { 2542 | "url": "https://github.com/sponsors/ljharb" 2543 | } 2544 | }, 2545 | "node_modules/undici-types": { 2546 | "version": "5.26.5", 2547 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 2548 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 2549 | "dev": true 2550 | }, 2551 | "node_modules/v8-to-istanbul": { 2552 | "version": "9.3.0", 2553 | "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", 2554 | "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", 2555 | "dev": true, 2556 | "dependencies": { 2557 | "@jridgewell/trace-mapping": "^0.3.12", 2558 | "@types/istanbul-lib-coverage": "^2.0.1", 2559 | "convert-source-map": "^2.0.0" 2560 | }, 2561 | "engines": { 2562 | "node": ">=10.12.0" 2563 | } 2564 | }, 2565 | "node_modules/v8-to-istanbul/node_modules/convert-source-map": { 2566 | "version": "2.0.0", 2567 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", 2568 | "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", 2569 | "dev": true 2570 | }, 2571 | "node_modules/valibot": { 2572 | "version": "0.37.0", 2573 | "resolved": "https://registry.npmjs.org/valibot/-/valibot-0.37.0.tgz", 2574 | "integrity": "sha512-FQz52I8RXgFgOHym3XHYSREbNtkgSjF9prvMFH1nBsRyfL6SfCzoT1GuSDTlbsuPubM7/6Kbw0ZMQb8A+V+VsQ==", 2575 | "peerDependencies": { 2576 | "typescript": ">=5" 2577 | }, 2578 | "peerDependenciesMeta": { 2579 | "typescript": { 2580 | "optional": true 2581 | } 2582 | } 2583 | }, 2584 | "node_modules/which": { 2585 | "version": "2.0.2", 2586 | "dev": true, 2587 | "license": "ISC", 2588 | "dependencies": { 2589 | "isexe": "^2.0.0" 2590 | }, 2591 | "bin": { 2592 | "node-which": "bin/node-which" 2593 | }, 2594 | "engines": { 2595 | "node": ">= 8" 2596 | } 2597 | }, 2598 | "node_modules/which-boxed-primitive": { 2599 | "version": "1.0.2", 2600 | "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", 2601 | "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", 2602 | "dev": true, 2603 | "dependencies": { 2604 | "is-bigint": "^1.0.1", 2605 | "is-boolean-object": "^1.1.0", 2606 | "is-number-object": "^1.0.4", 2607 | "is-string": "^1.0.5", 2608 | "is-symbol": "^1.0.3" 2609 | }, 2610 | "funding": { 2611 | "url": "https://github.com/sponsors/ljharb" 2612 | } 2613 | }, 2614 | "node_modules/which-collection": { 2615 | "version": "1.0.2", 2616 | "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", 2617 | "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", 2618 | "dev": true, 2619 | "dependencies": { 2620 | "is-map": "^2.0.3", 2621 | "is-set": "^2.0.3", 2622 | "is-weakmap": "^2.0.2", 2623 | "is-weakset": "^2.0.3" 2624 | }, 2625 | "engines": { 2626 | "node": ">= 0.4" 2627 | }, 2628 | "funding": { 2629 | "url": "https://github.com/sponsors/ljharb" 2630 | } 2631 | }, 2632 | "node_modules/which-typed-array": { 2633 | "version": "1.1.15", 2634 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", 2635 | "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", 2636 | "dev": true, 2637 | "dependencies": { 2638 | "available-typed-arrays": "^1.0.7", 2639 | "call-bind": "^1.0.7", 2640 | "for-each": "^0.3.3", 2641 | "gopd": "^1.0.1", 2642 | "has-tostringtag": "^1.0.2" 2643 | }, 2644 | "engines": { 2645 | "node": ">= 0.4" 2646 | }, 2647 | "funding": { 2648 | "url": "https://github.com/sponsors/ljharb" 2649 | } 2650 | }, 2651 | "node_modules/wif": { 2652 | "version": "5.0.0", 2653 | "resolved": "https://registry.npmjs.org/wif/-/wif-5.0.0.tgz", 2654 | "integrity": "sha512-iFzrC/9ne740qFbNjTZ2FciSRJlHIXoxqk/Y5EnE08QOXu1WjJyCCswwDTYbohAOEnlCtLaAAQBhyaLRFh2hMA==", 2655 | "dependencies": { 2656 | "bs58check": "^4.0.0" 2657 | } 2658 | }, 2659 | "node_modules/wrap-ansi-cjs": { 2660 | "name": "wrap-ansi", 2661 | "version": "7.0.0", 2662 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2663 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2664 | "dev": true, 2665 | "dependencies": { 2666 | "ansi-styles": "^4.0.0", 2667 | "string-width": "^4.1.0", 2668 | "strip-ansi": "^6.0.0" 2669 | }, 2670 | "engines": { 2671 | "node": ">=10" 2672 | }, 2673 | "funding": { 2674 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2675 | } 2676 | }, 2677 | "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { 2678 | "version": "4.3.0", 2679 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 2680 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 2681 | "dev": true, 2682 | "dependencies": { 2683 | "color-convert": "^2.0.1" 2684 | }, 2685 | "engines": { 2686 | "node": ">=8" 2687 | }, 2688 | "funding": { 2689 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 2690 | } 2691 | }, 2692 | "node_modules/wrap-ansi-cjs/node_modules/color-convert": { 2693 | "version": "2.0.1", 2694 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 2695 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 2696 | "dev": true, 2697 | "dependencies": { 2698 | "color-name": "~1.1.4" 2699 | }, 2700 | "engines": { 2701 | "node": ">=7.0.0" 2702 | } 2703 | }, 2704 | "node_modules/wrap-ansi-cjs/node_modules/color-name": { 2705 | "version": "1.1.4", 2706 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 2707 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 2708 | "dev": true 2709 | }, 2710 | "node_modules/wrappy": { 2711 | "version": "1.0.2", 2712 | "dev": true, 2713 | "license": "ISC" 2714 | }, 2715 | "node_modules/yocto-queue": { 2716 | "version": "0.1.0", 2717 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", 2718 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", 2719 | "dev": true, 2720 | "engines": { 2721 | "node": ">=10" 2722 | }, 2723 | "funding": { 2724 | "url": "https://github.com/sponsors/sindresorhus" 2725 | } 2726 | } 2727 | } 2728 | } 2729 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bip32", 3 | "version": "5.0.0-rc.0", 4 | "type": "module", 5 | "description": "A BIP32 compatible library", 6 | "keywords": [ 7 | "bip32", 8 | "bitcoinjs", 9 | "bitcoin", 10 | "secp256k1" 11 | ], 12 | "main": "./src/cjs/index.cjs", 13 | "module": "./src/esm/index.js", 14 | "types": "./src/cjs/index.d.ts", 15 | "exports": { 16 | ".": { 17 | "require": "./src/cjs/index.cjs", 18 | "import": "./src/esm/index.js", 19 | "types": "./src/cjs/index.d.ts" 20 | } 21 | }, 22 | "engines": { 23 | "node": ">=18.0.0" 24 | }, 25 | "scripts": { 26 | "build": "tsc -p ./tsconfig.json && tsc -p ./tsconfig.cjs.json", 27 | "checkHybrid": "chmod +x test.cjs && node test.cjs", 28 | "coverage-report": "npm run build && npm run nobuild:coverage-report", 29 | "coverage": "npm run build && npm run nobuild:coverage", 30 | "format": "npm run prettier -- --write", 31 | "format:ci": "npm run prettier -- --check", 32 | "gitdiff:ci": "npm run build && git diff --exit-code", 33 | "lint": "tslint -p tsconfig.json -c tslint.json", 34 | "nobuild:coverage-report": "c8 report --reporter=lcov", 35 | "nobuild:coverage": "c8 --check-coverage --branches 90 --functions 90 npm run nobuild:unit", 36 | "nobuild:unit": "tape test/*.js", 37 | "postbuild": "find src/cjs -type f -name \"*.js\" -exec bash -c 'mv \"$0\" \"${0%.js}.cjs\"' {} \\; && chmod +x fixup.cjs && node fixup.cjs", 38 | "prettier": "prettier 'ts-src/**/*.ts' --ignore-path ./.prettierignore", 39 | "test": "npm run build && npm run format:ci && npm run lint && npm run nobuild:coverage", 40 | "unit": "npm run build && npm run nobuild:unit" 41 | }, 42 | "repository": { 43 | "type": "git", 44 | "url": "git+https://github.com/bitcoinjs/bip32.git" 45 | }, 46 | "files": [ 47 | "src" 48 | ], 49 | "dependencies": { 50 | "@noble/hashes": "^1.2.0", 51 | "@scure/base": "^1.1.1", 52 | "uint8array-tools": "^0.0.8", 53 | "valibot": "^0.37.0", 54 | "wif": "^5.0.0" 55 | }, 56 | "devDependencies": { 57 | "@types/node": "18.x", 58 | "@types/tape": "^5.6.4", 59 | "c8": "^10.1.2", 60 | "prettier": "1.16.4", 61 | "tape": "^5.3.0", 62 | "tiny-secp256k1": "^2.2.1", 63 | "tslint": "^6.1.0", 64 | "typescript": "^5.0.4" 65 | }, 66 | "author": "Daniel Cousens", 67 | "license": "MIT", 68 | "bugs": { 69 | "url": "https://github.com/bitcoinjs/bip32/issues" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/cjs/bip32.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.BIP32Factory = BIP32Factory; 27 | const crypto = __importStar(require("./crypto.cjs")); 28 | const testecc_js_1 = require("./testecc.cjs"); 29 | const base_1 = require("@scure/base"); 30 | const sha256_1 = require("@noble/hashes/sha256"); 31 | const v = __importStar(require("valibot")); 32 | const types_js_1 = require("./types.cjs"); 33 | const wif = __importStar(require("wif")); 34 | const tools = __importStar(require("uint8array-tools")); 35 | const _bs58check = (0, base_1.base58check)(sha256_1.sha256); 36 | const bs58check = { 37 | encode: (data) => _bs58check.encode(data), 38 | decode: (str) => _bs58check.decode(str), 39 | }; 40 | function BIP32Factory(ecc) { 41 | (0, testecc_js_1.testEcc)(ecc); 42 | const BITCOIN = { 43 | messagePrefix: '\x18Bitcoin Signed Message:\n', 44 | bech32: 'bc', 45 | bip32: { 46 | public: 0x0488b21e, 47 | private: 0x0488ade4, 48 | }, 49 | pubKeyHash: 0x00, 50 | scriptHash: 0x05, 51 | wif: 0x80, 52 | }; 53 | const HIGHEST_BIT = 0x80000000; 54 | function toXOnly(pubKey) { 55 | return pubKey.length === 32 ? pubKey : pubKey.slice(1, 33); 56 | } 57 | class Bip32Signer { 58 | __D; 59 | __Q; 60 | lowR = false; 61 | constructor(__D, __Q) { 62 | this.__D = __D; 63 | this.__Q = __Q; 64 | } 65 | get publicKey() { 66 | if (this.__Q === undefined) 67 | this.__Q = ecc.pointFromScalar(this.__D, true); 68 | return this.__Q; 69 | } 70 | get privateKey() { 71 | return this.__D; 72 | } 73 | sign(hash, lowR) { 74 | if (!this.privateKey) 75 | throw new Error('Missing private key'); 76 | if (lowR === undefined) 77 | lowR = this.lowR; 78 | if (lowR === false) { 79 | return ecc.sign(hash, this.privateKey); 80 | } 81 | else { 82 | let sig = ecc.sign(hash, this.privateKey); 83 | const extraData = new Uint8Array(32); 84 | let counter = 0; 85 | // if first try is lowR, skip the loop 86 | // for second try and on, add extra entropy counting up 87 | while (sig[0] > 0x7f) { 88 | counter++; 89 | tools.writeUInt32(extraData, 0, counter, 'LE'); 90 | sig = ecc.sign(hash, this.privateKey, extraData); 91 | } 92 | return sig; 93 | } 94 | } 95 | signSchnorr(hash) { 96 | if (!this.privateKey) 97 | throw new Error('Missing private key'); 98 | if (!ecc.signSchnorr) 99 | throw new Error('signSchnorr not supported by ecc library'); 100 | return ecc.signSchnorr(hash, this.privateKey); 101 | } 102 | verify(hash, signature) { 103 | return ecc.verify(hash, this.publicKey, signature); 104 | } 105 | verifySchnorr(hash, signature) { 106 | if (!ecc.verifySchnorr) 107 | throw new Error('verifySchnorr not supported by ecc library'); 108 | return ecc.verifySchnorr(hash, this.publicKey.subarray(1, 33), signature); 109 | } 110 | } 111 | class BIP32 extends Bip32Signer { 112 | chainCode; 113 | network; 114 | __DEPTH; 115 | __INDEX; 116 | __PARENT_FINGERPRINT; 117 | constructor(__D, __Q, chainCode, network, __DEPTH = 0, __INDEX = 0, __PARENT_FINGERPRINT = 0x00000000) { 118 | super(__D, __Q); 119 | this.chainCode = chainCode; 120 | this.network = network; 121 | this.__DEPTH = __DEPTH; 122 | this.__INDEX = __INDEX; 123 | this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT; 124 | v.parse(types_js_1.NetworkSchema, network); 125 | } 126 | get depth() { 127 | return this.__DEPTH; 128 | } 129 | get index() { 130 | return this.__INDEX; 131 | } 132 | get parentFingerprint() { 133 | return this.__PARENT_FINGERPRINT; 134 | } 135 | get identifier() { 136 | return crypto.hash160(this.publicKey); 137 | } 138 | get fingerprint() { 139 | return this.identifier.slice(0, 4); 140 | } 141 | get compressed() { 142 | return true; 143 | } 144 | // Private === not neutered 145 | // Public === neutered 146 | isNeutered() { 147 | return this.__D === undefined; 148 | } 149 | neutered() { 150 | return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint); 151 | } 152 | toBase58() { 153 | const network = this.network; 154 | const version = !this.isNeutered() 155 | ? network.bip32.private 156 | : network.bip32.public; 157 | const buffer = new Uint8Array(78); 158 | // 4 bytes: version bytes 159 | tools.writeUInt32(buffer, 0, version, 'BE'); 160 | // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, .... 161 | tools.writeUInt8(buffer, 4, this.depth); 162 | // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) 163 | tools.writeUInt32(buffer, 5, this.parentFingerprint, 'BE'); 164 | // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. 165 | // This is encoded in big endian. (0x00000000 if master key) 166 | tools.writeUInt32(buffer, 9, this.index, 'BE'); 167 | // 32 bytes: the chain code 168 | buffer.set(this.chainCode, 13); 169 | // 33 bytes: the public key or private key data 170 | if (!this.isNeutered()) { 171 | // 0x00 + k for private keys 172 | tools.writeUInt8(buffer, 45, 0); 173 | buffer.set(this.privateKey, 46); 174 | // 33 bytes: the public key 175 | } 176 | else { 177 | // X9.62 encoding for public keys 178 | buffer.set(this.publicKey, 45); 179 | } 180 | return bs58check.encode(buffer); 181 | } 182 | toWIF() { 183 | if (!this.privateKey) 184 | throw new TypeError('Missing private key'); 185 | return wif.encode({ 186 | version: this.network.wif, 187 | privateKey: this.privateKey, 188 | compressed: true, 189 | }); 190 | } 191 | // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions 192 | derive(index) { 193 | v.parse(types_js_1.Uint32Schema, index); 194 | const isHardened = index >= HIGHEST_BIT; 195 | const data = new Uint8Array(37); 196 | // Hardened child 197 | if (isHardened) { 198 | if (this.isNeutered()) 199 | throw new TypeError('Missing private key for hardened child key'); 200 | // data = 0x00 || ser256(kpar) || ser32(index) 201 | data[0] = 0x00; 202 | data.set(this.privateKey, 1); 203 | tools.writeUInt32(data, 33, index, 'BE'); 204 | // Normal child 205 | } 206 | else { 207 | // data = serP(point(kpar)) || ser32(index) 208 | // = serP(Kpar) || ser32(index) 209 | data.set(this.publicKey, 0); 210 | tools.writeUInt32(data, 33, index, 'BE'); 211 | } 212 | const I = crypto.hmacSHA512(this.chainCode, data); 213 | const IL = I.slice(0, 32); 214 | const IR = I.slice(32); 215 | // if parse256(IL) >= n, proceed with the next value for i 216 | if (!ecc.isPrivate(IL)) 217 | return this.derive(index + 1); 218 | // Private parent key -> private child key 219 | let hd; 220 | if (!this.isNeutered()) { 221 | // ki = parse256(IL) + kpar (mod n) 222 | const ki = ecc.privateAdd(this.privateKey, IL); 223 | // In case ki == 0, proceed with the next value for i 224 | if (ki == null) 225 | return this.derive(index + 1); 226 | hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, tools.readUInt32(this.fingerprint, 0, 'BE')); 227 | // Public parent key -> public child key 228 | } 229 | else { 230 | // Ki = point(parse256(IL)) + Kpar 231 | // = G*IL + Kpar 232 | const Ki = ecc.pointAddScalar(this.publicKey, IL, true); 233 | // In case Ki is the point at infinity, proceed with the next value for i 234 | if (Ki === null) 235 | return this.derive(index + 1); 236 | hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, tools.readUInt32(this.fingerprint, 0, 'BE')); 237 | } 238 | return hd; 239 | } 240 | deriveHardened(index) { 241 | if (typeof v.parse(types_js_1.Uint31Schema, index) === 'number') 242 | // Only derives hardened private keys by default 243 | return this.derive(index + HIGHEST_BIT); 244 | throw new TypeError('Expected UInt31, got ' + index); 245 | } 246 | derivePath(path) { 247 | v.parse(types_js_1.Bip32PathSchema, path); 248 | let splitPath = path.split('/'); 249 | if (splitPath[0] === 'm') { 250 | if (this.parentFingerprint) 251 | throw new TypeError('Expected master, got child'); 252 | splitPath = splitPath.slice(1); 253 | } 254 | return splitPath.reduce((prevHd, indexStr) => { 255 | let index; 256 | if (indexStr.slice(-1) === `'`) { 257 | index = parseInt(indexStr.slice(0, -1), 10); 258 | return prevHd.deriveHardened(index); 259 | } 260 | else { 261 | index = parseInt(indexStr, 10); 262 | return prevHd.derive(index); 263 | } 264 | }, this); 265 | } 266 | tweak(t) { 267 | if (this.privateKey) 268 | return this.tweakFromPrivateKey(t); 269 | return this.tweakFromPublicKey(t); 270 | } 271 | tweakFromPublicKey(t) { 272 | const xOnlyPubKey = toXOnly(this.publicKey); 273 | if (!ecc.xOnlyPointAddTweak) 274 | throw new Error('xOnlyPointAddTweak not supported by ecc library'); 275 | const tweakedPublicKey = ecc.xOnlyPointAddTweak(xOnlyPubKey, t); 276 | if (!tweakedPublicKey || tweakedPublicKey.xOnlyPubkey === null) 277 | throw new Error('Cannot tweak public key!'); 278 | const parityByte = Uint8Array.from([ 279 | tweakedPublicKey.parity === 0 ? 0x02 : 0x03, 280 | ]); 281 | const tweakedPublicKeyCompresed = tools.concat([ 282 | parityByte, 283 | tweakedPublicKey.xOnlyPubkey, 284 | ]); 285 | return new Bip32Signer(undefined, tweakedPublicKeyCompresed); 286 | } 287 | tweakFromPrivateKey(t) { 288 | const hasOddY = this.publicKey[0] === 3 || 289 | (this.publicKey[0] === 4 && (this.publicKey[64] & 1) === 1); 290 | const privateKey = (() => { 291 | if (!hasOddY) 292 | return this.privateKey; 293 | else if (!ecc.privateNegate) 294 | throw new Error('privateNegate not supported by ecc library'); 295 | else 296 | return ecc.privateNegate(this.privateKey); 297 | })(); 298 | const tweakedPrivateKey = ecc.privateAdd(privateKey, t); 299 | if (!tweakedPrivateKey) 300 | throw new Error('Invalid tweaked private key!'); 301 | return new Bip32Signer(tweakedPrivateKey, undefined); 302 | } 303 | } 304 | function fromBase58(inString, network) { 305 | const buffer = bs58check.decode(inString); 306 | if (buffer.length !== 78) 307 | throw new TypeError('Invalid buffer length'); 308 | network = network || BITCOIN; 309 | // 4 bytes: version bytes 310 | const version = tools.readUInt32(buffer, 0, 'BE'); 311 | if (version !== network.bip32.private && version !== network.bip32.public) 312 | throw new TypeError('Invalid network version'); 313 | // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... 314 | const depth = buffer[4]; 315 | // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) 316 | const parentFingerprint = tools.readUInt32(buffer, 5, 'BE'); 317 | if (depth === 0) { 318 | if (parentFingerprint !== 0x00000000) 319 | throw new TypeError('Invalid parent fingerprint'); 320 | } 321 | // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. 322 | // This is encoded in MSB order. (0x00000000 if master key) 323 | const index = tools.readUInt32(buffer, 9, 'BE'); 324 | if (depth === 0 && index !== 0) 325 | throw new TypeError('Invalid index'); 326 | // 32 bytes: the chain code 327 | const chainCode = buffer.slice(13, 45); 328 | let hd; 329 | // 33 bytes: private key data (0x00 + k) 330 | if (version === network.bip32.private) { 331 | if (buffer[45] !== 0x00) 332 | throw new TypeError('Invalid private key'); 333 | const k = buffer.slice(46, 78); 334 | hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint); 335 | // 33 bytes: public key data (0x02 + X or 0x03 + X) 336 | } 337 | else { 338 | const X = buffer.slice(45, 78); 339 | hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint); 340 | } 341 | return hd; 342 | } 343 | function fromPrivateKey(privateKey, chainCode, network) { 344 | return fromPrivateKeyLocal(privateKey, chainCode, network); 345 | } 346 | function fromPrivateKeyLocal(privateKey, chainCode, network, depth, index, parentFingerprint) { 347 | v.parse(types_js_1.Buffer256Bit, privateKey); 348 | v.parse(types_js_1.Buffer256Bit, chainCode); 349 | network = network || BITCOIN; 350 | if (!ecc.isPrivate(privateKey)) 351 | throw new TypeError('Private key not in range [1, n)'); 352 | return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint); 353 | } 354 | function fromPublicKey(publicKey, chainCode, network) { 355 | return fromPublicKeyLocal(publicKey, chainCode, network); 356 | } 357 | function fromPublicKeyLocal(publicKey, chainCode, network, depth, index, parentFingerprint) { 358 | v.parse(types_js_1.Buffer33Bytes, publicKey); 359 | v.parse(types_js_1.Buffer256Bit, chainCode); 360 | network = network || BITCOIN; 361 | // verify the X coordinate is a point on the curve 362 | if (!ecc.isPoint(publicKey)) 363 | throw new TypeError('Point is not on the curve'); 364 | return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint); 365 | } 366 | function fromSeed(seed, network) { 367 | v.parse(v.instance(Uint8Array), seed); 368 | if (seed.length < 16) 369 | throw new TypeError('Seed should be at least 128 bits'); 370 | if (seed.length > 64) 371 | throw new TypeError('Seed should be at most 512 bits'); 372 | network = network || BITCOIN; 373 | const I = crypto.hmacSHA512(tools.fromUtf8('Bitcoin seed'), seed); 374 | const IL = I.slice(0, 32); 375 | const IR = I.slice(32); 376 | return fromPrivateKey(IL, IR, network); 377 | } 378 | return { 379 | fromSeed, 380 | fromBase58, 381 | fromPublicKey, 382 | fromPrivateKey, 383 | }; 384 | } 385 | -------------------------------------------------------------------------------- /src/cjs/bip32.d.ts: -------------------------------------------------------------------------------- 1 | interface Network { 2 | wif: number; 3 | bip32: { 4 | public: number; 5 | private: number; 6 | }; 7 | messagePrefix?: string; 8 | bech32?: string; 9 | pubKeyHash?: number; 10 | scriptHash?: number; 11 | } 12 | export interface Signer { 13 | publicKey: Uint8Array; 14 | lowR: boolean; 15 | sign(hash: Uint8Array, lowR?: boolean): Uint8Array; 16 | verify(hash: Uint8Array, signature: Uint8Array): boolean; 17 | signSchnorr(hash: Uint8Array): Uint8Array; 18 | verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean; 19 | } 20 | export interface BIP32Interface extends Signer { 21 | chainCode: Uint8Array; 22 | network: Network; 23 | depth: number; 24 | index: number; 25 | parentFingerprint: number; 26 | privateKey?: Uint8Array; 27 | identifier: Uint8Array; 28 | fingerprint: Uint8Array; 29 | isNeutered(): boolean; 30 | neutered(): BIP32Interface; 31 | toBase58(): string; 32 | toWIF(): string; 33 | derive(index: number): BIP32Interface; 34 | deriveHardened(index: number): BIP32Interface; 35 | derivePath(path: string): BIP32Interface; 36 | tweak(t: Uint8Array): Signer; 37 | } 38 | export interface BIP32API { 39 | fromSeed(seed: Uint8Array, network?: Network): BIP32Interface; 40 | fromBase58(inString: string, network?: Network): BIP32Interface; 41 | fromPublicKey(publicKey: Uint8Array, chainCode: Uint8Array, network?: Network): BIP32Interface; 42 | fromPrivateKey(privateKey: Uint8Array, chainCode: Uint8Array, network?: Network): BIP32Interface; 43 | } 44 | interface XOnlyPointAddTweakResult { 45 | parity: 1 | 0; 46 | xOnlyPubkey: Uint8Array; 47 | } 48 | export interface TinySecp256k1Interface { 49 | isPoint(p: Uint8Array): boolean; 50 | isPrivate(d: Uint8Array): boolean; 51 | pointFromScalar(d: Uint8Array, compressed?: boolean): Uint8Array | null; 52 | pointAddScalar(p: Uint8Array, tweak: Uint8Array, compressed?: boolean): Uint8Array | null; 53 | privateAdd(d: Uint8Array, tweak: Uint8Array): Uint8Array | null; 54 | sign(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array; 55 | signSchnorr?(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array; 56 | verify(h: Uint8Array, Q: Uint8Array, signature: Uint8Array, strict?: boolean): boolean; 57 | verifySchnorr?(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean; 58 | xOnlyPointAddTweak?(p: Uint8Array, tweak: Uint8Array): XOnlyPointAddTweakResult | null; 59 | privateNegate?(d: Uint8Array): Uint8Array; 60 | } 61 | export declare function BIP32Factory(ecc: TinySecp256k1Interface): BIP32API; 62 | export {}; 63 | -------------------------------------------------------------------------------- /src/cjs/crypto.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.hash160 = hash160; 4 | exports.hmacSHA512 = hmacSHA512; 5 | const hmac_1 = require("@noble/hashes/hmac"); 6 | const ripemd160_1 = require("@noble/hashes/ripemd160"); 7 | const sha256_1 = require("@noble/hashes/sha256"); 8 | const sha512_1 = require("@noble/hashes/sha512"); 9 | function hash160(buffer) { 10 | return (0, ripemd160_1.ripemd160)((0, sha256_1.sha256)(buffer)); 11 | } 12 | function hmacSHA512(key, data) { 13 | return (0, hmac_1.hmac)(sha512_1.sha512, key, data); 14 | } 15 | -------------------------------------------------------------------------------- /src/cjs/crypto.d.ts: -------------------------------------------------------------------------------- 1 | export declare function hash160(buffer: Uint8Array): Uint8Array; 2 | export declare function hmacSHA512(key: Uint8Array, data: Uint8Array): Uint8Array; 3 | -------------------------------------------------------------------------------- /src/cjs/index.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.BIP32Factory = exports.default = void 0; 4 | var bip32_js_1 = require("./bip32.cjs"); 5 | Object.defineProperty(exports, "default", { enumerable: true, get: function () { return bip32_js_1.BIP32Factory; } }); 6 | Object.defineProperty(exports, "BIP32Factory", { enumerable: true, get: function () { return bip32_js_1.BIP32Factory; } }); 7 | -------------------------------------------------------------------------------- /src/cjs/index.d.ts: -------------------------------------------------------------------------------- 1 | export { BIP32Factory as default, BIP32Factory, BIP32Interface, BIP32API, TinySecp256k1Interface, } from './bip32.js'; 2 | -------------------------------------------------------------------------------- /src/cjs/testecc.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.testEcc = testEcc; 27 | const tools = __importStar(require("uint8array-tools")); 28 | const h = (hex) => tools.fromHex(hex); 29 | function testEcc(ecc) { 30 | assert(ecc.isPoint(h('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'))); 31 | assert(!ecc.isPoint(h('030000000000000000000000000000000000000000000000000000000000000005'))); 32 | assert(ecc.isPrivate(h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'))); 33 | // order - 1 34 | assert(ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'))); 35 | // 0 36 | assert(!ecc.isPrivate(h('0000000000000000000000000000000000000000000000000000000000000000'))); 37 | // order 38 | assert(!ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'))); 39 | // order + 1 40 | assert(!ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142'))); 41 | assert(tools.compare(ecc.pointFromScalar(h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af')), h('02b07ba9dca9523b7ef4bd97703d43d20399eb698e194704791a25ce77a400df99')) === 0); 42 | if (ecc.xOnlyPointAddTweak) { 43 | assert(ecc.xOnlyPointAddTweak(h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')) === null); 44 | let xOnlyRes = ecc.xOnlyPointAddTweak(h('1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b'), h('a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac')); 45 | assert(tools.compare(xOnlyRes.xOnlyPubkey, h('e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf')) === 0 && xOnlyRes.parity === 1); 46 | xOnlyRes = ecc.xOnlyPointAddTweak(h('2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991'), h('823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47')); 47 | } 48 | assert(tools.compare(ecc.pointAddScalar(h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('0000000000000000000000000000000000000000000000000000000000000003')), h('02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5')) === 0); 49 | assert(tools.compare(ecc.privateAdd(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e'), h('0000000000000000000000000000000000000000000000000000000000000002')), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')) === 0); 50 | if (ecc.privateNegate) { 51 | assert(tools.compare(ecc.privateNegate(h('0000000000000000000000000000000000000000000000000000000000000001')), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')) === 0); 52 | assert(tools.compare(ecc.privateNegate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e')), h('0000000000000000000000000000000000000000000000000000000000000003')) === 0); 53 | assert(tools.compare(ecc.privateNegate(h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af')), h('4eede1bf775995d70a494f0a7bb6bc11e0b8cccd41cce8009ab1132c8b0a3792')) === 0); 54 | } 55 | assert(tools.compare(ecc.sign(h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')), h('54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5')) === 0); 56 | assert(ecc.verify(h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5'))); 57 | if (ecc.signSchnorr) { 58 | assert(tools.compare(ecc.signSchnorr(h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), h('c90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b14e5c9'), h('c87aa53824b4d7ae2eb035a2b5bbbccc080e76cdc6d1692c4b0b62d798e6d906')), h('5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7')) === 0); 59 | } 60 | if (ecc.verifySchnorr) { 61 | assert(ecc.verifySchnorr(h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), h('dd308afec5777e13121fa72b9cc1b7cc0139715309b086c960e18fd969774eb8'), h('5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7'))); 62 | } 63 | } 64 | function assert(bool) { 65 | if (!bool) 66 | throw new Error('ecc library invalid'); 67 | } 68 | -------------------------------------------------------------------------------- /src/cjs/testecc.d.ts: -------------------------------------------------------------------------------- 1 | import { TinySecp256k1Interface } from './bip32'; 2 | export declare function testEcc(ecc: TinySecp256k1Interface): void; 3 | -------------------------------------------------------------------------------- /src/cjs/types.cjs: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { 3 | if (k2 === undefined) k2 = k; 4 | var desc = Object.getOwnPropertyDescriptor(m, k); 5 | if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { 6 | desc = { enumerable: true, get: function() { return m[k]; } }; 7 | } 8 | Object.defineProperty(o, k2, desc); 9 | }) : (function(o, m, k, k2) { 10 | if (k2 === undefined) k2 = k; 11 | o[k2] = m[k]; 12 | })); 13 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { 14 | Object.defineProperty(o, "default", { enumerable: true, value: v }); 15 | }) : function(o, v) { 16 | o["default"] = v; 17 | }); 18 | var __importStar = (this && this.__importStar) || function (mod) { 19 | if (mod && mod.__esModule) return mod; 20 | var result = {}; 21 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); 22 | __setModuleDefault(result, mod); 23 | return result; 24 | }; 25 | Object.defineProperty(exports, "__esModule", { value: true }); 26 | exports.Bip32PathSchema = exports.NetworkSchema = exports.Buffer33Bytes = exports.Buffer256Bit = exports.Uint31Schema = exports.Uint32Schema = void 0; 27 | const v = __importStar(require("valibot")); 28 | exports.Uint32Schema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(0xffffffff)); 29 | exports.Uint31Schema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(0x7fffffff)); 30 | const Uint8Schema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(0xff)); 31 | exports.Buffer256Bit = v.pipe(v.instance(Uint8Array), v.length(32)); 32 | exports.Buffer33Bytes = v.pipe(v.instance(Uint8Array), v.length(33)); 33 | exports.NetworkSchema = v.object({ 34 | wif: Uint8Schema, 35 | bip32: v.object({ 36 | public: exports.Uint32Schema, 37 | private: exports.Uint32Schema, 38 | }), 39 | }); 40 | exports.Bip32PathSchema = v.pipe(v.string(), v.regex(/^(m\/)?(\d+'?\/)*\d+'?$/)); 41 | -------------------------------------------------------------------------------- /src/cjs/types.d.ts: -------------------------------------------------------------------------------- 1 | import * as v from 'valibot'; 2 | export declare const Uint32Schema: v.SchemaWithPipe<[v.NumberSchema, v.IntegerAction, v.MinValueAction, v.MaxValueAction]>; 3 | export declare const Uint31Schema: v.SchemaWithPipe<[v.NumberSchema, v.IntegerAction, v.MinValueAction, v.MaxValueAction]>; 4 | export declare const Buffer256Bit: v.SchemaWithPipe<[v.InstanceSchema, v.LengthAction]>; 5 | export declare const Buffer33Bytes: v.SchemaWithPipe<[v.InstanceSchema, v.LengthAction]>; 6 | export declare const NetworkSchema: v.ObjectSchema<{ 7 | readonly wif: v.SchemaWithPipe<[v.NumberSchema, v.IntegerAction, v.MinValueAction, v.MaxValueAction]>; 8 | readonly bip32: v.ObjectSchema<{ 9 | readonly public: v.SchemaWithPipe<[v.NumberSchema, v.IntegerAction, v.MinValueAction, v.MaxValueAction]>; 10 | readonly private: v.SchemaWithPipe<[v.NumberSchema, v.IntegerAction, v.MinValueAction, v.MaxValueAction]>; 11 | }, undefined>; 12 | }, undefined>; 13 | export declare const Bip32PathSchema: v.SchemaWithPipe<[v.StringSchema, v.RegexAction]>; 14 | export type Network = v.InferOutput; 15 | -------------------------------------------------------------------------------- /src/esm/bip32.js: -------------------------------------------------------------------------------- 1 | import * as crypto from './crypto.js'; 2 | import { testEcc } from './testecc.js'; 3 | import { base58check } from '@scure/base'; 4 | import { sha256 } from '@noble/hashes/sha256'; 5 | import * as v from 'valibot'; 6 | import { Bip32PathSchema, Buffer256Bit, Buffer33Bytes, NetworkSchema, Uint31Schema, Uint32Schema, } from './types.js'; 7 | import * as wif from 'wif'; 8 | import * as tools from 'uint8array-tools'; 9 | const _bs58check = base58check(sha256); 10 | const bs58check = { 11 | encode: (data) => _bs58check.encode(data), 12 | decode: (str) => _bs58check.decode(str), 13 | }; 14 | export function BIP32Factory(ecc) { 15 | testEcc(ecc); 16 | const BITCOIN = { 17 | messagePrefix: '\x18Bitcoin Signed Message:\n', 18 | bech32: 'bc', 19 | bip32: { 20 | public: 0x0488b21e, 21 | private: 0x0488ade4, 22 | }, 23 | pubKeyHash: 0x00, 24 | scriptHash: 0x05, 25 | wif: 0x80, 26 | }; 27 | const HIGHEST_BIT = 0x80000000; 28 | function toXOnly(pubKey) { 29 | return pubKey.length === 32 ? pubKey : pubKey.slice(1, 33); 30 | } 31 | class Bip32Signer { 32 | __D; 33 | __Q; 34 | lowR = false; 35 | constructor(__D, __Q) { 36 | this.__D = __D; 37 | this.__Q = __Q; 38 | } 39 | get publicKey() { 40 | if (this.__Q === undefined) 41 | this.__Q = ecc.pointFromScalar(this.__D, true); 42 | return this.__Q; 43 | } 44 | get privateKey() { 45 | return this.__D; 46 | } 47 | sign(hash, lowR) { 48 | if (!this.privateKey) 49 | throw new Error('Missing private key'); 50 | if (lowR === undefined) 51 | lowR = this.lowR; 52 | if (lowR === false) { 53 | return ecc.sign(hash, this.privateKey); 54 | } 55 | else { 56 | let sig = ecc.sign(hash, this.privateKey); 57 | const extraData = new Uint8Array(32); 58 | let counter = 0; 59 | // if first try is lowR, skip the loop 60 | // for second try and on, add extra entropy counting up 61 | while (sig[0] > 0x7f) { 62 | counter++; 63 | tools.writeUInt32(extraData, 0, counter, 'LE'); 64 | sig = ecc.sign(hash, this.privateKey, extraData); 65 | } 66 | return sig; 67 | } 68 | } 69 | signSchnorr(hash) { 70 | if (!this.privateKey) 71 | throw new Error('Missing private key'); 72 | if (!ecc.signSchnorr) 73 | throw new Error('signSchnorr not supported by ecc library'); 74 | return ecc.signSchnorr(hash, this.privateKey); 75 | } 76 | verify(hash, signature) { 77 | return ecc.verify(hash, this.publicKey, signature); 78 | } 79 | verifySchnorr(hash, signature) { 80 | if (!ecc.verifySchnorr) 81 | throw new Error('verifySchnorr not supported by ecc library'); 82 | return ecc.verifySchnorr(hash, this.publicKey.subarray(1, 33), signature); 83 | } 84 | } 85 | class BIP32 extends Bip32Signer { 86 | chainCode; 87 | network; 88 | __DEPTH; 89 | __INDEX; 90 | __PARENT_FINGERPRINT; 91 | constructor(__D, __Q, chainCode, network, __DEPTH = 0, __INDEX = 0, __PARENT_FINGERPRINT = 0x00000000) { 92 | super(__D, __Q); 93 | this.chainCode = chainCode; 94 | this.network = network; 95 | this.__DEPTH = __DEPTH; 96 | this.__INDEX = __INDEX; 97 | this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT; 98 | v.parse(NetworkSchema, network); 99 | } 100 | get depth() { 101 | return this.__DEPTH; 102 | } 103 | get index() { 104 | return this.__INDEX; 105 | } 106 | get parentFingerprint() { 107 | return this.__PARENT_FINGERPRINT; 108 | } 109 | get identifier() { 110 | return crypto.hash160(this.publicKey); 111 | } 112 | get fingerprint() { 113 | return this.identifier.slice(0, 4); 114 | } 115 | get compressed() { 116 | return true; 117 | } 118 | // Private === not neutered 119 | // Public === neutered 120 | isNeutered() { 121 | return this.__D === undefined; 122 | } 123 | neutered() { 124 | return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint); 125 | } 126 | toBase58() { 127 | const network = this.network; 128 | const version = !this.isNeutered() 129 | ? network.bip32.private 130 | : network.bip32.public; 131 | const buffer = new Uint8Array(78); 132 | // 4 bytes: version bytes 133 | tools.writeUInt32(buffer, 0, version, 'BE'); 134 | // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, .... 135 | tools.writeUInt8(buffer, 4, this.depth); 136 | // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) 137 | tools.writeUInt32(buffer, 5, this.parentFingerprint, 'BE'); 138 | // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. 139 | // This is encoded in big endian. (0x00000000 if master key) 140 | tools.writeUInt32(buffer, 9, this.index, 'BE'); 141 | // 32 bytes: the chain code 142 | buffer.set(this.chainCode, 13); 143 | // 33 bytes: the public key or private key data 144 | if (!this.isNeutered()) { 145 | // 0x00 + k for private keys 146 | tools.writeUInt8(buffer, 45, 0); 147 | buffer.set(this.privateKey, 46); 148 | // 33 bytes: the public key 149 | } 150 | else { 151 | // X9.62 encoding for public keys 152 | buffer.set(this.publicKey, 45); 153 | } 154 | return bs58check.encode(buffer); 155 | } 156 | toWIF() { 157 | if (!this.privateKey) 158 | throw new TypeError('Missing private key'); 159 | return wif.encode({ 160 | version: this.network.wif, 161 | privateKey: this.privateKey, 162 | compressed: true, 163 | }); 164 | } 165 | // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions 166 | derive(index) { 167 | v.parse(Uint32Schema, index); 168 | const isHardened = index >= HIGHEST_BIT; 169 | const data = new Uint8Array(37); 170 | // Hardened child 171 | if (isHardened) { 172 | if (this.isNeutered()) 173 | throw new TypeError('Missing private key for hardened child key'); 174 | // data = 0x00 || ser256(kpar) || ser32(index) 175 | data[0] = 0x00; 176 | data.set(this.privateKey, 1); 177 | tools.writeUInt32(data, 33, index, 'BE'); 178 | // Normal child 179 | } 180 | else { 181 | // data = serP(point(kpar)) || ser32(index) 182 | // = serP(Kpar) || ser32(index) 183 | data.set(this.publicKey, 0); 184 | tools.writeUInt32(data, 33, index, 'BE'); 185 | } 186 | const I = crypto.hmacSHA512(this.chainCode, data); 187 | const IL = I.slice(0, 32); 188 | const IR = I.slice(32); 189 | // if parse256(IL) >= n, proceed with the next value for i 190 | if (!ecc.isPrivate(IL)) 191 | return this.derive(index + 1); 192 | // Private parent key -> private child key 193 | let hd; 194 | if (!this.isNeutered()) { 195 | // ki = parse256(IL) + kpar (mod n) 196 | const ki = ecc.privateAdd(this.privateKey, IL); 197 | // In case ki == 0, proceed with the next value for i 198 | if (ki == null) 199 | return this.derive(index + 1); 200 | hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, tools.readUInt32(this.fingerprint, 0, 'BE')); 201 | // Public parent key -> public child key 202 | } 203 | else { 204 | // Ki = point(parse256(IL)) + Kpar 205 | // = G*IL + Kpar 206 | const Ki = ecc.pointAddScalar(this.publicKey, IL, true); 207 | // In case Ki is the point at infinity, proceed with the next value for i 208 | if (Ki === null) 209 | return this.derive(index + 1); 210 | hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, tools.readUInt32(this.fingerprint, 0, 'BE')); 211 | } 212 | return hd; 213 | } 214 | deriveHardened(index) { 215 | if (typeof v.parse(Uint31Schema, index) === 'number') 216 | // Only derives hardened private keys by default 217 | return this.derive(index + HIGHEST_BIT); 218 | throw new TypeError('Expected UInt31, got ' + index); 219 | } 220 | derivePath(path) { 221 | v.parse(Bip32PathSchema, path); 222 | let splitPath = path.split('/'); 223 | if (splitPath[0] === 'm') { 224 | if (this.parentFingerprint) 225 | throw new TypeError('Expected master, got child'); 226 | splitPath = splitPath.slice(1); 227 | } 228 | return splitPath.reduce((prevHd, indexStr) => { 229 | let index; 230 | if (indexStr.slice(-1) === `'`) { 231 | index = parseInt(indexStr.slice(0, -1), 10); 232 | return prevHd.deriveHardened(index); 233 | } 234 | else { 235 | index = parseInt(indexStr, 10); 236 | return prevHd.derive(index); 237 | } 238 | }, this); 239 | } 240 | tweak(t) { 241 | if (this.privateKey) 242 | return this.tweakFromPrivateKey(t); 243 | return this.tweakFromPublicKey(t); 244 | } 245 | tweakFromPublicKey(t) { 246 | const xOnlyPubKey = toXOnly(this.publicKey); 247 | if (!ecc.xOnlyPointAddTweak) 248 | throw new Error('xOnlyPointAddTweak not supported by ecc library'); 249 | const tweakedPublicKey = ecc.xOnlyPointAddTweak(xOnlyPubKey, t); 250 | if (!tweakedPublicKey || tweakedPublicKey.xOnlyPubkey === null) 251 | throw new Error('Cannot tweak public key!'); 252 | const parityByte = Uint8Array.from([ 253 | tweakedPublicKey.parity === 0 ? 0x02 : 0x03, 254 | ]); 255 | const tweakedPublicKeyCompresed = tools.concat([ 256 | parityByte, 257 | tweakedPublicKey.xOnlyPubkey, 258 | ]); 259 | return new Bip32Signer(undefined, tweakedPublicKeyCompresed); 260 | } 261 | tweakFromPrivateKey(t) { 262 | const hasOddY = this.publicKey[0] === 3 || 263 | (this.publicKey[0] === 4 && (this.publicKey[64] & 1) === 1); 264 | const privateKey = (() => { 265 | if (!hasOddY) 266 | return this.privateKey; 267 | else if (!ecc.privateNegate) 268 | throw new Error('privateNegate not supported by ecc library'); 269 | else 270 | return ecc.privateNegate(this.privateKey); 271 | })(); 272 | const tweakedPrivateKey = ecc.privateAdd(privateKey, t); 273 | if (!tweakedPrivateKey) 274 | throw new Error('Invalid tweaked private key!'); 275 | return new Bip32Signer(tweakedPrivateKey, undefined); 276 | } 277 | } 278 | function fromBase58(inString, network) { 279 | const buffer = bs58check.decode(inString); 280 | if (buffer.length !== 78) 281 | throw new TypeError('Invalid buffer length'); 282 | network = network || BITCOIN; 283 | // 4 bytes: version bytes 284 | const version = tools.readUInt32(buffer, 0, 'BE'); 285 | if (version !== network.bip32.private && version !== network.bip32.public) 286 | throw new TypeError('Invalid network version'); 287 | // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... 288 | const depth = buffer[4]; 289 | // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) 290 | const parentFingerprint = tools.readUInt32(buffer, 5, 'BE'); 291 | if (depth === 0) { 292 | if (parentFingerprint !== 0x00000000) 293 | throw new TypeError('Invalid parent fingerprint'); 294 | } 295 | // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. 296 | // This is encoded in MSB order. (0x00000000 if master key) 297 | const index = tools.readUInt32(buffer, 9, 'BE'); 298 | if (depth === 0 && index !== 0) 299 | throw new TypeError('Invalid index'); 300 | // 32 bytes: the chain code 301 | const chainCode = buffer.slice(13, 45); 302 | let hd; 303 | // 33 bytes: private key data (0x00 + k) 304 | if (version === network.bip32.private) { 305 | if (buffer[45] !== 0x00) 306 | throw new TypeError('Invalid private key'); 307 | const k = buffer.slice(46, 78); 308 | hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint); 309 | // 33 bytes: public key data (0x02 + X or 0x03 + X) 310 | } 311 | else { 312 | const X = buffer.slice(45, 78); 313 | hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint); 314 | } 315 | return hd; 316 | } 317 | function fromPrivateKey(privateKey, chainCode, network) { 318 | return fromPrivateKeyLocal(privateKey, chainCode, network); 319 | } 320 | function fromPrivateKeyLocal(privateKey, chainCode, network, depth, index, parentFingerprint) { 321 | v.parse(Buffer256Bit, privateKey); 322 | v.parse(Buffer256Bit, chainCode); 323 | network = network || BITCOIN; 324 | if (!ecc.isPrivate(privateKey)) 325 | throw new TypeError('Private key not in range [1, n)'); 326 | return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint); 327 | } 328 | function fromPublicKey(publicKey, chainCode, network) { 329 | return fromPublicKeyLocal(publicKey, chainCode, network); 330 | } 331 | function fromPublicKeyLocal(publicKey, chainCode, network, depth, index, parentFingerprint) { 332 | v.parse(Buffer33Bytes, publicKey); 333 | v.parse(Buffer256Bit, chainCode); 334 | network = network || BITCOIN; 335 | // verify the X coordinate is a point on the curve 336 | if (!ecc.isPoint(publicKey)) 337 | throw new TypeError('Point is not on the curve'); 338 | return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint); 339 | } 340 | function fromSeed(seed, network) { 341 | v.parse(v.instance(Uint8Array), seed); 342 | if (seed.length < 16) 343 | throw new TypeError('Seed should be at least 128 bits'); 344 | if (seed.length > 64) 345 | throw new TypeError('Seed should be at most 512 bits'); 346 | network = network || BITCOIN; 347 | const I = crypto.hmacSHA512(tools.fromUtf8('Bitcoin seed'), seed); 348 | const IL = I.slice(0, 32); 349 | const IR = I.slice(32); 350 | return fromPrivateKey(IL, IR, network); 351 | } 352 | return { 353 | fromSeed, 354 | fromBase58, 355 | fromPublicKey, 356 | fromPrivateKey, 357 | }; 358 | } 359 | -------------------------------------------------------------------------------- /src/esm/crypto.js: -------------------------------------------------------------------------------- 1 | import { hmac } from '@noble/hashes/hmac'; 2 | import { ripemd160 } from '@noble/hashes/ripemd160'; 3 | import { sha256 } from '@noble/hashes/sha256'; 4 | import { sha512 } from '@noble/hashes/sha512'; 5 | export function hash160(buffer) { 6 | return ripemd160(sha256(buffer)); 7 | } 8 | export function hmacSHA512(key, data) { 9 | return hmac(sha512, key, data); 10 | } 11 | -------------------------------------------------------------------------------- /src/esm/index.js: -------------------------------------------------------------------------------- 1 | export { BIP32Factory as default, BIP32Factory, } from './bip32.js'; 2 | -------------------------------------------------------------------------------- /src/esm/testecc.js: -------------------------------------------------------------------------------- 1 | import * as tools from 'uint8array-tools'; 2 | const h = (hex) => tools.fromHex(hex); 3 | export function testEcc(ecc) { 4 | assert(ecc.isPoint(h('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'))); 5 | assert(!ecc.isPoint(h('030000000000000000000000000000000000000000000000000000000000000005'))); 6 | assert(ecc.isPrivate(h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'))); 7 | // order - 1 8 | assert(ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'))); 9 | // 0 10 | assert(!ecc.isPrivate(h('0000000000000000000000000000000000000000000000000000000000000000'))); 11 | // order 12 | assert(!ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'))); 13 | // order + 1 14 | assert(!ecc.isPrivate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142'))); 15 | assert(tools.compare(ecc.pointFromScalar(h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af')), h('02b07ba9dca9523b7ef4bd97703d43d20399eb698e194704791a25ce77a400df99')) === 0); 16 | if (ecc.xOnlyPointAddTweak) { 17 | assert(ecc.xOnlyPointAddTweak(h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')) === null); 18 | let xOnlyRes = ecc.xOnlyPointAddTweak(h('1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b'), h('a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac')); 19 | assert(tools.compare(xOnlyRes.xOnlyPubkey, h('e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf')) === 0 && xOnlyRes.parity === 1); 20 | xOnlyRes = ecc.xOnlyPointAddTweak(h('2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991'), h('823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47')); 21 | } 22 | assert(tools.compare(ecc.pointAddScalar(h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('0000000000000000000000000000000000000000000000000000000000000003')), h('02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5')) === 0); 23 | assert(tools.compare(ecc.privateAdd(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e'), h('0000000000000000000000000000000000000000000000000000000000000002')), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')) === 0); 24 | if (ecc.privateNegate) { 25 | assert(tools.compare(ecc.privateNegate(h('0000000000000000000000000000000000000000000000000000000000000001')), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')) === 0); 26 | assert(tools.compare(ecc.privateNegate(h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e')), h('0000000000000000000000000000000000000000000000000000000000000003')) === 0); 27 | assert(tools.compare(ecc.privateNegate(h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af')), h('4eede1bf775995d70a494f0a7bb6bc11e0b8cccd41cce8009ab1132c8b0a3792')) === 0); 28 | } 29 | assert(tools.compare(ecc.sign(h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140')), h('54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5')) === 0); 30 | assert(ecc.verify(h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), h('54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5'))); 31 | if (ecc.signSchnorr) { 32 | assert(tools.compare(ecc.signSchnorr(h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), h('c90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b14e5c9'), h('c87aa53824b4d7ae2eb035a2b5bbbccc080e76cdc6d1692c4b0b62d798e6d906')), h('5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7')) === 0); 33 | } 34 | if (ecc.verifySchnorr) { 35 | assert(ecc.verifySchnorr(h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), h('dd308afec5777e13121fa72b9cc1b7cc0139715309b086c960e18fd969774eb8'), h('5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7'))); 36 | } 37 | } 38 | function assert(bool) { 39 | if (!bool) 40 | throw new Error('ecc library invalid'); 41 | } 42 | -------------------------------------------------------------------------------- /src/esm/types.js: -------------------------------------------------------------------------------- 1 | import * as v from 'valibot'; 2 | export const Uint32Schema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(0xffffffff)); 3 | export const Uint31Schema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(0x7fffffff)); 4 | const Uint8Schema = v.pipe(v.number(), v.integer(), v.minValue(0), v.maxValue(0xff)); 5 | export const Buffer256Bit = v.pipe(v.instance(Uint8Array), v.length(32)); 6 | export const Buffer33Bytes = v.pipe(v.instance(Uint8Array), v.length(33)); 7 | export const NetworkSchema = v.object({ 8 | wif: Uint8Schema, 9 | bip32: v.object({ 10 | public: Uint32Schema, 11 | private: Uint32Schema, 12 | }), 13 | }); 14 | export const Bip32PathSchema = v.pipe(v.string(), v.regex(/^(m\/)?(\d+'?\/)*\d+'?$/)); 15 | -------------------------------------------------------------------------------- /test.cjs: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const childProcess = require('child_process'); 3 | 4 | let mainFile = JSON.parse(fs.readFileSync('./package.json').toString()).module; 5 | if (!mainFile.startsWith('.')) { 6 | // ESM imports of files must start with ./ 7 | mainFile = `./${mainFile}`; 8 | } 9 | const cjsFile = './tmp.cjs'; 10 | const esmFile = './tmp.mjs'; 11 | const cjs = `const x = require('.')\nconsole.log(x)`; 12 | const esm = `import * as x from '${mainFile}';\nconsole.log(x)`; 13 | 14 | fs.writeFileSync(cjsFile, cjs); 15 | fs.writeFileSync(esmFile, esm); 16 | 17 | const result1 = childProcess.spawnSync('node', [cjsFile], { 18 | cwd: __dirname, 19 | }); 20 | const result2 = childProcess.spawnSync('node', [esmFile], { 21 | cwd: __dirname, 22 | }); 23 | 24 | fs.unlinkSync(cjsFile); 25 | fs.unlinkSync(esmFile); 26 | 27 | const errors = []; 28 | if (result1.status !== 0) { 29 | errors.push(result1.stderr.toString()); 30 | } 31 | if (result2.status !== 0) { 32 | errors.push(result2.stderr.toString()); 33 | } 34 | if (errors.length > 0) { 35 | console.error( 36 | `Failed to run this library under CJS or ESM. Errors:\n${errors.join('\n')}`, 37 | ); 38 | process.exit(1); 39 | } 40 | -------------------------------------------------------------------------------- /test/fixtures/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "valid": [ 3 | { 4 | "network": "bitcoin", 5 | "master": { 6 | "seed": "000102030405060708090a0b0c0d0e0f", 7 | "wif": "L52XzL2cMkHxqxBXRyEpnPQZGUs3uKiL3R11XbAdHigRzDozKZeW", 8 | "pubKey": "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2", 9 | "privKey": "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35", 10 | "chainCode": "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508", 11 | "base58": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8", 12 | "base58Priv": "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi", 13 | "identifier": "3442193e1bb70916e914552172cd4e2dbc9df811", 14 | "fingerprint": "3442193e" 15 | }, 16 | "children": [ 17 | { 18 | "path": "m/0'", 19 | "m": 0, 20 | "hardened": true, 21 | "wif": "L5BmPijJjrKbiUfG4zbiFKNqkvuJ8usooJmzuD7Z8dkRoTThYnAT", 22 | "pubKey": "035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56", 23 | "privKey": "edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea", 24 | "chainCode": "47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141", 25 | "base58": "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw", 26 | "base58Priv": "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7", 27 | "identifier": "5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7", 28 | "fingerprint": "5c1bd648", 29 | "index": 2147483648, 30 | "depth": 1 31 | }, 32 | { 33 | "path": "m/0'/1", 34 | "m": 1, 35 | "wif": "KyFAjQ5rgrKvhXvNMtFB5PCSKUYD1yyPEe3xr3T34TZSUHycXtMM", 36 | "pubKey": "03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c", 37 | "privKey": "3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc93368", 38 | "chainCode": "2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19", 39 | "base58": "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ", 40 | "base58Priv": "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs", 41 | "identifier": "bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe", 42 | "fingerprint": "bef5a2f9", 43 | "index": 1, 44 | "depth": 2 45 | }, 46 | { 47 | "path": "m/0'/1/2'", 48 | "m": 2, 49 | "hardened": true, 50 | "wif": "L43t3od1Gh7Lj55Bzjj1xDAgJDcL7YFo2nEcNaMGiyRZS1CidBVU", 51 | "pubKey": "0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2", 52 | "privKey": "cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca", 53 | "chainCode": "04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f", 54 | "base58": "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5", 55 | "base58Priv": "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM", 56 | "identifier": "ee7ab90cde56a8c0e2bb086ac49748b8db9dce72", 57 | "fingerprint": "ee7ab90c", 58 | "index": 2147483650, 59 | "depth": 3 60 | }, 61 | { 62 | "path": "m/0'/1/2'/2", 63 | "m": 2, 64 | "wif": "KwjQsVuMjbCP2Zmr3VaFaStav7NvevwjvvkqrWd5Qmh1XVnCteBR", 65 | "pubKey": "02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29", 66 | "privKey": "0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4", 67 | "chainCode": "cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd", 68 | "base58": "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV", 69 | "base58Priv": "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334", 70 | "identifier": "d880d7d893848509a62d8fb74e32148dac68412f", 71 | "fingerprint": "d880d7d8", 72 | "index": 2, 73 | "depth": 4 74 | }, 75 | { 76 | "path": "m/0'/1/2'/2/1000000000", 77 | "m": 1000000000, 78 | "wif": "Kybw8izYevo5xMh1TK7aUr7jHFCxXS1zv8p3oqFz3o2zFbhRXHYs", 79 | "pubKey": "022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011", 80 | "privKey": "471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8", 81 | "chainCode": "c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e", 82 | "base58": "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy", 83 | "base58Priv": "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76", 84 | "identifier": "d69aa102255fed74378278c7812701ea641fdf32", 85 | "fingerprint": "d69aa102", 86 | "index": 1000000000, 87 | "depth": 5 88 | } 89 | ] 90 | }, 91 | { 92 | "network": "bitcoin", 93 | "master": { 94 | "seed": "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542", 95 | "wif": "KyjXhyHF9wTphBkfpxjL8hkDXDUSbE3tKANT94kXSyh6vn6nKaoy", 96 | "pubKey": "03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7", 97 | "privKey": "4b03d6fc340455b363f51020ad3ecca4f0850280cf436c70c727923f6db46c3e", 98 | "chainCode": "60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689", 99 | "base58": "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB", 100 | "base58Priv": "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U", 101 | "identifier": "bd16bee53961a47d6ad888e29545434a89bdfe95", 102 | "fingerprint": "bd16bee5" 103 | }, 104 | "children": [ 105 | { 106 | "path": "m/0", 107 | "m": 0, 108 | "wif": "L2ysLrR6KMSAtx7uPqmYpoTeiRzydXBattRXjXz5GDFPrdfPzKbj", 109 | "pubKey": "02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea", 110 | "privKey": "abe74a98f6c7eabee0428f53798f0ab8aa1bd37873999041703c742f15ac7e1e", 111 | "chainCode": "f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c", 112 | "base58": "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH", 113 | "base58Priv": "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt", 114 | "identifier": "5a61ff8eb7aaca3010db97ebda76121610b78096", 115 | "fingerprint": "5a61ff8e", 116 | "index": 0, 117 | "depth": 1 118 | }, 119 | { 120 | "path": "m/0/2147483647'", 121 | "m": 2147483647, 122 | "hardened": true, 123 | "wif": "L1m5VpbXmMp57P3knskwhoMTLdhAAaXiHvnGLMribbfwzVRpz2Sr", 124 | "pubKey": "03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b", 125 | "privKey": "877c779ad9687164e9c2f4f0f4ff0340814392330693ce95a58fe18fd52e6e93", 126 | "chainCode": "be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9", 127 | "base58": "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a", 128 | "base58Priv": "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9", 129 | "identifier": "d8ab493736da02f11ed682f88339e720fb0379d1", 130 | "fingerprint": "d8ab4937", 131 | "index": 4294967295, 132 | "depth": 2 133 | }, 134 | { 135 | "path": "m/0/2147483647'/1", 136 | "m": 1, 137 | "wif": "KzyzXnznxSv249b4KuNkBwowaN3akiNeEHy5FWoPCJpStZbEKXN2", 138 | "pubKey": "03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9", 139 | "privKey": "704addf544a06e5ee4bea37098463c23613da32020d604506da8c0518e1da4b7", 140 | "chainCode": "f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb", 141 | "base58": "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon", 142 | "base58Priv": "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef", 143 | "identifier": "78412e3a2296a40de124307b6485bd19833e2e34", 144 | "fingerprint": "78412e3a", 145 | "index": 1, 146 | "depth": 3 147 | }, 148 | { 149 | "path": "m/0/2147483647'/1/2147483646'", 150 | "m": 2147483646, 151 | "hardened": true, 152 | "wif": "L5KhaMvPYRW1ZoFmRjUtxxPypQ94m6BcDrPhqArhggdaTbbAFJEF", 153 | "pubKey": "02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0", 154 | "privKey": "f1c7c871a54a804afe328b4c83a1c33b8e5ff48f5087273f04efa83b247d6a2d", 155 | "chainCode": "637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29", 156 | "base58": "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL", 157 | "base58Priv": "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc", 158 | "identifier": "31a507b815593dfc51ffc7245ae7e5aee304246e", 159 | "fingerprint": "31a507b8", 160 | "index": 4294967294, 161 | "depth": 4 162 | }, 163 | { 164 | "path": "m/0/2147483647'/1/2147483646'/2", 165 | "m": 2, 166 | "wif": "L3WAYNAZPxx1fr7KCz7GN9nD5qMBnNiqEJNJMU1z9MMaannAt4aK", 167 | "pubKey": "024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c", 168 | "privKey": "bb7d39bdb83ecf58f2fd82b6d918341cbef428661ef01ab97c28a4842125ac23", 169 | "chainCode": "9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271", 170 | "base58": "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt", 171 | "base58Priv": "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j", 172 | "identifier": "26132fdbe7bf89cbc64cf8dafa3f9f88b8666220", 173 | "fingerprint": "26132fdb", 174 | "index": 2, 175 | "depth": 5 176 | } 177 | ] 178 | }, 179 | { 180 | "comment": "Private key has leading zeros (seed vers.)", 181 | "network": "bitcoin", 182 | "master": { 183 | "seed": "d13de7bd1e54422d1a3b3b699a27fb460de2849e7e66a005c647e8e4a54075cb", 184 | "wif": "KwDiCU5bs8xQwsRgxjhkcJcVuR7NE4Mei8X9uSAVviVTE7JmMoS6", 185 | "pubKey": "0298ccc720d5dea817c7077605263bae52bca083cf8888fee77ff4c1b4797ee180", 186 | "privKey": "0000081d1e4bad6731c84450c9a3dbb70e8ba30118d3419f2c74077b7996a078", 187 | "chainCode": "c23ab32b36ddff49fae350a1bed8ec6b4d9fc252238dd789b7273ba4416054eb", 188 | "base58": "xpub661MyMwAqRbcGUbHLLJ5n2DzFAt8mmaDxbmbdimh68m8EiXGEQPiJya4BJat5yMzy4e68VSUoLGCu5uvzf8dUoGvwuJsLE6F1cibmWsxFNn", 189 | "base58Priv": "xprv9s21ZrQH143K3zWpEJm5QtHFh93eNJrNbNqzqLN5XoE9MvC7gs5TmBFaL2PpaXpDc8FBYVe5EChc73ApjSQ5fWsXS7auHy1MmG6hdpywE1q", 190 | "identifier": "1a87677be6f73cc9655e8b4c5d2fd0aeeb1b23c7", 191 | "fingerprint": "1a87677b" 192 | }, 193 | "children": [ 194 | { 195 | "hardened": true, 196 | "path": "m/44'/0'/0'/0/0'", 197 | "wif": "L3z3MSqZtDQ1FPHKi7oWf1nc9rMEGFtZUDCoFa7n4F695g5qZiSu", 198 | "pubKey": "027c3591221e28939e45f8ea297d62c3640ebb09d7058b01d09c963d984a40ad49", 199 | "privKey": "c9d464f63c78ed923b5fed4917bbbbd6936543baf12227067ddc99b63a54a058", 200 | "chainCode": "ca27553aa89617e982e621637d6478f564b32738f8bbe2e48d0a58a8e0f6da40", 201 | "base58": "xpub6GcBnm7FfDg5ERWACCvtuotN6Tdoc37r3SZ1asBHvCWzPkqWn3MVKPWKzy6GsfmdMUGanR3D12dH1cp5tJauuubwc4FAJDn67SH2uUjwAT1", 202 | "base58Priv": "xprvA3cqPFaMpr7n1wRh6BPtYfwdYRoKCaPzgDdQnUmgMrz1WxWNEW3EmbBr9ieh9BJAsRGKFPLvotb4p4Aq79jddUVKPVJt7exVzLHcv777JVf", 203 | "identifier": "e371d69b5dae6eacee832a130ee9f55545275a09", 204 | "fingerprint": "e371d69b", 205 | "index": 2147483648, 206 | "depth": 5 207 | } 208 | ] 209 | }, 210 | { 211 | "comment": "Private key has leading zeros", 212 | "network": "bitcoin", 213 | "master": { 214 | "wif": "KwDiBh3sys6SzXrv4cSUVpDHsVc8XiD3o3xyMx9wvUcu3nPJJ6PE", 215 | "pubKey": "02b3e3e297165289611a2387e8089fcaf099926e4d31fdddb50c0ae0dfa36c97e6", 216 | "privKey": "00000055378cf5fafb56c711c674143f9b0ee82ab0ba2924f19b64f5ae7cdbfd", 217 | "chainCode": "9c8a5c863e5941f3d99453e6ba66b328bb17cf0b8dec89ed4fc5ace397a1c089", 218 | "base58": "xpub661MyMwAqRbcG6q1FFDUUHr61LatpoMSZRQpVWR4MHzfGnfUp8GMT5xfKcrt4xB7nJCgXn1NBqgCGGDkJx1ZLRKeM58HZkhV5NjBWK1AyQY", 219 | "base58Priv": "xprv9s21ZrQH143K3ckY9DgU79uMTJkQRLdbCCVDh81SnxTgPzLLGax6uHeBULTtaEtcAvKjXfT7ZWtHzKjTpujMkUd9dDb8msDeAfnJxrgAYhr", 220 | "identifier": "afc10e1e7abbe99731c4c4606a3556d832372680", 221 | "fingerprint": "afc10e1e" 222 | }, 223 | "children": [ 224 | { 225 | "hardened": true, 226 | "path": "m/44'/0'/0'/0/0'", 227 | "wif": "KxwPsTN9AdQ2CjGihVP8MnSadbtyByskCiX1GCEhjovKj4m3d7Xs", 228 | "pubKey": "030e13168e3f9560da5cebca9c91b78280e7ffa221d097c6dac3e98f450355d6f6", 229 | "privKey": "3348069561d2a0fb925e74bf198762acc47dce7db27372257d2d959a9e6f8aeb", 230 | "chainCode": "7a16b2f4ad4cc1069338237f373dabf1fe329a5f3a0d95c4b98d061204676293", 231 | "base58": "xpub6FqvhT2Bdh4YaWA3nqsNTaYNmCEXJnSJnBgntrH8GQVX8hf6exHusxyqgyd6kKKNTvtbpmNPGEH74VxJaAuo14NS52WBmWG9krq1ESqdR6T", 232 | "base58Priv": "xprvA2raHwVHoKWFN25agpLN6SbeDAQ2uKiTQxmC6TsWi4xYFuKx7QyfLAfMqgvyXVr6fcDspooYFsas1ngymgmVSPjTCU5JRfwj6w4zukhfucS", 233 | "identifier": "b2d8238bfeb71a89c8244b7e53105cd97021904e", 234 | "fingerprint": "b2d8238b", 235 | "index": 2147483648, 236 | "depth": 5 237 | } 238 | ] 239 | }, 240 | { 241 | "network": "litecoin", 242 | "master": { 243 | "seed": "000102030405060708090a0b0c0d0e0f", 244 | "wif": "TAroS5Knm8GZcnpPycBgzjwwDLWMyQjDrcuGPPoArgrbW7Ln22qp", 245 | "pubKey": "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2", 246 | "privKey": "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35", 247 | "chainCode": "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508", 248 | "base58": "Ltub2SSUS19CirucWFod2ZsYA2J4v4U76YiCXHdcQttnoiy5aGanFHCPDBX7utfG6f95u1cUbZJNafmvzNCzZZJTw1EmyFoL8u1gJbGM8ipu491", 249 | "base58Priv": "Ltpv71G8qDifUiNetP6nmxPA5STrUVmv2J9YSmXajv8VsYBUyuPhvN9xCaQrfX2wo5xxJNtEazYCFRUu5FmokYMM79pcqz8pcdo4rNXAFPgyB4k", 250 | "identifier": "3442193e1bb70916e914552172cd4e2dbc9df811", 251 | "fingerprint": "3442193e" 252 | }, 253 | "children": [ 254 | { 255 | "path": "m/0'", 256 | "m": 0, 257 | "hardened": true, 258 | "wif": "TB22qU2V9EJCVKJ8cdYaTfvDhnYcCzthcWgFm1k6hbvbKM1NLxoL", 259 | "pubKey": "035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56", 260 | "privKey": "edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea", 261 | "chainCode": "47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141", 262 | "base58": "Ltub2UhtRiSfp82berwLEKkB34QBEt2TUdCDCu4WNzGumvAMwYsxfWjULKsXhADxqy3cuDu3TnqoKJr1xmB8Wb2qzthWAtbb4CutpXPuSU1YMgG", 263 | "base58Priv": "Ltpv73XYpw28ZyVe2zEVyiFnxUZxoKLGQNdZ8NxUi1WcqjNmMBgtLbh3KimGSnPHCoLv1RmvxHs4dnKmo1oXQ8dXuDu8uroxrbVxZPA1gXboYvx", 264 | "identifier": "5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7", 265 | "fingerprint": "5c1bd648", 266 | "index": 2147483648, 267 | "depth": 1 268 | } 269 | ] 270 | } 271 | ], 272 | "invalid": { 273 | "fromBase58": [ 274 | { 275 | "exception": "Invalid checksum", 276 | "string": "xprvQQQQQQQQQQQQQQQQCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334" 277 | }, 278 | { 279 | "exception": "Invalid buffer length", 280 | "network": "bitcoin", 281 | "string": "HAsbc6CgKmTYEQg2CTz7m5STEPAB" 282 | }, 283 | { 284 | "exception": "Invalid parent fingerprint", 285 | "network": "bitcoin", 286 | "string": "xprv9tnJFvAXAXPfPnMTKfwpwnkty7MzJwELVgp4NTBquaKXy4RndyfJJCJJf7zNaVpBpzrwVRutZNLRCVLEcZHcvuCNG3zGbGBcZn57FbNnmSP" 287 | }, 288 | { 289 | "exception": "Invalid private key", 290 | "network": "bitcoin", 291 | "string": "xprv9s21ZrQH143K3yLysFvsu3n1dMwhNusmNHr7xArzAeCc7MQYqDBBStmqnZq6WLi668siBBNs3SjiyaexduHu9sXT9ixTsqptL67ADqcaBdm" 292 | }, 293 | { 294 | "exception": "Invalid index", 295 | "network": "bitcoin", 296 | "string": "xprv9s21ZrQYdgnodnKW4Drm1Qg7poU6Gf2WUDsjPxvYiK7iLBMrsjbnF1wsZZQgmXNeMSG3s7jmHk1b3JrzhG5w8mwXGxqFxfrweico7k8DtxR" 297 | }, 298 | { 299 | "exception": "Invalid network version", 300 | "network": "litecoin", 301 | "string": "1111111111111adADjFaSNPxwXqLjHLj4mBfYxuewDPbw9hEj1uaXCzMxRPXDFF3cUoezTFYom4sEmEVSQmENPPR315cFk9YUFVek73wE9" 302 | }, 303 | { 304 | "exception": "Invalid network version", 305 | "string": "8FH81Rao5EgGmdScoN66TJAHsQP7phEMeyMTku9NBJd7hXgaj3HTvSNjqJjoqBpxdbuushwPEM5otvxXt2p9dcw33AqNKzZEPMqGHmz7Dpayi6Vb" 306 | }, 307 | { 308 | "exception": "Invalid network version", 309 | "network": "bitcoin", 310 | "string": "Ltpv73XYpw28ZyVe2zEVyiFnxUZxoKLGQNdZ8NxUi1WcqjNmMBgtLbh3KimGSnPHCoLv1RmvxHs4dnKmo1oXQ8dXuDu8uroxrbVxZPA1gXboYvx" 311 | }, 312 | { 313 | "exception": "Invalid buffer length", 314 | "string": "9XpNiB4DberdMn4jZiMhNGtuZUd7xUrCEGw4MG967zsVNvUKBEC9XLrmVmFasanWGp15zXfTNw4vW4KdvUAynEwyKjdho9QdLMPA2H5uyt" 315 | }, 316 | { 317 | "exception": "Invalid buffer length", 318 | "string": "7JJikZQ2NUXjSAnAF2SjFYE3KXbnnVxzRBNddFE1DjbDEHVGEJzYC7zqSgPoauBJS3cWmZwsER94oYSFrW9vZ4Ch5FtGeifdzmtS3FGYDB1vxFZsYKgMc" 319 | }, 320 | { 321 | "exception": "Invalid parent fingerprint", 322 | "string": "xpub67tVq9SuNQCfm2PXBqjGRAtNZ935kx2uHJaURePth4JBpMfEy6jum7Euj7FTpbs7fnjhfZcNEktCucWHcJf74dbKLKNSTZCQozdDVwvkJhs" 323 | }, 324 | { 325 | "exception": "Invalid index", 326 | "string": "xpub661MyMwTWkfYZq6BEh3ywGVXFvNj5hhzmWMhFBHSqmub31B1LZ9wbJ3DEYXZ8bHXGqnHKfepTud5a2XxGdnnePzZa2m2DyzTnFGBUXtaf9M" 327 | }, 328 | { 329 | "exception": "Point is not on the curve", 330 | "string": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gYymDsxxRe3WWeZQ7TadaLSdKUffezzczTCpB8j3JP96UwE2n6w1" 331 | } 332 | ], 333 | "fromSeed": [ 334 | { 335 | "exception": "Seed should be at least 128 bits", 336 | "seed": "ffff" 337 | }, 338 | { 339 | "exception": "Seed should be at most 512 bits", 340 | "seed": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 341 | } 342 | ], 343 | "deriveHardened": [ 344 | { 345 | "exception": "ValiError: Invalid value: Expected <=2147483647 but received 2147483648", 346 | "index": 2147483648 347 | }, 348 | { 349 | "exception": "ValiError: Invalid type: Expected number but received null", 350 | "index": null 351 | }, 352 | { 353 | "exception": "ValiError: Invalid type: Expected number but received \"foo\"", 354 | "index": "foo" 355 | }, 356 | { 357 | "exception": "ValiError: Invalid value: Expected >=0 but received -1", 358 | "index": -1 359 | } 360 | ], 361 | "derive": [ 362 | { 363 | "exception": "ValiError: Invalid value: Expected <=4294967295 but received 429496729", 364 | "index": 4294967296 365 | }, 366 | { 367 | "exception": "ValiError: Invalid type: Expected number but received null", 368 | "index": null 369 | }, 370 | { 371 | "exception": "ValiError: Invalid type: Expected number but received \"foo\"", 372 | "index": "foo" 373 | }, 374 | { 375 | "exception": "ValiError: Invalid value: Expected >=0 but received -1", 376 | "index": -1 377 | } 378 | ], 379 | "derivePath": [ 380 | { 381 | "exception": "ValiError: Invalid type: Expected string but received 2", 382 | "derivationPath": 2 383 | }, 384 | { 385 | "exception": "ValiError: Invalid type: Expected string but received Array", 386 | "derivationPath": [2, 3, 4] 387 | }, 388 | { 389 | "exception": "ValiError: Invalid format: Expected /^(m\/)?(\\d+'?\/)*\\d+'?$/ but received \"/\"", 390 | "derivationPath": "/" 391 | }, 392 | { 393 | "exception": "ValiError: Invalid format: Expected /^(m\/)?(\\d+'?\/)*\\d+'?$/ but received \"m/m/123\"", 394 | "derivationPath": "m/m/123" 395 | }, 396 | { 397 | "exception": "ValiError: Invalid format: Expected /^(m\/)?(\\d+'?\/)*\\d+'?$/ but received \"a/0/1/2\"", 398 | "derivationPath": "a/0/1/2" 399 | }, 400 | { 401 | "exception": "ValiError: Invalid format: Expected /^(m\/)?(\\d+'?\/)*\\d+'?$/ but received \"m/0/ 1 /2\"", 402 | "derivationPath": "m/0/ 1 /2" 403 | }, 404 | { 405 | "exception": "ValiError: Invalid format: Expected /^(m\/)?(\\d+'?\/)*\\d+'?$/ but received \"m/0/1.5/2\"", 406 | "derivationPath": "m/0/1.5/2" 407 | } 408 | ] 409 | } 410 | } 411 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import BIP32Creator from '../src/esm/index.js' 2 | import tape from 'tape' 3 | import fixtures from './fixtures/index.json' assert { type: "json" } 4 | const { valid, invalid } = fixtures 5 | import * as ecc from "tiny-secp256k1"; 6 | import * as tools from "uint8array-tools"; 7 | const BIP32 = BIP32Creator(ecc) 8 | let LITECOIN = { 9 | wif: 0xb0, 10 | bip32: { 11 | public: 0x019da462, 12 | private: 0x019d9cfe 13 | } 14 | } 15 | 16 | // TODO: amend the JSON 17 | let validAll = [] 18 | valid.forEach((f) => { 19 | f.master.network = f.network 20 | f.master.children = f.children 21 | f.master.comment = f.comment 22 | f.children.forEach((fc) => { 23 | fc.network = f.network 24 | validAll.push(fc) 25 | }) 26 | delete f.children 27 | validAll.push(f.master) 28 | }) 29 | 30 | function verify (t, hd, prv, f, network) { 31 | t.equal(tools.toHex(hd.chainCode), f.chainCode) 32 | t.equal(hd.depth, f.depth >>> 0) 33 | t.equal(hd.index, f.index >>> 0) 34 | t.equal(hd.compressed, true) 35 | t.equal(tools.toHex(hd.fingerprint), f.fingerprint) 36 | t.equal(tools.toHex(hd.identifier), f.identifier) 37 | t.equal(tools.toHex(hd.publicKey), f.pubKey) 38 | if (prv) t.equal(hd.toBase58(), f.base58Priv) 39 | if (prv) t.equal(tools.toHex(hd.privateKey), f.privKey) 40 | if (prv) t.equal(hd.toWIF(), f.wif) 41 | if (!prv) t.throws(() => hd.toWIF(), /Missing private key/) 42 | if (!prv) t.equal(hd.privateKey, undefined) 43 | t.equal(hd.neutered().toBase58(), f.base58) 44 | t.equal(hd.isNeutered(), !prv) 45 | 46 | if (!f.children) return 47 | if (!prv && f.children.some(x => x.hardened)) return 48 | 49 | // test deriving path from master 50 | f.children.forEach((cf) => { 51 | let chd = hd.derivePath(cf.path) 52 | verify(t, chd, prv, cf, network) 53 | 54 | let chdNoM = hd.derivePath(cf.path.slice(2)) // no m/ 55 | verify(t, chdNoM, prv, cf, network) 56 | }) 57 | 58 | // test deriving path from successive children 59 | let shd = hd 60 | f.children.forEach((cf) => { 61 | if (cf.m === undefined) return 62 | if (cf.hardened) { 63 | shd = shd.deriveHardened(cf.m) 64 | } else { 65 | // verify any publicly derived children 66 | if (cf.base58) verify(t, shd.neutered().derive(cf.m), false, cf, network) 67 | 68 | shd = shd.derive(cf.m) 69 | verify(t, shd, prv, cf, network) 70 | } 71 | 72 | t.throws(() => { 73 | shd.derivePath('m/0') 74 | }, /Expected master, got child/) 75 | 76 | verify(t, shd, prv, cf, network) 77 | }) 78 | } 79 | 80 | validAll.forEach((ff) => { 81 | tape(ff.comment || ff.base58Priv, (t) => { 82 | let network 83 | if (ff.network === 'litecoin') network = LITECOIN 84 | 85 | let hd = BIP32.fromBase58(ff.base58Priv, network) 86 | verify(t, hd, true, ff, network) 87 | 88 | hd = BIP32.fromBase58(ff.base58, network) 89 | verify(t, hd, false, ff, network) 90 | 91 | if (ff.seed) { 92 | let seed = Buffer.from(ff.seed, 'hex') 93 | hd = BIP32.fromSeed(seed, network) 94 | verify(t, hd, true, ff, network) 95 | } 96 | 97 | t.end() 98 | }) 99 | }) 100 | 101 | tape('invalid ecc library throws', (t) => { 102 | t.throws(() => { 103 | BIP32Creator({ isPoint: () => false }) 104 | }, /ecc library invalid/) 105 | // Run with no schnorr and check it doesn't throw 106 | BIP32Creator({ ...ecc, signSchnorr: null, verifySchnorr: null }) 107 | t.end() 108 | }) 109 | 110 | tape('fromBase58 throws', (t) => { 111 | invalid.fromBase58.forEach((f) => { 112 | t.throws(() => { 113 | let network 114 | if (f.network === 'litecoin') network = LITECOIN 115 | 116 | BIP32.fromBase58(f.string, network) 117 | }, new RegExp(f.exception)) 118 | }) 119 | 120 | t.end() 121 | }) 122 | 123 | tape('works for Private -> public (neutered)', (t) => { 124 | let f = valid[1] 125 | let c = f.master.children[0] 126 | 127 | let master = BIP32.fromBase58(f.master.base58Priv) 128 | let child = master.derive(c.m).neutered() 129 | 130 | t.plan(1) 131 | t.equal(child.toBase58(), c.base58) 132 | }) 133 | 134 | tape('works for Private -> public (neutered, hardened)', (t) => { 135 | let f = valid[0] 136 | let c = f.master.children[0] 137 | 138 | let master = BIP32.fromBase58(f.master.base58Priv) 139 | let child = master.deriveHardened(c.m).neutered() 140 | 141 | t.plan(1) 142 | t.equal(c.base58, child.toBase58()) 143 | }) 144 | 145 | tape('works for Public -> public', (t) => { 146 | let f = valid[1] 147 | let c = f.master.children[0] 148 | 149 | let master = BIP32.fromBase58(f.master.base58) 150 | let child = master.derive(c.m) 151 | 152 | t.plan(2) 153 | t.equal(c.base58, child.toBase58()) 154 | 155 | const hdNeutered = BIP32.fromPublicKey(Buffer.from(f.master.pubKey, 'hex'), Buffer.from(f.master.chainCode, 'hex')) 156 | t.equal(child.toBase58(), hdNeutered.derive(c.m).toBase58()) 157 | }) 158 | 159 | tape('throws on Public -> public (hardened)', (t) => { 160 | let f = valid[0] 161 | let c = f.master.children[0] 162 | 163 | let master = BIP32.fromBase58(f.master.base58) 164 | 165 | t.plan(1) 166 | t.throws(() => { 167 | master.deriveHardened(c.m) 168 | }, /Missing private key for hardened child key/) 169 | }) 170 | 171 | tape('throws on wrong types', (t) => { 172 | let f = valid[0] 173 | let master = BIP32.fromBase58(f.master.base58) 174 | 175 | invalid.derive.forEach((fx) => { 176 | t.throws(() => { 177 | master.derive(fx.index) 178 | }, fx.exception) 179 | }) 180 | 181 | invalid.deriveHardened.forEach((fx) => { 182 | t.throws(() => { 183 | master.deriveHardened(fx.index) 184 | }, fx.exception) 185 | }) 186 | 187 | invalid.derivePath.forEach((fx) => { 188 | t.throws(() => { 189 | master.derivePath(fx.derivationPath) 190 | }, fx.exception) 191 | }) 192 | 193 | let ZERO = Buffer.alloc(32, 0) 194 | let ONES = Buffer.alloc(32, 1) 195 | 196 | t.throws(() => { 197 | BIP32.fromPrivateKey(Buffer.alloc(2), ONES) 198 | }, /ValiError: Invalid length: Expected 32 but received 2/) 199 | 200 | t.throws(() => { 201 | BIP32.fromPrivateKey(ZERO, ONES) 202 | }, /Private key not in range \[1, n\)/) 203 | 204 | t.end() 205 | }) 206 | 207 | tape('works when private key has leading zeros', (t) => { 208 | let key = 'xprv9s21ZrQH143K3ckY9DgU79uMTJkQRLdbCCVDh81SnxTgPzLLGax6uHeBULTtaEtcAvKjXfT7ZWtHzKjTpujMkUd9dDb8msDeAfnJxrgAYhr' 209 | let hdkey = BIP32.fromBase58(key) 210 | 211 | t.plan(2) 212 | t.equal(tools.toHex(hdkey.privateKey), '00000055378cf5fafb56c711c674143f9b0ee82ab0ba2924f19b64f5ae7cdbfd') 213 | let child = hdkey.derivePath('m/44\'/0\'/0\'/0/0\'') 214 | t.equal(tools.toHex(child.privateKey), '3348069561d2a0fb925e74bf198762acc47dce7db27372257d2d959a9e6f8aeb') 215 | }) 216 | 217 | tape('fromSeed', (t) => { 218 | // TODO 219 | // 'throws if IL is not within interval [1, n - 1] | IL === n || IL === 0' 220 | invalid.fromSeed.forEach((f) => { 221 | t.throws(() => { 222 | BIP32.fromSeed(Buffer.from(f.seed, 'hex')) 223 | }, new RegExp(f.exception)) 224 | }) 225 | 226 | t.end() 227 | }) 228 | 229 | tape('ecdsa', (t) => { 230 | let seed = Buffer.alloc(32, 1) 231 | let hash = Buffer.alloc(32, 2) 232 | let signature = Buffer.from('9636ee2fac31b795a308856b821ebe297dda7b28220fb46ea1fbbd7285977cc04c82b734956246a0f15a9698f03f546d8d96fe006c8e7bd2256ca7c8229e6f5c', 'hex') 233 | let schnorrsig = Buffer.from('2fae8b517cb0e7302ca48a4109d1819e3d75af96bd58d297023e3058c4e98ff812fe6ae32a2b2bc4abab10f88f7fe56efbafc8a4e4fa437af78926f528b0585e', 'hex') 234 | let signatureLowR = Buffer.from('0587a40b391b76596c257bf59565b24eaff2cc42b45caa2640902e73fb97a6e702c3402ab89348a7dae1bf171c3e172fa60353d7b01621a94cb7caca59b995db', 'hex') 235 | let node = BIP32.fromSeed(seed) 236 | 237 | t.plan(11) 238 | t.equal(tools.toHex(node.sign(hash)), tools.toHex(signature)) 239 | t.equal(tools.toHex(node.sign(hash, true)), tools.toHex(signatureLowR)) 240 | t.equal(tools.toHex(node.signSchnorr(hash)), tools.toHex(schnorrsig)) 241 | t.equal(node.verify(hash, signature), true) 242 | t.equal(node.verify(seed, signature), false) 243 | t.equal(node.verify(hash, signatureLowR), true) 244 | t.equal(node.verify(seed, signatureLowR), false) 245 | t.equal(node.verifySchnorr(hash, schnorrsig), true) 246 | t.equal(node.verifySchnorr(seed, schnorrsig), false) 247 | 248 | const neuteredNode = node.neutered() 249 | t.throws(() => neuteredNode.sign(hash), /Missing private key/) 250 | t.throws(() => neuteredNode.signSchnorr(hash), /Missing private key/) 251 | }) 252 | 253 | tape('ecdsa - no schnorr', (t) => { 254 | let seed = Buffer.alloc(32, 1) 255 | let hash = Buffer.alloc(32, 2) 256 | const tweak = Buffer.alloc(32, 3) 257 | 258 | const bip32NoSchnorr = BIP32Creator({ ...ecc, signSchnorr: null, verifySchnorr: null }) 259 | const node = bip32NoSchnorr.fromSeed(seed) 260 | 261 | t.plan(5) 262 | t.throws(() => node.signSchnorr(hash), /signSchnorr not supported by ecc library/) 263 | t.throws(() => node.verifySchnorr(hash), /verifySchnorr not supported by ecc library/) 264 | 265 | const tweakedNode = node.tweak(tweak) 266 | t.throws(() => tweakedNode.signSchnorr(hash), /signSchnorr not supported by ecc library/) 267 | t.throws(() => tweakedNode.verifySchnorr(hash), /verifySchnorr not supported by ecc library/) 268 | 269 | const signer = node.neutered().tweak(tweak) 270 | t.throws(() => signer.verifySchnorr(hash), /verifySchnorr not supported by ecc library/) 271 | }) 272 | 273 | tape('ecc without tweak support', (t) => { 274 | let seed = Buffer.alloc(32, 1) 275 | const tweak = Buffer.alloc(32, 3) 276 | 277 | const bip32NoTweak = BIP32Creator({ ...ecc, xOnlyPointAddTweak: null, privateNegate: null }) 278 | const node = bip32NoTweak.fromSeed(seed) 279 | const nodeWithoutPrivKey = bip32NoTweak.fromPublicKey(node.publicKey, node.chainCode) 280 | 281 | t.plan(2) 282 | t.throws(() => node.tweak(tweak), /privateNegate not supported by ecc library/) 283 | t.throws(() => nodeWithoutPrivKey.tweak(tweak), /xOnlyPointAddTweak not supported by ecc library/) 284 | }) 285 | 286 | tape('tweak', (t) => { 287 | const seed = Buffer.alloc(32, 1) 288 | const hash = Buffer.alloc(32, 2) 289 | const tweak = Buffer.alloc(32, 3) 290 | const signature = Buffer.from('5a38c6652feb5166c9c91cfa5fa4a4c7cec27445d4619499df8afdd05ebc823246d644b0c7d3b960625393df537f900528ec4b14e6ddab8fd0c7e87c98cfe9d0', 'hex') 291 | const schnorrsig = Buffer.from('20506478d341d0ab1afd32671eb1550b1c5329ad5179a19712212b857f06b3210d949964cd513ff25719e2e9b0087d5a9745afd5d38641ce0dfa86f67c86de63', 'hex') 292 | const signatureLowR = Buffer.from('5a38c6652feb5166c9c91cfa5fa4a4c7cec27445d4619499df8afdd05ebc823246d644b0c7d3b960625393df537f900528ec4b14e6ddab8fd0c7e87c98cfe9d0', 'hex') 293 | const signer = BIP32.fromSeed(seed).tweak(tweak) 294 | 295 | t.plan(9) 296 | t.equal(tools.toHex(signer.sign(hash)), tools.toHex(signature)) 297 | t.equal(tools.toHex(signer.sign(hash, true)), tools.toHex(signatureLowR)) 298 | t.equal(tools.toHex(signer.signSchnorr(hash)), tools.toHex(schnorrsig)) 299 | t.equal(signer.verify(hash, signature), true) 300 | t.equal(signer.verify(seed, signature), false) 301 | t.equal(signer.verify(hash, signatureLowR), true) 302 | t.equal(signer.verify(seed, signatureLowR), false) 303 | t.equal(signer.verifySchnorr(hash, schnorrsig), true) 304 | t.equal(signer.verifySchnorr(seed, schnorrsig), false) 305 | }) 306 | 307 | tape('tweak - neutered', (t) => { 308 | const seed = Buffer.alloc(32, 1) 309 | const hash = Buffer.alloc(32, 2) 310 | const tweak = Buffer.alloc(32, 3) 311 | const signature = Buffer.from('5a38c6652feb5166c9c91cfa5fa4a4c7cec27445d4619499df8afdd05ebc823246d644b0c7d3b960625393df537f900528ec4b14e6ddab8fd0c7e87c98cfe9d0', 'hex') 312 | const schnorrsig = Buffer.from('20506478d341d0ab1afd32671eb1550b1c5329ad5179a19712212b857f06b3210d949964cd513ff25719e2e9b0087d5a9745afd5d38641ce0dfa86f67c86de63', 'hex') 313 | const signatureLowR = Buffer.from('5a38c6652feb5166c9c91cfa5fa4a4c7cec27445d4619499df8afdd05ebc823246d644b0c7d3b960625393df537f900528ec4b14e6ddab8fd0c7e87c98cfe9d0', 'hex') 314 | const signer = BIP32.fromSeed(seed).neutered().tweak(tweak) 315 | 316 | t.plan(8) 317 | t.throws(() => signer.sign(hash), /Missing private key/) 318 | t.throws(() => signer.signSchnorr(hash), /Missing private key/) 319 | 320 | t.equal(signer.verify(hash, signature), true) 321 | t.equal(signer.verify(seed, signature), false) 322 | t.equal(signer.verify(hash, signatureLowR), true) 323 | t.equal(signer.verify(seed, signatureLowR), false) 324 | t.equal(signer.verifySchnorr(hash, schnorrsig), true) 325 | t.equal(signer.verifySchnorr(seed, schnorrsig), false) 326 | }) 327 | -------------------------------------------------------------------------------- /ts-src/bip32.ts: -------------------------------------------------------------------------------- 1 | import * as crypto from './crypto.js'; 2 | import { testEcc } from './testecc.js'; 3 | import { base58check } from '@scure/base'; 4 | import { sha256 } from '@noble/hashes/sha256'; 5 | import * as v from 'valibot'; 6 | import { 7 | Bip32PathSchema, 8 | Buffer256Bit, 9 | Buffer33Bytes, 10 | NetworkSchema, 11 | Uint31Schema, 12 | Uint32Schema, 13 | } from './types.js'; 14 | import * as wif from 'wif'; 15 | import * as tools from 'uint8array-tools'; 16 | const _bs58check = base58check(sha256); 17 | const bs58check = { 18 | encode: (data: Uint8Array): string => _bs58check.encode(data), 19 | decode: (str: string): Uint8Array => _bs58check.decode(str), 20 | }; 21 | 22 | interface Network { 23 | wif: number; 24 | bip32: { 25 | public: number; 26 | private: number; 27 | }; 28 | messagePrefix?: string; 29 | bech32?: string; 30 | pubKeyHash?: number; 31 | scriptHash?: number; 32 | } 33 | export interface Signer { 34 | publicKey: Uint8Array; 35 | lowR: boolean; 36 | sign(hash: Uint8Array, lowR?: boolean): Uint8Array; 37 | verify(hash: Uint8Array, signature: Uint8Array): boolean; 38 | signSchnorr(hash: Uint8Array): Uint8Array; 39 | verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean; 40 | } 41 | export interface BIP32Interface extends Signer { 42 | chainCode: Uint8Array; 43 | network: Network; 44 | depth: number; 45 | index: number; 46 | parentFingerprint: number; 47 | privateKey?: Uint8Array; 48 | identifier: Uint8Array; 49 | fingerprint: Uint8Array; 50 | isNeutered(): boolean; 51 | neutered(): BIP32Interface; 52 | toBase58(): string; 53 | toWIF(): string; 54 | derive(index: number): BIP32Interface; 55 | deriveHardened(index: number): BIP32Interface; 56 | derivePath(path: string): BIP32Interface; 57 | tweak(t: Uint8Array): Signer; 58 | } 59 | 60 | export interface BIP32API { 61 | fromSeed(seed: Uint8Array, network?: Network): BIP32Interface; 62 | fromBase58(inString: string, network?: Network): BIP32Interface; 63 | fromPublicKey( 64 | publicKey: Uint8Array, 65 | chainCode: Uint8Array, 66 | network?: Network, 67 | ): BIP32Interface; 68 | fromPrivateKey( 69 | privateKey: Uint8Array, 70 | chainCode: Uint8Array, 71 | network?: Network, 72 | ): BIP32Interface; 73 | } 74 | 75 | interface XOnlyPointAddTweakResult { 76 | parity: 1 | 0; 77 | xOnlyPubkey: Uint8Array; 78 | } 79 | 80 | export interface TinySecp256k1Interface { 81 | isPoint(p: Uint8Array): boolean; 82 | isPrivate(d: Uint8Array): boolean; 83 | pointFromScalar(d: Uint8Array, compressed?: boolean): Uint8Array | null; 84 | pointAddScalar( 85 | p: Uint8Array, 86 | tweak: Uint8Array, 87 | compressed?: boolean, 88 | ): Uint8Array | null; 89 | privateAdd(d: Uint8Array, tweak: Uint8Array): Uint8Array | null; 90 | sign(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array; 91 | signSchnorr?(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array; 92 | verify( 93 | h: Uint8Array, 94 | Q: Uint8Array, 95 | signature: Uint8Array, 96 | strict?: boolean, 97 | ): boolean; 98 | verifySchnorr?(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean; 99 | xOnlyPointAddTweak?( 100 | p: Uint8Array, 101 | tweak: Uint8Array, 102 | ): XOnlyPointAddTweakResult | null; 103 | privateNegate?(d: Uint8Array): Uint8Array; 104 | } 105 | 106 | export function BIP32Factory(ecc: TinySecp256k1Interface): BIP32API { 107 | testEcc(ecc); 108 | 109 | const BITCOIN: Network = { 110 | messagePrefix: '\x18Bitcoin Signed Message:\n', 111 | bech32: 'bc', 112 | bip32: { 113 | public: 0x0488b21e, 114 | private: 0x0488ade4, 115 | }, 116 | pubKeyHash: 0x00, 117 | scriptHash: 0x05, 118 | wif: 0x80, 119 | }; 120 | 121 | const HIGHEST_BIT = 0x80000000; 122 | 123 | function toXOnly(pubKey: Uint8Array) { 124 | return pubKey.length === 32 ? pubKey : pubKey.slice(1, 33); 125 | } 126 | 127 | class Bip32Signer implements Signer { 128 | lowR: boolean = false; 129 | 130 | constructor( 131 | protected __D: Uint8Array | undefined, 132 | protected __Q: Uint8Array | undefined, 133 | ) {} 134 | 135 | get publicKey(): Uint8Array { 136 | if (this.__Q === undefined) 137 | this.__Q = ecc.pointFromScalar(this.__D!, true)!; 138 | return this.__Q!; 139 | } 140 | 141 | get privateKey(): Uint8Array | undefined { 142 | return this.__D; 143 | } 144 | 145 | sign(hash: Uint8Array, lowR?: boolean): Uint8Array { 146 | if (!this.privateKey) throw new Error('Missing private key'); 147 | if (lowR === undefined) lowR = this.lowR; 148 | if (lowR === false) { 149 | return ecc.sign(hash, this.privateKey); 150 | } else { 151 | let sig = ecc.sign(hash, this.privateKey); 152 | const extraData = new Uint8Array(32); 153 | let counter = 0; 154 | // if first try is lowR, skip the loop 155 | // for second try and on, add extra entropy counting up 156 | while (sig[0] > 0x7f) { 157 | counter++; 158 | tools.writeUInt32(extraData, 0, counter, 'LE'); 159 | sig = ecc.sign(hash, this.privateKey, extraData); 160 | } 161 | return sig; 162 | } 163 | } 164 | 165 | signSchnorr(hash: Uint8Array): Uint8Array { 166 | if (!this.privateKey) throw new Error('Missing private key'); 167 | if (!ecc.signSchnorr) 168 | throw new Error('signSchnorr not supported by ecc library'); 169 | return ecc.signSchnorr(hash, this.privateKey); 170 | } 171 | 172 | verify(hash: Uint8Array, signature: Uint8Array): boolean { 173 | return ecc.verify(hash, this.publicKey, signature); 174 | } 175 | 176 | verifySchnorr(hash: Uint8Array, signature: Uint8Array): boolean { 177 | if (!ecc.verifySchnorr) 178 | throw new Error('verifySchnorr not supported by ecc library'); 179 | return ecc.verifySchnorr(hash, this.publicKey.subarray(1, 33), signature); 180 | } 181 | } 182 | 183 | class BIP32 extends Bip32Signer implements BIP32Interface { 184 | constructor( 185 | __D: Uint8Array | undefined, 186 | __Q: Uint8Array | undefined, 187 | public chainCode: Uint8Array, 188 | public network: Network, 189 | private __DEPTH = 0, 190 | private __INDEX = 0, 191 | private __PARENT_FINGERPRINT = 0x00000000, 192 | ) { 193 | super(__D, __Q); 194 | v.parse(NetworkSchema, network); 195 | } 196 | 197 | get depth(): number { 198 | return this.__DEPTH; 199 | } 200 | 201 | get index(): number { 202 | return this.__INDEX; 203 | } 204 | 205 | get parentFingerprint(): number { 206 | return this.__PARENT_FINGERPRINT; 207 | } 208 | 209 | get identifier(): Uint8Array { 210 | return crypto.hash160(this.publicKey); 211 | } 212 | 213 | get fingerprint(): Uint8Array { 214 | return this.identifier.slice(0, 4); 215 | } 216 | 217 | get compressed(): boolean { 218 | return true; 219 | } 220 | 221 | // Private === not neutered 222 | // Public === neutered 223 | isNeutered(): boolean { 224 | return this.__D === undefined; 225 | } 226 | 227 | neutered(): BIP32Interface { 228 | return fromPublicKeyLocal( 229 | this.publicKey, 230 | this.chainCode, 231 | this.network, 232 | this.depth, 233 | this.index, 234 | this.parentFingerprint, 235 | ); 236 | } 237 | 238 | toBase58(): string { 239 | const network = this.network; 240 | const version = !this.isNeutered() 241 | ? network.bip32.private 242 | : network.bip32.public; 243 | const buffer = new Uint8Array(78); 244 | 245 | // 4 bytes: version bytes 246 | tools.writeUInt32(buffer, 0, version, 'BE'); 247 | 248 | // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, .... 249 | tools.writeUInt8(buffer, 4, this.depth); 250 | 251 | // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) 252 | tools.writeUInt32(buffer, 5, this.parentFingerprint, 'BE'); 253 | 254 | // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. 255 | // This is encoded in big endian. (0x00000000 if master key) 256 | tools.writeUInt32(buffer, 9, this.index, 'BE'); 257 | 258 | // 32 bytes: the chain code 259 | buffer.set(this.chainCode, 13); 260 | 261 | // 33 bytes: the public key or private key data 262 | if (!this.isNeutered()) { 263 | // 0x00 + k for private keys 264 | tools.writeUInt8(buffer, 45, 0); 265 | 266 | buffer.set(this.privateKey!, 46); 267 | 268 | // 33 bytes: the public key 269 | } else { 270 | // X9.62 encoding for public keys 271 | buffer.set(this.publicKey, 45); 272 | } 273 | 274 | return bs58check.encode(buffer); 275 | } 276 | 277 | toWIF(): string { 278 | if (!this.privateKey) throw new TypeError('Missing private key'); 279 | return wif.encode({ 280 | version: this.network.wif, 281 | privateKey: this.privateKey, 282 | compressed: true, 283 | }); 284 | } 285 | 286 | // https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions 287 | derive(index: number): BIP32Interface { 288 | v.parse(Uint32Schema, index); 289 | 290 | const isHardened = index >= HIGHEST_BIT; 291 | const data = new Uint8Array(37); 292 | 293 | // Hardened child 294 | if (isHardened) { 295 | if (this.isNeutered()) 296 | throw new TypeError('Missing private key for hardened child key'); 297 | 298 | // data = 0x00 || ser256(kpar) || ser32(index) 299 | data[0] = 0x00; 300 | data.set(this.privateKey!, 1); 301 | tools.writeUInt32(data, 33, index, 'BE'); 302 | 303 | // Normal child 304 | } else { 305 | // data = serP(point(kpar)) || ser32(index) 306 | // = serP(Kpar) || ser32(index) 307 | data.set(this.publicKey, 0); 308 | tools.writeUInt32(data, 33, index, 'BE'); 309 | } 310 | 311 | const I = crypto.hmacSHA512(this.chainCode, data); 312 | const IL = I.slice(0, 32); 313 | const IR = I.slice(32); 314 | 315 | // if parse256(IL) >= n, proceed with the next value for i 316 | if (!ecc.isPrivate(IL)) return this.derive(index + 1); 317 | 318 | // Private parent key -> private child key 319 | let hd: BIP32Interface; 320 | if (!this.isNeutered()) { 321 | // ki = parse256(IL) + kpar (mod n) 322 | const ki = ecc.privateAdd(this.privateKey!, IL)!; 323 | 324 | // In case ki == 0, proceed with the next value for i 325 | if (ki == null) return this.derive(index + 1); 326 | 327 | hd = fromPrivateKeyLocal( 328 | ki, 329 | IR, 330 | this.network, 331 | this.depth + 1, 332 | index, 333 | tools.readUInt32(this.fingerprint, 0, 'BE'), 334 | ); 335 | 336 | // Public parent key -> public child key 337 | } else { 338 | // Ki = point(parse256(IL)) + Kpar 339 | // = G*IL + Kpar 340 | const Ki = ecc.pointAddScalar(this.publicKey, IL, true)!; 341 | 342 | // In case Ki is the point at infinity, proceed with the next value for i 343 | if (Ki === null) return this.derive(index + 1); 344 | 345 | hd = fromPublicKeyLocal( 346 | Ki, 347 | IR, 348 | this.network, 349 | this.depth + 1, 350 | index, 351 | tools.readUInt32(this.fingerprint, 0, 'BE'), 352 | ); 353 | } 354 | 355 | return hd; 356 | } 357 | 358 | deriveHardened(index: number): BIP32Interface { 359 | if (typeof v.parse(Uint31Schema, index) === 'number') 360 | // Only derives hardened private keys by default 361 | return this.derive(index + HIGHEST_BIT); 362 | throw new TypeError('Expected UInt31, got ' + index); 363 | } 364 | 365 | derivePath(path: string): BIP32Interface { 366 | v.parse(Bip32PathSchema, path); 367 | 368 | let splitPath = path.split('/'); 369 | if (splitPath[0] === 'm') { 370 | if (this.parentFingerprint) 371 | throw new TypeError('Expected master, got child'); 372 | 373 | splitPath = splitPath.slice(1); 374 | } 375 | 376 | return splitPath.reduce( 377 | (prevHd, indexStr) => { 378 | let index; 379 | if (indexStr.slice(-1) === `'`) { 380 | index = parseInt(indexStr.slice(0, -1), 10); 381 | return prevHd.deriveHardened(index); 382 | } else { 383 | index = parseInt(indexStr, 10); 384 | return prevHd.derive(index); 385 | } 386 | }, 387 | this as BIP32Interface, 388 | ); 389 | } 390 | 391 | tweak(t: Uint8Array): Signer { 392 | if (this.privateKey) return this.tweakFromPrivateKey(t); 393 | return this.tweakFromPublicKey(t); 394 | } 395 | 396 | private tweakFromPublicKey(t: Uint8Array): Signer { 397 | const xOnlyPubKey = toXOnly(this.publicKey); 398 | if (!ecc.xOnlyPointAddTweak) 399 | throw new Error('xOnlyPointAddTweak not supported by ecc library'); 400 | const tweakedPublicKey = ecc.xOnlyPointAddTweak(xOnlyPubKey, t); 401 | if (!tweakedPublicKey || tweakedPublicKey.xOnlyPubkey === null) 402 | throw new Error('Cannot tweak public key!'); 403 | const parityByte = Uint8Array.from([ 404 | tweakedPublicKey.parity === 0 ? 0x02 : 0x03, 405 | ]); 406 | const tweakedPublicKeyCompresed = tools.concat([ 407 | parityByte, 408 | tweakedPublicKey.xOnlyPubkey, 409 | ]); 410 | 411 | return new Bip32Signer(undefined, tweakedPublicKeyCompresed); 412 | } 413 | 414 | private tweakFromPrivateKey(t: Uint8Array): Signer { 415 | const hasOddY = 416 | this.publicKey[0] === 3 || 417 | (this.publicKey[0] === 4 && (this.publicKey[64] & 1) === 1); 418 | const privateKey = (() => { 419 | if (!hasOddY) return this.privateKey; 420 | else if (!ecc.privateNegate) 421 | throw new Error('privateNegate not supported by ecc library'); 422 | else return ecc.privateNegate(this.privateKey!); 423 | })(); 424 | const tweakedPrivateKey = ecc.privateAdd(privateKey!, t); 425 | if (!tweakedPrivateKey) throw new Error('Invalid tweaked private key!'); 426 | 427 | return new Bip32Signer(tweakedPrivateKey, undefined); 428 | } 429 | } 430 | 431 | function fromBase58(inString: string, network?: Network): BIP32Interface { 432 | const buffer = bs58check.decode(inString); 433 | if (buffer.length !== 78) throw new TypeError('Invalid buffer length'); 434 | network = network || BITCOIN; 435 | 436 | // 4 bytes: version bytes 437 | const version = tools.readUInt32(buffer, 0, 'BE'); 438 | if (version !== network.bip32.private && version !== network.bip32.public) 439 | throw new TypeError('Invalid network version'); 440 | 441 | // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... 442 | const depth = buffer[4]; 443 | 444 | // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) 445 | const parentFingerprint = tools.readUInt32(buffer, 5, 'BE'); 446 | if (depth === 0) { 447 | if (parentFingerprint !== 0x00000000) 448 | throw new TypeError('Invalid parent fingerprint'); 449 | } 450 | 451 | // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. 452 | // This is encoded in MSB order. (0x00000000 if master key) 453 | const index = tools.readUInt32(buffer, 9, 'BE'); 454 | if (depth === 0 && index !== 0) throw new TypeError('Invalid index'); 455 | 456 | // 32 bytes: the chain code 457 | const chainCode = buffer.slice(13, 45); 458 | let hd: BIP32Interface; 459 | 460 | // 33 bytes: private key data (0x00 + k) 461 | if (version === network.bip32.private) { 462 | if (buffer[45] !== 0x00) throw new TypeError('Invalid private key'); 463 | const k = buffer.slice(46, 78); 464 | 465 | hd = fromPrivateKeyLocal( 466 | k, 467 | chainCode, 468 | network, 469 | depth, 470 | index, 471 | parentFingerprint, 472 | ); 473 | 474 | // 33 bytes: public key data (0x02 + X or 0x03 + X) 475 | } else { 476 | const X = buffer.slice(45, 78); 477 | 478 | hd = fromPublicKeyLocal( 479 | X, 480 | chainCode, 481 | network, 482 | depth, 483 | index, 484 | parentFingerprint, 485 | ); 486 | } 487 | 488 | return hd; 489 | } 490 | 491 | function fromPrivateKey( 492 | privateKey: Uint8Array, 493 | chainCode: Uint8Array, 494 | network?: Network, 495 | ): BIP32Interface { 496 | return fromPrivateKeyLocal(privateKey, chainCode, network); 497 | } 498 | 499 | function fromPrivateKeyLocal( 500 | privateKey: Uint8Array, 501 | chainCode: Uint8Array, 502 | network?: Network, 503 | depth?: number, 504 | index?: number, 505 | parentFingerprint?: number, 506 | ): BIP32Interface { 507 | v.parse(Buffer256Bit, privateKey); 508 | v.parse(Buffer256Bit, chainCode); 509 | 510 | network = network || BITCOIN; 511 | 512 | if (!ecc.isPrivate(privateKey)) 513 | throw new TypeError('Private key not in range [1, n)'); 514 | return new BIP32( 515 | privateKey, 516 | undefined, 517 | chainCode, 518 | network, 519 | depth, 520 | index, 521 | parentFingerprint, 522 | ); 523 | } 524 | 525 | function fromPublicKey( 526 | publicKey: Uint8Array, 527 | chainCode: Uint8Array, 528 | network?: Network, 529 | ): BIP32Interface { 530 | return fromPublicKeyLocal(publicKey, chainCode, network); 531 | } 532 | 533 | function fromPublicKeyLocal( 534 | publicKey: Uint8Array, 535 | chainCode: Uint8Array, 536 | network?: Network, 537 | depth?: number, 538 | index?: number, 539 | parentFingerprint?: number, 540 | ): BIP32Interface { 541 | v.parse(Buffer33Bytes, publicKey); 542 | v.parse(Buffer256Bit, chainCode); 543 | 544 | network = network || BITCOIN; 545 | 546 | // verify the X coordinate is a point on the curve 547 | if (!ecc.isPoint(publicKey)) 548 | throw new TypeError('Point is not on the curve'); 549 | return new BIP32( 550 | undefined, 551 | publicKey, 552 | chainCode, 553 | network, 554 | depth, 555 | index, 556 | parentFingerprint, 557 | ); 558 | } 559 | 560 | function fromSeed(seed: Uint8Array, network?: Network): BIP32Interface { 561 | v.parse(v.instance(Uint8Array), seed); 562 | if (seed.length < 16) 563 | throw new TypeError('Seed should be at least 128 bits'); 564 | if (seed.length > 64) 565 | throw new TypeError('Seed should be at most 512 bits'); 566 | network = network || BITCOIN; 567 | 568 | const I = crypto.hmacSHA512(tools.fromUtf8('Bitcoin seed'), seed); 569 | const IL = I.slice(0, 32); 570 | const IR = I.slice(32); 571 | 572 | return fromPrivateKey(IL, IR, network); 573 | } 574 | 575 | return { 576 | fromSeed, 577 | fromBase58, 578 | fromPublicKey, 579 | fromPrivateKey, 580 | }; 581 | } 582 | -------------------------------------------------------------------------------- /ts-src/crypto.ts: -------------------------------------------------------------------------------- 1 | import { hmac } from '@noble/hashes/hmac'; 2 | import { ripemd160 } from '@noble/hashes/ripemd160'; 3 | import { sha256 } from '@noble/hashes/sha256'; 4 | import { sha512 } from '@noble/hashes/sha512'; 5 | 6 | export function hash160(buffer: Uint8Array): Uint8Array { 7 | return ripemd160(sha256(buffer)); 8 | } 9 | 10 | export function hmacSHA512(key: Uint8Array, data: Uint8Array): Uint8Array { 11 | return hmac(sha512, key, data); 12 | } 13 | -------------------------------------------------------------------------------- /ts-src/index.ts: -------------------------------------------------------------------------------- 1 | export { 2 | BIP32Factory as default, 3 | BIP32Factory, 4 | BIP32Interface, 5 | BIP32API, 6 | TinySecp256k1Interface, 7 | } from './bip32.js'; 8 | -------------------------------------------------------------------------------- /ts-src/testecc.ts: -------------------------------------------------------------------------------- 1 | import { TinySecp256k1Interface } from './bip32'; 2 | import * as tools from 'uint8array-tools'; 3 | 4 | const h = (hex: string): Uint8Array => tools.fromHex(hex); 5 | 6 | export function testEcc(ecc: TinySecp256k1Interface): void { 7 | assert( 8 | ecc.isPoint( 9 | h('0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 10 | ), 11 | ); 12 | assert( 13 | !ecc.isPoint( 14 | h('030000000000000000000000000000000000000000000000000000000000000005'), 15 | ), 16 | ); 17 | assert( 18 | ecc.isPrivate( 19 | h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 20 | ), 21 | ); 22 | // order - 1 23 | assert( 24 | ecc.isPrivate( 25 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'), 26 | ), 27 | ); 28 | // 0 29 | assert( 30 | !ecc.isPrivate( 31 | h('0000000000000000000000000000000000000000000000000000000000000000'), 32 | ), 33 | ); 34 | // order 35 | assert( 36 | !ecc.isPrivate( 37 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'), 38 | ), 39 | ); 40 | // order + 1 41 | assert( 42 | !ecc.isPrivate( 43 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364142'), 44 | ), 45 | ); 46 | assert( 47 | tools.compare( 48 | ecc.pointFromScalar( 49 | h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af'), 50 | )!, 51 | h('02b07ba9dca9523b7ef4bd97703d43d20399eb698e194704791a25ce77a400df99'), 52 | ) === 0, 53 | ); 54 | if (ecc.xOnlyPointAddTweak) { 55 | assert( 56 | ecc.xOnlyPointAddTweak( 57 | h('79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 58 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'), 59 | ) === null, 60 | ); 61 | 62 | let xOnlyRes = ecc.xOnlyPointAddTweak( 63 | h('1617d38ed8d8657da4d4761e8057bc396ea9e4b9d29776d4be096016dbd2509b'), 64 | h('a8397a935f0dfceba6ba9618f6451ef4d80637abf4e6af2669fbc9de6a8fd2ac'), 65 | ); 66 | assert( 67 | tools.compare( 68 | xOnlyRes!.xOnlyPubkey, 69 | h('e478f99dab91052ab39a33ea35fd5e6e4933f4d28023cd597c9a1f6760346adf'), 70 | ) === 0 && xOnlyRes!.parity === 1, 71 | ); 72 | 73 | xOnlyRes = ecc.xOnlyPointAddTweak( 74 | h('2c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991'), 75 | h('823c3cd2142744b075a87eade7e1b8678ba308d566226a0056ca2b7a76f86b47'), 76 | ); 77 | } 78 | assert( 79 | tools.compare( 80 | ecc.pointAddScalar( 81 | h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 82 | h('0000000000000000000000000000000000000000000000000000000000000003'), 83 | )!, 84 | h('02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5'), 85 | ) === 0, 86 | ); 87 | assert( 88 | tools.compare( 89 | ecc.privateAdd( 90 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e'), 91 | h('0000000000000000000000000000000000000000000000000000000000000002'), 92 | )!, 93 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'), 94 | ) === 0, 95 | ); 96 | if (ecc.privateNegate) { 97 | assert( 98 | tools.compare( 99 | ecc.privateNegate( 100 | h('0000000000000000000000000000000000000000000000000000000000000001'), 101 | ), 102 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'), 103 | ) === 0, 104 | ); 105 | assert( 106 | tools.compare( 107 | ecc.privateNegate( 108 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd036413e'), 109 | ), 110 | h('0000000000000000000000000000000000000000000000000000000000000003'), 111 | ) === 0, 112 | ); 113 | assert( 114 | tools.compare( 115 | ecc.privateNegate( 116 | h('b1121e4088a66a28f5b6b0f5844943ecd9f610196d7bb83b25214b60452c09af'), 117 | ), 118 | h('4eede1bf775995d70a494f0a7bb6bc11e0b8cccd41cce8009ab1132c8b0a3792'), 119 | ) === 0, 120 | ); 121 | } 122 | assert( 123 | tools.compare( 124 | ecc.sign( 125 | h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), 126 | h('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140'), 127 | )!, 128 | h( 129 | '54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5', 130 | ), 131 | ) === 0, 132 | ); 133 | assert( 134 | ecc.verify( 135 | h('5e9f0a0d593efdcf78ac923bc3313e4e7d408d574354ee2b3288c0da9fbba6ed'), 136 | h('0379be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798'), 137 | h( 138 | '54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5', 139 | ), 140 | ), 141 | ); 142 | if (ecc.signSchnorr) { 143 | assert( 144 | tools.compare( 145 | ecc.signSchnorr( 146 | h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), 147 | h('c90fdaa22168c234c4c6628b80dc1cd129024e088a67cc74020bbea63b14e5c9'), 148 | h('c87aa53824b4d7ae2eb035a2b5bbbccc080e76cdc6d1692c4b0b62d798e6d906'), 149 | )!, 150 | h( 151 | '5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7', 152 | ), 153 | ) === 0, 154 | ); 155 | } 156 | if (ecc.verifySchnorr) { 157 | assert( 158 | ecc.verifySchnorr( 159 | h('7e2d58d8b3bcdf1abadec7829054f90dda9805aab56c77333024b9d0a508b75c'), 160 | h('dd308afec5777e13121fa72b9cc1b7cc0139715309b086c960e18fd969774eb8'), 161 | h( 162 | '5831aaeed7b44bb74e5eab94ba9d4294c49bcf2a60728d8b4c200f50dd313c1bab745879a5ad954a72c45a91c3a51d3c7adea98d82f8481e0e1e03674a6f3fb7', 163 | ), 164 | ), 165 | ); 166 | } 167 | } 168 | 169 | function assert(bool: boolean): void { 170 | if (!bool) throw new Error('ecc library invalid'); 171 | } 172 | -------------------------------------------------------------------------------- /ts-src/types.ts: -------------------------------------------------------------------------------- 1 | import * as v from 'valibot'; 2 | 3 | export const Uint32Schema = v.pipe( 4 | v.number(), 5 | v.integer(), 6 | v.minValue(0), 7 | v.maxValue(0xffffffff), 8 | ); 9 | 10 | export const Uint31Schema = v.pipe( 11 | v.number(), 12 | v.integer(), 13 | v.minValue(0), 14 | v.maxValue(0x7fffffff), 15 | ); 16 | 17 | const Uint8Schema = v.pipe( 18 | v.number(), 19 | v.integer(), 20 | v.minValue(0), 21 | v.maxValue(0xff), 22 | ); 23 | 24 | export const Buffer256Bit = v.pipe( 25 | v.instance(Uint8Array), 26 | v.length(32), 27 | ); 28 | 29 | export const Buffer33Bytes = v.pipe( 30 | v.instance(Uint8Array), 31 | v.length(33), 32 | ); 33 | 34 | export const NetworkSchema = v.object({ 35 | wif: Uint8Schema, 36 | bip32: v.object({ 37 | public: Uint32Schema, 38 | private: Uint32Schema, 39 | }), 40 | }); 41 | 42 | export const Bip32PathSchema = v.pipe( 43 | v.string(), 44 | v.regex(/^(m\/)?(\d+'?\/)*\d+'?$/), 45 | ); 46 | 47 | export type Network = v.InferOutput; 48 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNEXT", 4 | "module": "commonjs", 5 | "outDir": "./src", 6 | "rootDir": "./ts-src", 7 | "types": ["node"], 8 | "allowJs": false, 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "strictFunctionTypes": true, 13 | "strictBindCallApply": true, 14 | "strictPropertyInitialization": true, 15 | "noImplicitThis": true, 16 | "alwaysStrict": true, 17 | "noUnusedLocals": true, 18 | "noUnusedParameters": true, 19 | "skipLibCheck": true 20 | }, 21 | "include": ["ts-src/**/*.ts"], 22 | "exclude": ["**/*.spec.ts", "node_modules/**/*"] 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig.cjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "emitDeclarationOnly": false, 6 | "esModuleInterop": true, 7 | "outDir": "src/cjs", 8 | "module": "commonjs" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "src/esm", 5 | "esModuleInterop": true, 6 | "resolveJsonModule": true, 7 | "module": "ESNext", 8 | "moduleResolution": "Node" 9 | }, 10 | } 11 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": ["tslint:recommended"], 4 | "rules": { 5 | "arrow-parens": [true, "ban-single-arg-parens"], 6 | "curly": false, 7 | "indent": [ 8 | true, 9 | "spaces", 10 | 2 11 | ], 12 | "interface-name": [false], 13 | "match-default-export-name": true, 14 | "max-classes-per-file": [false], 15 | "member-access": [true, "no-public"], 16 | "no-bitwise": false, 17 | "no-console": false, 18 | "no-empty": [true, "allow-empty-catch"], 19 | "no-implicit-dependencies": true, 20 | "no-return-await": true, 21 | "no-var-requires": false, 22 | "no-unused-expression": false, 23 | "object-literal-sort-keys": false, 24 | "quotemark": [true, "single"], 25 | "variable-name": [ 26 | true, 27 | "ban-keywords", 28 | "check-format", 29 | "allow-leading-underscore", 30 | "allow-pascal-case" 31 | ] 32 | }, 33 | "rulesDirectory": [] 34 | } 35 | --------------------------------------------------------------------------------