diff --git a/.github/workflows/main_ci.yml b/.github/workflows/main_ci.yml index 04a6363..2109d39 100644 --- a/.github/workflows/main_ci.yml +++ b/.github/workflows/main_ci.yml @@ -10,60 +10,60 @@ jobs: audit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm audit unit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run unit coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run coverage format: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run format:ci gitdiff: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run gitdiff:ci lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-node@v4 with: - node-version: 12 + node-version: 18 registry-url: https://registry.npmjs.org/ - run: npm ci - run: npm run lint diff --git a/package-lock.json b/package-lock.json index c056b9c..a70c9b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,2110 +1,2352 @@ { "name": "bip174", "version": "2.1.1", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@babel/code-frame": { + "packages": { + "": { + "name": "bip174", + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "uint8array-tools": "^0.0.9", + "varuint-bitcoin": "^2.0.0" + }, + "devDependencies": { + "@types/node": "12.0.8", + "@types/tape": "4.2.33", + "bitcoinjs-lib": "^6.1.6", + "c8": "^10.1.2", + "prettier": "^1.18.2", + "rimraf": "^2.6.3", + "tape": "^5.3.0", + "tslint": "5.17.0", + "typescript": "3.5.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/code-frame": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@babel/highlight": "^7.22.10", "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "@babel/generator": { + "node_modules/@babel/highlight": { "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", "dev": true, - "requires": { - "@babel/types": "^7.22.10", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, - "requires": { - "@babel/types": "^7.22.5" + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", "dev": true, - "requires": { - "@babel/types": "^7.22.5" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", - "dev": true + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", - "dev": true + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" }, - "@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/parser": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.11.tgz", - "integrity": "sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==", - "dev": true - }, - "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/traverse": { - "version": "7.23.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", - "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/generator": "^7.23.0", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.0", - "@babel/types": "^7.23.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.22.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", - "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.13", - "chalk": "^2.4.2" - } - }, - "@babel/generator": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", - "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", - "dev": true, - "requires": { - "@babel/types": "^7.23.0", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/highlight": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", - "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", - "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", - "dev": true - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/types": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", - "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - } + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "@babel/types": { - "version": "7.22.11", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.11.tgz", - "integrity": "sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "to-fast-properties": "^2.0.0" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "@jridgewell/resolve-uri": { + "node_modules/@jridgewell/resolve-uri": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } }, - "@jridgewell/sourcemap-codec": { + "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true + "dev": true, + "license": "MIT" }, - "@jridgewell/trace-mapping": { + "node_modules/@jridgewell/trace-mapping": { "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "@types/node": { + "node_modules/@ljharb/resumer": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@ljharb/through": "^2.3.13", + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@ljharb/through": { + "version": "2.3.13", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { "version": "12.0.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.8.tgz", - "integrity": "sha512-b8bbUOTwzIY3V5vDTY1fIJ+ePKDUBqt2hC2woVGotdQQhG/2Sh62HOKHrT7ab+VerXAcPyAiTEipPu/FsreUtg==", - "dev": true + "dev": true, + "license": "MIT" }, - "@types/tape": { + "node_modules/@types/tape": { "version": "4.2.33", - "resolved": "https://registry.npmjs.org/@types/tape/-/tape-4.2.33.tgz", - "integrity": "sha512-ltfyuY5BIkYlGuQfwqzTDT8f0q8Z5DGppvUnWGs39oqDmMd6/UWhNpX3ZMh/VYvfxs3rFGHMrLC/eGRdLiDGuw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "@types/node": "*" } }, - "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true - }, - "ansi-styles": { + "node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" } }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "node_modules/argparse": { + "version": "1.0.10", "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", "dev": true, - "requires": { - "sprintf-js": "~1.0.2" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "array-buffer-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", - "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "node_modules/array.prototype.every": { + "version": "1.1.6", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "is-array-buffer": "^3.0.1" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "arraybuffer.prototype.slice": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz", - "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==", + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "get-intrinsic": "^1.2.1", - "is-array-buffer": "^3.0.2", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "balanced-match": { + "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base-x": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.0.tgz", + "integrity": "sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==", "dev": true }, - "base-x": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz", - "integrity": "sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==", + "node_modules/bech32": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-2.0.0.tgz", + "integrity": "sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==", + "dev": true + }, + "node_modules/bip174": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.1.tgz", + "integrity": "sha512-mdFV5+/v0XyNYXjBS6CQPLo9ekCx4gtKZFnJm5PMto7Fs9hTTDpkkzOB7/FtluRI6JbUUAu+snTYfJRgHLZbZQ==", "dev": true, - "requires": { - "safe-buffer": "^5.0.1" + "engines": { + "node": ">=8.0.0" } }, - "bech32": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", - "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", - "dev": true + "node_modules/bitcoinjs-lib": { + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-6.1.6.tgz", + "integrity": "sha512-Fk8+Vc+e2rMoDU5gXkW9tD+313rhkm5h6N9HfZxXvYU9LedttVvmXKTgd9k5rsQJjkSfsv6XRM8uhJv94SrvcA==", + "dev": true, + "dependencies": { + "@noble/hashes": "^1.2.0", + "bech32": "^2.0.0", + "bip174": "^2.1.1", + "bs58check": "^3.0.1", + "typeforce": "^1.11.3", + "varuint-bitcoin": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "node_modules/bitcoinjs-lib/node_modules/varuint-bitcoin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", + "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" + "dependencies": { + "safe-buffer": "^5.1.1" } }, - "bip174": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bip174/-/bip174-2.1.0.tgz", - "integrity": "sha512-lkc0XyiX9E9KiVAS1ZiOqK1xfiwvf4FXDDdkDq5crcDzOq+xGytY+14qCsqz7kCiy8rpN1CRNfacRhf9G3JNSA==", - "dev": true + "node_modules/brace-expansion": { + "version": "1.1.11", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, - "bip32": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/bip32/-/bip32-2.0.6.tgz", - "integrity": "sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==", - "dev": true, - "requires": { - "@types/node": "10.12.18", - "bs58check": "^2.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "tiny-secp256k1": "^1.1.3", - "typeforce": "^1.11.5", - "wif": "^2.0.6" - }, - "dependencies": { - "@types/node": { - "version": "10.12.18", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", - "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==", - "dev": true + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "dev": true, + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bs58check": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", + "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "^1.2.0", + "bs58": "^5.0.0" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/c8": { + "version": "10.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^7.0.1", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "monocart-coverage-reports": "^2" + }, + "peerDependenciesMeta": { + "monocart-coverage-reports": { + "optional": true } } }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha512-nemMHz95EmS38a26XbbdxIYj5csHd3RMP3H5bwQknX0WYHF01qhpufP42mLOwVICuH2JmhIhXiWs89MfUGL7Xw==", + "node_modules/c8/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/c8/node_modules/brace-expansion": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/c8/node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/c8/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/c8/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/c8/node_modules/cross-spawn": { + "version": "7.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/c8/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/c8/node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/node_modules/foreground-child": { + "version": "3.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/c8/node_modules/glob": { + "version": "10.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/c8/node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/c8/node_modules/istanbul-reports": { + "version": "3.1.7", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/node_modules/minimatch": { + "version": "9.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/c8/node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/c8/node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/semver": { + "version": "7.6.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/c8/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/c8/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/c8/node_modules/test-exclude": { + "version": "7.0.1", "dev": true, - "requires": { - "safe-buffer": "^5.0.1" + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^10.4.1", + "minimatch": "^9.0.4" + }, + "engines": { + "node": ">=18" } }, - "bitcoin-ops": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.1.tgz", - "integrity": "sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==", - "dev": true - }, - "bitcoinjs-lib": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-5.2.0.tgz", - "integrity": "sha512-5DcLxGUDejgNBYcieMIUfjORtUeNWl828VWLHJGVKZCb4zIS1oOySTUr0LGmcqJBQgTBz3bGbRQla4FgrdQEIQ==", - "dev": true, - "requires": { - "bech32": "^1.1.2", - "bip174": "^2.0.1", - "bip32": "^2.0.4", - "bip66": "^1.1.0", - "bitcoin-ops": "^1.4.0", - "bs58check": "^2.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.3", - "merkle-lib": "^2.0.10", - "pushdata-bitcoin": "^1.0.1", - "randombytes": "^2.0.1", - "tiny-secp256k1": "^1.1.1", - "typeforce": "^1.11.3", - "varuint-bitcoin": "^1.0.4", - "wif": "^2.0.1" + "node_modules/c8/node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/c8/node_modules/wrap-ansi": { + "version": "7.0.0", "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "node_modules/c8/node_modules/y18n": { + "version": "5.0.8", "dev": true, - "requires": { - "base-x": "^3.0.2" + "license": "ISC", + "engines": { + "node": ">=10" } }, - "bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "node_modules/c8/node_modules/yargs": { + "version": "17.7.2", "dev": true, - "requires": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" } }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", - "dev": true - }, - "caching-transform": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", - "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "node_modules/c8/node_modules/yargs-parser": { + "version": "21.1.1", "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^2.0.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.4.2" + "license": "ISC", + "engines": { + "node": ">=12" } }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/call-bind": { + "version": "1.0.7", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "chalk": { + "node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" } }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "color-convert": { + "node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "color-name": "1.1.3" } }, - "color-name": { + "node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, - "commander": { + "node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "cp-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", - "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "make-dir": "^2.0.0", - "nested-error-stacks": "^2.0.0", - "pify": "^4.0.1", - "safe-buffer": "^5.0.1" - } + "license": "MIT" }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "node_modules/concat-map": { + "version": "0.0.1", "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } + "license": "MIT" }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "node_modules/data-view-buffer": { + "version": "1.0.1", "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA==", + "node_modules/data-view-byte-length": { + "version": "1.0.1", "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/data-view-byte-offset": { + "version": "1.0.0", "dev": true, - "requires": { - "ms": "2.1.2" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "node_modules/deep-equal": { + "version": "2.2.3", "dev": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.5", + "es-get-iterator": "^1.1.3", + "get-intrinsic": "^1.2.2", + "is-arguments": "^1.1.1", + "is-array-buffer": "^3.0.2", + "is-date-object": "^1.0.5", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "isarray": "^2.0.5", + "object-is": "^1.1.5", "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "side-channel": "^1.0.4", + "which-boxed-primitive": "^1.0.2", + "which-collection": "^1.0.1", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha512-B0n2zDIXpzLzKeoEozorDSa1cHc1t0NjmxP0zuAxbizNU2MBqYJJKYXrrFdKuQliojXynrxgd7l4ahfg/+aA5g==", + "node_modules/define-data-property": { + "version": "1.1.4", "dev": true, - "requires": { - "strip-bom": "^3.0.0" + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "node_modules/define-properties": { + "version": "1.2.1", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "defined": { + "node_modules/defined": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "dev": true + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "diff": { + "node_modules/diff": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "dotignore": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", - "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", "dev": true, - "requires": { - "minimatch": "^3.0.4" + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" } }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "node_modules/dotignore": { + "version": "0.1.2", "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" } }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/eastasianwidth": { + "version": "0.2.0", "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } + "license": "MIT" }, - "es-abstract": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz", - "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==", + "node_modules/es-abstract": { + "version": "1.23.3", "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.0", - "arraybuffer.prototype.slice": "^1.0.1", - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.2.1", - "get-symbol-description": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.5", - "is-array-buffer": "^3.0.2", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.3", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.0", - "safe-array-concat": "^1.0.0", - "safe-regex-test": "^1.0.0", - "string.prototype.trim": "^1.2.7", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-buffer": "^1.0.0", - "typed-array-byte-length": "^1.0.0", - "typed-array-byte-offset": "^1.0.0", - "typed-array-length": "^1.0.4", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.10" + "which-typed-array": "^1.1.15" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "node_modules/es-define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" } }, - "es-to-primitive": { + "node_modules/es-to-primitive": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true + "node_modules/escalade": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "escape-string-regexp": { + "node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=0.8.0" } }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "node_modules/esprima": { + "version": "4.0.1", "dev": true, - "requires": { - "locate-path": "^3.0.0" + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" } }, - "for-each": { + "node_modules/for-each": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-callable": "^1.1.3" } }, - "foreground-child": { - "version": "1.5.6", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", - "integrity": "sha512-3TOY+4TKV0Ml83PXJQY+JFQaHNV38lzQDIzzXYg1kWdBLenGgoZhAs0CKgzI31vi2pWEpQMq/Yi4bpKwCPkw7g==", - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fs.realpath": { + "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "node_modules/function.prototype.name": { + "version": "1.1.6", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "functions-have-names": { + "node_modules/functions-have-names": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "get-caller-file": { + "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } }, - "get-intrinsic": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", - "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==", + "node_modules/get-intrinsic": { + "version": "1.2.4", "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", "has-proto": "^1.0.1", - "has-symbols": "^1.0.3" + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/get-package-type": { + "version": "0.1.0", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "license": "MIT", + "engines": { + "node": ">=8.0.0" } }, - "glob": { + "node_modules/get-symbol-description": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "node_modules/globalthis": { + "version": "1.0.4", "dev": true, - "requires": { - "define-properties": "^1.1.3" + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "gopd": { + "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "has": { + "node_modules/has": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" } }, - "has-bigints": { + "node_modules/has-bigints": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, - "requires": { - "get-intrinsic": "^1.1.1" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true + "node_modules/has-dynamic-import": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true + "node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/has-property-descriptors": { + "version": "1.0.2", "dev": true, - "requires": { - "has-symbols": "^1.0.2" + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "node_modules/has-proto": { + "version": "1.0.3", "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "node_modules/has-symbols": { + "version": "1.0.3", "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "hasha": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", - "integrity": "sha512-w0Kz8lJFBoyaurBiNrIvxPqr/gJ6fOfSkpAPOepN3oECqGJag37xPbOv57izi/KP8auHgNYxn5fXtAb+1LsJ6w==", + "node_modules/has-tostringtag": { + "version": "1.0.2", "dev": true, - "requires": { - "is-stream": "^1.0.1" + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "node_modules/hasown": { + "version": "2.0.2", "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-escaper": { + "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true + "dev": true, + "license": "MIT" }, - "inflight": { + "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, - "inherits": { + "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "dev": true, + "license": "ISC" }, - "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "node_modules/internal-slot": { + "version": "1.0.7", "dev": true, - "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" } }, - "is-arguments": { + "node_modules/is-arguments": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-array-buffer": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", - "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "node_modules/is-array-buffer": { + "version": "3.0.4", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { + "node_modules/is-bigint": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-boolean-object": { + "node_modules/is-boolean-object": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-callable": { + "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-core-module": { + "node_modules/is-core-module": { "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-date-object": { + "node_modules/is-data-view": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true + "node_modules/is-map": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true + "node_modules/is-negative-zero": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-number-object": { + "node_modules/is-number-object": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-regex": { + "node_modules/is-regex": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "call-bind": "^1.0.2", "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "node_modules/is-set": { + "version": "2.0.3", "dev": true, - "requires": { - "call-bind": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "dev": true + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "is-string": { + "node_modules/is-string": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-symbol": { + "node_modules/is-symbol": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-typed-array": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", - "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "node_modules/is-typed-array": { + "version": "1.1.13", "dev": true, - "requires": { - "which-typed-array": "^1.1.11" + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/is-weakmap": { + "version": "2.0.2", "dev": true, - "requires": { - "call-bind": "^1.0.2" + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", - "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "node_modules/is-weakref": { + "version": "1.0.2", "dev": true, - "requires": { - "append-transform": "^1.0.0" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "node_modules/is-weakset": { + "version": "2.0.3", "dev": true, - "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "node_modules/isarray": { + "version": "2.0.5", "dev": true, - "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } + "license": "MIT" }, - "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "node_modules/isexe": { + "version": "2.0.0", "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", - "source-map": "^0.6.1" - } + "license": "ISC" }, - "istanbul-reports": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", - "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "node_modules/jackspeak": { + "version": "3.4.0", "dev": true, - "requires": { - "html-escaper": "^2.0.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" } }, - "js-tokens": { + "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, - "js-yaml": { + "node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "node_modules/minimist": { + "version": "1.2.8", "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "node_modules/minipass": { + "version": "7.1.2", "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "node_modules/mkdirp": { + "version": "0.5.6", "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" } }, - "merge-source-map": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", - "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "node_modules/mock-property": { + "version": "1.0.3", "dev": true, - "requires": { - "source-map": "^0.6.1" + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.1", + "functions-have-names": "^1.2.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "hasown": "^2.0.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "merkle-lib": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz", - "integrity": "sha512-XrNQvUbn1DL5hKNe46Ccs+Tu3/PYOlrcZILuGUhb95oKBPjc/nmIC8D462PQkipVDGKRvwhn+QFg2cCdIvmDJA==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/object-inspect": { + "version": "1.13.1", "dev": true, - "requires": { - "brace-expansion": "^1.1.7" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "node_modules/object-is": { + "version": "1.1.6", "dev": true, - "requires": { - "minimist": "^1.2.6" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "dev": true - }, - "nested-error-stacks": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz", - "integrity": "sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "nyc": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", - "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "caching-transform": "^3.0.2", - "convert-source-map": "^1.6.0", - "cp-file": "^6.2.0", - "find-cache-dir": "^2.1.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.5", - "istanbul-lib-hook": "^2.0.7", - "istanbul-lib-instrument": "^3.3.0", - "istanbul-lib-report": "^2.0.8", - "istanbul-lib-source-maps": "^3.0.6", - "istanbul-reports": "^2.2.4", - "js-yaml": "^3.13.1", - "make-dir": "^2.1.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.2.3", - "uuid": "^3.3.2", - "yargs": "^13.2.2", - "yargs-parser": "^13.0.0" - } - }, - "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true - }, - "object-is": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", - "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "node_modules/object-keys": { + "version": "1.1.1", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "node_modules/object.assign": { + "version": "4.1.5", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "once": { + "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "wrappy": "1" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==", - "dev": true - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", - "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "path-is-absolute": { + "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", - "dev": true - }, - "pushdata-bitcoin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz", - "integrity": "sha512-hw7rcYTJRAl4olM8Owe8x0fBuJJ+WGbMhQuLWOXEMN3PxPCKQHRkhfL+XG0+iXUmSHjkMmb3Ba55Mt21cZc9kQ==", + "node_modules/path-key": { + "version": "3.1.1", "dev": true, - "requires": { - "bitcoin-ops": "^1.3.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "node_modules/path-parse": { + "version": "1.0.7", "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } + "license": "MIT" }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "node_modules/path-scurry": { + "version": "1.11.1", "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.2", "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + "license": "ISC", + "engines": { + "node": "14 || >=16.14" } }, - "readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/possible-typed-array-names": { + "version": "1.0.0", "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "regexp.prototype.flags": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz", - "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==", + "node_modules/prettier": { + "version": "1.19.1", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "functions-have-names": "^1.2.3" + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" } }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", "dev": true, - "requires": { - "es6-error": "^4.0.1" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "require-directory": { + "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } }, - "resolve": { + "node_modules/resolve": { "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha512-Fn9X8rX8yYF4m81rZCK/5VmrmsSbqS/i3rDLl6ZZHAXgC2nTAx3dhwG8q8odP/RmdLa2YrybDJaAMg+X1ajY3w==", - "dev": true, - "requires": { - "through": "~2.3.4" - } - }, - "rimraf": { + "node_modules/rimraf": { "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "safe-array-concat": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz", - "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==", + "node_modules/safe-array-concat": { + "version": "1.1.2", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.0", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", "has-symbols": "^1.0.3", "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "safe-buffer": { + "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "node_modules/safe-regex-test": { + "version": "1.0.3", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "semver": { + "node_modules/semver": { "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "license": "ISC", + "bin": { + "semver": "bin/semver" } }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/set-function-length": { + "version": "1.2.2", "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" } }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "node_modules/set-function-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } }, - "spawn-wrap": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", - "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "node_modules/shebang-regex": { + "version": "3.0.0", "dev": true, - "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "node_modules/side-channel": { + "version": "1.0.6", "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true + "node_modules/sprintf-js": { + "version": "1.0.3", + "dev": true, + "license": "BSD-3-Clause" }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/stop-iteration-iterator": { + "version": "1.0.0", "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "license": "MIT", + "dependencies": { + "internal-slot": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" } }, - "spdx-license-ids": { - "version": "3.0.13", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz", - "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==", - "dev": true + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "string.prototype.trim": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz", - "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==", + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "node_modules/string.prototype.trim": { + "version": "1.2.9", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "node_modules/string.prototype.trimend": { + "version": "1.0.8", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", "dev": true, - "requires": { - "safe-buffer": "~5.2.0" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", "dev": true, - "requires": { - "ansi-regex": "^4.1.0" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "supports-color": { + "node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "supports-preserve-symlinks-flag": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "tape": { - "version": "4.15.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.15.0.tgz", - "integrity": "sha512-SfRmG2I8QGGgJE/MCiLH8c11L5XxyUXxwK9xLRD0uiK5fehRkkSZGmR6Y1pxOt8vJ19m3sY+POTQpiaVv45/LQ==", - "dev": true, - "requires": { - "call-bind": "~1.0.2", - "deep-equal": "~1.1.1", - "defined": "~1.0.0", - "dotignore": "~0.1.2", - "for-each": "~0.3.3", - "glob": "~7.2.0", - "has": "~1.0.3", - "inherits": "~2.0.4", - "is-regex": "~1.1.4", - "minimist": "~1.2.5", - "object-inspect": "~1.12.0", - "resolve": "~1.22.0", - "resumer": "~0.0.0", - "string.prototype.trim": "~1.2.5", - "through": "~2.3.8" - } - }, - "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", - "dev": true, - "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, - "tiny-secp256k1": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz", - "integrity": "sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA==", + "node_modules/tape": { + "version": "5.7.5", "dev": true, - "requires": { - "bindings": "^1.3.0", - "bn.js": "^4.11.8", - "create-hmac": "^1.1.7", - "elliptic": "^6.4.0", - "nan": "^2.13.2" + "license": "MIT", + "dependencies": { + "@ljharb/resumer": "^0.1.2", + "@ljharb/through": "^2.3.12", + "array.prototype.every": "^1.1.5", + "call-bind": "^1.0.7", + "deep-equal": "^2.2.3", + "defined": "^1.0.1", + "dotignore": "^0.1.2", + "for-each": "^0.3.3", + "get-package-type": "^0.1.0", + "glob": "^7.2.3", + "has-dynamic-import": "^2.1.0", + "hasown": "^2.0.1", + "inherits": "^2.0.4", + "is-regex": "^1.1.4", + "minimist": "^1.2.8", + "mock-property": "^1.0.3", + "object-inspect": "^1.13.1", + "object-is": "^1.1.5", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "resolve": "^2.0.0-next.5", + "string.prototype.trim": "^1.2.8" + }, + "bin": { + "tape": "bin/tape" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true + "node_modules/tape/node_modules/resolve": { + "version": "2.0.0-next.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "tslib": { + "node_modules/tslib": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true + "dev": true, + "license": "0BSD" }, - "tslint": { + "node_modules/tslint": { "version": "5.17.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz", - "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", @@ -2118,235 +2360,327 @@ "semver": "^5.3.0", "tslib": "^1.8.0", "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" } }, - "tsutils": { + "node_modules/tsutils": { "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, - "typed-array-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", - "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "node_modules/typed-array-buffer": { + "version": "1.0.2", "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1", - "is-typed-array": "^1.1.10" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" } }, - "typed-array-byte-length": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", - "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "node_modules/typed-array-byte-length": { + "version": "1.0.1", "dev": true, - "requires": { - "call-bind": "^1.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typed-array-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", - "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "has-proto": "^1.0.1", - "is-typed-array": "^1.1.10" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "node_modules/typed-array-length": { + "version": "1.0.6", "dev": true, - "requires": { - "call-bind": "^1.0.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "typeforce": { + "node_modules/typeforce": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", "integrity": "sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==", "dev": true }, - "typescript": { + "node_modules/typescript": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", - "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==", - "dev": true + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uint8array-tools": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.9.tgz", + "integrity": "sha512-9vqDWmoSXOoi+K14zNaf6LBV51Q8MayF0/IiQs3GlygIKUYtog603e6virExkjjFosfJUBI4LhbQK1iq8IG11A==", + "engines": { + "node": ">=14.0.0" + } }, - "unbox-primitive": { + "node_modules/unbox-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "call-bind": "^1.0.2", "has-bigints": "^1.0.2", "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "node_modules/v8-to-istanbul": { + "version": "9.2.0", "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "varuint-bitcoin": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.2.tgz", - "integrity": "sha512-4EVb+w4rx+YfVM32HQX42AbbT7/1f5zwAYhIujKXKk8NQK+JfRVl3pqT3hjNn/L+RstigmGGKVwHA/P0wgITZw==", + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", "dev": true, - "requires": { - "safe-buffer": "^5.1.1" + "license": "MIT" + }, + "node_modules/varuint-bitcoin": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-2.0.0.tgz", + "integrity": "sha512-6QZbU/rHO2ZQYpWFDALCDSRsXbAs1VOEmXAxtbtjLtKuMJ/FQ8YbhfxlaiKv5nklci0M6lZtlZyxo9Q+qNnyog==", + "dependencies": { + "uint8array-tools": "^0.0.8" } }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" + "node_modules/varuint-bitcoin/node_modules/uint8array-tools": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/uint8array-tools/-/uint8array-tools-0.0.8.tgz", + "integrity": "sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==", + "engines": { + "node": ">=14.0.0" } }, - "which-boxed-primitive": { + "node_modules/which-boxed-primitive": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "is-bigint": "^1.0.1", "is-boolean-object": "^1.1.0", "is-number-object": "^1.0.4", "is-string": "^1.0.5", "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "which-module": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", - "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", - "dev": true + "node_modules/which-collection": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "which-typed-array": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz", - "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==", + "node_modules/which-typed-array": { + "version": "1.1.15", "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "wif": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", - "integrity": "sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==", + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", "dev": true, - "requires": { - "bs58check": "<3.0.0" + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", - "dev": true + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" }, - "yargs": { - "version": "13.3.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", - "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.2" - } - }, - "yargs-parser": { - "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } } } diff --git a/package.json b/package.json index 31682f9..fa7f846 100644 --- a/package.json +++ b/package.json @@ -2,18 +2,28 @@ "name": "bip174", "version": "2.1.1", "description": "", - "main": "src/lib/psbt.js", - "types": "src/lib/psbt.d.ts", + "main": "src/cjs/lib/psbt.js", + "module": "src/esm/lib/psbt.js", + "types": "src/cjs/lib/psbt.d.ts", + "exports": { + ".": { + "types": "./src/cjs/lib/psbt.d.ts", + "import": "./src/esm/lib/psbt.js", + "require": "./src/cjs/lib/psbt.js" + } + }, + "type": "module", "files": [ - "src/lib" + "src/cjs/lib", + "src/esm/lib" ], "engines": { - "node": ">=8.0.0" + "node": ">=18.0.0" }, "scripts": { - "build": "npm run clean && tsc -p ./tsconfig.json && rimraf 'src/tests/**/*.d.ts' && npm run formatjs", + "build": "npm run clean && tsc -p ./tsconfig.json && tsc -p ./tsconfig.cjs.json && npm run formatjs", "clean": "rimraf src types", - "coverage": "nyc --check-coverage --exclude='src/tests/**/*.js' --reporter=lcov --reporter=text --branches 90 --functions 90 --lines 90 npm run unit", + "coverage": "c8 --check-coverage --include='src/esm/lib/**/*.js' --reporter=lcov --reporter=text --branches 90 --functions 90 --lines 90 npm run unit", "flb": "npm run format && npm run lint && npm run build", "format": "npm run prettier -- --write", "formatjs": "npm run prettierjs -- --write > /dev/null 2>&1", @@ -23,20 +33,24 @@ "prettier": "prettier 'ts_src/**/*.ts' --ignore-path ./.prettierignore", "prettierjs": "prettier 'src/**/*.js' --ignore-path ./.prettierignore", "test": "npm run format:ci && npm run lint && npm run build && npm run coverage", - "unit": "tape src/tests/*.js src/tests/fromBIP/*.js" + "unit": "tape src/esm/tests/*.js src/esm/tests/fromBIP/*.js" }, "repository": { "type": "git", "url": "git+https://github.com/bitcoinjs/bip174.git" }, + "dependencies": { + "uint8array-tools": "^0.0.9", + "varuint-bitcoin": "^2.0.0" + }, "devDependencies": { "@types/node": "12.0.8", "@types/tape": "4.2.33", - "bitcoinjs-lib": "^5.0.5", - "nyc": "^14.1.1", + "bitcoinjs-lib": "^6.1.6", + "c8": "^10.1.2", "prettier": "^1.18.2", "rimraf": "^2.6.3", - "tape": "^4.10.2", + "tape": "^5.3.0", "tslint": "5.17.0", "typescript": "3.5.2" }, diff --git a/src/lib/combiner/index.d.ts b/src/cjs/lib/combiner/index.d.ts similarity index 58% rename from src/lib/combiner/index.d.ts rename to src/cjs/lib/combiner/index.d.ts index 386685a..f4ebd8c 100644 --- a/src/lib/combiner/index.d.ts +++ b/src/cjs/lib/combiner/index.d.ts @@ -1,2 +1,2 @@ -import { PsbtAttributes } from '../parser'; +import { PsbtAttributes } from '../parser/index.js'; export declare function combine(psbts: PsbtAttributes[]): PsbtAttributes; diff --git a/src/cjs/lib/combiner/index.js b/src/cjs/lib/combiner/index.js new file mode 100644 index 0000000..29e44a6 --- /dev/null +++ b/src/cjs/lib/combiner/index.js @@ -0,0 +1,95 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const index_js_1 = require('../parser/index.js'); +const tools = __importStar(require('uint8array-tools')); +function combine(psbts) { + const self = psbts[0]; + const selfKeyVals = index_js_1.psbtToKeyVals(self); + const others = psbts.slice(1); + if (others.length === 0) throw new Error('Combine: Nothing to combine'); + const selfTx = getTx(self); + if (selfTx === undefined) { + throw new Error('Combine: Self missing transaction'); + } + const selfGlobalSet = getKeySet(selfKeyVals.globalKeyVals); + const selfInputSets = selfKeyVals.inputKeyVals.map(getKeySet); + const selfOutputSets = selfKeyVals.outputKeyVals.map(getKeySet); + for (const other of others) { + const otherTx = getTx(other); + if ( + otherTx === undefined || + tools.compare(otherTx.toBuffer(), selfTx.toBuffer()) !== 0 + ) { + throw new Error( + 'Combine: One of the Psbts does not have the same transaction.', + ); + } + const otherKeyVals = index_js_1.psbtToKeyVals(other); + const otherGlobalSet = getKeySet(otherKeyVals.globalKeyVals); + otherGlobalSet.forEach( + keyPusher( + selfGlobalSet, + selfKeyVals.globalKeyVals, + otherKeyVals.globalKeyVals, + ), + ); + const otherInputSets = otherKeyVals.inputKeyVals.map(getKeySet); + otherInputSets.forEach((inputSet, idx) => + inputSet.forEach( + keyPusher( + selfInputSets[idx], + selfKeyVals.inputKeyVals[idx], + otherKeyVals.inputKeyVals[idx], + ), + ), + ); + const otherOutputSets = otherKeyVals.outputKeyVals.map(getKeySet); + otherOutputSets.forEach((outputSet, idx) => + outputSet.forEach( + keyPusher( + selfOutputSets[idx], + selfKeyVals.outputKeyVals[idx], + otherKeyVals.outputKeyVals[idx], + ), + ), + ); + } + return index_js_1.psbtFromKeyVals(selfTx, { + globalMapKeyVals: selfKeyVals.globalKeyVals, + inputKeyVals: selfKeyVals.inputKeyVals, + outputKeyVals: selfKeyVals.outputKeyVals, + }); +} +exports.combine = combine; +function keyPusher(selfSet, selfKeyVals, otherKeyVals) { + return key => { + if (selfSet.has(key)) return; + const newKv = otherKeyVals.filter(kv => tools.toHex(kv.key) === key)[0]; + selfKeyVals.push(newKv); + selfSet.add(key); + }; +} +function getTx(psbt) { + return psbt.globalMap.unsignedTx; +} +function getKeySet(keyVals) { + const set = new Set(); + keyVals.forEach(keyVal => { + const hex = tools.toHex(keyVal.key); + if (set.has(hex)) + throw new Error('Combine: KeyValue Map keys should be unique'); + set.add(hex); + }); + return set; +} diff --git a/src/lib/converter/global/globalXpub.d.ts b/src/cjs/lib/converter/global/globalXpub.d.ts similarity index 75% rename from src/lib/converter/global/globalXpub.d.ts rename to src/cjs/lib/converter/global/globalXpub.d.ts index 5b96567..a3b0d11 100644 --- a/src/lib/converter/global/globalXpub.d.ts +++ b/src/cjs/lib/converter/global/globalXpub.d.ts @@ -1,6 +1,6 @@ import { GlobalXpub, KeyValue } from '../../interfaces'; export declare function decode(keyVal: KeyValue): GlobalXpub; export declare function encode(data: GlobalXpub): KeyValue; -export declare const expected = "{ masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; }"; +export declare const expected = "{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }"; export declare function check(data: any): data is GlobalXpub; export declare function canAddToArray(array: GlobalXpub[], item: GlobalXpub, dupeSet: Set): boolean; diff --git a/src/lib/converter/global/globalXpub.js b/src/cjs/lib/converter/global/globalXpub.js similarity index 60% rename from src/lib/converter/global/globalXpub.js rename to src/cjs/lib/converter/global/globalXpub.js index 1d4b9c8..198e604 100644 --- a/src/lib/converter/global/globalXpub.js +++ b/src/cjs/lib/converter/global/globalXpub.js @@ -1,18 +1,30 @@ 'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); const range = n => [...Array(n).keys()]; function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.GlobalTypes.GLOBAL_XPUB) { + if (keyVal.key[0] !== typeFields_js_1.GlobalTypes.GLOBAL_XPUB) { throw new Error( 'Decode Error: could not decode globalXpub with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (keyVal.key.length !== 79 || ![2, 3].includes(keyVal.key[46])) { throw new Error( 'Decode Error: globalXpub has invalid extended pubkey in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ((keyVal.value.length / 4) % 1 !== 0) { @@ -27,7 +39,7 @@ function decode(keyVal) { path: 'm', }; for (const i of range(keyVal.value.length / 4 - 1)) { - const val = keyVal.value.readUInt32LE(i * 4 + 4); + const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE'); const isHard = !!(val & 0x80000000); const idx = val & 0x7fffffff; data.path += '/' + idx.toString(10) + (isHard ? "'" : ''); @@ -36,17 +48,17 @@ function decode(keyVal) { } exports.decode = decode; function encode(data) { - const head = Buffer.from([typeFields_1.GlobalTypes.GLOBAL_XPUB]); - const key = Buffer.concat([head, data.extendedPubkey]); + const head = new Uint8Array([typeFields_js_1.GlobalTypes.GLOBAL_XPUB]); + const key = tools.concat([head, data.extendedPubkey]); const splitPath = data.path.split('/'); - const value = Buffer.allocUnsafe(splitPath.length * 4); - data.masterFingerprint.copy(value, 0); + const value = new Uint8Array(splitPath.length * 4); + value.set(data.masterFingerprint, 0); let offset = 4; splitPath.slice(1).forEach(level => { const isHard = level.slice(-1) === "'"; let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10); if (isHard) num += 0x80000000; - value.writeUInt32LE(num, offset); + tools.writeUInt32(value, offset, num, 'LE'); offset += 4; }); return { @@ -56,16 +68,16 @@ function encode(data) { } exports.encode = encode; exports.expected = - '{ masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; }'; + '{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }'; function check(data) { const epk = data.extendedPubkey; const mfp = data.masterFingerprint; const p = data.path; return ( - Buffer.isBuffer(epk) && + epk instanceof Uint8Array && epk.length === 78 && [2, 3].indexOf(epk[45]) > -1 && - Buffer.isBuffer(mfp) && + mfp instanceof Uint8Array && mfp.length === 4 && typeof p === 'string' && !!p.match(/^m(\/\d+'?)*$/) @@ -73,11 +85,12 @@ function check(data) { } exports.check = check; function canAddToArray(array, item, dupeSet) { - const dupeString = item.extendedPubkey.toString('hex'); + const dupeString = tools.toHex(item.extendedPubkey); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); return ( - array.filter(v => v.extendedPubkey.equals(item.extendedPubkey)).length === 0 + array.filter(v => tools.compare(v.extendedPubkey, item.extendedPubkey)) + .length === 0 ); } exports.canAddToArray = canAddToArray; diff --git a/src/lib/converter/global/unsignedTx.d.ts b/src/cjs/lib/converter/global/unsignedTx.d.ts similarity index 100% rename from src/lib/converter/global/unsignedTx.d.ts rename to src/cjs/lib/converter/global/unsignedTx.d.ts diff --git a/src/lib/converter/global/unsignedTx.js b/src/cjs/lib/converter/global/unsignedTx.js similarity index 58% rename from src/lib/converter/global/unsignedTx.js rename to src/cjs/lib/converter/global/unsignedTx.js index cf273c4..bc402e0 100644 --- a/src/lib/converter/global/unsignedTx.js +++ b/src/cjs/lib/converter/global/unsignedTx.js @@ -1,9 +1,9 @@ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); +const typeFields_js_1 = require('../../typeFields.js'); function encode(data) { return { - key: Buffer.from([typeFields_1.GlobalTypes.UNSIGNED_TX]), + key: new Uint8Array([typeFields_js_1.GlobalTypes.UNSIGNED_TX]), value: data.toBuffer(), }; } diff --git a/src/cjs/lib/converter/index.d.ts b/src/cjs/lib/converter/index.d.ts new file mode 100644 index 0000000..f152688 --- /dev/null +++ b/src/cjs/lib/converter/index.d.ts @@ -0,0 +1,108 @@ +import * as globalXpub from './global/globalXpub.js'; +import * as unsignedTx from './global/unsignedTx.js'; +import * as finalScriptSig from './input/finalScriptSig.js'; +import * as finalScriptWitness from './input/finalScriptWitness.js'; +import * as nonWitnessUtxo from './input/nonWitnessUtxo.js'; +import * as partialSig from './input/partialSig.js'; +import * as porCommitment from './input/porCommitment.js'; +import * as sighashType from './input/sighashType.js'; +import * as tapKeySig from './input/tapKeySig.js'; +import * as tapLeafScript from './input/tapLeafScript.js'; +import * as tapMerkleRoot from './input/tapMerkleRoot.js'; +import * as tapScriptSig from './input/tapScriptSig.js'; +import * as witnessUtxo from './input/witnessUtxo.js'; +import * as tapTree from './output/tapTree.js'; +declare const globals: { + unsignedTx: typeof unsignedTx; + globalXpub: typeof globalXpub; + checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined; +}; +declare const inputs: { + nonWitnessUtxo: typeof nonWitnessUtxo; + partialSig: typeof partialSig; + sighashType: typeof sighashType; + finalScriptSig: typeof finalScriptSig; + finalScriptWitness: typeof finalScriptWitness; + porCommitment: typeof porCommitment; + witnessUtxo: typeof witnessUtxo; + bip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").Bip32Derivation; + encode: (data: import("../interfaces.js").Bip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").Bip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").Bip32Derivation[], item: import("../interfaces.js").Bip32Derivation, dupeSet: Set) => boolean; + }; + redeemScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + witnessScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined; + tapKeySig: typeof tapKeySig; + tapScriptSig: typeof tapScriptSig; + tapLeafScript: typeof tapLeafScript; + tapBip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").TapBip32Derivation; + encode: (data: import("../interfaces.js").TapBip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").TapBip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").TapBip32Derivation[], item: import("../interfaces.js").TapBip32Derivation, dupeSet: Set) => boolean; + }; + tapInternalKey: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + tapMerkleRoot: typeof tapMerkleRoot; +}; +declare const outputs: { + bip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").Bip32Derivation; + encode: (data: import("../interfaces.js").Bip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").Bip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").Bip32Derivation[], item: import("../interfaces.js").Bip32Derivation, dupeSet: Set) => boolean; + }; + redeemScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + witnessScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined; + tapBip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").TapBip32Derivation; + encode: (data: import("../interfaces.js").TapBip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").TapBip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").TapBip32Derivation[], item: import("../interfaces.js").TapBip32Derivation, dupeSet: Set) => boolean; + }; + tapTree: typeof tapTree; + tapInternalKey: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; +}; +export { globals, inputs, outputs }; diff --git a/src/cjs/lib/converter/index.js b/src/cjs/lib/converter/index.js new file mode 100644 index 0000000..16c908e --- /dev/null +++ b/src/cjs/lib/converter/index.js @@ -0,0 +1,100 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../typeFields.js'); +const globalXpub = __importStar(require('./global/globalXpub.js')); +const unsignedTx = __importStar(require('./global/unsignedTx.js')); +const finalScriptSig = __importStar(require('./input/finalScriptSig.js')); +const finalScriptWitness = __importStar( + require('./input/finalScriptWitness.js'), +); +const nonWitnessUtxo = __importStar(require('./input/nonWitnessUtxo.js')); +const partialSig = __importStar(require('./input/partialSig.js')); +const porCommitment = __importStar(require('./input/porCommitment.js')); +const sighashType = __importStar(require('./input/sighashType.js')); +const tapKeySig = __importStar(require('./input/tapKeySig.js')); +const tapLeafScript = __importStar(require('./input/tapLeafScript.js')); +const tapMerkleRoot = __importStar(require('./input/tapMerkleRoot.js')); +const tapScriptSig = __importStar(require('./input/tapScriptSig.js')); +const witnessUtxo = __importStar(require('./input/witnessUtxo.js')); +const tapTree = __importStar(require('./output/tapTree.js')); +const bip32Derivation = __importStar(require('./shared/bip32Derivation.js')); +const checkPubkey = __importStar(require('./shared/checkPubkey.js')); +const redeemScript = __importStar(require('./shared/redeemScript.js')); +const tapBip32Derivation = __importStar( + require('./shared/tapBip32Derivation.js'), +); +const tapInternalKey = __importStar(require('./shared/tapInternalKey.js')); +const witnessScript = __importStar(require('./shared/witnessScript.js')); +const globals = { + unsignedTx, + globalXpub, + // pass an Array of key bytes that require pubkey beside the key + checkPubkey: checkPubkey.makeChecker([]), +}; +exports.globals = globals; +const inputs = { + nonWitnessUtxo, + partialSig, + sighashType, + finalScriptSig, + finalScriptWitness, + porCommitment, + witnessUtxo, + bip32Derivation: bip32Derivation.makeConverter( + typeFields_js_1.InputTypes.BIP32_DERIVATION, + ), + redeemScript: redeemScript.makeConverter( + typeFields_js_1.InputTypes.REDEEM_SCRIPT, + ), + witnessScript: witnessScript.makeConverter( + typeFields_js_1.InputTypes.WITNESS_SCRIPT, + ), + checkPubkey: checkPubkey.makeChecker([ + typeFields_js_1.InputTypes.PARTIAL_SIG, + typeFields_js_1.InputTypes.BIP32_DERIVATION, + ]), + tapKeySig, + tapScriptSig, + tapLeafScript, + tapBip32Derivation: tapBip32Derivation.makeConverter( + typeFields_js_1.InputTypes.TAP_BIP32_DERIVATION, + ), + tapInternalKey: tapInternalKey.makeConverter( + typeFields_js_1.InputTypes.TAP_INTERNAL_KEY, + ), + tapMerkleRoot, +}; +exports.inputs = inputs; +const outputs = { + bip32Derivation: bip32Derivation.makeConverter( + typeFields_js_1.OutputTypes.BIP32_DERIVATION, + ), + redeemScript: redeemScript.makeConverter( + typeFields_js_1.OutputTypes.REDEEM_SCRIPT, + ), + witnessScript: witnessScript.makeConverter( + typeFields_js_1.OutputTypes.WITNESS_SCRIPT, + ), + checkPubkey: checkPubkey.makeChecker([ + typeFields_js_1.OutputTypes.BIP32_DERIVATION, + ]), + tapBip32Derivation: tapBip32Derivation.makeConverter( + typeFields_js_1.OutputTypes.TAP_BIP32_DERIVATION, + ), + tapTree, + tapInternalKey: tapInternalKey.makeConverter( + typeFields_js_1.OutputTypes.TAP_INTERNAL_KEY, + ), +}; +exports.outputs = outputs; diff --git a/src/lib/converter/input/finalScriptSig.d.ts b/src/cjs/lib/converter/input/finalScriptSig.d.ts similarity index 87% rename from src/lib/converter/input/finalScriptSig.d.ts rename to src/cjs/lib/converter/input/finalScriptSig.d.ts index 1d82b86..f08bc72 100644 --- a/src/lib/converter/input/finalScriptSig.d.ts +++ b/src/cjs/lib/converter/input/finalScriptSig.d.ts @@ -1,6 +1,6 @@ import { FinalScriptSig, KeyValue } from '../../interfaces'; export declare function decode(keyVal: KeyValue): FinalScriptSig; export declare function encode(data: FinalScriptSig): KeyValue; -export declare const expected = "Buffer"; +export declare const expected = "Uint8Array"; export declare function check(data: any): data is FinalScriptSig; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/cjs/lib/converter/input/finalScriptSig.js b/src/cjs/lib/converter/input/finalScriptSig.js new file mode 100644 index 0000000..239598f --- /dev/null +++ b/src/cjs/lib/converter/input/finalScriptSig.js @@ -0,0 +1,42 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.FINAL_SCRIPTSIG) { + throw new Error( + 'Decode Error: could not decode finalScriptSig with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; +} +exports.decode = decode; +function encode(data) { + const key = new Uint8Array([typeFields_js_1.InputTypes.FINAL_SCRIPTSIG]); + return { + key, + value: data, + }; +} +exports.encode = encode; +exports.expected = 'Uint8Array'; +function check(data) { + return data instanceof Uint8Array; +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.finalScriptSig === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/finalScriptWitness.d.ts b/src/cjs/lib/converter/input/finalScriptWitness.d.ts similarity index 88% rename from src/lib/converter/input/finalScriptWitness.d.ts rename to src/cjs/lib/converter/input/finalScriptWitness.d.ts index d640ab6..aa64099 100644 --- a/src/lib/converter/input/finalScriptWitness.d.ts +++ b/src/cjs/lib/converter/input/finalScriptWitness.d.ts @@ -1,6 +1,6 @@ import { FinalScriptWitness, KeyValue } from '../../interfaces'; export declare function decode(keyVal: KeyValue): FinalScriptWitness; export declare function encode(data: FinalScriptWitness): KeyValue; -export declare const expected = "Buffer"; +export declare const expected = "Uint8Array"; export declare function check(data: any): data is FinalScriptWitness; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/cjs/lib/converter/input/finalScriptWitness.js b/src/cjs/lib/converter/input/finalScriptWitness.js new file mode 100644 index 0000000..9c1f91a --- /dev/null +++ b/src/cjs/lib/converter/input/finalScriptWitness.js @@ -0,0 +1,44 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.FINAL_SCRIPTWITNESS) { + throw new Error( + 'Decode Error: could not decode finalScriptWitness with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; +} +exports.decode = decode; +function encode(data) { + const key = new Uint8Array([typeFields_js_1.InputTypes.FINAL_SCRIPTWITNESS]); + return { + key, + value: data, + }; +} +exports.encode = encode; +exports.expected = 'Uint8Array'; +function check(data) { + return data instanceof Uint8Array; +} +exports.check = check; +function canAdd(currentData, newData) { + return ( + !!currentData && !!newData && currentData.finalScriptWitness === undefined + ); +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/nonWitnessUtxo.d.ts b/src/cjs/lib/converter/input/nonWitnessUtxo.d.ts similarity index 87% rename from src/lib/converter/input/nonWitnessUtxo.d.ts rename to src/cjs/lib/converter/input/nonWitnessUtxo.d.ts index 0e30673..498a9ba 100644 --- a/src/lib/converter/input/nonWitnessUtxo.d.ts +++ b/src/cjs/lib/converter/input/nonWitnessUtxo.d.ts @@ -1,6 +1,6 @@ import { KeyValue, NonWitnessUtxo } from '../../interfaces'; export declare function decode(keyVal: KeyValue): NonWitnessUtxo; export declare function encode(data: NonWitnessUtxo): KeyValue; -export declare const expected = "Buffer"; +export declare const expected = "Uint8Array"; export declare function check(data: any): data is NonWitnessUtxo; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/cjs/lib/converter/input/nonWitnessUtxo.js b/src/cjs/lib/converter/input/nonWitnessUtxo.js new file mode 100644 index 0000000..5d7847a --- /dev/null +++ b/src/cjs/lib/converter/input/nonWitnessUtxo.js @@ -0,0 +1,41 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.NON_WITNESS_UTXO) { + throw new Error( + 'Decode Error: could not decode nonWitnessUtxo with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; +} +exports.decode = decode; +function encode(data) { + return { + key: new Uint8Array([typeFields_js_1.InputTypes.NON_WITNESS_UTXO]), + value: data, + }; +} +exports.encode = encode; +exports.expected = 'Uint8Array'; +function check(data) { + return data instanceof Uint8Array; +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.nonWitnessUtxo === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/partialSig.d.ts b/src/cjs/lib/converter/input/partialSig.d.ts similarity index 81% rename from src/lib/converter/input/partialSig.d.ts rename to src/cjs/lib/converter/input/partialSig.d.ts index e60f6a9..b7fd8c5 100644 --- a/src/lib/converter/input/partialSig.d.ts +++ b/src/cjs/lib/converter/input/partialSig.d.ts @@ -1,6 +1,6 @@ import { KeyValue, PartialSig } from '../../interfaces'; export declare function decode(keyVal: KeyValue): PartialSig; export declare function encode(pSig: PartialSig): KeyValue; -export declare const expected = "{ pubkey: Buffer; signature: Buffer; }"; +export declare const expected = "{ pubkey: Uint8Array; signature: Uint8Array; }"; export declare function check(data: any): data is PartialSig; export declare function canAddToArray(array: PartialSig[], item: PartialSig, dupeSet: Set): boolean; diff --git a/src/lib/converter/input/partialSig.js b/src/cjs/lib/converter/input/partialSig.js similarity index 57% rename from src/lib/converter/input/partialSig.js rename to src/cjs/lib/converter/input/partialSig.js index 50a1090..a790584 100644 --- a/src/lib/converter/input/partialSig.js +++ b/src/cjs/lib/converter/input/partialSig.js @@ -1,11 +1,23 @@ 'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.PARTIAL_SIG) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.PARTIAL_SIG) { throw new Error( 'Decode Error: could not decode partialSig with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ( @@ -14,7 +26,7 @@ function decode(keyVal) { ) { throw new Error( 'Decode Error: partialSig has invalid pubkey in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const pubkey = keyVal.key.slice(1); @@ -25,18 +37,18 @@ function decode(keyVal) { } exports.decode = decode; function encode(pSig) { - const head = Buffer.from([typeFields_1.InputTypes.PARTIAL_SIG]); + const head = new Uint8Array([typeFields_js_1.InputTypes.PARTIAL_SIG]); return { - key: Buffer.concat([head, pSig.pubkey]), + key: tools.concat([head, pSig.pubkey]), value: pSig.signature, }; } exports.encode = encode; -exports.expected = '{ pubkey: Buffer; signature: Buffer; }'; +exports.expected = '{ pubkey: Uint8Array; signature: Uint8Array; }'; function check(data) { return ( - Buffer.isBuffer(data.pubkey) && - Buffer.isBuffer(data.signature) && + data.pubkey instanceof Uint8Array && + data.signature instanceof Uint8Array && [33, 65].includes(data.pubkey.length) && [2, 3, 4].includes(data.pubkey[0]) && isDerSigWithSighash(data.signature) @@ -44,7 +56,7 @@ function check(data) { } exports.check = check; function isDerSigWithSighash(buf) { - if (!Buffer.isBuffer(buf) || buf.length < 9) return false; + if (!(buf instanceof Uint8Array) || buf.length < 9) return false; if (buf[0] !== 0x30) return false; if (buf.length !== buf[1] + 3) return false; if (buf[2] !== 0x02) return false; @@ -57,9 +69,11 @@ function isDerSigWithSighash(buf) { return true; } function canAddToArray(array, item, dupeSet) { - const dupeString = item.pubkey.toString('hex'); + const dupeString = tools.toHex(item.pubkey); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); - return array.filter(v => v.pubkey.equals(item.pubkey)).length === 0; + return ( + array.filter(v => tools.compare(v.pubkey, item.pubkey) === 0).length === 0 + ); } exports.canAddToArray = canAddToArray; diff --git a/src/lib/converter/input/porCommitment.d.ts b/src/cjs/lib/converter/input/porCommitment.d.ts similarity index 100% rename from src/lib/converter/input/porCommitment.d.ts rename to src/cjs/lib/converter/input/porCommitment.d.ts diff --git a/src/cjs/lib/converter/input/porCommitment.js b/src/cjs/lib/converter/input/porCommitment.js new file mode 100644 index 0000000..30cd582 --- /dev/null +++ b/src/cjs/lib/converter/input/porCommitment.js @@ -0,0 +1,42 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.POR_COMMITMENT) { + throw new Error( + 'Decode Error: could not decode porCommitment with key 0x' + + tools.toHex(keyVal.key), + ); + } + return tools.toUtf8(keyVal.value); +} +exports.decode = decode; +function encode(data) { + const key = new Uint8Array([typeFields_js_1.InputTypes.POR_COMMITMENT]); + return { + key, + value: tools.fromUtf8(data), + }; +} +exports.encode = encode; +exports.expected = 'string'; +function check(data) { + return typeof data === 'string'; +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.porCommitment === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/sighashType.d.ts b/src/cjs/lib/converter/input/sighashType.d.ts similarity index 100% rename from src/lib/converter/input/sighashType.d.ts rename to src/cjs/lib/converter/input/sighashType.d.ts diff --git a/src/cjs/lib/converter/input/sighashType.js b/src/cjs/lib/converter/input/sighashType.js new file mode 100644 index 0000000..623f100 --- /dev/null +++ b/src/cjs/lib/converter/input/sighashType.js @@ -0,0 +1,44 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.SIGHASH_TYPE) { + throw new Error( + 'Decode Error: could not decode sighashType with key 0x' + + tools.toHex(keyVal.key), + ); + } + return Number(tools.readUInt32(keyVal.value, 0, 'LE')); +} +exports.decode = decode; +function encode(data) { + const key = Uint8Array.from([typeFields_js_1.InputTypes.SIGHASH_TYPE]); + const value = new Uint8Array(4); + tools.writeUInt32(value, 0, data, 'LE'); + return { + key, + value, + }; +} +exports.encode = encode; +exports.expected = 'number'; +function check(data) { + return typeof data === 'number'; +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.sighashType === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/tapKeySig.d.ts b/src/cjs/lib/converter/input/tapKeySig.d.ts similarity index 87% rename from src/lib/converter/input/tapKeySig.d.ts rename to src/cjs/lib/converter/input/tapKeySig.d.ts index 6c3a46b..07b357b 100644 --- a/src/lib/converter/input/tapKeySig.d.ts +++ b/src/cjs/lib/converter/input/tapKeySig.d.ts @@ -1,6 +1,6 @@ import { KeyValue, TapKeySig } from '../../interfaces'; export declare function decode(keyVal: KeyValue): TapKeySig; export declare function encode(value: TapKeySig): KeyValue; -export declare const expected = "Buffer"; +export declare const expected = "Uint8Array"; export declare function check(data: any): data is TapKeySig; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/cjs/lib/converter/input/tapKeySig.js b/src/cjs/lib/converter/input/tapKeySig.js new file mode 100644 index 0000000..9449eeb --- /dev/null +++ b/src/cjs/lib/converter/input/tapKeySig.js @@ -0,0 +1,49 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if ( + keyVal.key[0] !== typeFields_js_1.InputTypes.TAP_KEY_SIG || + keyVal.key.length !== 1 + ) { + throw new Error( + 'Decode Error: could not decode tapKeySig with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (!check(keyVal.value)) { + throw new Error( + 'Decode Error: tapKeySig not a valid 64-65-byte BIP340 signature', + ); + } + return keyVal.value; +} +exports.decode = decode; +function encode(value) { + const key = Uint8Array.from([typeFields_js_1.InputTypes.TAP_KEY_SIG]); + return { key, value }; +} +exports.encode = encode; +exports.expected = 'Uint8Array'; +function check(data) { + return ( + data instanceof Uint8Array && (data.length === 64 || data.length === 65) + ); +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.tapKeySig === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/tapLeafScript.d.ts b/src/cjs/lib/converter/input/tapLeafScript.d.ts similarity index 77% rename from src/lib/converter/input/tapLeafScript.d.ts rename to src/cjs/lib/converter/input/tapLeafScript.d.ts index 33fc2c5..f0ac9da 100644 --- a/src/lib/converter/input/tapLeafScript.d.ts +++ b/src/cjs/lib/converter/input/tapLeafScript.d.ts @@ -1,6 +1,6 @@ import { KeyValue, TapLeafScript } from '../../interfaces'; export declare function decode(keyVal: KeyValue): TapLeafScript; export declare function encode(tScript: TapLeafScript): KeyValue; -export declare const expected = "{ controlBlock: Buffer; leafVersion: number, script: Buffer; }"; +export declare const expected = "{ controlBlock: Uint8Array; leafVersion: number, script: Uint8Array; }"; export declare function check(data: any): data is TapLeafScript; export declare function canAddToArray(array: TapLeafScript[], item: TapLeafScript, dupeSet: Set): boolean; diff --git a/src/lib/converter/input/tapLeafScript.js b/src/cjs/lib/converter/input/tapLeafScript.js similarity index 50% rename from src/lib/converter/input/tapLeafScript.js rename to src/cjs/lib/converter/input/tapLeafScript.js index f2cd4da..ff4382b 100644 --- a/src/lib/converter/input/tapLeafScript.js +++ b/src/cjs/lib/converter/input/tapLeafScript.js @@ -1,24 +1,36 @@ 'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.TAP_LEAF_SCRIPT) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.TAP_LEAF_SCRIPT) { throw new Error( 'Decode Error: could not decode tapLeafScript with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ((keyVal.key.length - 2) % 32 !== 0) { throw new Error( 'Decode Error: tapLeafScript has invalid control block in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const leafVersion = keyVal.value[keyVal.value.length - 1]; if ((keyVal.key[1] & 0xfe) !== leafVersion) { throw new Error( 'Decode Error: tapLeafScript bad leaf version in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const script = keyVal.value.slice(0, -1); @@ -27,31 +39,32 @@ function decode(keyVal) { } exports.decode = decode; function encode(tScript) { - const head = Buffer.from([typeFields_1.InputTypes.TAP_LEAF_SCRIPT]); - const verBuf = Buffer.from([tScript.leafVersion]); + const head = Uint8Array.from([typeFields_js_1.InputTypes.TAP_LEAF_SCRIPT]); + const verBuf = Uint8Array.from([tScript.leafVersion]); return { - key: Buffer.concat([head, tScript.controlBlock]), - value: Buffer.concat([tScript.script, verBuf]), + key: tools.concat([head, tScript.controlBlock]), + value: tools.concat([tScript.script, verBuf]), }; } exports.encode = encode; exports.expected = - '{ controlBlock: Buffer; leafVersion: number, script: Buffer; }'; + '{ controlBlock: Uint8Array; leafVersion: number, script: Uint8Array; }'; function check(data) { return ( - Buffer.isBuffer(data.controlBlock) && + data.controlBlock instanceof Uint8Array && (data.controlBlock.length - 1) % 32 === 0 && (data.controlBlock[0] & 0xfe) === data.leafVersion && - Buffer.isBuffer(data.script) + data.script instanceof Uint8Array ); } exports.check = check; function canAddToArray(array, item, dupeSet) { - const dupeString = item.controlBlock.toString('hex'); + const dupeString = tools.toHex(item.controlBlock); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); return ( - array.filter(v => v.controlBlock.equals(item.controlBlock)).length === 0 + array.filter(v => tools.compare(v.controlBlock, item.controlBlock) === 0) + .length === 0 ); } exports.canAddToArray = canAddToArray; diff --git a/src/lib/converter/input/tapMerkleRoot.d.ts b/src/cjs/lib/converter/input/tapMerkleRoot.d.ts similarity index 87% rename from src/lib/converter/input/tapMerkleRoot.d.ts rename to src/cjs/lib/converter/input/tapMerkleRoot.d.ts index def3a44..1e222dc 100644 --- a/src/lib/converter/input/tapMerkleRoot.d.ts +++ b/src/cjs/lib/converter/input/tapMerkleRoot.d.ts @@ -1,6 +1,6 @@ import { KeyValue, TapMerkleRoot } from '../../interfaces'; export declare function decode(keyVal: KeyValue): TapMerkleRoot; export declare function encode(value: TapMerkleRoot): KeyValue; -export declare const expected = "Buffer"; +export declare const expected = "Uint8Array"; export declare function check(data: any): data is TapMerkleRoot; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/cjs/lib/converter/input/tapMerkleRoot.js b/src/cjs/lib/converter/input/tapMerkleRoot.js new file mode 100644 index 0000000..a233a7f --- /dev/null +++ b/src/cjs/lib/converter/input/tapMerkleRoot.js @@ -0,0 +1,45 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if ( + keyVal.key[0] !== typeFields_js_1.InputTypes.TAP_MERKLE_ROOT || + keyVal.key.length !== 1 + ) { + throw new Error( + 'Decode Error: could not decode tapMerkleRoot with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (!check(keyVal.value)) { + throw new Error('Decode Error: tapMerkleRoot not a 32-byte hash'); + } + return keyVal.value; +} +exports.decode = decode; +function encode(value) { + const key = Uint8Array.from([typeFields_js_1.InputTypes.TAP_MERKLE_ROOT]); + return { key, value }; +} +exports.encode = encode; +exports.expected = 'Uint8Array'; +function check(data) { + return data instanceof Uint8Array && data.length === 32; +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.tapMerkleRoot === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/input/tapScriptSig.d.ts b/src/cjs/lib/converter/input/tapScriptSig.d.ts similarity index 77% rename from src/lib/converter/input/tapScriptSig.d.ts rename to src/cjs/lib/converter/input/tapScriptSig.d.ts index 28884a9..6172daa 100644 --- a/src/lib/converter/input/tapScriptSig.d.ts +++ b/src/cjs/lib/converter/input/tapScriptSig.d.ts @@ -1,6 +1,6 @@ import { KeyValue, TapScriptSig } from '../../interfaces'; export declare function decode(keyVal: KeyValue): TapScriptSig; export declare function encode(tSig: TapScriptSig): KeyValue; -export declare const expected = "{ pubkey: Buffer; leafHash: Buffer; signature: Buffer; }"; +export declare const expected = "{ pubkey: Uint8Array; leafHash: Uint8Array; signature: Uint8Array; }"; export declare function check(data: any): data is TapScriptSig; export declare function canAddToArray(array: TapScriptSig[], item: TapScriptSig, dupeSet: Set): boolean; diff --git a/src/cjs/lib/converter/input/tapScriptSig.js b/src/cjs/lib/converter/input/tapScriptSig.js new file mode 100644 index 0000000..ad2b2db --- /dev/null +++ b/src/cjs/lib/converter/input/tapScriptSig.js @@ -0,0 +1,76 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.TAP_SCRIPT_SIG) { + throw new Error( + 'Decode Error: could not decode tapScriptSig with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (keyVal.key.length !== 65) { + throw new Error( + 'Decode Error: tapScriptSig has invalid key 0x' + tools.toHex(keyVal.key), + ); + } + if (keyVal.value.length !== 64 && keyVal.value.length !== 65) { + throw new Error( + 'Decode Error: tapScriptSig has invalid signature in key 0x' + + tools.toHex(keyVal.key), + ); + } + const pubkey = keyVal.key.slice(1, 33); + const leafHash = keyVal.key.slice(33); + return { + pubkey, + leafHash, + signature: keyVal.value, + }; +} +exports.decode = decode; +function encode(tSig) { + const head = Uint8Array.from([typeFields_js_1.InputTypes.TAP_SCRIPT_SIG]); + return { + key: tools.concat([head, tSig.pubkey, tSig.leafHash]), + value: tSig.signature, + }; +} +exports.encode = encode; +exports.expected = + '{ pubkey: Uint8Array; leafHash: Uint8Array; signature: Uint8Array; }'; +function check(data) { + return ( + data.pubkey instanceof Uint8Array && + data.leafHash instanceof Uint8Array && + data.signature instanceof Uint8Array && + data.pubkey.length === 32 && + data.leafHash.length === 32 && + (data.signature.length === 64 || data.signature.length === 65) + ); +} +exports.check = check; +function canAddToArray(array, item, dupeSet) { + const dupeString = tools.toHex(item.pubkey) + tools.toHex(item.leafHash); + if (dupeSet.has(dupeString)) return false; + dupeSet.add(dupeString); + return ( + array.filter( + v => + tools.compare(v.pubkey, item.pubkey) === 0 && + tools.compare(v.leafHash, item.leafHash) === 0, + ).length === 0 + ); +} +exports.canAddToArray = canAddToArray; diff --git a/src/lib/converter/input/witnessUtxo.d.ts b/src/cjs/lib/converter/input/witnessUtxo.d.ts similarity index 81% rename from src/lib/converter/input/witnessUtxo.d.ts rename to src/cjs/lib/converter/input/witnessUtxo.d.ts index d977aec..f670563 100644 --- a/src/lib/converter/input/witnessUtxo.d.ts +++ b/src/cjs/lib/converter/input/witnessUtxo.d.ts @@ -1,6 +1,6 @@ import { KeyValue, WitnessUtxo } from '../../interfaces'; export declare function decode(keyVal: KeyValue): WitnessUtxo; export declare function encode(data: WitnessUtxo): KeyValue; -export declare const expected = "{ script: Buffer; value: number; }"; +export declare const expected = "{ script: Uint8Array; value: bigint; }"; export declare function check(data: any): data is WitnessUtxo; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/cjs/lib/converter/input/witnessUtxo.js b/src/cjs/lib/converter/input/witnessUtxo.js new file mode 100644 index 0000000..1c56e96 --- /dev/null +++ b/src/cjs/lib/converter/input/witnessUtxo.js @@ -0,0 +1,62 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const typeFields_js_1 = require('../../typeFields.js'); +const tools = __importStar(require('uint8array-tools')); +const varuint = __importStar(require('varuint-bitcoin')); +function decode(keyVal) { + if (keyVal.key[0] !== typeFields_js_1.InputTypes.WITNESS_UTXO) { + throw new Error( + 'Decode Error: could not decode witnessUtxo with key 0x' + + tools.toHex(keyVal.key), + ); + } + const value = tools.readInt64(keyVal.value, 0, 'LE'); + let _offset = 8; + const { numberValue: scriptLen, bytes } = varuint.decode( + keyVal.value, + _offset, + ); + _offset += bytes; + const script = keyVal.value.slice(_offset); + if (script.length !== scriptLen) { + throw new Error('Decode Error: WITNESS_UTXO script is not proper length'); + } + return { + script, + value, + }; +} +exports.decode = decode; +function encode(data) { + const { script, value } = data; + const varuintlen = varuint.encodingLength(script.length); + const result = new Uint8Array(8 + varuintlen + script.length); + tools.writeInt64(result, 0, BigInt(value), 'LE'); + varuint.encode(script.length, result, 8); + result.set(script, 8 + varuintlen); + return { + key: Uint8Array.from([typeFields_js_1.InputTypes.WITNESS_UTXO]), + value: result, + }; +} +exports.encode = encode; +exports.expected = '{ script: Uint8Array; value: bigint; }'; +function check(data) { + return data.script instanceof Uint8Array && typeof data.value === 'bigint'; +} +exports.check = check; +function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.witnessUtxo === undefined; +} +exports.canAdd = canAdd; diff --git a/src/lib/converter/output/tapTree.d.ts b/src/cjs/lib/converter/output/tapTree.d.ts similarity index 89% rename from src/lib/converter/output/tapTree.d.ts rename to src/cjs/lib/converter/output/tapTree.d.ts index 06c76e1..f976363 100644 --- a/src/lib/converter/output/tapTree.d.ts +++ b/src/cjs/lib/converter/output/tapTree.d.ts @@ -1,6 +1,6 @@ import { KeyValue, TapTree } from '../../interfaces'; export declare function decode(keyVal: KeyValue): TapTree; export declare function encode(tree: TapTree): KeyValue; -export declare const expected = "{ leaves: [{ depth: number; leafVersion: number, script: Buffer; }] }"; +export declare const expected = "{ leaves: [{ depth: number; leafVersion: number, script: Uint8Array; }] }"; export declare function check(data: any): data is TapTree; export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/lib/converter/output/tapTree.js b/src/cjs/lib/converter/output/tapTree.js similarity index 53% rename from src/lib/converter/output/tapTree.js rename to src/cjs/lib/converter/output/tapTree.js index f1ec8d8..ed3aac5 100644 --- a/src/lib/converter/output/tapTree.js +++ b/src/cjs/lib/converter/output/tapTree.js @@ -1,15 +1,27 @@ 'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -const varuint = require('../varint'); +const typeFields_js_1 = require('../../typeFields.js'); +const varuint = __importStar(require('varuint-bitcoin')); +const tools = __importStar(require('uint8array-tools')); function decode(keyVal) { if ( - keyVal.key[0] !== typeFields_1.OutputTypes.TAP_TREE || + keyVal.key[0] !== typeFields_js_1.OutputTypes.TAP_TREE || keyVal.key.length !== 1 ) { throw new Error( 'Decode Error: could not decode tapTree with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } let _offset = 0; @@ -17,8 +29,11 @@ function decode(keyVal) { while (_offset < keyVal.value.length) { const depth = keyVal.value[_offset++]; const leafVersion = keyVal.value[_offset++]; - const scriptLen = varuint.decode(keyVal.value, _offset); - _offset += varuint.encodingLength(scriptLen); + const { numberValue: scriptLen, bytes } = varuint.decode( + keyVal.value, + _offset, + ); + _offset += bytes; data.push({ depth, leafVersion, @@ -30,22 +45,22 @@ function decode(keyVal) { } exports.decode = decode; function encode(tree) { - const key = Buffer.from([typeFields_1.OutputTypes.TAP_TREE]); + const key = Uint8Array.from([typeFields_js_1.OutputTypes.TAP_TREE]); const bufs = [].concat( ...tree.leaves.map(tapLeaf => [ - Buffer.of(tapLeaf.depth, tapLeaf.leafVersion), - varuint.encode(tapLeaf.script.length), + Uint8Array.of(tapLeaf.depth, tapLeaf.leafVersion), + varuint.encode(BigInt(tapLeaf.script.length)).buffer, tapLeaf.script, ]), ); return { key, - value: Buffer.concat(bufs), + value: tools.concat(bufs), }; } exports.encode = encode; exports.expected = - '{ leaves: [{ depth: number; leafVersion: number, script: Buffer; }] }'; + '{ leaves: [{ depth: number; leafVersion: number, script: Uint8Array; }] }'; function check(data) { return ( Array.isArray(data.leaves) && @@ -54,7 +69,7 @@ function check(data) { tapLeaf.depth >= 0 && tapLeaf.depth <= 128 && (tapLeaf.leafVersion & 0xfe) === tapLeaf.leafVersion && - Buffer.isBuffer(tapLeaf.script), + tapLeaf.script instanceof Uint8Array, ) ); } diff --git a/src/lib/converter/shared/bip32Derivation.d.ts b/src/cjs/lib/converter/shared/bip32Derivation.d.ts similarity index 84% rename from src/lib/converter/shared/bip32Derivation.d.ts rename to src/cjs/lib/converter/shared/bip32Derivation.d.ts index 6528887..d3b646d 100644 --- a/src/lib/converter/shared/bip32Derivation.d.ts +++ b/src/cjs/lib/converter/shared/bip32Derivation.d.ts @@ -1,6 +1,5 @@ -/// import { Bip32Derivation, KeyValue } from '../../interfaces'; -export declare function makeConverter(TYPE_BYTE: number, isValidPubkey?: (pubkey: Buffer) => boolean): { +export declare function makeConverter(TYPE_BYTE: number, isValidPubkey?: (pubkey: Uint8Array) => boolean): { decode: (keyVal: KeyValue) => Bip32Derivation; encode: (data: Bip32Derivation) => KeyValue; check: (data: any) => data is Bip32Derivation; diff --git a/src/cjs/lib/converter/shared/bip32Derivation.js b/src/cjs/lib/converter/shared/bip32Derivation.js new file mode 100644 index 0000000..5a074b6 --- /dev/null +++ b/src/cjs/lib/converter/shared/bip32Derivation.js @@ -0,0 +1,98 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const tools = __importStar(require('uint8array-tools')); +const range = n => [...Array(n).keys()]; +const isValidDERKey = pubkey => + (pubkey.length === 33 && [2, 3].includes(pubkey[0])) || + (pubkey.length === 65 && 4 === pubkey[0]); +function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { + function decode(keyVal) { + if (keyVal.key[0] !== TYPE_BYTE) { + throw new Error( + 'Decode Error: could not decode bip32Derivation with key 0x' + + tools.toHex(keyVal.key), + ); + } + const pubkey = keyVal.key.slice(1); + if (!isValidPubkey(pubkey)) { + throw new Error( + 'Decode Error: bip32Derivation has invalid pubkey in key 0x' + + tools.toHex(keyVal.key), + ); + } + if ((keyVal.value.length / 4) % 1 !== 0) { + throw new Error( + 'Decode Error: Input BIP32_DERIVATION value length should be multiple of 4', + ); + } + const data = { + masterFingerprint: keyVal.value.slice(0, 4), + pubkey, + path: 'm', + }; + for (const i of range(keyVal.value.length / 4 - 1)) { + const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE'); + const isHard = !!(val & 0x80000000); + const idx = val & 0x7fffffff; + data.path += '/' + idx.toString(10) + (isHard ? "'" : ''); + } + return data; + } + function encode(data) { + const head = Uint8Array.from([TYPE_BYTE]); + const key = tools.concat([head, data.pubkey]); + const splitPath = data.path.split('/'); + const value = new Uint8Array(splitPath.length * 4); + value.set(data.masterFingerprint, 0); + let offset = 4; + splitPath.slice(1).forEach(level => { + const isHard = level.slice(-1) === "'"; + let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10); + if (isHard) num += 0x80000000; + tools.writeUInt32(value, offset, num, 'LE'); + offset += 4; + }); + return { + key, + value, + }; + } + const expected = + '{ masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; }'; + function check(data) { + return ( + data.pubkey instanceof Uint8Array && + data.masterFingerprint instanceof Uint8Array && + typeof data.path === 'string' && + isValidPubkey(data.pubkey) && + data.masterFingerprint.length === 4 + ); + } + function canAddToArray(array, item, dupeSet) { + const dupeString = tools.toHex(item.pubkey); + if (dupeSet.has(dupeString)) return false; + dupeSet.add(dupeString); + return ( + array.filter(v => tools.compare(v.pubkey, item.pubkey) === 0).length === 0 + ); + } + return { + decode, + encode, + check, + expected, + canAddToArray, + }; +} +exports.makeConverter = makeConverter; diff --git a/src/lib/converter/shared/checkPubkey.d.ts b/src/cjs/lib/converter/shared/checkPubkey.d.ts similarity index 61% rename from src/lib/converter/shared/checkPubkey.d.ts rename to src/cjs/lib/converter/shared/checkPubkey.d.ts index 4b282b3..0966a06 100644 --- a/src/lib/converter/shared/checkPubkey.d.ts +++ b/src/cjs/lib/converter/shared/checkPubkey.d.ts @@ -1,3 +1,2 @@ -/// import { KeyValue } from '../../interfaces'; -export declare function makeChecker(pubkeyTypes: number[]): (keyVal: KeyValue) => Buffer | undefined; +export declare function makeChecker(pubkeyTypes: number[]): (keyVal: KeyValue) => Uint8Array | undefined; diff --git a/src/cjs/lib/converter/shared/checkPubkey.js b/src/cjs/lib/converter/shared/checkPubkey.js new file mode 100644 index 0000000..3498a6a --- /dev/null +++ b/src/cjs/lib/converter/shared/checkPubkey.js @@ -0,0 +1,33 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const tools = __importStar(require('uint8array-tools')); +function makeChecker(pubkeyTypes) { + return checkPubkey; + function checkPubkey(keyVal) { + let pubkey; + if (pubkeyTypes.includes(keyVal.key[0])) { + pubkey = keyVal.key.slice(1); + if ( + !(pubkey.length === 33 || pubkey.length === 65) || + ![2, 3, 4].includes(pubkey[0]) + ) { + throw new Error( + 'Format Error: invalid pubkey in key 0x' + tools.toHex(keyVal.key), + ); + } + } + return pubkey; + } +} +exports.makeChecker = makeChecker; diff --git a/src/lib/converter/shared/redeemScript.d.ts b/src/cjs/lib/converter/shared/redeemScript.d.ts similarity index 100% rename from src/lib/converter/shared/redeemScript.d.ts rename to src/cjs/lib/converter/shared/redeemScript.d.ts diff --git a/src/cjs/lib/converter/shared/redeemScript.js b/src/cjs/lib/converter/shared/redeemScript.js new file mode 100644 index 0000000..9fbdfe9 --- /dev/null +++ b/src/cjs/lib/converter/shared/redeemScript.js @@ -0,0 +1,47 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const tools = __importStar(require('uint8array-tools')); +function makeConverter(TYPE_BYTE) { + function decode(keyVal) { + if (keyVal.key[0] !== TYPE_BYTE) { + throw new Error( + 'Decode Error: could not decode redeemScript with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; + } + function encode(data) { + const key = Uint8Array.from([TYPE_BYTE]); + return { + key, + value: data, + }; + } + const expected = 'Uint8Array'; + function check(data) { + return data instanceof Uint8Array; + } + function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.redeemScript === undefined; + } + return { + decode, + encode, + check, + expected, + canAdd, + }; +} +exports.makeConverter = makeConverter; diff --git a/src/lib/converter/shared/tapBip32Derivation.d.ts b/src/cjs/lib/converter/shared/tapBip32Derivation.d.ts similarity index 100% rename from src/lib/converter/shared/tapBip32Derivation.d.ts rename to src/cjs/lib/converter/shared/tapBip32Derivation.d.ts diff --git a/src/cjs/lib/converter/shared/tapBip32Derivation.js b/src/cjs/lib/converter/shared/tapBip32Derivation.js new file mode 100644 index 0000000..aeb9289 --- /dev/null +++ b/src/cjs/lib/converter/shared/tapBip32Derivation.js @@ -0,0 +1,66 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const varuint = __importStar(require('varuint-bitcoin')); +const tools = __importStar(require('uint8array-tools')); +const bip32Derivation = __importStar(require('./bip32Derivation.js')); +const isValidBIP340Key = pubkey => pubkey.length === 32; +function makeConverter(TYPE_BYTE) { + const parent = bip32Derivation.makeConverter(TYPE_BYTE, isValidBIP340Key); + function decode(keyVal) { + const { numberValue: nHashes, bytes: nHashesLen } = varuint.decode( + keyVal.value, + ); + const base = parent.decode({ + key: keyVal.key, + value: keyVal.value.slice(nHashesLen + Number(nHashes) * 32), + }); + const leafHashes = new Array(Number(nHashes)); + for (let i = 0, _offset = nHashesLen; i < nHashes; i++, _offset += 32) { + leafHashes[i] = keyVal.value.slice(_offset, _offset + 32); + } + return { ...base, leafHashes }; + } + function encode(data) { + const base = parent.encode(data); + const nHashesLen = varuint.encodingLength(data.leafHashes.length); + const nHashesBuf = new Uint8Array(nHashesLen); + varuint.encode(data.leafHashes.length, nHashesBuf); + const value = tools.concat([nHashesBuf, ...data.leafHashes, base.value]); + return { ...base, value }; + } + const expected = + '{ ' + + 'masterFingerprint: Uint8Array; ' + + 'pubkey: Uint8Array; ' + + 'path: string; ' + + 'leafHashes: Uint8Array[]; ' + + '}'; + function check(data) { + return ( + Array.isArray(data.leafHashes) && + data.leafHashes.every( + leafHash => leafHash instanceof Uint8Array && leafHash.length === 32, + ) && + parent.check(data) + ); + } + return { + decode, + encode, + check, + expected, + canAddToArray: parent.canAddToArray, + }; +} +exports.makeConverter = makeConverter; diff --git a/src/lib/converter/shared/tapInternalKey.d.ts b/src/cjs/lib/converter/shared/tapInternalKey.d.ts similarity index 100% rename from src/lib/converter/shared/tapInternalKey.d.ts rename to src/cjs/lib/converter/shared/tapInternalKey.d.ts diff --git a/src/cjs/lib/converter/shared/tapInternalKey.js b/src/cjs/lib/converter/shared/tapInternalKey.js new file mode 100644 index 0000000..6f915aa --- /dev/null +++ b/src/cjs/lib/converter/shared/tapInternalKey.js @@ -0,0 +1,51 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const tools = __importStar(require('uint8array-tools')); +function makeConverter(TYPE_BYTE) { + function decode(keyVal) { + if (keyVal.key[0] !== TYPE_BYTE || keyVal.key.length !== 1) { + throw new Error( + 'Decode Error: could not decode tapInternalKey with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (keyVal.value.length !== 32) { + throw new Error( + 'Decode Error: tapInternalKey not a 32-byte x-only pubkey', + ); + } + return keyVal.value; + } + function encode(value) { + const key = Uint8Array.from([TYPE_BYTE]); + return { key, value }; + } + const expected = 'Uint8Array'; + function check(data) { + return data instanceof Uint8Array && data.length === 32; + } + function canAdd(currentData, newData) { + return ( + !!currentData && !!newData && currentData.tapInternalKey === undefined + ); + } + return { + decode, + encode, + check, + expected, + canAdd, + }; +} +exports.makeConverter = makeConverter; diff --git a/src/lib/converter/shared/witnessScript.d.ts b/src/cjs/lib/converter/shared/witnessScript.d.ts similarity index 100% rename from src/lib/converter/shared/witnessScript.d.ts rename to src/cjs/lib/converter/shared/witnessScript.d.ts diff --git a/src/cjs/lib/converter/shared/witnessScript.js b/src/cjs/lib/converter/shared/witnessScript.js new file mode 100644 index 0000000..c31be2c --- /dev/null +++ b/src/cjs/lib/converter/shared/witnessScript.js @@ -0,0 +1,49 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const tools = __importStar(require('uint8array-tools')); +function makeConverter(TYPE_BYTE) { + function decode(keyVal) { + if (keyVal.key[0] !== TYPE_BYTE) { + throw new Error( + 'Decode Error: could not decode witnessScript with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; + } + function encode(data) { + const key = Uint8Array.from([TYPE_BYTE]); + return { + key, + value: data, + }; + } + const expected = 'Uint8Array'; + function check(data) { + return data instanceof Uint8Array; + } + function canAdd(currentData, newData) { + return ( + !!currentData && !!newData && currentData.witnessScript === undefined + ); + } + return { + decode, + encode, + check, + expected, + canAdd, + }; +} +exports.makeConverter = makeConverter; diff --git a/src/cjs/lib/converter/tools.d.ts b/src/cjs/lib/converter/tools.d.ts new file mode 100644 index 0000000..0fbb8a6 --- /dev/null +++ b/src/cjs/lib/converter/tools.d.ts @@ -0,0 +1,5 @@ +import { KeyValue } from '../interfaces'; +export declare const range: (n: number) => number[]; +export declare function reverseBuffer(buffer: Uint8Array): Uint8Array; +export declare function keyValsToBuffer(keyVals: KeyValue[]): Uint8Array; +export declare function keyValToBuffer(keyVal: KeyValue): Uint8Array; diff --git a/src/cjs/lib/converter/tools.js b/src/cjs/lib/converter/tools.js new file mode 100644 index 0000000..7379f34 --- /dev/null +++ b/src/cjs/lib/converter/tools.js @@ -0,0 +1,48 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const varuint = __importStar(require('varuint-bitcoin')); +const tools = __importStar(require('uint8array-tools')); +exports.range = n => [...Array(n).keys()]; +function reverseBuffer(buffer) { + if (buffer.length < 1) return buffer; + let j = buffer.length - 1; + let tmp = 0; + for (let i = 0; i < buffer.length / 2; i++) { + tmp = buffer[i]; + buffer[i] = buffer[j]; + buffer[j] = tmp; + j--; + } + return buffer; +} +exports.reverseBuffer = reverseBuffer; +function keyValsToBuffer(keyVals) { + const buffers = keyVals.map(keyValToBuffer); + buffers.push(Uint8Array.from([0])); + return tools.concat(buffers); +} +exports.keyValsToBuffer = keyValsToBuffer; +function keyValToBuffer(keyVal) { + const keyLen = keyVal.key.length; + const valLen = keyVal.value.length; + const keyVarIntLen = varuint.encodingLength(keyLen); + const valVarIntLen = varuint.encodingLength(valLen); + const buffer = new Uint8Array(keyVarIntLen + keyLen + valVarIntLen + valLen); + varuint.encode(keyLen, buffer, 0); + buffer.set(keyVal.key, keyVarIntLen); + varuint.encode(valLen, buffer, keyVarIntLen + keyLen); + buffer.set(keyVal.value, keyVarIntLen + keyLen + valVarIntLen); + return buffer; +} +exports.keyValToBuffer = keyValToBuffer; diff --git a/src/lib/interfaces.d.ts b/src/cjs/lib/interfaces.d.ts similarity index 70% rename from src/lib/interfaces.d.ts rename to src/cjs/lib/interfaces.d.ts index a445c7d..9a5112e 100644 --- a/src/lib/interfaces.d.ts +++ b/src/cjs/lib/interfaces.d.ts @@ -1,5 +1,4 @@ -/// -export declare type TransactionFromBuffer = (buffer: Buffer) => Transaction; +export declare type TransactionFromBuffer = (buffer: Uint8Array) => Transaction; export interface Transaction { getInputOutputCounts(): { inputCount: number; @@ -7,11 +6,11 @@ export interface Transaction { }; addInput(objectArg: any): void; addOutput(objectArg: any): void; - toBuffer(): Buffer; + toBuffer(): Uint8Array; } export interface KeyValue { - key: Buffer; - value: Buffer; + key: Uint8Array; + value: Uint8Array; } export interface PsbtGlobal extends PsbtGlobalUpdate { unsignedTx: Transaction; @@ -59,57 +58,57 @@ export interface PsbtOutputExtended extends PsbtOutput { [index: string]: any; } export interface GlobalXpub { - extendedPubkey: Buffer; - masterFingerprint: Buffer; + extendedPubkey: Uint8Array; + masterFingerprint: Uint8Array; path: string; } export interface PartialSig { - pubkey: Buffer; - signature: Buffer; + pubkey: Uint8Array; + signature: Uint8Array; } export interface Bip32Derivation { - masterFingerprint: Buffer; - pubkey: Buffer; + masterFingerprint: Uint8Array; + pubkey: Uint8Array; path: string; } export interface WitnessUtxo { - script: Buffer; - value: number; + script: Uint8Array; + value: bigint; } -export declare type NonWitnessUtxo = Buffer; +export declare type NonWitnessUtxo = Uint8Array; export declare type SighashType = number; -export declare type RedeemScript = Buffer; -export declare type WitnessScript = Buffer; -export declare type FinalScriptSig = Buffer; -export declare type FinalScriptWitness = Buffer; +export declare type RedeemScript = Uint8Array; +export declare type WitnessScript = Uint8Array; +export declare type FinalScriptSig = Uint8Array; +export declare type FinalScriptWitness = Uint8Array; export declare type PorCommitment = string; -export declare type TapKeySig = Buffer; +export declare type TapKeySig = Uint8Array; export interface TapScriptSig extends PartialSig { - leafHash: Buffer; + leafHash: Uint8Array; } interface TapScript { leafVersion: number; - script: Buffer; + script: Uint8Array; } -export declare type ControlBlock = Buffer; +export declare type ControlBlock = Uint8Array; export interface TapLeafScript extends TapScript { controlBlock: ControlBlock; } export interface TapBip32Derivation extends Bip32Derivation { - leafHashes: Buffer[]; + leafHashes: Uint8Array[]; } -export declare type TapInternalKey = Buffer; -export declare type TapMerkleRoot = Buffer; +export declare type TapInternalKey = Uint8Array; +export declare type TapMerkleRoot = Uint8Array; export interface TapLeaf extends TapScript { depth: number; } export interface TapTree { leaves: TapLeaf[]; } -export declare type TransactionIOCountGetter = (txBuffer: Buffer) => { +export declare type TransactionIOCountGetter = (txBuffer: Uint8Array) => { inputCount: number; outputCount: number; }; -export declare type TransactionVersionSetter = (version: number, txBuffer: Buffer) => Buffer; -export declare type TransactionLocktimeSetter = (locktime: number, txBuffer: Buffer) => Buffer; +export declare type TransactionVersionSetter = (version: number, txBuffer: Uint8Array) => Uint8Array; +export declare type TransactionLocktimeSetter = (locktime: number, txBuffer: Uint8Array) => Uint8Array; export {}; diff --git a/src/lib/interfaces.js b/src/cjs/lib/interfaces.js similarity index 100% rename from src/lib/interfaces.js rename to src/cjs/lib/interfaces.js diff --git a/src/lib/parser/fromBuffer.d.ts b/src/cjs/lib/parser/fromBuffer.d.ts similarity index 58% rename from src/lib/parser/fromBuffer.d.ts rename to src/cjs/lib/parser/fromBuffer.d.ts index 729a74b..f59bc3b 100644 --- a/src/lib/parser/fromBuffer.d.ts +++ b/src/cjs/lib/parser/fromBuffer.d.ts @@ -1,12 +1,11 @@ -/// import { KeyValue, Transaction, TransactionFromBuffer } from '../interfaces'; -import { PsbtAttributes } from './index'; -export declare function psbtFromBuffer(buffer: Buffer, txGetter: TransactionFromBuffer): PsbtAttributes; +import { PsbtAttributes } from './index.js'; +export declare function psbtFromBuffer(buffer: Uint8Array, txGetter: TransactionFromBuffer): PsbtAttributes; interface PsbtFromKeyValsArg { globalMapKeyVals: KeyValue[]; inputKeyVals: KeyValue[][]; outputKeyVals: KeyValue[][]; } -export declare function checkKeyBuffer(type: string, keyBuf: Buffer, keyNum: number): void; +export declare function checkKeyBuffer(type: string, keyBuf: Uint8Array, keyNum: number): void; export declare function psbtFromKeyVals(unsignedTx: Transaction, { globalMapKeyVals, inputKeyVals, outputKeyVals }: PsbtFromKeyValsArg): PsbtAttributes; export {}; diff --git a/src/lib/parser/fromBuffer.js b/src/cjs/lib/parser/fromBuffer.js similarity index 72% rename from src/lib/parser/fromBuffer.js rename to src/cjs/lib/parser/fromBuffer.js index 5d05844..91249a4 100644 --- a/src/lib/parser/fromBuffer.js +++ b/src/cjs/lib/parser/fromBuffer.js @@ -1,25 +1,37 @@ 'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; Object.defineProperty(exports, '__esModule', { value: true }); -const convert = require('../converter'); -const tools_1 = require('../converter/tools'); -const varuint = require('../converter/varint'); -const typeFields_1 = require('../typeFields'); +const convert = __importStar(require('../converter/index.js')); +const tools_js_1 = require('../converter/tools.js'); +const varuint = __importStar(require('varuint-bitcoin')); +const tools = __importStar(require('uint8array-tools')); +const typeFields_js_1 = require('../typeFields.js'); function psbtFromBuffer(buffer, txGetter) { let offset = 0; function varSlice() { - const keyLen = varuint.decode(buffer, offset); - offset += varuint.encodingLength(keyLen); - const key = buffer.slice(offset, offset + keyLen); - offset += keyLen; + const { numberValue: keyLen, bytes } = varuint.decode(buffer, offset); + offset += bytes; + const key = buffer.slice(offset, offset + Number(keyLen)); + offset += Number(keyLen); return key; } function readUInt32BE() { - const num = buffer.readUInt32BE(offset); + const num = tools.readUInt32(buffer, offset, 'BE'); offset += 4; return num; } function readUInt8() { - const num = buffer.readUInt8(offset); + const num = tools.readUInt8(buffer, offset); offset += 1; return num; } @@ -35,7 +47,7 @@ function psbtFromBuffer(buffer, txGetter) { if (offset >= buffer.length) { throw new Error('Format Error: Unexpected End of PSBT'); } - const isEnd = buffer.readUInt8(offset) === 0; + const isEnd = tools.readUInt8(buffer, offset) === 0; if (isEnd) { offset++; } @@ -53,7 +65,7 @@ function psbtFromBuffer(buffer, txGetter) { const globalKeyIndex = {}; while (!checkEndOfKeyValPairs()) { const keyVal = getKeyValue(); - const hexKey = keyVal.key.toString('hex'); + const hexKey = tools.toHex(keyVal.key); if (globalKeyIndex[hexKey]) { throw new Error( 'Format Error: Keys must be unique for global keymap: key ' + hexKey, @@ -63,7 +75,7 @@ function psbtFromBuffer(buffer, txGetter) { globalMapKeyVals.push(keyVal); } const unsignedTxMaps = globalMapKeyVals.filter( - keyVal => keyVal.key[0] === typeFields_1.GlobalTypes.UNSIGNED_TX, + keyVal => keyVal.key[0] === typeFields_js_1.GlobalTypes.UNSIGNED_TX, ); if (unsignedTxMaps.length !== 1) { throw new Error('Format Error: Only one UNSIGNED_TX allowed'); @@ -74,12 +86,12 @@ function psbtFromBuffer(buffer, txGetter) { const inputKeyVals = []; const outputKeyVals = []; // Get input fields - for (const index of tools_1.range(inputCount)) { + for (const index of tools_js_1.range(inputCount)) { const inputKeyIndex = {}; const input = []; while (!checkEndOfKeyValPairs()) { const keyVal = getKeyValue(); - const hexKey = keyVal.key.toString('hex'); + const hexKey = tools.toHex(keyVal.key); if (inputKeyIndex[hexKey]) { throw new Error( 'Format Error: Keys must be unique for each input: ' + @@ -94,12 +106,12 @@ function psbtFromBuffer(buffer, txGetter) { } inputKeyVals.push(input); } - for (const index of tools_1.range(outputCount)) { + for (const index of tools_js_1.range(outputCount)) { const outputKeyIndex = {}; const output = []; while (!checkEndOfKeyValPairs()) { const keyVal = getKeyValue(); - const hexKey = keyVal.key.toString('hex'); + const hexKey = tools.toHex(keyVal.key); if (outputKeyIndex[hexKey]) { throw new Error( 'Format Error: Keys must be unique for each output: ' + @@ -122,9 +134,10 @@ function psbtFromBuffer(buffer, txGetter) { } exports.psbtFromBuffer = psbtFromBuffer; function checkKeyBuffer(type, keyBuf, keyNum) { - if (!keyBuf.equals(Buffer.from([keyNum]))) { + if (tools.compare(keyBuf, Uint8Array.from([keyNum]))) { throw new Error( - `Format Error: Invalid ${type} key: ${keyBuf.toString('hex')}`, + // `Format Error: Invalid ${type} key: ${keyBuf.toString('hex')}`, + `Format Error: Invalid ${type} key: ${tools.toHex(keyBuf)}`, ); } } @@ -142,18 +155,18 @@ function psbtFromKeyVals( // If a globalMap item needs pubkey, uncomment // const pubkey = convert.globals.checkPubkey(keyVal); switch (keyVal.key[0]) { - case typeFields_1.GlobalTypes.UNSIGNED_TX: + case typeFields_js_1.GlobalTypes.UNSIGNED_TX: checkKeyBuffer( 'global', keyVal.key, - typeFields_1.GlobalTypes.UNSIGNED_TX, + typeFields_js_1.GlobalTypes.UNSIGNED_TX, ); if (txCount > 0) { throw new Error('Format Error: GlobalMap has multiple UNSIGNED_TX'); } txCount++; break; - case typeFields_1.GlobalTypes.GLOBAL_XPUB: + case typeFields_js_1.GlobalTypes.GLOBAL_XPUB: if (globalMap.globalXpub === undefined) { globalMap.globalXpub = []; } @@ -171,16 +184,16 @@ function psbtFromKeyVals( const inputs = []; const outputs = []; // Get input fields - for (const index of tools_1.range(inputCount)) { + for (const index of tools_js_1.range(inputCount)) { const input = {}; for (const keyVal of inputKeyVals[index]) { convert.inputs.checkPubkey(keyVal); switch (keyVal.key[0]) { - case typeFields_1.InputTypes.NON_WITNESS_UTXO: + case typeFields_js_1.InputTypes.NON_WITNESS_UTXO: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.NON_WITNESS_UTXO, + typeFields_js_1.InputTypes.NON_WITNESS_UTXO, ); if (input.nonWitnessUtxo !== undefined) { throw new Error( @@ -189,57 +202,57 @@ function psbtFromKeyVals( } input.nonWitnessUtxo = convert.inputs.nonWitnessUtxo.decode(keyVal); break; - case typeFields_1.InputTypes.WITNESS_UTXO: + case typeFields_js_1.InputTypes.WITNESS_UTXO: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.WITNESS_UTXO, + typeFields_js_1.InputTypes.WITNESS_UTXO, ); if (input.witnessUtxo !== undefined) { throw new Error('Format Error: Input has multiple WITNESS_UTXO'); } input.witnessUtxo = convert.inputs.witnessUtxo.decode(keyVal); break; - case typeFields_1.InputTypes.PARTIAL_SIG: + case typeFields_js_1.InputTypes.PARTIAL_SIG: if (input.partialSig === undefined) { input.partialSig = []; } input.partialSig.push(convert.inputs.partialSig.decode(keyVal)); break; - case typeFields_1.InputTypes.SIGHASH_TYPE: + case typeFields_js_1.InputTypes.SIGHASH_TYPE: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.SIGHASH_TYPE, + typeFields_js_1.InputTypes.SIGHASH_TYPE, ); if (input.sighashType !== undefined) { throw new Error('Format Error: Input has multiple SIGHASH_TYPE'); } input.sighashType = convert.inputs.sighashType.decode(keyVal); break; - case typeFields_1.InputTypes.REDEEM_SCRIPT: + case typeFields_js_1.InputTypes.REDEEM_SCRIPT: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.REDEEM_SCRIPT, + typeFields_js_1.InputTypes.REDEEM_SCRIPT, ); if (input.redeemScript !== undefined) { throw new Error('Format Error: Input has multiple REDEEM_SCRIPT'); } input.redeemScript = convert.inputs.redeemScript.decode(keyVal); break; - case typeFields_1.InputTypes.WITNESS_SCRIPT: + case typeFields_js_1.InputTypes.WITNESS_SCRIPT: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.WITNESS_SCRIPT, + typeFields_js_1.InputTypes.WITNESS_SCRIPT, ); if (input.witnessScript !== undefined) { throw new Error('Format Error: Input has multiple WITNESS_SCRIPT'); } input.witnessScript = convert.inputs.witnessScript.decode(keyVal); break; - case typeFields_1.InputTypes.BIP32_DERIVATION: + case typeFields_js_1.InputTypes.BIP32_DERIVATION: if (input.bip32Derivation === undefined) { input.bip32Derivation = []; } @@ -247,53 +260,53 @@ function psbtFromKeyVals( convert.inputs.bip32Derivation.decode(keyVal), ); break; - case typeFields_1.InputTypes.FINAL_SCRIPTSIG: + case typeFields_js_1.InputTypes.FINAL_SCRIPTSIG: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.FINAL_SCRIPTSIG, + typeFields_js_1.InputTypes.FINAL_SCRIPTSIG, ); input.finalScriptSig = convert.inputs.finalScriptSig.decode(keyVal); break; - case typeFields_1.InputTypes.FINAL_SCRIPTWITNESS: + case typeFields_js_1.InputTypes.FINAL_SCRIPTWITNESS: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.FINAL_SCRIPTWITNESS, + typeFields_js_1.InputTypes.FINAL_SCRIPTWITNESS, ); input.finalScriptWitness = convert.inputs.finalScriptWitness.decode( keyVal, ); break; - case typeFields_1.InputTypes.POR_COMMITMENT: + case typeFields_js_1.InputTypes.POR_COMMITMENT: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.POR_COMMITMENT, + typeFields_js_1.InputTypes.POR_COMMITMENT, ); input.porCommitment = convert.inputs.porCommitment.decode(keyVal); break; - case typeFields_1.InputTypes.TAP_KEY_SIG: + case typeFields_js_1.InputTypes.TAP_KEY_SIG: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.TAP_KEY_SIG, + typeFields_js_1.InputTypes.TAP_KEY_SIG, ); input.tapKeySig = convert.inputs.tapKeySig.decode(keyVal); break; - case typeFields_1.InputTypes.TAP_SCRIPT_SIG: + case typeFields_js_1.InputTypes.TAP_SCRIPT_SIG: if (input.tapScriptSig === undefined) { input.tapScriptSig = []; } input.tapScriptSig.push(convert.inputs.tapScriptSig.decode(keyVal)); break; - case typeFields_1.InputTypes.TAP_LEAF_SCRIPT: + case typeFields_js_1.InputTypes.TAP_LEAF_SCRIPT: if (input.tapLeafScript === undefined) { input.tapLeafScript = []; } input.tapLeafScript.push(convert.inputs.tapLeafScript.decode(keyVal)); break; - case typeFields_1.InputTypes.TAP_BIP32_DERIVATION: + case typeFields_js_1.InputTypes.TAP_BIP32_DERIVATION: if (input.tapBip32Derivation === undefined) { input.tapBip32Derivation = []; } @@ -301,19 +314,19 @@ function psbtFromKeyVals( convert.inputs.tapBip32Derivation.decode(keyVal), ); break; - case typeFields_1.InputTypes.TAP_INTERNAL_KEY: + case typeFields_js_1.InputTypes.TAP_INTERNAL_KEY: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.TAP_INTERNAL_KEY, + typeFields_js_1.InputTypes.TAP_INTERNAL_KEY, ); input.tapInternalKey = convert.inputs.tapInternalKey.decode(keyVal); break; - case typeFields_1.InputTypes.TAP_MERKLE_ROOT: + case typeFields_js_1.InputTypes.TAP_MERKLE_ROOT: checkKeyBuffer( 'input', keyVal.key, - typeFields_1.InputTypes.TAP_MERKLE_ROOT, + typeFields_js_1.InputTypes.TAP_MERKLE_ROOT, ); input.tapMerkleRoot = convert.inputs.tapMerkleRoot.decode(keyVal); break; @@ -325,34 +338,34 @@ function psbtFromKeyVals( } inputs.push(input); } - for (const index of tools_1.range(outputCount)) { + for (const index of tools_js_1.range(outputCount)) { const output = {}; for (const keyVal of outputKeyVals[index]) { convert.outputs.checkPubkey(keyVal); switch (keyVal.key[0]) { - case typeFields_1.OutputTypes.REDEEM_SCRIPT: + case typeFields_js_1.OutputTypes.REDEEM_SCRIPT: checkKeyBuffer( 'output', keyVal.key, - typeFields_1.OutputTypes.REDEEM_SCRIPT, + typeFields_js_1.OutputTypes.REDEEM_SCRIPT, ); if (output.redeemScript !== undefined) { throw new Error('Format Error: Output has multiple REDEEM_SCRIPT'); } output.redeemScript = convert.outputs.redeemScript.decode(keyVal); break; - case typeFields_1.OutputTypes.WITNESS_SCRIPT: + case typeFields_js_1.OutputTypes.WITNESS_SCRIPT: checkKeyBuffer( 'output', keyVal.key, - typeFields_1.OutputTypes.WITNESS_SCRIPT, + typeFields_js_1.OutputTypes.WITNESS_SCRIPT, ); if (output.witnessScript !== undefined) { throw new Error('Format Error: Output has multiple WITNESS_SCRIPT'); } output.witnessScript = convert.outputs.witnessScript.decode(keyVal); break; - case typeFields_1.OutputTypes.BIP32_DERIVATION: + case typeFields_js_1.OutputTypes.BIP32_DERIVATION: if (output.bip32Derivation === undefined) { output.bip32Derivation = []; } @@ -360,23 +373,23 @@ function psbtFromKeyVals( convert.outputs.bip32Derivation.decode(keyVal), ); break; - case typeFields_1.OutputTypes.TAP_INTERNAL_KEY: + case typeFields_js_1.OutputTypes.TAP_INTERNAL_KEY: checkKeyBuffer( 'output', keyVal.key, - typeFields_1.OutputTypes.TAP_INTERNAL_KEY, + typeFields_js_1.OutputTypes.TAP_INTERNAL_KEY, ); output.tapInternalKey = convert.outputs.tapInternalKey.decode(keyVal); break; - case typeFields_1.OutputTypes.TAP_TREE: + case typeFields_js_1.OutputTypes.TAP_TREE: checkKeyBuffer( 'output', keyVal.key, - typeFields_1.OutputTypes.TAP_TREE, + typeFields_js_1.OutputTypes.TAP_TREE, ); output.tapTree = convert.outputs.tapTree.decode(keyVal); break; - case typeFields_1.OutputTypes.TAP_BIP32_DERIVATION: + case typeFields_js_1.OutputTypes.TAP_BIP32_DERIVATION: if (output.tapBip32Derivation === undefined) { output.tapBip32Derivation = []; } diff --git a/src/lib/parser/index.d.ts b/src/cjs/lib/parser/index.d.ts similarity index 73% rename from src/lib/parser/index.d.ts rename to src/cjs/lib/parser/index.d.ts index c9364df..bbd9eae 100644 --- a/src/lib/parser/index.d.ts +++ b/src/cjs/lib/parser/index.d.ts @@ -1,6 +1,6 @@ import { PsbtGlobal, PsbtInput, PsbtOutput } from '../interfaces'; -export * from './fromBuffer'; -export * from './toBuffer'; +export * from './fromBuffer.js'; +export * from './toBuffer.js'; export interface PsbtAttributes { globalMap: PsbtGlobal; inputs: PsbtInput[]; diff --git a/src/lib/parser/index.js b/src/cjs/lib/parser/index.js similarity index 69% rename from src/lib/parser/index.js rename to src/cjs/lib/parser/index.js index d6a752f..6f30632 100644 --- a/src/lib/parser/index.js +++ b/src/cjs/lib/parser/index.js @@ -3,5 +3,5 @@ function __export(m) { for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; } Object.defineProperty(exports, '__esModule', { value: true }); -__export(require('./fromBuffer')); -__export(require('./toBuffer')); +__export(require('./fromBuffer.js')); +__export(require('./toBuffer.js')); diff --git a/src/lib/parser/toBuffer.d.ts b/src/cjs/lib/parser/toBuffer.d.ts similarity index 73% rename from src/lib/parser/toBuffer.d.ts rename to src/cjs/lib/parser/toBuffer.d.ts index ba62352..4e7b230 100644 --- a/src/lib/parser/toBuffer.d.ts +++ b/src/cjs/lib/parser/toBuffer.d.ts @@ -1,7 +1,6 @@ -/// import { KeyValue } from '../interfaces'; -import { PsbtAttributes } from './index'; -export declare function psbtToBuffer({ globalMap, inputs, outputs, }: PsbtAttributes): Buffer; +import { PsbtAttributes } from './index.js'; +export declare function psbtToBuffer({ globalMap, inputs, outputs, }: PsbtAttributes): Uint8Array; export declare function psbtToKeyVals({ globalMap, inputs, outputs, }: PsbtAttributes): { globalKeyVals: KeyValue[]; inputKeyVals: KeyValue[][]; diff --git a/src/cjs/lib/parser/toBuffer.js b/src/cjs/lib/parser/toBuffer.js new file mode 100644 index 0000000..c1596aa --- /dev/null +++ b/src/cjs/lib/parser/toBuffer.js @@ -0,0 +1,76 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const convert = __importStar(require('../converter/index.js')); +const tools_js_1 = require('../converter/tools.js'); +const tools = __importStar(require('uint8array-tools')); +function psbtToBuffer({ globalMap, inputs, outputs }) { + const { globalKeyVals, inputKeyVals, outputKeyVals } = psbtToKeyVals({ + globalMap, + inputs, + outputs, + }); + const globalBuffer = tools_js_1.keyValsToBuffer(globalKeyVals); + const keyValsOrEmptyToBuffer = keyVals => + keyVals.length === 0 + ? [Uint8Array.from([0])] + : keyVals.map(tools_js_1.keyValsToBuffer); + const inputBuffers = keyValsOrEmptyToBuffer(inputKeyVals); + const outputBuffers = keyValsOrEmptyToBuffer(outputKeyVals); + const header = new Uint8Array(5); + header.set([0x70, 0x73, 0x62, 0x74, 0xff], 0); + return tools.concat( + [header, globalBuffer].concat(inputBuffers, outputBuffers), + ); +} +exports.psbtToBuffer = psbtToBuffer; +const sortKeyVals = (a, b) => { + return tools.compare(a.key, b.key); +}; +function keyValsFromMap(keyValMap, converterFactory) { + const keyHexSet = new Set(); + const keyVals = Object.entries(keyValMap).reduce((result, [key, value]) => { + if (key === 'unknownKeyVals') return result; + // We are checking for undefined anyways. So ignore TS error + // @ts-ignore + const converter = converterFactory[key]; + if (converter === undefined) return result; + const encodedKeyVals = (Array.isArray(value) ? value : [value]).map( + converter.encode, + ); + const keyHexes = encodedKeyVals.map(kv => tools.toHex(kv.key)); + keyHexes.forEach(hex => { + if (keyHexSet.has(hex)) + throw new Error('Serialize Error: Duplicate key: ' + hex); + keyHexSet.add(hex); + }); + return result.concat(encodedKeyVals); + }, []); + // Get other keyVals that have not yet been gotten + const otherKeyVals = keyValMap.unknownKeyVals + ? keyValMap.unknownKeyVals.filter(keyVal => { + return !keyHexSet.has(tools.toHex(keyVal.key)); + }) + : []; + return keyVals.concat(otherKeyVals).sort(sortKeyVals); +} +function psbtToKeyVals({ globalMap, inputs, outputs }) { + // First parse the global keyVals + // Get any extra keyvals to pass along + return { + globalKeyVals: keyValsFromMap(globalMap, convert.globals), + inputKeyVals: inputs.map(i => keyValsFromMap(i, convert.inputs)), + outputKeyVals: outputs.map(o => keyValsFromMap(o, convert.outputs)), + }; +} +exports.psbtToKeyVals = psbtToKeyVals; diff --git a/src/lib/psbt.d.ts b/src/cjs/lib/psbt.d.ts similarity index 59% rename from src/lib/psbt.d.ts rename to src/cjs/lib/psbt.d.ts index 184758c..48bd057 100644 --- a/src/lib/psbt.d.ts +++ b/src/cjs/lib/psbt.d.ts @@ -1,16 +1,15 @@ -/// -import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, Transaction, TransactionFromBuffer } from './interfaces'; +import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, Transaction, TransactionFromBuffer } from './interfaces.js'; export declare class Psbt { static fromBase64(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType; static fromHex(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType; - static fromBuffer(this: T, buffer: Buffer, txFromBuffer: TransactionFromBuffer): InstanceType; + static fromBuffer(this: T, buffer: Uint8Array, txFromBuffer: TransactionFromBuffer): InstanceType; readonly inputs: PsbtInput[]; readonly outputs: PsbtOutput[]; readonly globalMap: PsbtGlobal; constructor(tx: Transaction); toBase64(): string; toHex(): string; - toBuffer(): Buffer; + toBuffer(): Uint8Array; updateGlobal(updateData: PsbtGlobalUpdate): this; updateInput(inputIndex: number, updateData: PsbtInputUpdate): this; updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this; @@ -21,5 +20,7 @@ export declare class Psbt { addOutput(outputData: PsbtOutputExtended): this; clearFinalizedInput(inputIndex: number): this; combine(...those: this[]): this; - getTransaction(): Buffer; + getTransaction(): Uint8Array; } +export { Bip32Derivation, NonWitnessUtxo, ControlBlock, FinalScriptSig, FinalScriptWitness, GlobalXpub, KeyValue, PartialSig, PorCommitment, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, RedeemScript, SighashType, TapBip32Derivation, TapInternalKey, TapKeySig, TapLeaf, TapLeafScript, TapMerkleRoot, TapScriptSig, TapTree, Transaction, TransactionFromBuffer, TransactionIOCountGetter, TransactionLocktimeSetter, TransactionVersionSetter, WitnessScript, WitnessUtxo, } from './interfaces.js'; +export { checkForInput, checkForOutput } from './utils.js'; diff --git a/src/cjs/lib/psbt.js b/src/cjs/lib/psbt.js new file mode 100644 index 0000000..c41024a --- /dev/null +++ b/src/cjs/lib/psbt.js @@ -0,0 +1,163 @@ +'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; +Object.defineProperty(exports, '__esModule', { value: true }); +const index_js_1 = require('./combiner/index.js'); +const index_js_2 = require('./parser/index.js'); +const typeFields_js_1 = require('./typeFields.js'); +const utils_js_1 = require('./utils.js'); +const tools = __importStar(require('uint8array-tools')); +class Psbt { + constructor(tx) { + this.inputs = []; + this.outputs = []; + this.globalMap = { + unsignedTx: tx, + }; + } + static fromBase64(data, txFromBuffer) { + const buffer = tools.fromBase64(data); + return this.fromBuffer(buffer, txFromBuffer); + } + static fromHex(data, txFromBuffer) { + const buffer = tools.fromHex(data); + return this.fromBuffer(buffer, txFromBuffer); + } + static fromBuffer(buffer, txFromBuffer) { + const results = index_js_2.psbtFromBuffer(buffer, txFromBuffer); + const psbt = new this(results.globalMap.unsignedTx); + Object.assign(psbt, results); + return psbt; + } + toBase64() { + const buffer = this.toBuffer(); + return tools.toBase64(buffer); + } + toHex() { + const buffer = this.toBuffer(); + return tools.toHex(buffer); + } + toBuffer() { + return index_js_2.psbtToBuffer(this); + } + updateGlobal(updateData) { + utils_js_1.updateGlobal(updateData, this.globalMap); + return this; + } + updateInput(inputIndex, updateData) { + const input = utils_js_1.checkForInput(this.inputs, inputIndex); + utils_js_1.updateInput(updateData, input); + return this; + } + updateOutput(outputIndex, updateData) { + const output = utils_js_1.checkForOutput(this.outputs, outputIndex); + utils_js_1.updateOutput(updateData, output); + return this; + } + addUnknownKeyValToGlobal(keyVal) { + utils_js_1.checkHasKey( + keyVal, + this.globalMap.unknownKeyVals, + utils_js_1.getEnumLength(typeFields_js_1.GlobalTypes), + ); + if (!this.globalMap.unknownKeyVals) this.globalMap.unknownKeyVals = []; + this.globalMap.unknownKeyVals.push(keyVal); + return this; + } + addUnknownKeyValToInput(inputIndex, keyVal) { + const input = utils_js_1.checkForInput(this.inputs, inputIndex); + utils_js_1.checkHasKey( + keyVal, + input.unknownKeyVals, + utils_js_1.getEnumLength(typeFields_js_1.InputTypes), + ); + if (!input.unknownKeyVals) input.unknownKeyVals = []; + input.unknownKeyVals.push(keyVal); + return this; + } + addUnknownKeyValToOutput(outputIndex, keyVal) { + const output = utils_js_1.checkForOutput(this.outputs, outputIndex); + utils_js_1.checkHasKey( + keyVal, + output.unknownKeyVals, + utils_js_1.getEnumLength(typeFields_js_1.OutputTypes), + ); + if (!output.unknownKeyVals) output.unknownKeyVals = []; + output.unknownKeyVals.push(keyVal); + return this; + } + addInput(inputData) { + this.globalMap.unsignedTx.addInput(inputData); + this.inputs.push({ + unknownKeyVals: [], + }); + const addKeyVals = inputData.unknownKeyVals || []; + const inputIndex = this.inputs.length - 1; + if (!Array.isArray(addKeyVals)) { + throw new Error('unknownKeyVals must be an Array'); + } + addKeyVals.forEach(keyVal => + this.addUnknownKeyValToInput(inputIndex, keyVal), + ); + utils_js_1.addInputAttributes(this.inputs, inputData); + return this; + } + addOutput(outputData) { + this.globalMap.unsignedTx.addOutput(outputData); + this.outputs.push({ + unknownKeyVals: [], + }); + const addKeyVals = outputData.unknownKeyVals || []; + const outputIndex = this.outputs.length - 1; + if (!Array.isArray(addKeyVals)) { + throw new Error('unknownKeyVals must be an Array'); + } + addKeyVals.forEach(keyVal => + this.addUnknownKeyValToOutput(outputIndex, keyVal), + ); + utils_js_1.addOutputAttributes(this.outputs, outputData); + return this; + } + clearFinalizedInput(inputIndex) { + const input = utils_js_1.checkForInput(this.inputs, inputIndex); + utils_js_1.inputCheckUncleanFinalized(inputIndex, input); + for (const key of Object.keys(input)) { + if ( + ![ + 'witnessUtxo', + 'nonWitnessUtxo', + 'finalScriptSig', + 'finalScriptWitness', + 'unknownKeyVals', + ].includes(key) + ) { + // @ts-ignore + delete input[key]; + } + } + return this; + } + combine(...those) { + // Combine this with those. + // Return self for chaining. + const result = index_js_1.combine([this].concat(those)); + Object.assign(this, result); + return this; + } + getTransaction() { + return this.globalMap.unsignedTx.toBuffer(); + } +} +exports.Psbt = Psbt; +var utils_js_2 = require('./utils.js'); +exports.checkForInput = utils_js_2.checkForInput; +exports.checkForOutput = utils_js_2.checkForOutput; diff --git a/src/lib/typeFields.d.ts b/src/cjs/lib/typeFields.d.ts similarity index 100% rename from src/lib/typeFields.d.ts rename to src/cjs/lib/typeFields.d.ts diff --git a/src/lib/typeFields.js b/src/cjs/lib/typeFields.js similarity index 100% rename from src/lib/typeFields.js rename to src/cjs/lib/typeFields.js diff --git a/src/lib/utils.d.ts b/src/cjs/lib/utils.d.ts similarity index 88% rename from src/lib/utils.d.ts rename to src/cjs/lib/utils.d.ts index 3ba2cda..40f5e34 100644 --- a/src/lib/utils.d.ts +++ b/src/cjs/lib/utils.d.ts @@ -1,5 +1,4 @@ -/// -import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from './interfaces'; +import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from './interfaces.js'; export declare function checkForInput(inputs: PsbtInput[], inputIndex: number): PsbtInput; export declare function checkForOutput(outputs: PsbtOutput[], outputIndex: number): PsbtOutput; export declare function checkHasKey(checkKeyVal: KeyValue, keyVals: KeyValue[] | undefined, enumLength: number): void; @@ -10,5 +9,5 @@ export declare const updateInput: (updateData: PsbtInputUpdate, mainData: PsbtIn export declare const updateOutput: (updateData: PsbtOutputUpdate, mainData: PsbtOutput) => void; export declare function addInputAttributes(inputs: PsbtInput[], data: any): void; export declare function addOutputAttributes(outputs: PsbtOutput[], data: any): void; -export declare function defaultVersionSetter(version: number, txBuf: Buffer): Buffer; -export declare function defaultLocktimeSetter(locktime: number, txBuf: Buffer): Buffer; +export declare function defaultVersionSetter(version: number, txBuf: Uint8Array): Uint8Array; +export declare function defaultLocktimeSetter(locktime: number, txBuf: Uint8Array): Uint8Array; diff --git a/src/lib/utils.js b/src/cjs/lib/utils.js similarity index 83% rename from src/lib/utils.js rename to src/cjs/lib/utils.js index 1e58ae0..03c4ca1 100644 --- a/src/lib/utils.js +++ b/src/cjs/lib/utils.js @@ -1,6 +1,18 @@ 'use strict'; +var __importStar = + (this && this.__importStar) || + function(mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) + for (var k in mod) + if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result['default'] = mod; + return result; + }; Object.defineProperty(exports, '__esModule', { value: true }); -const converter = require('./converter'); +const converter = __importStar(require('./converter/index.js')); +const tools = __importStar(require('uint8array-tools')); function checkForInput(inputs, inputIndex) { const input = inputs[inputIndex]; if (input === undefined) throw new Error(`No input #${inputIndex}`); @@ -21,9 +33,10 @@ function checkHasKey(checkKeyVal, keyVals, enumLength) { } if ( keyVals && - keyVals.filter(kv => kv.key.equals(checkKeyVal.key)).length !== 0 + keyVals.filter(kv => tools.compare(kv.key, checkKeyVal.key) === 0) + .length !== 0 ) { - throw new Error(`Duplicate Key: ${checkKeyVal.key.toString('hex')}`); + throw new Error(`Duplicate Key: ${tools.toHex(checkKeyVal.key)}`); } } exports.checkHasKey = checkHasKey; @@ -62,6 +75,7 @@ function throwForUpdateMaker(typeName, name, expected, data) { } function updateMaker(typeName) { return (updateData, mainData) => { + // @ts-ignore for (const name of Object.keys(updateData)) { // @ts-ignore const data = updateData[name]; @@ -121,18 +135,18 @@ function addOutputAttributes(outputs, data) { } exports.addOutputAttributes = addOutputAttributes; function defaultVersionSetter(version, txBuf) { - if (!Buffer.isBuffer(txBuf) || txBuf.length < 4) { + if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) { throw new Error('Set Version: Invalid Transaction'); } - txBuf.writeUInt32LE(version, 0); + tools.writeUInt32(txBuf, 0, version, 'LE'); return txBuf; } exports.defaultVersionSetter = defaultVersionSetter; function defaultLocktimeSetter(locktime, txBuf) { - if (!Buffer.isBuffer(txBuf) || txBuf.length < 4) { + if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) { throw new Error('Set Locktime: Invalid Transaction'); } - txBuf.writeUInt32LE(locktime, txBuf.length - 4); + tools.writeUInt32(txBuf, txBuf.length - 4, locktime, 'LE'); return txBuf; } exports.defaultLocktimeSetter = defaultLocktimeSetter; diff --git a/src/esm/lib/combiner/index.d.ts b/src/esm/lib/combiner/index.d.ts new file mode 100644 index 0000000..f4ebd8c --- /dev/null +++ b/src/esm/lib/combiner/index.d.ts @@ -0,0 +1,2 @@ +import { PsbtAttributes } from '../parser/index.js'; +export declare function combine(psbts: PsbtAttributes[]): PsbtAttributes; diff --git a/src/lib/combiner/index.js b/src/esm/lib/combiner/index.js similarity index 80% rename from src/lib/combiner/index.js rename to src/esm/lib/combiner/index.js index 6206421..bb4e01b 100644 --- a/src/lib/combiner/index.js +++ b/src/esm/lib/combiner/index.js @@ -1,9 +1,8 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const parser_1 = require('../parser'); -function combine(psbts) { +import { psbtFromKeyVals, psbtToKeyVals } from '../parser/index.js'; +import * as tools from 'uint8array-tools'; +export function combine(psbts) { const self = psbts[0]; - const selfKeyVals = parser_1.psbtToKeyVals(self); + const selfKeyVals = psbtToKeyVals(self); const others = psbts.slice(1); if (others.length === 0) throw new Error('Combine: Nothing to combine'); const selfTx = getTx(self); @@ -17,13 +16,13 @@ function combine(psbts) { const otherTx = getTx(other); if ( otherTx === undefined || - !otherTx.toBuffer().equals(selfTx.toBuffer()) + tools.compare(otherTx.toBuffer(), selfTx.toBuffer()) !== 0 ) { throw new Error( 'Combine: One of the Psbts does not have the same transaction.', ); } - const otherKeyVals = parser_1.psbtToKeyVals(other); + const otherKeyVals = psbtToKeyVals(other); const otherGlobalSet = getKeySet(otherKeyVals.globalKeyVals); otherGlobalSet.forEach( keyPusher( @@ -53,17 +52,16 @@ function combine(psbts) { ), ); } - return parser_1.psbtFromKeyVals(selfTx, { + return psbtFromKeyVals(selfTx, { globalMapKeyVals: selfKeyVals.globalKeyVals, inputKeyVals: selfKeyVals.inputKeyVals, outputKeyVals: selfKeyVals.outputKeyVals, }); } -exports.combine = combine; function keyPusher(selfSet, selfKeyVals, otherKeyVals) { return key => { if (selfSet.has(key)) return; - const newKv = otherKeyVals.filter(kv => kv.key.toString('hex') === key)[0]; + const newKv = otherKeyVals.filter(kv => tools.toHex(kv.key) === key)[0]; selfKeyVals.push(newKv); selfSet.add(key); }; @@ -74,7 +72,7 @@ function getTx(psbt) { function getKeySet(keyVals) { const set = new Set(); keyVals.forEach(keyVal => { - const hex = keyVal.key.toString('hex'); + const hex = tools.toHex(keyVal.key); if (set.has(hex)) throw new Error('Combine: KeyValue Map keys should be unique'); set.add(hex); diff --git a/src/esm/lib/converter/global/globalXpub.d.ts b/src/esm/lib/converter/global/globalXpub.d.ts new file mode 100644 index 0000000..a3b0d11 --- /dev/null +++ b/src/esm/lib/converter/global/globalXpub.d.ts @@ -0,0 +1,6 @@ +import { GlobalXpub, KeyValue } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): GlobalXpub; +export declare function encode(data: GlobalXpub): KeyValue; +export declare const expected = "{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }"; +export declare function check(data: any): data is GlobalXpub; +export declare function canAddToArray(array: GlobalXpub[], item: GlobalXpub, dupeSet: Set): boolean; diff --git a/src/esm/lib/converter/global/globalXpub.js b/src/esm/lib/converter/global/globalXpub.js new file mode 100644 index 0000000..b9596f7 --- /dev/null +++ b/src/esm/lib/converter/global/globalXpub.js @@ -0,0 +1,79 @@ +import { GlobalTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +const range = n => [...Array(n).keys()]; +export function decode(keyVal) { + if (keyVal.key[0] !== GlobalTypes.GLOBAL_XPUB) { + throw new Error( + 'Decode Error: could not decode globalXpub with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (keyVal.key.length !== 79 || ![2, 3].includes(keyVal.key[46])) { + throw new Error( + 'Decode Error: globalXpub has invalid extended pubkey in key 0x' + + tools.toHex(keyVal.key), + ); + } + if ((keyVal.value.length / 4) % 1 !== 0) { + throw new Error( + 'Decode Error: Global GLOBAL_XPUB value length should be multiple of 4', + ); + } + const extendedPubkey = keyVal.key.slice(1); + const data = { + masterFingerprint: keyVal.value.slice(0, 4), + extendedPubkey, + path: 'm', + }; + for (const i of range(keyVal.value.length / 4 - 1)) { + const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE'); + const isHard = !!(val & 0x80000000); + const idx = val & 0x7fffffff; + data.path += '/' + idx.toString(10) + (isHard ? "'" : ''); + } + return data; +} +export function encode(data) { + const head = new Uint8Array([GlobalTypes.GLOBAL_XPUB]); + const key = tools.concat([head, data.extendedPubkey]); + const splitPath = data.path.split('/'); + const value = new Uint8Array(splitPath.length * 4); + value.set(data.masterFingerprint, 0); + let offset = 4; + splitPath.slice(1).forEach(level => { + const isHard = level.slice(-1) === "'"; + let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10); + if (isHard) num += 0x80000000; + tools.writeUInt32(value, offset, num, 'LE'); + offset += 4; + }); + return { + key, + value, + }; +} +export const expected = + '{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }'; +export function check(data) { + const epk = data.extendedPubkey; + const mfp = data.masterFingerprint; + const p = data.path; + return ( + epk instanceof Uint8Array && + epk.length === 78 && + [2, 3].indexOf(epk[45]) > -1 && + mfp instanceof Uint8Array && + mfp.length === 4 && + typeof p === 'string' && + !!p.match(/^m(\/\d+'?)*$/) + ); +} +export function canAddToArray(array, item, dupeSet) { + const dupeString = tools.toHex(item.extendedPubkey); + if (dupeSet.has(dupeString)) return false; + dupeSet.add(dupeString); + return ( + array.filter(v => tools.compare(v.extendedPubkey, item.extendedPubkey)) + .length === 0 + ); +} diff --git a/src/esm/lib/converter/global/unsignedTx.d.ts b/src/esm/lib/converter/global/unsignedTx.d.ts new file mode 100644 index 0000000..ddcdce4 --- /dev/null +++ b/src/esm/lib/converter/global/unsignedTx.d.ts @@ -0,0 +1,2 @@ +import { KeyValue, Transaction } from '../../interfaces'; +export declare function encode(data: Transaction): KeyValue; diff --git a/src/esm/lib/converter/global/unsignedTx.js b/src/esm/lib/converter/global/unsignedTx.js new file mode 100644 index 0000000..fc5038a --- /dev/null +++ b/src/esm/lib/converter/global/unsignedTx.js @@ -0,0 +1,7 @@ +import { GlobalTypes } from '../../typeFields.js'; +export function encode(data) { + return { + key: new Uint8Array([GlobalTypes.UNSIGNED_TX]), + value: data.toBuffer(), + }; +} diff --git a/src/esm/lib/converter/index.d.ts b/src/esm/lib/converter/index.d.ts new file mode 100644 index 0000000..f152688 --- /dev/null +++ b/src/esm/lib/converter/index.d.ts @@ -0,0 +1,108 @@ +import * as globalXpub from './global/globalXpub.js'; +import * as unsignedTx from './global/unsignedTx.js'; +import * as finalScriptSig from './input/finalScriptSig.js'; +import * as finalScriptWitness from './input/finalScriptWitness.js'; +import * as nonWitnessUtxo from './input/nonWitnessUtxo.js'; +import * as partialSig from './input/partialSig.js'; +import * as porCommitment from './input/porCommitment.js'; +import * as sighashType from './input/sighashType.js'; +import * as tapKeySig from './input/tapKeySig.js'; +import * as tapLeafScript from './input/tapLeafScript.js'; +import * as tapMerkleRoot from './input/tapMerkleRoot.js'; +import * as tapScriptSig from './input/tapScriptSig.js'; +import * as witnessUtxo from './input/witnessUtxo.js'; +import * as tapTree from './output/tapTree.js'; +declare const globals: { + unsignedTx: typeof unsignedTx; + globalXpub: typeof globalXpub; + checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined; +}; +declare const inputs: { + nonWitnessUtxo: typeof nonWitnessUtxo; + partialSig: typeof partialSig; + sighashType: typeof sighashType; + finalScriptSig: typeof finalScriptSig; + finalScriptWitness: typeof finalScriptWitness; + porCommitment: typeof porCommitment; + witnessUtxo: typeof witnessUtxo; + bip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").Bip32Derivation; + encode: (data: import("../interfaces.js").Bip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").Bip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").Bip32Derivation[], item: import("../interfaces.js").Bip32Derivation, dupeSet: Set) => boolean; + }; + redeemScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + witnessScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined; + tapKeySig: typeof tapKeySig; + tapScriptSig: typeof tapScriptSig; + tapLeafScript: typeof tapLeafScript; + tapBip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").TapBip32Derivation; + encode: (data: import("../interfaces.js").TapBip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").TapBip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").TapBip32Derivation[], item: import("../interfaces.js").TapBip32Derivation, dupeSet: Set) => boolean; + }; + tapInternalKey: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + tapMerkleRoot: typeof tapMerkleRoot; +}; +declare const outputs: { + bip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").Bip32Derivation; + encode: (data: import("../interfaces.js").Bip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").Bip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").Bip32Derivation[], item: import("../interfaces.js").Bip32Derivation, dupeSet: Set) => boolean; + }; + redeemScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + witnessScript: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; + checkPubkey: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array | undefined; + tapBip32Derivation: { + decode: (keyVal: import("../interfaces.js").KeyValue) => import("../interfaces.js").TapBip32Derivation; + encode: (data: import("../interfaces.js").TapBip32Derivation) => import("../interfaces.js").KeyValue; + check: (data: any) => data is import("../interfaces.js").TapBip32Derivation; + expected: string; + canAddToArray: (array: import("../interfaces.js").TapBip32Derivation[], item: import("../interfaces.js").TapBip32Derivation, dupeSet: Set) => boolean; + }; + tapTree: typeof tapTree; + tapInternalKey: { + decode: (keyVal: import("../interfaces.js").KeyValue) => Uint8Array; + encode: (data: Uint8Array) => import("../interfaces.js").KeyValue; + check: (data: any) => data is Uint8Array; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; + }; +}; +export { globals, inputs, outputs }; diff --git a/src/esm/lib/converter/index.js b/src/esm/lib/converter/index.js new file mode 100644 index 0000000..a6e0dd5 --- /dev/null +++ b/src/esm/lib/converter/index.js @@ -0,0 +1,63 @@ +import { InputTypes, OutputTypes } from '../typeFields.js'; +import * as globalXpub from './global/globalXpub.js'; +import * as unsignedTx from './global/unsignedTx.js'; +import * as finalScriptSig from './input/finalScriptSig.js'; +import * as finalScriptWitness from './input/finalScriptWitness.js'; +import * as nonWitnessUtxo from './input/nonWitnessUtxo.js'; +import * as partialSig from './input/partialSig.js'; +import * as porCommitment from './input/porCommitment.js'; +import * as sighashType from './input/sighashType.js'; +import * as tapKeySig from './input/tapKeySig.js'; +import * as tapLeafScript from './input/tapLeafScript.js'; +import * as tapMerkleRoot from './input/tapMerkleRoot.js'; +import * as tapScriptSig from './input/tapScriptSig.js'; +import * as witnessUtxo from './input/witnessUtxo.js'; +import * as tapTree from './output/tapTree.js'; +import * as bip32Derivation from './shared/bip32Derivation.js'; +import * as checkPubkey from './shared/checkPubkey.js'; +import * as redeemScript from './shared/redeemScript.js'; +import * as tapBip32Derivation from './shared/tapBip32Derivation.js'; +import * as tapInternalKey from './shared/tapInternalKey.js'; +import * as witnessScript from './shared/witnessScript.js'; +const globals = { + unsignedTx, + globalXpub, + // pass an Array of key bytes that require pubkey beside the key + checkPubkey: checkPubkey.makeChecker([]), +}; +const inputs = { + nonWitnessUtxo, + partialSig, + sighashType, + finalScriptSig, + finalScriptWitness, + porCommitment, + witnessUtxo, + bip32Derivation: bip32Derivation.makeConverter(InputTypes.BIP32_DERIVATION), + redeemScript: redeemScript.makeConverter(InputTypes.REDEEM_SCRIPT), + witnessScript: witnessScript.makeConverter(InputTypes.WITNESS_SCRIPT), + checkPubkey: checkPubkey.makeChecker([ + InputTypes.PARTIAL_SIG, + InputTypes.BIP32_DERIVATION, + ]), + tapKeySig, + tapScriptSig, + tapLeafScript, + tapBip32Derivation: tapBip32Derivation.makeConverter( + InputTypes.TAP_BIP32_DERIVATION, + ), + tapInternalKey: tapInternalKey.makeConverter(InputTypes.TAP_INTERNAL_KEY), + tapMerkleRoot, +}; +const outputs = { + bip32Derivation: bip32Derivation.makeConverter(OutputTypes.BIP32_DERIVATION), + redeemScript: redeemScript.makeConverter(OutputTypes.REDEEM_SCRIPT), + witnessScript: witnessScript.makeConverter(OutputTypes.WITNESS_SCRIPT), + checkPubkey: checkPubkey.makeChecker([OutputTypes.BIP32_DERIVATION]), + tapBip32Derivation: tapBip32Derivation.makeConverter( + OutputTypes.TAP_BIP32_DERIVATION, + ), + tapTree, + tapInternalKey: tapInternalKey.makeConverter(OutputTypes.TAP_INTERNAL_KEY), +}; +export { globals, inputs, outputs }; diff --git a/src/esm/lib/converter/input/finalScriptSig.d.ts b/src/esm/lib/converter/input/finalScriptSig.d.ts new file mode 100644 index 0000000..f08bc72 --- /dev/null +++ b/src/esm/lib/converter/input/finalScriptSig.d.ts @@ -0,0 +1,6 @@ +import { FinalScriptSig, KeyValue } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): FinalScriptSig; +export declare function encode(data: FinalScriptSig): KeyValue; +export declare const expected = "Uint8Array"; +export declare function check(data: any): data is FinalScriptSig; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/finalScriptSig.js b/src/esm/lib/converter/input/finalScriptSig.js new file mode 100644 index 0000000..1a95767 --- /dev/null +++ b/src/esm/lib/converter/input/finalScriptSig.js @@ -0,0 +1,25 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.FINAL_SCRIPTSIG) { + throw new Error( + 'Decode Error: could not decode finalScriptSig with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; +} +export function encode(data) { + const key = new Uint8Array([InputTypes.FINAL_SCRIPTSIG]); + return { + key, + value: data, + }; +} +export const expected = 'Uint8Array'; +export function check(data) { + return data instanceof Uint8Array; +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.finalScriptSig === undefined; +} diff --git a/src/esm/lib/converter/input/finalScriptWitness.d.ts b/src/esm/lib/converter/input/finalScriptWitness.d.ts new file mode 100644 index 0000000..aa64099 --- /dev/null +++ b/src/esm/lib/converter/input/finalScriptWitness.d.ts @@ -0,0 +1,6 @@ +import { FinalScriptWitness, KeyValue } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): FinalScriptWitness; +export declare function encode(data: FinalScriptWitness): KeyValue; +export declare const expected = "Uint8Array"; +export declare function check(data: any): data is FinalScriptWitness; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/finalScriptWitness.js b/src/esm/lib/converter/input/finalScriptWitness.js new file mode 100644 index 0000000..83851c1 --- /dev/null +++ b/src/esm/lib/converter/input/finalScriptWitness.js @@ -0,0 +1,27 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.FINAL_SCRIPTWITNESS) { + throw new Error( + 'Decode Error: could not decode finalScriptWitness with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; +} +export function encode(data) { + const key = new Uint8Array([InputTypes.FINAL_SCRIPTWITNESS]); + return { + key, + value: data, + }; +} +export const expected = 'Uint8Array'; +export function check(data) { + return data instanceof Uint8Array; +} +export function canAdd(currentData, newData) { + return ( + !!currentData && !!newData && currentData.finalScriptWitness === undefined + ); +} diff --git a/src/esm/lib/converter/input/nonWitnessUtxo.d.ts b/src/esm/lib/converter/input/nonWitnessUtxo.d.ts new file mode 100644 index 0000000..498a9ba --- /dev/null +++ b/src/esm/lib/converter/input/nonWitnessUtxo.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, NonWitnessUtxo } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): NonWitnessUtxo; +export declare function encode(data: NonWitnessUtxo): KeyValue; +export declare const expected = "Uint8Array"; +export declare function check(data: any): data is NonWitnessUtxo; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/nonWitnessUtxo.js b/src/esm/lib/converter/input/nonWitnessUtxo.js new file mode 100644 index 0000000..0a296a4 --- /dev/null +++ b/src/esm/lib/converter/input/nonWitnessUtxo.js @@ -0,0 +1,24 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.NON_WITNESS_UTXO) { + throw new Error( + 'Decode Error: could not decode nonWitnessUtxo with key 0x' + + tools.toHex(keyVal.key), + ); + } + return keyVal.value; +} +export function encode(data) { + return { + key: new Uint8Array([InputTypes.NON_WITNESS_UTXO]), + value: data, + }; +} +export const expected = 'Uint8Array'; +export function check(data) { + return data instanceof Uint8Array; +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.nonWitnessUtxo === undefined; +} diff --git a/src/esm/lib/converter/input/partialSig.d.ts b/src/esm/lib/converter/input/partialSig.d.ts new file mode 100644 index 0000000..b7fd8c5 --- /dev/null +++ b/src/esm/lib/converter/input/partialSig.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, PartialSig } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): PartialSig; +export declare function encode(pSig: PartialSig): KeyValue; +export declare const expected = "{ pubkey: Uint8Array; signature: Uint8Array; }"; +export declare function check(data: any): data is PartialSig; +export declare function canAddToArray(array: PartialSig[], item: PartialSig, dupeSet: Set): boolean; diff --git a/src/esm/lib/converter/input/partialSig.js b/src/esm/lib/converter/input/partialSig.js new file mode 100644 index 0000000..29b5d19 --- /dev/null +++ b/src/esm/lib/converter/input/partialSig.js @@ -0,0 +1,62 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.PARTIAL_SIG) { + throw new Error( + 'Decode Error: could not decode partialSig with key 0x' + + tools.toHex(keyVal.key), + ); + } + if ( + !(keyVal.key.length === 34 || keyVal.key.length === 66) || + ![2, 3, 4].includes(keyVal.key[1]) + ) { + throw new Error( + 'Decode Error: partialSig has invalid pubkey in key 0x' + + tools.toHex(keyVal.key), + ); + } + const pubkey = keyVal.key.slice(1); + return { + pubkey, + signature: keyVal.value, + }; +} +export function encode(pSig) { + const head = new Uint8Array([InputTypes.PARTIAL_SIG]); + return { + key: tools.concat([head, pSig.pubkey]), + value: pSig.signature, + }; +} +export const expected = '{ pubkey: Uint8Array; signature: Uint8Array; }'; +export function check(data) { + return ( + data.pubkey instanceof Uint8Array && + data.signature instanceof Uint8Array && + [33, 65].includes(data.pubkey.length) && + [2, 3, 4].includes(data.pubkey[0]) && + isDerSigWithSighash(data.signature) + ); +} +function isDerSigWithSighash(buf) { + if (!(buf instanceof Uint8Array) || buf.length < 9) return false; + if (buf[0] !== 0x30) return false; + if (buf.length !== buf[1] + 3) return false; + if (buf[2] !== 0x02) return false; + const rLen = buf[3]; + if (rLen > 33 || rLen < 1) return false; + if (buf[3 + rLen + 1] !== 0x02) return false; + const sLen = buf[3 + rLen + 2]; + if (sLen > 33 || sLen < 1) return false; + if (buf.length !== 3 + rLen + 2 + sLen + 2) return false; + return true; +} +export function canAddToArray(array, item, dupeSet) { + const dupeString = tools.toHex(item.pubkey); + if (dupeSet.has(dupeString)) return false; + dupeSet.add(dupeString); + return ( + array.filter(v => tools.compare(v.pubkey, item.pubkey) === 0).length === 0 + ); +} diff --git a/src/esm/lib/converter/input/porCommitment.d.ts b/src/esm/lib/converter/input/porCommitment.d.ts new file mode 100644 index 0000000..1f45bb3 --- /dev/null +++ b/src/esm/lib/converter/input/porCommitment.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, PorCommitment } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): PorCommitment; +export declare function encode(data: PorCommitment): KeyValue; +export declare const expected = "string"; +export declare function check(data: any): data is PorCommitment; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/porCommitment.js b/src/esm/lib/converter/input/porCommitment.js new file mode 100644 index 0000000..71935ca --- /dev/null +++ b/src/esm/lib/converter/input/porCommitment.js @@ -0,0 +1,25 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.POR_COMMITMENT) { + throw new Error( + 'Decode Error: could not decode porCommitment with key 0x' + + tools.toHex(keyVal.key), + ); + } + return tools.toUtf8(keyVal.value); +} +export function encode(data) { + const key = new Uint8Array([InputTypes.POR_COMMITMENT]); + return { + key, + value: tools.fromUtf8(data), + }; +} +export const expected = 'string'; +export function check(data) { + return typeof data === 'string'; +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.porCommitment === undefined; +} diff --git a/src/esm/lib/converter/input/sighashType.d.ts b/src/esm/lib/converter/input/sighashType.d.ts new file mode 100644 index 0000000..a86e990 --- /dev/null +++ b/src/esm/lib/converter/input/sighashType.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, SighashType } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): SighashType; +export declare function encode(data: SighashType): KeyValue; +export declare const expected = "number"; +export declare function check(data: any): data is SighashType; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/sighashType.js b/src/esm/lib/converter/input/sighashType.js new file mode 100644 index 0000000..f67434e --- /dev/null +++ b/src/esm/lib/converter/input/sighashType.js @@ -0,0 +1,27 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.SIGHASH_TYPE) { + throw new Error( + 'Decode Error: could not decode sighashType with key 0x' + + tools.toHex(keyVal.key), + ); + } + return Number(tools.readUInt32(keyVal.value, 0, 'LE')); +} +export function encode(data) { + const key = Uint8Array.from([InputTypes.SIGHASH_TYPE]); + const value = new Uint8Array(4); + tools.writeUInt32(value, 0, data, 'LE'); + return { + key, + value, + }; +} +export const expected = 'number'; +export function check(data) { + return typeof data === 'number'; +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.sighashType === undefined; +} diff --git a/src/esm/lib/converter/input/tapKeySig.d.ts b/src/esm/lib/converter/input/tapKeySig.d.ts new file mode 100644 index 0000000..07b357b --- /dev/null +++ b/src/esm/lib/converter/input/tapKeySig.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, TapKeySig } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): TapKeySig; +export declare function encode(value: TapKeySig): KeyValue; +export declare const expected = "Uint8Array"; +export declare function check(data: any): data is TapKeySig; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/tapKeySig.js b/src/esm/lib/converter/input/tapKeySig.js new file mode 100644 index 0000000..5b6686d --- /dev/null +++ b/src/esm/lib/converter/input/tapKeySig.js @@ -0,0 +1,29 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.TAP_KEY_SIG || keyVal.key.length !== 1) { + throw new Error( + 'Decode Error: could not decode tapKeySig with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (!check(keyVal.value)) { + throw new Error( + 'Decode Error: tapKeySig not a valid 64-65-byte BIP340 signature', + ); + } + return keyVal.value; +} +export function encode(value) { + const key = Uint8Array.from([InputTypes.TAP_KEY_SIG]); + return { key, value }; +} +export const expected = 'Uint8Array'; +export function check(data) { + return ( + data instanceof Uint8Array && (data.length === 64 || data.length === 65) + ); +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.tapKeySig === undefined; +} diff --git a/src/esm/lib/converter/input/tapLeafScript.d.ts b/src/esm/lib/converter/input/tapLeafScript.d.ts new file mode 100644 index 0000000..f0ac9da --- /dev/null +++ b/src/esm/lib/converter/input/tapLeafScript.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, TapLeafScript } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): TapLeafScript; +export declare function encode(tScript: TapLeafScript): KeyValue; +export declare const expected = "{ controlBlock: Uint8Array; leafVersion: number, script: Uint8Array; }"; +export declare function check(data: any): data is TapLeafScript; +export declare function canAddToArray(array: TapLeafScript[], item: TapLeafScript, dupeSet: Set): boolean; diff --git a/src/esm/lib/converter/input/tapLeafScript.js b/src/esm/lib/converter/input/tapLeafScript.js new file mode 100644 index 0000000..79bb32e --- /dev/null +++ b/src/esm/lib/converter/input/tapLeafScript.js @@ -0,0 +1,53 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.TAP_LEAF_SCRIPT) { + throw new Error( + 'Decode Error: could not decode tapLeafScript with key 0x' + + tools.toHex(keyVal.key), + ); + } + if ((keyVal.key.length - 2) % 32 !== 0) { + throw new Error( + 'Decode Error: tapLeafScript has invalid control block in key 0x' + + tools.toHex(keyVal.key), + ); + } + const leafVersion = keyVal.value[keyVal.value.length - 1]; + if ((keyVal.key[1] & 0xfe) !== leafVersion) { + throw new Error( + 'Decode Error: tapLeafScript bad leaf version in key 0x' + + tools.toHex(keyVal.key), + ); + } + const script = keyVal.value.slice(0, -1); + const controlBlock = keyVal.key.slice(1); + return { controlBlock, script, leafVersion }; +} +export function encode(tScript) { + const head = Uint8Array.from([InputTypes.TAP_LEAF_SCRIPT]); + const verBuf = Uint8Array.from([tScript.leafVersion]); + return { + key: tools.concat([head, tScript.controlBlock]), + value: tools.concat([tScript.script, verBuf]), + }; +} +export const expected = + '{ controlBlock: Uint8Array; leafVersion: number, script: Uint8Array; }'; +export function check(data) { + return ( + data.controlBlock instanceof Uint8Array && + (data.controlBlock.length - 1) % 32 === 0 && + (data.controlBlock[0] & 0xfe) === data.leafVersion && + data.script instanceof Uint8Array + ); +} +export function canAddToArray(array, item, dupeSet) { + const dupeString = tools.toHex(item.controlBlock); + if (dupeSet.has(dupeString)) return false; + dupeSet.add(dupeString); + return ( + array.filter(v => tools.compare(v.controlBlock, item.controlBlock) === 0) + .length === 0 + ); +} diff --git a/src/esm/lib/converter/input/tapMerkleRoot.d.ts b/src/esm/lib/converter/input/tapMerkleRoot.d.ts new file mode 100644 index 0000000..1e222dc --- /dev/null +++ b/src/esm/lib/converter/input/tapMerkleRoot.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, TapMerkleRoot } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): TapMerkleRoot; +export declare function encode(value: TapMerkleRoot): KeyValue; +export declare const expected = "Uint8Array"; +export declare function check(data: any): data is TapMerkleRoot; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/tapMerkleRoot.js b/src/esm/lib/converter/input/tapMerkleRoot.js new file mode 100644 index 0000000..d69a655 --- /dev/null +++ b/src/esm/lib/converter/input/tapMerkleRoot.js @@ -0,0 +1,25 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.TAP_MERKLE_ROOT || keyVal.key.length !== 1) { + throw new Error( + 'Decode Error: could not decode tapMerkleRoot with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (!check(keyVal.value)) { + throw new Error('Decode Error: tapMerkleRoot not a 32-byte hash'); + } + return keyVal.value; +} +export function encode(value) { + const key = Uint8Array.from([InputTypes.TAP_MERKLE_ROOT]); + return { key, value }; +} +export const expected = 'Uint8Array'; +export function check(data) { + return data instanceof Uint8Array && data.length === 32; +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.tapMerkleRoot === undefined; +} diff --git a/src/esm/lib/converter/input/tapScriptSig.d.ts b/src/esm/lib/converter/input/tapScriptSig.d.ts new file mode 100644 index 0000000..6172daa --- /dev/null +++ b/src/esm/lib/converter/input/tapScriptSig.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, TapScriptSig } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): TapScriptSig; +export declare function encode(tSig: TapScriptSig): KeyValue; +export declare const expected = "{ pubkey: Uint8Array; leafHash: Uint8Array; signature: Uint8Array; }"; +export declare function check(data: any): data is TapScriptSig; +export declare function canAddToArray(array: TapScriptSig[], item: TapScriptSig, dupeSet: Set): boolean; diff --git a/src/esm/lib/converter/input/tapScriptSig.js b/src/esm/lib/converter/input/tapScriptSig.js new file mode 100644 index 0000000..03f1307 --- /dev/null +++ b/src/esm/lib/converter/input/tapScriptSig.js @@ -0,0 +1,59 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.TAP_SCRIPT_SIG) { + throw new Error( + 'Decode Error: could not decode tapScriptSig with key 0x' + + tools.toHex(keyVal.key), + ); + } + if (keyVal.key.length !== 65) { + throw new Error( + 'Decode Error: tapScriptSig has invalid key 0x' + tools.toHex(keyVal.key), + ); + } + if (keyVal.value.length !== 64 && keyVal.value.length !== 65) { + throw new Error( + 'Decode Error: tapScriptSig has invalid signature in key 0x' + + tools.toHex(keyVal.key), + ); + } + const pubkey = keyVal.key.slice(1, 33); + const leafHash = keyVal.key.slice(33); + return { + pubkey, + leafHash, + signature: keyVal.value, + }; +} +export function encode(tSig) { + const head = Uint8Array.from([InputTypes.TAP_SCRIPT_SIG]); + return { + key: tools.concat([head, tSig.pubkey, tSig.leafHash]), + value: tSig.signature, + }; +} +export const expected = + '{ pubkey: Uint8Array; leafHash: Uint8Array; signature: Uint8Array; }'; +export function check(data) { + return ( + data.pubkey instanceof Uint8Array && + data.leafHash instanceof Uint8Array && + data.signature instanceof Uint8Array && + data.pubkey.length === 32 && + data.leafHash.length === 32 && + (data.signature.length === 64 || data.signature.length === 65) + ); +} +export function canAddToArray(array, item, dupeSet) { + const dupeString = tools.toHex(item.pubkey) + tools.toHex(item.leafHash); + if (dupeSet.has(dupeString)) return false; + dupeSet.add(dupeString); + return ( + array.filter( + v => + tools.compare(v.pubkey, item.pubkey) === 0 && + tools.compare(v.leafHash, item.leafHash) === 0, + ).length === 0 + ); +} diff --git a/src/esm/lib/converter/input/witnessUtxo.d.ts b/src/esm/lib/converter/input/witnessUtxo.d.ts new file mode 100644 index 0000000..f670563 --- /dev/null +++ b/src/esm/lib/converter/input/witnessUtxo.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, WitnessUtxo } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): WitnessUtxo; +export declare function encode(data: WitnessUtxo): KeyValue; +export declare const expected = "{ script: Uint8Array; value: bigint; }"; +export declare function check(data: any): data is WitnessUtxo; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/input/witnessUtxo.js b/src/esm/lib/converter/input/witnessUtxo.js new file mode 100644 index 0000000..75f6177 --- /dev/null +++ b/src/esm/lib/converter/input/witnessUtxo.js @@ -0,0 +1,45 @@ +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +import * as varuint from 'varuint-bitcoin'; +export function decode(keyVal) { + if (keyVal.key[0] !== InputTypes.WITNESS_UTXO) { + throw new Error( + 'Decode Error: could not decode witnessUtxo with key 0x' + + tools.toHex(keyVal.key), + ); + } + const value = tools.readInt64(keyVal.value, 0, 'LE'); + let _offset = 8; + const { numberValue: scriptLen, bytes } = varuint.decode( + keyVal.value, + _offset, + ); + _offset += bytes; + const script = keyVal.value.slice(_offset); + if (script.length !== scriptLen) { + throw new Error('Decode Error: WITNESS_UTXO script is not proper length'); + } + return { + script, + value, + }; +} +export function encode(data) { + const { script, value } = data; + const varuintlen = varuint.encodingLength(script.length); + const result = new Uint8Array(8 + varuintlen + script.length); + tools.writeInt64(result, 0, BigInt(value), 'LE'); + varuint.encode(script.length, result, 8); + result.set(script, 8 + varuintlen); + return { + key: Uint8Array.from([InputTypes.WITNESS_UTXO]), + value: result, + }; +} +export const expected = '{ script: Uint8Array; value: bigint; }'; +export function check(data) { + return data.script instanceof Uint8Array && typeof data.value === 'bigint'; +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.witnessUtxo === undefined; +} diff --git a/src/esm/lib/converter/output/tapTree.d.ts b/src/esm/lib/converter/output/tapTree.d.ts new file mode 100644 index 0000000..f976363 --- /dev/null +++ b/src/esm/lib/converter/output/tapTree.d.ts @@ -0,0 +1,6 @@ +import { KeyValue, TapTree } from '../../interfaces'; +export declare function decode(keyVal: KeyValue): TapTree; +export declare function encode(tree: TapTree): KeyValue; +export declare const expected = "{ leaves: [{ depth: number; leafVersion: number, script: Uint8Array; }] }"; +export declare function check(data: any): data is TapTree; +export declare function canAdd(currentData: any, newData: any): boolean; diff --git a/src/esm/lib/converter/output/tapTree.js b/src/esm/lib/converter/output/tapTree.js new file mode 100644 index 0000000..afb4bfb --- /dev/null +++ b/src/esm/lib/converter/output/tapTree.js @@ -0,0 +1,60 @@ +import { OutputTypes } from '../../typeFields.js'; +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; +export function decode(keyVal) { + if (keyVal.key[0] !== OutputTypes.TAP_TREE || keyVal.key.length !== 1) { + throw new Error( + 'Decode Error: could not decode tapTree with key 0x' + + tools.toHex(keyVal.key), + ); + } + let _offset = 0; + const data = []; + while (_offset < keyVal.value.length) { + const depth = keyVal.value[_offset++]; + const leafVersion = keyVal.value[_offset++]; + const { numberValue: scriptLen, bytes } = varuint.decode( + keyVal.value, + _offset, + ); + _offset += bytes; + data.push({ + depth, + leafVersion, + script: keyVal.value.slice(_offset, _offset + scriptLen), + }); + _offset += scriptLen; + } + return { leaves: data }; +} +export function encode(tree) { + const key = Uint8Array.from([OutputTypes.TAP_TREE]); + const bufs = [].concat( + ...tree.leaves.map(tapLeaf => [ + Uint8Array.of(tapLeaf.depth, tapLeaf.leafVersion), + varuint.encode(BigInt(tapLeaf.script.length)).buffer, + tapLeaf.script, + ]), + ); + return { + key, + value: tools.concat(bufs), + }; +} +export const expected = + '{ leaves: [{ depth: number; leafVersion: number, script: Uint8Array; }] }'; +export function check(data) { + return ( + Array.isArray(data.leaves) && + data.leaves.every( + tapLeaf => + tapLeaf.depth >= 0 && + tapLeaf.depth <= 128 && + (tapLeaf.leafVersion & 0xfe) === tapLeaf.leafVersion && + tapLeaf.script instanceof Uint8Array, + ) + ); +} +export function canAdd(currentData, newData) { + return !!currentData && !!newData && currentData.tapTree === undefined; +} diff --git a/src/esm/lib/converter/shared/bip32Derivation.d.ts b/src/esm/lib/converter/shared/bip32Derivation.d.ts new file mode 100644 index 0000000..d3b646d --- /dev/null +++ b/src/esm/lib/converter/shared/bip32Derivation.d.ts @@ -0,0 +1,8 @@ +import { Bip32Derivation, KeyValue } from '../../interfaces'; +export declare function makeConverter(TYPE_BYTE: number, isValidPubkey?: (pubkey: Uint8Array) => boolean): { + decode: (keyVal: KeyValue) => Bip32Derivation; + encode: (data: Bip32Derivation) => KeyValue; + check: (data: any) => data is Bip32Derivation; + expected: string; + canAddToArray: (array: Bip32Derivation[], item: Bip32Derivation, dupeSet: Set) => boolean; +}; diff --git a/src/lib/converter/shared/bip32Derivation.js b/src/esm/lib/converter/shared/bip32Derivation.js similarity index 68% rename from src/lib/converter/shared/bip32Derivation.js rename to src/esm/lib/converter/shared/bip32Derivation.js index 359120b..0bf45db 100644 --- a/src/lib/converter/shared/bip32Derivation.js +++ b/src/esm/lib/converter/shared/bip32Derivation.js @@ -1,22 +1,21 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); +import * as tools from 'uint8array-tools'; const range = n => [...Array(n).keys()]; const isValidDERKey = pubkey => (pubkey.length === 33 && [2, 3].includes(pubkey[0])) || (pubkey.length === 65 && 4 === pubkey[0]); -function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { +export function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { function decode(keyVal) { if (keyVal.key[0] !== TYPE_BYTE) { throw new Error( 'Decode Error: could not decode bip32Derivation with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const pubkey = keyVal.key.slice(1); if (!isValidPubkey(pubkey)) { throw new Error( 'Decode Error: bip32Derivation has invalid pubkey in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ((keyVal.value.length / 4) % 1 !== 0) { @@ -30,7 +29,7 @@ function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { path: 'm', }; for (const i of range(keyVal.value.length / 4 - 1)) { - const val = keyVal.value.readUInt32LE(i * 4 + 4); + const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE'); const isHard = !!(val & 0x80000000); const idx = val & 0x7fffffff; data.path += '/' + idx.toString(10) + (isHard ? "'" : ''); @@ -38,17 +37,17 @@ function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { return data; } function encode(data) { - const head = Buffer.from([TYPE_BYTE]); - const key = Buffer.concat([head, data.pubkey]); + const head = Uint8Array.from([TYPE_BYTE]); + const key = tools.concat([head, data.pubkey]); const splitPath = data.path.split('/'); - const value = Buffer.allocUnsafe(splitPath.length * 4); - data.masterFingerprint.copy(value, 0); + const value = new Uint8Array(splitPath.length * 4); + value.set(data.masterFingerprint, 0); let offset = 4; splitPath.slice(1).forEach(level => { const isHard = level.slice(-1) === "'"; let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10); if (isHard) num += 0x80000000; - value.writeUInt32LE(num, offset); + tools.writeUInt32(value, offset, num, 'LE'); offset += 4; }); return { @@ -57,21 +56,23 @@ function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { }; } const expected = - '{ masterFingerprint: Buffer; pubkey: Buffer; path: string; }'; + '{ masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; }'; function check(data) { return ( - Buffer.isBuffer(data.pubkey) && - Buffer.isBuffer(data.masterFingerprint) && + data.pubkey instanceof Uint8Array && + data.masterFingerprint instanceof Uint8Array && typeof data.path === 'string' && isValidPubkey(data.pubkey) && data.masterFingerprint.length === 4 ); } function canAddToArray(array, item, dupeSet) { - const dupeString = item.pubkey.toString('hex'); + const dupeString = tools.toHex(item.pubkey); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); - return array.filter(v => v.pubkey.equals(item.pubkey)).length === 0; + return ( + array.filter(v => tools.compare(v.pubkey, item.pubkey) === 0).length === 0 + ); } return { decode, @@ -81,4 +82,3 @@ function makeConverter(TYPE_BYTE, isValidPubkey = isValidDERKey) { canAddToArray, }; } -exports.makeConverter = makeConverter; diff --git a/src/esm/lib/converter/shared/checkPubkey.d.ts b/src/esm/lib/converter/shared/checkPubkey.d.ts new file mode 100644 index 0000000..0966a06 --- /dev/null +++ b/src/esm/lib/converter/shared/checkPubkey.d.ts @@ -0,0 +1,2 @@ +import { KeyValue } from '../../interfaces'; +export declare function makeChecker(pubkeyTypes: number[]): (keyVal: KeyValue) => Uint8Array | undefined; diff --git a/src/lib/converter/shared/checkPubkey.js b/src/esm/lib/converter/shared/checkPubkey.js similarity index 60% rename from src/lib/converter/shared/checkPubkey.js rename to src/esm/lib/converter/shared/checkPubkey.js index d59625d..6ffd454 100644 --- a/src/lib/converter/shared/checkPubkey.js +++ b/src/esm/lib/converter/shared/checkPubkey.js @@ -1,6 +1,5 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -function makeChecker(pubkeyTypes) { +import * as tools from 'uint8array-tools'; +export function makeChecker(pubkeyTypes) { return checkPubkey; function checkPubkey(keyVal) { let pubkey; @@ -11,11 +10,10 @@ function makeChecker(pubkeyTypes) { ![2, 3, 4].includes(pubkey[0]) ) { throw new Error( - 'Format Error: invalid pubkey in key 0x' + keyVal.key.toString('hex'), + 'Format Error: invalid pubkey in key 0x' + tools.toHex(keyVal.key), ); } } return pubkey; } } -exports.makeChecker = makeChecker; diff --git a/src/esm/lib/converter/shared/redeemScript.d.ts b/src/esm/lib/converter/shared/redeemScript.d.ts new file mode 100644 index 0000000..fa1f0d8 --- /dev/null +++ b/src/esm/lib/converter/shared/redeemScript.d.ts @@ -0,0 +1,8 @@ +import { KeyValue, RedeemScript } from '../../interfaces'; +export declare function makeConverter(TYPE_BYTE: number): { + decode: (keyVal: KeyValue) => RedeemScript; + encode: (data: RedeemScript) => KeyValue; + check: (data: any) => data is RedeemScript; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; +}; diff --git a/src/lib/converter/shared/redeemScript.js b/src/esm/lib/converter/shared/redeemScript.js similarity index 63% rename from src/lib/converter/shared/redeemScript.js rename to src/esm/lib/converter/shared/redeemScript.js index 7b5746a..8e64416 100644 --- a/src/lib/converter/shared/redeemScript.js +++ b/src/esm/lib/converter/shared/redeemScript.js @@ -1,25 +1,24 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -function makeConverter(TYPE_BYTE) { +import * as tools from 'uint8array-tools'; +export function makeConverter(TYPE_BYTE) { function decode(keyVal) { if (keyVal.key[0] !== TYPE_BYTE) { throw new Error( 'Decode Error: could not decode redeemScript with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; } function encode(data) { - const key = Buffer.from([TYPE_BYTE]); + const key = Uint8Array.from([TYPE_BYTE]); return { key, value: data, }; } - const expected = 'Buffer'; + const expected = 'Uint8Array'; function check(data) { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } function canAdd(currentData, newData) { return !!currentData && !!newData && currentData.redeemScript === undefined; @@ -32,4 +31,3 @@ function makeConverter(TYPE_BYTE) { canAdd, }; } -exports.makeConverter = makeConverter; diff --git a/src/esm/lib/converter/shared/tapBip32Derivation.d.ts b/src/esm/lib/converter/shared/tapBip32Derivation.d.ts new file mode 100644 index 0000000..ef42ca9 --- /dev/null +++ b/src/esm/lib/converter/shared/tapBip32Derivation.d.ts @@ -0,0 +1,8 @@ +import { KeyValue, TapBip32Derivation } from '../../interfaces'; +export declare function makeConverter(TYPE_BYTE: number): { + decode: (keyVal: KeyValue) => TapBip32Derivation; + encode: (data: TapBip32Derivation) => KeyValue; + check: (data: any) => data is TapBip32Derivation; + expected: string; + canAddToArray: (array: TapBip32Derivation[], item: TapBip32Derivation, dupeSet: Set) => boolean; +}; diff --git a/src/lib/converter/shared/tapBip32Derivation.js b/src/esm/lib/converter/shared/tapBip32Derivation.js similarity index 51% rename from src/lib/converter/shared/tapBip32Derivation.js rename to src/esm/lib/converter/shared/tapBip32Derivation.js index 021ca9e..b25bbe7 100644 --- a/src/lib/converter/shared/tapBip32Derivation.js +++ b/src/esm/lib/converter/shared/tapBip32Derivation.js @@ -1,43 +1,43 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const varuint = require('../varint'); -const bip32Derivation = require('./bip32Derivation'); +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; +import * as bip32Derivation from './bip32Derivation.js'; const isValidBIP340Key = pubkey => pubkey.length === 32; -function makeConverter(TYPE_BYTE) { +export function makeConverter(TYPE_BYTE) { const parent = bip32Derivation.makeConverter(TYPE_BYTE, isValidBIP340Key); function decode(keyVal) { - const nHashes = varuint.decode(keyVal.value); - const nHashesLen = varuint.encodingLength(nHashes); + const { numberValue: nHashes, bytes: nHashesLen } = varuint.decode( + keyVal.value, + ); const base = parent.decode({ key: keyVal.key, - value: keyVal.value.slice(nHashesLen + nHashes * 32), + value: keyVal.value.slice(nHashesLen + Number(nHashes) * 32), }); - const leafHashes = new Array(nHashes); + const leafHashes = new Array(Number(nHashes)); for (let i = 0, _offset = nHashesLen; i < nHashes; i++, _offset += 32) { leafHashes[i] = keyVal.value.slice(_offset, _offset + 32); } - return Object.assign({}, base, { leafHashes }); + return { ...base, leafHashes }; } function encode(data) { const base = parent.encode(data); const nHashesLen = varuint.encodingLength(data.leafHashes.length); - const nHashesBuf = Buffer.allocUnsafe(nHashesLen); + const nHashesBuf = new Uint8Array(nHashesLen); varuint.encode(data.leafHashes.length, nHashesBuf); - const value = Buffer.concat([nHashesBuf, ...data.leafHashes, base.value]); - return Object.assign({}, base, { value }); + const value = tools.concat([nHashesBuf, ...data.leafHashes, base.value]); + return { ...base, value }; } const expected = '{ ' + - 'masterFingerprint: Buffer; ' + - 'pubkey: Buffer; ' + + 'masterFingerprint: Uint8Array; ' + + 'pubkey: Uint8Array; ' + 'path: string; ' + - 'leafHashes: Buffer[]; ' + + 'leafHashes: Uint8Array[]; ' + '}'; function check(data) { return ( Array.isArray(data.leafHashes) && data.leafHashes.every( - leafHash => Buffer.isBuffer(leafHash) && leafHash.length === 32, + leafHash => leafHash instanceof Uint8Array && leafHash.length === 32, ) && parent.check(data) ); @@ -50,4 +50,3 @@ function makeConverter(TYPE_BYTE) { canAddToArray: parent.canAddToArray, }; } -exports.makeConverter = makeConverter; diff --git a/src/esm/lib/converter/shared/tapInternalKey.d.ts b/src/esm/lib/converter/shared/tapInternalKey.d.ts new file mode 100644 index 0000000..30e5e4f --- /dev/null +++ b/src/esm/lib/converter/shared/tapInternalKey.d.ts @@ -0,0 +1,8 @@ +import { KeyValue, TapInternalKey } from '../../interfaces'; +export declare function makeConverter(TYPE_BYTE: number): { + decode: (keyVal: KeyValue) => TapInternalKey; + encode: (data: TapInternalKey) => KeyValue; + check: (data: any) => data is TapInternalKey; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; +}; diff --git a/src/lib/converter/shared/tapInternalKey.js b/src/esm/lib/converter/shared/tapInternalKey.js similarity index 68% rename from src/lib/converter/shared/tapInternalKey.js rename to src/esm/lib/converter/shared/tapInternalKey.js index e0e918e..252af20 100644 --- a/src/lib/converter/shared/tapInternalKey.js +++ b/src/esm/lib/converter/shared/tapInternalKey.js @@ -1,11 +1,10 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -function makeConverter(TYPE_BYTE) { +import * as tools from 'uint8array-tools'; +export function makeConverter(TYPE_BYTE) { function decode(keyVal) { if (keyVal.key[0] !== TYPE_BYTE || keyVal.key.length !== 1) { throw new Error( 'Decode Error: could not decode tapInternalKey with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (keyVal.value.length !== 32) { @@ -16,12 +15,12 @@ function makeConverter(TYPE_BYTE) { return keyVal.value; } function encode(value) { - const key = Buffer.from([TYPE_BYTE]); + const key = Uint8Array.from([TYPE_BYTE]); return { key, value }; } - const expected = 'Buffer'; + const expected = 'Uint8Array'; function check(data) { - return Buffer.isBuffer(data) && data.length === 32; + return data instanceof Uint8Array && data.length === 32; } function canAdd(currentData, newData) { return ( @@ -36,4 +35,3 @@ function makeConverter(TYPE_BYTE) { canAdd, }; } -exports.makeConverter = makeConverter; diff --git a/src/esm/lib/converter/shared/witnessScript.d.ts b/src/esm/lib/converter/shared/witnessScript.d.ts new file mode 100644 index 0000000..809c322 --- /dev/null +++ b/src/esm/lib/converter/shared/witnessScript.d.ts @@ -0,0 +1,8 @@ +import { KeyValue, WitnessScript } from '../../interfaces'; +export declare function makeConverter(TYPE_BYTE: number): { + decode: (keyVal: KeyValue) => WitnessScript; + encode: (data: WitnessScript) => KeyValue; + check: (data: any) => data is WitnessScript; + expected: string; + canAdd: (currentData: any, newData: any) => boolean; +}; diff --git a/src/lib/converter/shared/witnessScript.js b/src/esm/lib/converter/shared/witnessScript.js similarity index 64% rename from src/lib/converter/shared/witnessScript.js rename to src/esm/lib/converter/shared/witnessScript.js index d66a421..0a18693 100644 --- a/src/lib/converter/shared/witnessScript.js +++ b/src/esm/lib/converter/shared/witnessScript.js @@ -1,25 +1,24 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -function makeConverter(TYPE_BYTE) { +import * as tools from 'uint8array-tools'; +export function makeConverter(TYPE_BYTE) { function decode(keyVal) { if (keyVal.key[0] !== TYPE_BYTE) { throw new Error( 'Decode Error: could not decode witnessScript with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; } function encode(data) { - const key = Buffer.from([TYPE_BYTE]); + const key = Uint8Array.from([TYPE_BYTE]); return { key, value: data, }; } - const expected = 'Buffer'; + const expected = 'Uint8Array'; function check(data) { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } function canAdd(currentData, newData) { return ( @@ -34,4 +33,3 @@ function makeConverter(TYPE_BYTE) { canAdd, }; } -exports.makeConverter = makeConverter; diff --git a/src/esm/lib/converter/tools.d.ts b/src/esm/lib/converter/tools.d.ts new file mode 100644 index 0000000..0fbb8a6 --- /dev/null +++ b/src/esm/lib/converter/tools.d.ts @@ -0,0 +1,5 @@ +import { KeyValue } from '../interfaces'; +export declare const range: (n: number) => number[]; +export declare function reverseBuffer(buffer: Uint8Array): Uint8Array; +export declare function keyValsToBuffer(keyVals: KeyValue[]): Uint8Array; +export declare function keyValToBuffer(keyVal: KeyValue): Uint8Array; diff --git a/src/esm/lib/converter/tools.js b/src/esm/lib/converter/tools.js new file mode 100644 index 0000000..3e39cc1 --- /dev/null +++ b/src/esm/lib/converter/tools.js @@ -0,0 +1,32 @@ +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; +export const range = n => [...Array(n).keys()]; +export function reverseBuffer(buffer) { + if (buffer.length < 1) return buffer; + let j = buffer.length - 1; + let tmp = 0; + for (let i = 0; i < buffer.length / 2; i++) { + tmp = buffer[i]; + buffer[i] = buffer[j]; + buffer[j] = tmp; + j--; + } + return buffer; +} +export function keyValsToBuffer(keyVals) { + const buffers = keyVals.map(keyValToBuffer); + buffers.push(Uint8Array.from([0])); + return tools.concat(buffers); +} +export function keyValToBuffer(keyVal) { + const keyLen = keyVal.key.length; + const valLen = keyVal.value.length; + const keyVarIntLen = varuint.encodingLength(keyLen); + const valVarIntLen = varuint.encodingLength(valLen); + const buffer = new Uint8Array(keyVarIntLen + keyLen + valVarIntLen + valLen); + varuint.encode(keyLen, buffer, 0); + buffer.set(keyVal.key, keyVarIntLen); + varuint.encode(valLen, buffer, keyVarIntLen + keyLen); + buffer.set(keyVal.value, keyVarIntLen + keyLen + valVarIntLen); + return buffer; +} diff --git a/src/esm/lib/interfaces.d.ts b/src/esm/lib/interfaces.d.ts new file mode 100644 index 0000000..9a5112e --- /dev/null +++ b/src/esm/lib/interfaces.d.ts @@ -0,0 +1,114 @@ +export declare type TransactionFromBuffer = (buffer: Uint8Array) => Transaction; +export interface Transaction { + getInputOutputCounts(): { + inputCount: number; + outputCount: number; + }; + addInput(objectArg: any): void; + addOutput(objectArg: any): void; + toBuffer(): Uint8Array; +} +export interface KeyValue { + key: Uint8Array; + value: Uint8Array; +} +export interface PsbtGlobal extends PsbtGlobalUpdate { + unsignedTx: Transaction; + unknownKeyVals?: KeyValue[]; +} +export interface PsbtGlobalUpdate { + globalXpub?: GlobalXpub[]; +} +export interface PsbtInput extends PsbtInputUpdate { + unknownKeyVals?: KeyValue[]; +} +export interface PsbtInputUpdate { + partialSig?: PartialSig[]; + nonWitnessUtxo?: NonWitnessUtxo; + witnessUtxo?: WitnessUtxo; + sighashType?: SighashType; + redeemScript?: RedeemScript; + witnessScript?: WitnessScript; + bip32Derivation?: Bip32Derivation[]; + finalScriptSig?: FinalScriptSig; + finalScriptWitness?: FinalScriptWitness; + porCommitment?: PorCommitment; + tapKeySig?: TapKeySig; + tapScriptSig?: TapScriptSig[]; + tapLeafScript?: TapLeafScript[]; + tapBip32Derivation?: TapBip32Derivation[]; + tapInternalKey?: TapInternalKey; + tapMerkleRoot?: TapMerkleRoot; +} +export interface PsbtInputExtended extends PsbtInput { + [index: string]: any; +} +export interface PsbtOutput extends PsbtOutputUpdate { + unknownKeyVals?: KeyValue[]; +} +export interface PsbtOutputUpdate { + redeemScript?: RedeemScript; + witnessScript?: WitnessScript; + bip32Derivation?: Bip32Derivation[]; + tapBip32Derivation?: TapBip32Derivation[]; + tapTree?: TapTree; + tapInternalKey?: TapInternalKey; +} +export interface PsbtOutputExtended extends PsbtOutput { + [index: string]: any; +} +export interface GlobalXpub { + extendedPubkey: Uint8Array; + masterFingerprint: Uint8Array; + path: string; +} +export interface PartialSig { + pubkey: Uint8Array; + signature: Uint8Array; +} +export interface Bip32Derivation { + masterFingerprint: Uint8Array; + pubkey: Uint8Array; + path: string; +} +export interface WitnessUtxo { + script: Uint8Array; + value: bigint; +} +export declare type NonWitnessUtxo = Uint8Array; +export declare type SighashType = number; +export declare type RedeemScript = Uint8Array; +export declare type WitnessScript = Uint8Array; +export declare type FinalScriptSig = Uint8Array; +export declare type FinalScriptWitness = Uint8Array; +export declare type PorCommitment = string; +export declare type TapKeySig = Uint8Array; +export interface TapScriptSig extends PartialSig { + leafHash: Uint8Array; +} +interface TapScript { + leafVersion: number; + script: Uint8Array; +} +export declare type ControlBlock = Uint8Array; +export interface TapLeafScript extends TapScript { + controlBlock: ControlBlock; +} +export interface TapBip32Derivation extends Bip32Derivation { + leafHashes: Uint8Array[]; +} +export declare type TapInternalKey = Uint8Array; +export declare type TapMerkleRoot = Uint8Array; +export interface TapLeaf extends TapScript { + depth: number; +} +export interface TapTree { + leaves: TapLeaf[]; +} +export declare type TransactionIOCountGetter = (txBuffer: Uint8Array) => { + inputCount: number; + outputCount: number; +}; +export declare type TransactionVersionSetter = (version: number, txBuffer: Uint8Array) => Uint8Array; +export declare type TransactionLocktimeSetter = (locktime: number, txBuffer: Uint8Array) => Uint8Array; +export {}; diff --git a/src/esm/lib/interfaces.js b/src/esm/lib/interfaces.js new file mode 100644 index 0000000..e69de29 diff --git a/src/esm/lib/parser/fromBuffer.d.ts b/src/esm/lib/parser/fromBuffer.d.ts new file mode 100644 index 0000000..f59bc3b --- /dev/null +++ b/src/esm/lib/parser/fromBuffer.d.ts @@ -0,0 +1,11 @@ +import { KeyValue, Transaction, TransactionFromBuffer } from '../interfaces'; +import { PsbtAttributes } from './index.js'; +export declare function psbtFromBuffer(buffer: Uint8Array, txGetter: TransactionFromBuffer): PsbtAttributes; +interface PsbtFromKeyValsArg { + globalMapKeyVals: KeyValue[]; + inputKeyVals: KeyValue[][]; + outputKeyVals: KeyValue[][]; +} +export declare function checkKeyBuffer(type: string, keyBuf: Uint8Array, keyNum: number): void; +export declare function psbtFromKeyVals(unsignedTx: Transaction, { globalMapKeyVals, inputKeyVals, outputKeyVals }: PsbtFromKeyValsArg): PsbtAttributes; +export {}; diff --git a/src/esm/lib/parser/fromBuffer.js b/src/esm/lib/parser/fromBuffer.js new file mode 100644 index 0000000..1df0911 --- /dev/null +++ b/src/esm/lib/parser/fromBuffer.js @@ -0,0 +1,329 @@ +import * as convert from '../converter/index.js'; +import { range } from '../converter/tools.js'; +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; +import { GlobalTypes, InputTypes, OutputTypes } from '../typeFields.js'; +export function psbtFromBuffer(buffer, txGetter) { + let offset = 0; + function varSlice() { + const { numberValue: keyLen, bytes } = varuint.decode(buffer, offset); + offset += bytes; + const key = buffer.slice(offset, offset + Number(keyLen)); + offset += Number(keyLen); + return key; + } + function readUInt32BE() { + const num = tools.readUInt32(buffer, offset, 'BE'); + offset += 4; + return num; + } + function readUInt8() { + const num = tools.readUInt8(buffer, offset); + offset += 1; + return num; + } + function getKeyValue() { + const key = varSlice(); + const value = varSlice(); + return { + key, + value, + }; + } + function checkEndOfKeyValPairs() { + if (offset >= buffer.length) { + throw new Error('Format Error: Unexpected End of PSBT'); + } + const isEnd = tools.readUInt8(buffer, offset) === 0; + if (isEnd) { + offset++; + } + return isEnd; + } + if (readUInt32BE() !== 0x70736274) { + throw new Error('Format Error: Invalid Magic Number'); + } + if (readUInt8() !== 0xff) { + throw new Error( + 'Format Error: Magic Number must be followed by 0xff separator', + ); + } + const globalMapKeyVals = []; + const globalKeyIndex = {}; + while (!checkEndOfKeyValPairs()) { + const keyVal = getKeyValue(); + const hexKey = tools.toHex(keyVal.key); + if (globalKeyIndex[hexKey]) { + throw new Error( + 'Format Error: Keys must be unique for global keymap: key ' + hexKey, + ); + } + globalKeyIndex[hexKey] = 1; + globalMapKeyVals.push(keyVal); + } + const unsignedTxMaps = globalMapKeyVals.filter( + keyVal => keyVal.key[0] === GlobalTypes.UNSIGNED_TX, + ); + if (unsignedTxMaps.length !== 1) { + throw new Error('Format Error: Only one UNSIGNED_TX allowed'); + } + const unsignedTx = txGetter(unsignedTxMaps[0].value); + // Get input and output counts to loop the respective fields + const { inputCount, outputCount } = unsignedTx.getInputOutputCounts(); + const inputKeyVals = []; + const outputKeyVals = []; + // Get input fields + for (const index of range(inputCount)) { + const inputKeyIndex = {}; + const input = []; + while (!checkEndOfKeyValPairs()) { + const keyVal = getKeyValue(); + const hexKey = tools.toHex(keyVal.key); + if (inputKeyIndex[hexKey]) { + throw new Error( + 'Format Error: Keys must be unique for each input: ' + + 'input index ' + + index + + ' key ' + + hexKey, + ); + } + inputKeyIndex[hexKey] = 1; + input.push(keyVal); + } + inputKeyVals.push(input); + } + for (const index of range(outputCount)) { + const outputKeyIndex = {}; + const output = []; + while (!checkEndOfKeyValPairs()) { + const keyVal = getKeyValue(); + const hexKey = tools.toHex(keyVal.key); + if (outputKeyIndex[hexKey]) { + throw new Error( + 'Format Error: Keys must be unique for each output: ' + + 'output index ' + + index + + ' key ' + + hexKey, + ); + } + outputKeyIndex[hexKey] = 1; + output.push(keyVal); + } + outputKeyVals.push(output); + } + return psbtFromKeyVals(unsignedTx, { + globalMapKeyVals, + inputKeyVals, + outputKeyVals, + }); +} +export function checkKeyBuffer(type, keyBuf, keyNum) { + if (tools.compare(keyBuf, Uint8Array.from([keyNum]))) { + throw new Error( + // `Format Error: Invalid ${type} key: ${keyBuf.toString('hex')}`, + `Format Error: Invalid ${type} key: ${tools.toHex(keyBuf)}`, + ); + } +} +export function psbtFromKeyVals( + unsignedTx, + { globalMapKeyVals, inputKeyVals, outputKeyVals }, +) { + // That was easy :-) + const globalMap = { + unsignedTx, + }; + let txCount = 0; + for (const keyVal of globalMapKeyVals) { + // If a globalMap item needs pubkey, uncomment + // const pubkey = convert.globals.checkPubkey(keyVal); + switch (keyVal.key[0]) { + case GlobalTypes.UNSIGNED_TX: + checkKeyBuffer('global', keyVal.key, GlobalTypes.UNSIGNED_TX); + if (txCount > 0) { + throw new Error('Format Error: GlobalMap has multiple UNSIGNED_TX'); + } + txCount++; + break; + case GlobalTypes.GLOBAL_XPUB: + if (globalMap.globalXpub === undefined) { + globalMap.globalXpub = []; + } + globalMap.globalXpub.push(convert.globals.globalXpub.decode(keyVal)); + break; + default: + // This will allow inclusion during serialization. + if (!globalMap.unknownKeyVals) globalMap.unknownKeyVals = []; + globalMap.unknownKeyVals.push(keyVal); + } + } + // Get input and output counts to loop the respective fields + const inputCount = inputKeyVals.length; + const outputCount = outputKeyVals.length; + const inputs = []; + const outputs = []; + // Get input fields + for (const index of range(inputCount)) { + const input = {}; + for (const keyVal of inputKeyVals[index]) { + convert.inputs.checkPubkey(keyVal); + switch (keyVal.key[0]) { + case InputTypes.NON_WITNESS_UTXO: + checkKeyBuffer('input', keyVal.key, InputTypes.NON_WITNESS_UTXO); + if (input.nonWitnessUtxo !== undefined) { + throw new Error( + 'Format Error: Input has multiple NON_WITNESS_UTXO', + ); + } + input.nonWitnessUtxo = convert.inputs.nonWitnessUtxo.decode(keyVal); + break; + case InputTypes.WITNESS_UTXO: + checkKeyBuffer('input', keyVal.key, InputTypes.WITNESS_UTXO); + if (input.witnessUtxo !== undefined) { + throw new Error('Format Error: Input has multiple WITNESS_UTXO'); + } + input.witnessUtxo = convert.inputs.witnessUtxo.decode(keyVal); + break; + case InputTypes.PARTIAL_SIG: + if (input.partialSig === undefined) { + input.partialSig = []; + } + input.partialSig.push(convert.inputs.partialSig.decode(keyVal)); + break; + case InputTypes.SIGHASH_TYPE: + checkKeyBuffer('input', keyVal.key, InputTypes.SIGHASH_TYPE); + if (input.sighashType !== undefined) { + throw new Error('Format Error: Input has multiple SIGHASH_TYPE'); + } + input.sighashType = convert.inputs.sighashType.decode(keyVal); + break; + case InputTypes.REDEEM_SCRIPT: + checkKeyBuffer('input', keyVal.key, InputTypes.REDEEM_SCRIPT); + if (input.redeemScript !== undefined) { + throw new Error('Format Error: Input has multiple REDEEM_SCRIPT'); + } + input.redeemScript = convert.inputs.redeemScript.decode(keyVal); + break; + case InputTypes.WITNESS_SCRIPT: + checkKeyBuffer('input', keyVal.key, InputTypes.WITNESS_SCRIPT); + if (input.witnessScript !== undefined) { + throw new Error('Format Error: Input has multiple WITNESS_SCRIPT'); + } + input.witnessScript = convert.inputs.witnessScript.decode(keyVal); + break; + case InputTypes.BIP32_DERIVATION: + if (input.bip32Derivation === undefined) { + input.bip32Derivation = []; + } + input.bip32Derivation.push( + convert.inputs.bip32Derivation.decode(keyVal), + ); + break; + case InputTypes.FINAL_SCRIPTSIG: + checkKeyBuffer('input', keyVal.key, InputTypes.FINAL_SCRIPTSIG); + input.finalScriptSig = convert.inputs.finalScriptSig.decode(keyVal); + break; + case InputTypes.FINAL_SCRIPTWITNESS: + checkKeyBuffer('input', keyVal.key, InputTypes.FINAL_SCRIPTWITNESS); + input.finalScriptWitness = convert.inputs.finalScriptWitness.decode( + keyVal, + ); + break; + case InputTypes.POR_COMMITMENT: + checkKeyBuffer('input', keyVal.key, InputTypes.POR_COMMITMENT); + input.porCommitment = convert.inputs.porCommitment.decode(keyVal); + break; + case InputTypes.TAP_KEY_SIG: + checkKeyBuffer('input', keyVal.key, InputTypes.TAP_KEY_SIG); + input.tapKeySig = convert.inputs.tapKeySig.decode(keyVal); + break; + case InputTypes.TAP_SCRIPT_SIG: + if (input.tapScriptSig === undefined) { + input.tapScriptSig = []; + } + input.tapScriptSig.push(convert.inputs.tapScriptSig.decode(keyVal)); + break; + case InputTypes.TAP_LEAF_SCRIPT: + if (input.tapLeafScript === undefined) { + input.tapLeafScript = []; + } + input.tapLeafScript.push(convert.inputs.tapLeafScript.decode(keyVal)); + break; + case InputTypes.TAP_BIP32_DERIVATION: + if (input.tapBip32Derivation === undefined) { + input.tapBip32Derivation = []; + } + input.tapBip32Derivation.push( + convert.inputs.tapBip32Derivation.decode(keyVal), + ); + break; + case InputTypes.TAP_INTERNAL_KEY: + checkKeyBuffer('input', keyVal.key, InputTypes.TAP_INTERNAL_KEY); + input.tapInternalKey = convert.inputs.tapInternalKey.decode(keyVal); + break; + case InputTypes.TAP_MERKLE_ROOT: + checkKeyBuffer('input', keyVal.key, InputTypes.TAP_MERKLE_ROOT); + input.tapMerkleRoot = convert.inputs.tapMerkleRoot.decode(keyVal); + break; + default: + // This will allow inclusion during serialization. + if (!input.unknownKeyVals) input.unknownKeyVals = []; + input.unknownKeyVals.push(keyVal); + } + } + inputs.push(input); + } + for (const index of range(outputCount)) { + const output = {}; + for (const keyVal of outputKeyVals[index]) { + convert.outputs.checkPubkey(keyVal); + switch (keyVal.key[0]) { + case OutputTypes.REDEEM_SCRIPT: + checkKeyBuffer('output', keyVal.key, OutputTypes.REDEEM_SCRIPT); + if (output.redeemScript !== undefined) { + throw new Error('Format Error: Output has multiple REDEEM_SCRIPT'); + } + output.redeemScript = convert.outputs.redeemScript.decode(keyVal); + break; + case OutputTypes.WITNESS_SCRIPT: + checkKeyBuffer('output', keyVal.key, OutputTypes.WITNESS_SCRIPT); + if (output.witnessScript !== undefined) { + throw new Error('Format Error: Output has multiple WITNESS_SCRIPT'); + } + output.witnessScript = convert.outputs.witnessScript.decode(keyVal); + break; + case OutputTypes.BIP32_DERIVATION: + if (output.bip32Derivation === undefined) { + output.bip32Derivation = []; + } + output.bip32Derivation.push( + convert.outputs.bip32Derivation.decode(keyVal), + ); + break; + case OutputTypes.TAP_INTERNAL_KEY: + checkKeyBuffer('output', keyVal.key, OutputTypes.TAP_INTERNAL_KEY); + output.tapInternalKey = convert.outputs.tapInternalKey.decode(keyVal); + break; + case OutputTypes.TAP_TREE: + checkKeyBuffer('output', keyVal.key, OutputTypes.TAP_TREE); + output.tapTree = convert.outputs.tapTree.decode(keyVal); + break; + case OutputTypes.TAP_BIP32_DERIVATION: + if (output.tapBip32Derivation === undefined) { + output.tapBip32Derivation = []; + } + output.tapBip32Derivation.push( + convert.outputs.tapBip32Derivation.decode(keyVal), + ); + break; + default: + if (!output.unknownKeyVals) output.unknownKeyVals = []; + output.unknownKeyVals.push(keyVal); + } + } + outputs.push(output); + } + return { globalMap, inputs, outputs }; +} diff --git a/src/esm/lib/parser/index.d.ts b/src/esm/lib/parser/index.d.ts new file mode 100644 index 0000000..bbd9eae --- /dev/null +++ b/src/esm/lib/parser/index.d.ts @@ -0,0 +1,8 @@ +import { PsbtGlobal, PsbtInput, PsbtOutput } from '../interfaces'; +export * from './fromBuffer.js'; +export * from './toBuffer.js'; +export interface PsbtAttributes { + globalMap: PsbtGlobal; + inputs: PsbtInput[]; + outputs: PsbtOutput[]; +} diff --git a/src/esm/lib/parser/index.js b/src/esm/lib/parser/index.js new file mode 100644 index 0000000..b16096c --- /dev/null +++ b/src/esm/lib/parser/index.js @@ -0,0 +1,2 @@ +export * from './fromBuffer.js'; +export * from './toBuffer.js'; diff --git a/src/esm/lib/parser/toBuffer.d.ts b/src/esm/lib/parser/toBuffer.d.ts new file mode 100644 index 0000000..4e7b230 --- /dev/null +++ b/src/esm/lib/parser/toBuffer.d.ts @@ -0,0 +1,8 @@ +import { KeyValue } from '../interfaces'; +import { PsbtAttributes } from './index.js'; +export declare function psbtToBuffer({ globalMap, inputs, outputs, }: PsbtAttributes): Uint8Array; +export declare function psbtToKeyVals({ globalMap, inputs, outputs, }: PsbtAttributes): { + globalKeyVals: KeyValue[]; + inputKeyVals: KeyValue[][]; + outputKeyVals: KeyValue[][]; +}; diff --git a/src/lib/parser/toBuffer.js b/src/esm/lib/parser/toBuffer.js similarity index 68% rename from src/lib/parser/toBuffer.js rename to src/esm/lib/parser/toBuffer.js index 798856f..054c654 100644 --- a/src/lib/parser/toBuffer.js +++ b/src/esm/lib/parser/toBuffer.js @@ -1,29 +1,27 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const convert = require('../converter'); -const tools_1 = require('../converter/tools'); -function psbtToBuffer({ globalMap, inputs, outputs }) { +import * as convert from '../converter/index.js'; +import { keyValsToBuffer } from '../converter/tools.js'; +import * as tools from 'uint8array-tools'; +export function psbtToBuffer({ globalMap, inputs, outputs }) { const { globalKeyVals, inputKeyVals, outputKeyVals } = psbtToKeyVals({ globalMap, inputs, outputs, }); - const globalBuffer = tools_1.keyValsToBuffer(globalKeyVals); + const globalBuffer = keyValsToBuffer(globalKeyVals); const keyValsOrEmptyToBuffer = keyVals => keyVals.length === 0 - ? [Buffer.from([0])] - : keyVals.map(tools_1.keyValsToBuffer); + ? [Uint8Array.from([0])] + : keyVals.map(keyValsToBuffer); const inputBuffers = keyValsOrEmptyToBuffer(inputKeyVals); const outputBuffers = keyValsOrEmptyToBuffer(outputKeyVals); - const header = Buffer.allocUnsafe(5); - header.writeUIntBE(0x70736274ff, 0, 5); - return Buffer.concat( + const header = new Uint8Array(5); + header.set([0x70, 0x73, 0x62, 0x74, 0xff], 0); + return tools.concat( [header, globalBuffer].concat(inputBuffers, outputBuffers), ); } -exports.psbtToBuffer = psbtToBuffer; const sortKeyVals = (a, b) => { - return a.key.compare(b.key); + return tools.compare(a.key, b.key); }; function keyValsFromMap(keyValMap, converterFactory) { const keyHexSet = new Set(); @@ -36,7 +34,7 @@ function keyValsFromMap(keyValMap, converterFactory) { const encodedKeyVals = (Array.isArray(value) ? value : [value]).map( converter.encode, ); - const keyHexes = encodedKeyVals.map(kv => kv.key.toString('hex')); + const keyHexes = encodedKeyVals.map(kv => tools.toHex(kv.key)); keyHexes.forEach(hex => { if (keyHexSet.has(hex)) throw new Error('Serialize Error: Duplicate key: ' + hex); @@ -47,12 +45,12 @@ function keyValsFromMap(keyValMap, converterFactory) { // Get other keyVals that have not yet been gotten const otherKeyVals = keyValMap.unknownKeyVals ? keyValMap.unknownKeyVals.filter(keyVal => { - return !keyHexSet.has(keyVal.key.toString('hex')); + return !keyHexSet.has(tools.toHex(keyVal.key)); }) : []; return keyVals.concat(otherKeyVals).sort(sortKeyVals); } -function psbtToKeyVals({ globalMap, inputs, outputs }) { +export function psbtToKeyVals({ globalMap, inputs, outputs }) { // First parse the global keyVals // Get any extra keyvals to pass along return { @@ -61,4 +59,3 @@ function psbtToKeyVals({ globalMap, inputs, outputs }) { outputKeyVals: outputs.map(o => keyValsFromMap(o, convert.outputs)), }; } -exports.psbtToKeyVals = psbtToKeyVals; diff --git a/src/esm/lib/psbt.d.ts b/src/esm/lib/psbt.d.ts new file mode 100644 index 0000000..48bd057 --- /dev/null +++ b/src/esm/lib/psbt.d.ts @@ -0,0 +1,26 @@ +import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, Transaction, TransactionFromBuffer } from './interfaces.js'; +export declare class Psbt { + static fromBase64(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType; + static fromHex(this: T, data: string, txFromBuffer: TransactionFromBuffer): InstanceType; + static fromBuffer(this: T, buffer: Uint8Array, txFromBuffer: TransactionFromBuffer): InstanceType; + readonly inputs: PsbtInput[]; + readonly outputs: PsbtOutput[]; + readonly globalMap: PsbtGlobal; + constructor(tx: Transaction); + toBase64(): string; + toHex(): string; + toBuffer(): Uint8Array; + updateGlobal(updateData: PsbtGlobalUpdate): this; + updateInput(inputIndex: number, updateData: PsbtInputUpdate): this; + updateOutput(outputIndex: number, updateData: PsbtOutputUpdate): this; + addUnknownKeyValToGlobal(keyVal: KeyValue): this; + addUnknownKeyValToInput(inputIndex: number, keyVal: KeyValue): this; + addUnknownKeyValToOutput(outputIndex: number, keyVal: KeyValue): this; + addInput(inputData: PsbtInputExtended): this; + addOutput(outputData: PsbtOutputExtended): this; + clearFinalizedInput(inputIndex: number): this; + combine(...those: this[]): this; + getTransaction(): Uint8Array; +} +export { Bip32Derivation, NonWitnessUtxo, ControlBlock, FinalScriptSig, FinalScriptWitness, GlobalXpub, KeyValue, PartialSig, PorCommitment, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputExtended, PsbtInputUpdate, PsbtOutput, PsbtOutputExtended, PsbtOutputUpdate, RedeemScript, SighashType, TapBip32Derivation, TapInternalKey, TapKeySig, TapLeaf, TapLeafScript, TapMerkleRoot, TapScriptSig, TapTree, Transaction, TransactionFromBuffer, TransactionIOCountGetter, TransactionLocktimeSetter, TransactionVersionSetter, WitnessScript, WitnessUtxo, } from './interfaces.js'; +export { checkForInput, checkForOutput } from './utils.js'; diff --git a/src/lib/psbt.js b/src/esm/lib/psbt.js similarity index 63% rename from src/lib/psbt.js rename to src/esm/lib/psbt.js index 01eeddb..88cc3ba 100644 --- a/src/lib/psbt.js +++ b/src/esm/lib/psbt.js @@ -1,10 +1,20 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const combiner_1 = require('./combiner'); -const parser_1 = require('./parser'); -const typeFields_1 = require('./typeFields'); -const utils_1 = require('./utils'); -class Psbt { +import { combine } from './combiner/index.js'; +import { psbtFromBuffer, psbtToBuffer } from './parser/index.js'; +import { GlobalTypes, InputTypes, OutputTypes } from './typeFields.js'; +import { + addInputAttributes, + addOutputAttributes, + checkForInput, + checkForOutput, + checkHasKey, + getEnumLength, + inputCheckUncleanFinalized, + updateGlobal, + updateInput, + updateOutput, +} from './utils.js'; +import * as tools from 'uint8array-tools'; +export class Psbt { constructor(tx) { this.inputs = []; this.outputs = []; @@ -13,72 +23,64 @@ class Psbt { }; } static fromBase64(data, txFromBuffer) { - const buffer = Buffer.from(data, 'base64'); + const buffer = tools.fromBase64(data); return this.fromBuffer(buffer, txFromBuffer); } static fromHex(data, txFromBuffer) { - const buffer = Buffer.from(data, 'hex'); + const buffer = tools.fromHex(data); return this.fromBuffer(buffer, txFromBuffer); } static fromBuffer(buffer, txFromBuffer) { - const results = parser_1.psbtFromBuffer(buffer, txFromBuffer); + const results = psbtFromBuffer(buffer, txFromBuffer); const psbt = new this(results.globalMap.unsignedTx); Object.assign(psbt, results); return psbt; } toBase64() { const buffer = this.toBuffer(); - return buffer.toString('base64'); + return tools.toBase64(buffer); } toHex() { const buffer = this.toBuffer(); - return buffer.toString('hex'); + return tools.toHex(buffer); } toBuffer() { - return parser_1.psbtToBuffer(this); + return psbtToBuffer(this); } updateGlobal(updateData) { - utils_1.updateGlobal(updateData, this.globalMap); + updateGlobal(updateData, this.globalMap); return this; } updateInput(inputIndex, updateData) { - const input = utils_1.checkForInput(this.inputs, inputIndex); - utils_1.updateInput(updateData, input); + const input = checkForInput(this.inputs, inputIndex); + updateInput(updateData, input); return this; } updateOutput(outputIndex, updateData) { - const output = utils_1.checkForOutput(this.outputs, outputIndex); - utils_1.updateOutput(updateData, output); + const output = checkForOutput(this.outputs, outputIndex); + updateOutput(updateData, output); return this; } addUnknownKeyValToGlobal(keyVal) { - utils_1.checkHasKey( + checkHasKey( keyVal, this.globalMap.unknownKeyVals, - utils_1.getEnumLength(typeFields_1.GlobalTypes), + getEnumLength(GlobalTypes), ); if (!this.globalMap.unknownKeyVals) this.globalMap.unknownKeyVals = []; this.globalMap.unknownKeyVals.push(keyVal); return this; } addUnknownKeyValToInput(inputIndex, keyVal) { - const input = utils_1.checkForInput(this.inputs, inputIndex); - utils_1.checkHasKey( - keyVal, - input.unknownKeyVals, - utils_1.getEnumLength(typeFields_1.InputTypes), - ); + const input = checkForInput(this.inputs, inputIndex); + checkHasKey(keyVal, input.unknownKeyVals, getEnumLength(InputTypes)); if (!input.unknownKeyVals) input.unknownKeyVals = []; input.unknownKeyVals.push(keyVal); return this; } addUnknownKeyValToOutput(outputIndex, keyVal) { - const output = utils_1.checkForOutput(this.outputs, outputIndex); - utils_1.checkHasKey( - keyVal, - output.unknownKeyVals, - utils_1.getEnumLength(typeFields_1.OutputTypes), - ); + const output = checkForOutput(this.outputs, outputIndex); + checkHasKey(keyVal, output.unknownKeyVals, getEnumLength(OutputTypes)); if (!output.unknownKeyVals) output.unknownKeyVals = []; output.unknownKeyVals.push(keyVal); return this; @@ -96,7 +98,7 @@ class Psbt { addKeyVals.forEach(keyVal => this.addUnknownKeyValToInput(inputIndex, keyVal), ); - utils_1.addInputAttributes(this.inputs, inputData); + addInputAttributes(this.inputs, inputData); return this; } addOutput(outputData) { @@ -112,12 +114,12 @@ class Psbt { addKeyVals.forEach(keyVal => this.addUnknownKeyValToOutput(outputIndex, keyVal), ); - utils_1.addOutputAttributes(this.outputs, outputData); + addOutputAttributes(this.outputs, outputData); return this; } clearFinalizedInput(inputIndex) { - const input = utils_1.checkForInput(this.inputs, inputIndex); - utils_1.inputCheckUncleanFinalized(inputIndex, input); + const input = checkForInput(this.inputs, inputIndex); + inputCheckUncleanFinalized(inputIndex, input); for (const key of Object.keys(input)) { if ( ![ @@ -137,7 +139,7 @@ class Psbt { combine(...those) { // Combine this with those. // Return self for chaining. - const result = combiner_1.combine([this].concat(those)); + const result = combine([this].concat(those)); Object.assign(this, result); return this; } @@ -145,4 +147,4 @@ class Psbt { return this.globalMap.unsignedTx.toBuffer(); } } -exports.Psbt = Psbt; +export { checkForInput, checkForOutput } from './utils.js'; diff --git a/src/esm/lib/typeFields.d.ts b/src/esm/lib/typeFields.d.ts new file mode 100644 index 0000000..e8cbcbe --- /dev/null +++ b/src/esm/lib/typeFields.d.ts @@ -0,0 +1,33 @@ +export declare enum GlobalTypes { + UNSIGNED_TX = 0, + GLOBAL_XPUB = 1 +} +export declare const GLOBAL_TYPE_NAMES: string[]; +export declare enum InputTypes { + NON_WITNESS_UTXO = 0, + WITNESS_UTXO = 1, + PARTIAL_SIG = 2, + SIGHASH_TYPE = 3, + REDEEM_SCRIPT = 4, + WITNESS_SCRIPT = 5, + BIP32_DERIVATION = 6, + FINAL_SCRIPTSIG = 7, + FINAL_SCRIPTWITNESS = 8, + POR_COMMITMENT = 9, + TAP_KEY_SIG = 19, + TAP_SCRIPT_SIG = 20, + TAP_LEAF_SCRIPT = 21, + TAP_BIP32_DERIVATION = 22, + TAP_INTERNAL_KEY = 23, + TAP_MERKLE_ROOT = 24 +} +export declare const INPUT_TYPE_NAMES: string[]; +export declare enum OutputTypes { + REDEEM_SCRIPT = 0, + WITNESS_SCRIPT = 1, + BIP32_DERIVATION = 2, + TAP_INTERNAL_KEY = 5, + TAP_TREE = 6, + TAP_BIP32_DERIVATION = 7 +} +export declare const OUTPUT_TYPE_NAMES: string[]; diff --git a/src/esm/lib/typeFields.js b/src/esm/lib/typeFields.js new file mode 100644 index 0000000..23cc1e3 --- /dev/null +++ b/src/esm/lib/typeFields.js @@ -0,0 +1,62 @@ +export var GlobalTypes; +(function(GlobalTypes) { + GlobalTypes[(GlobalTypes['UNSIGNED_TX'] = 0)] = 'UNSIGNED_TX'; + GlobalTypes[(GlobalTypes['GLOBAL_XPUB'] = 1)] = 'GLOBAL_XPUB'; +})(GlobalTypes || (GlobalTypes = {})); +export const GLOBAL_TYPE_NAMES = ['unsignedTx', 'globalXpub']; +export var InputTypes; +(function(InputTypes) { + InputTypes[(InputTypes['NON_WITNESS_UTXO'] = 0)] = 'NON_WITNESS_UTXO'; + InputTypes[(InputTypes['WITNESS_UTXO'] = 1)] = 'WITNESS_UTXO'; + InputTypes[(InputTypes['PARTIAL_SIG'] = 2)] = 'PARTIAL_SIG'; + InputTypes[(InputTypes['SIGHASH_TYPE'] = 3)] = 'SIGHASH_TYPE'; + InputTypes[(InputTypes['REDEEM_SCRIPT'] = 4)] = 'REDEEM_SCRIPT'; + InputTypes[(InputTypes['WITNESS_SCRIPT'] = 5)] = 'WITNESS_SCRIPT'; + InputTypes[(InputTypes['BIP32_DERIVATION'] = 6)] = 'BIP32_DERIVATION'; + InputTypes[(InputTypes['FINAL_SCRIPTSIG'] = 7)] = 'FINAL_SCRIPTSIG'; + InputTypes[(InputTypes['FINAL_SCRIPTWITNESS'] = 8)] = 'FINAL_SCRIPTWITNESS'; + InputTypes[(InputTypes['POR_COMMITMENT'] = 9)] = 'POR_COMMITMENT'; + InputTypes[(InputTypes['TAP_KEY_SIG'] = 19)] = 'TAP_KEY_SIG'; + InputTypes[(InputTypes['TAP_SCRIPT_SIG'] = 20)] = 'TAP_SCRIPT_SIG'; + InputTypes[(InputTypes['TAP_LEAF_SCRIPT'] = 21)] = 'TAP_LEAF_SCRIPT'; + InputTypes[(InputTypes['TAP_BIP32_DERIVATION'] = 22)] = + 'TAP_BIP32_DERIVATION'; + InputTypes[(InputTypes['TAP_INTERNAL_KEY'] = 23)] = 'TAP_INTERNAL_KEY'; + InputTypes[(InputTypes['TAP_MERKLE_ROOT'] = 24)] = 'TAP_MERKLE_ROOT'; +})(InputTypes || (InputTypes = {})); +export const INPUT_TYPE_NAMES = [ + 'nonWitnessUtxo', + 'witnessUtxo', + 'partialSig', + 'sighashType', + 'redeemScript', + 'witnessScript', + 'bip32Derivation', + 'finalScriptSig', + 'finalScriptWitness', + 'porCommitment', + 'tapKeySig', + 'tapScriptSig', + 'tapLeafScript', + 'tapBip32Derivation', + 'tapInternalKey', + 'tapMerkleRoot', +]; +export var OutputTypes; +(function(OutputTypes) { + OutputTypes[(OutputTypes['REDEEM_SCRIPT'] = 0)] = 'REDEEM_SCRIPT'; + OutputTypes[(OutputTypes['WITNESS_SCRIPT'] = 1)] = 'WITNESS_SCRIPT'; + OutputTypes[(OutputTypes['BIP32_DERIVATION'] = 2)] = 'BIP32_DERIVATION'; + OutputTypes[(OutputTypes['TAP_INTERNAL_KEY'] = 5)] = 'TAP_INTERNAL_KEY'; + OutputTypes[(OutputTypes['TAP_TREE'] = 6)] = 'TAP_TREE'; + OutputTypes[(OutputTypes['TAP_BIP32_DERIVATION'] = 7)] = + 'TAP_BIP32_DERIVATION'; +})(OutputTypes || (OutputTypes = {})); +export const OUTPUT_TYPE_NAMES = [ + 'redeemScript', + 'witnessScript', + 'bip32Derivation', + 'tapInternalKey', + 'tapTree', + 'tapBip32Derivation', +]; diff --git a/src/esm/lib/utils.d.ts b/src/esm/lib/utils.d.ts new file mode 100644 index 0000000..40f5e34 --- /dev/null +++ b/src/esm/lib/utils.d.ts @@ -0,0 +1,13 @@ +import { KeyValue, PsbtGlobal, PsbtGlobalUpdate, PsbtInput, PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate } from './interfaces.js'; +export declare function checkForInput(inputs: PsbtInput[], inputIndex: number): PsbtInput; +export declare function checkForOutput(outputs: PsbtOutput[], outputIndex: number): PsbtOutput; +export declare function checkHasKey(checkKeyVal: KeyValue, keyVals: KeyValue[] | undefined, enumLength: number): void; +export declare function getEnumLength(myenum: any): number; +export declare function inputCheckUncleanFinalized(inputIndex: number, input: PsbtInput): void; +export declare const updateGlobal: (updateData: PsbtGlobalUpdate, mainData: PsbtGlobal) => void; +export declare const updateInput: (updateData: PsbtInputUpdate, mainData: PsbtInput) => void; +export declare const updateOutput: (updateData: PsbtOutputUpdate, mainData: PsbtOutput) => void; +export declare function addInputAttributes(inputs: PsbtInput[], data: any): void; +export declare function addOutputAttributes(outputs: PsbtOutput[], data: any): void; +export declare function defaultVersionSetter(version: number, txBuf: Uint8Array): Uint8Array; +export declare function defaultLocktimeSetter(locktime: number, txBuf: Uint8Array): Uint8Array; diff --git a/src/esm/lib/utils.js b/src/esm/lib/utils.js new file mode 100644 index 0000000..70acaab --- /dev/null +++ b/src/esm/lib/utils.js @@ -0,0 +1,130 @@ +import * as converter from './converter/index.js'; +import * as tools from 'uint8array-tools'; +export function checkForInput(inputs, inputIndex) { + const input = inputs[inputIndex]; + if (input === undefined) throw new Error(`No input #${inputIndex}`); + return input; +} +export function checkForOutput(outputs, outputIndex) { + const output = outputs[outputIndex]; + if (output === undefined) throw new Error(`No output #${outputIndex}`); + return output; +} +export function checkHasKey(checkKeyVal, keyVals, enumLength) { + if (checkKeyVal.key[0] < enumLength) { + throw new Error( + `Use the method for your specific key instead of addUnknownKeyVal*`, + ); + } + if ( + keyVals && + keyVals.filter(kv => tools.compare(kv.key, checkKeyVal.key) === 0) + .length !== 0 + ) { + throw new Error(`Duplicate Key: ${tools.toHex(checkKeyVal.key)}`); + } +} +export function getEnumLength(myenum) { + let count = 0; + Object.keys(myenum).forEach(val => { + if (Number(isNaN(Number(val)))) { + count++; + } + }); + return count; +} +export function inputCheckUncleanFinalized(inputIndex, input) { + let result = false; + if (input.nonWitnessUtxo || input.witnessUtxo) { + const needScriptSig = !!input.redeemScript; + const needWitnessScript = !!input.witnessScript; + const scriptSigOK = !needScriptSig || !!input.finalScriptSig; + const witnessScriptOK = !needWitnessScript || !!input.finalScriptWitness; + const hasOneFinal = !!input.finalScriptSig || !!input.finalScriptWitness; + result = scriptSigOK && witnessScriptOK && hasOneFinal; + } + if (result === false) { + throw new Error( + `Input #${inputIndex} has too much or too little data to clean`, + ); + } +} +function throwForUpdateMaker(typeName, name, expected, data) { + throw new Error( + `Data for ${typeName} key ${name} is incorrect: Expected ` + + `${expected} and got ${JSON.stringify(data)}`, + ); +} +function updateMaker(typeName) { + return (updateData, mainData) => { + // @ts-ignore + for (const name of Object.keys(updateData)) { + // @ts-ignore + const data = updateData[name]; + // @ts-ignore + const { canAdd, canAddToArray, check, expected } = + // @ts-ignore + converter[typeName + 's'][name] || {}; + const isArray = !!canAddToArray; + // If unknown data. ignore and do not add + if (check) { + if (isArray) { + if ( + !Array.isArray(data) || + // @ts-ignore + (mainData[name] && !Array.isArray(mainData[name])) + ) { + throw new Error(`Key type ${name} must be an array`); + } + if (!data.every(check)) { + throwForUpdateMaker(typeName, name, expected, data); + } + // @ts-ignore + const arr = mainData[name] || []; + const dupeCheckSet = new Set(); + if (!data.every(v => canAddToArray(arr, v, dupeCheckSet))) { + throw new Error('Can not add duplicate data to array'); + } + // @ts-ignore + mainData[name] = arr.concat(data); + } else { + if (!check(data)) { + throwForUpdateMaker(typeName, name, expected, data); + } + if (!canAdd(mainData, data)) { + throw new Error(`Can not add duplicate data to ${typeName}`); + } + // @ts-ignore + mainData[name] = data; + } + } + } + }; +} +export const updateGlobal = updateMaker('global'); +export const updateInput = updateMaker('input'); +export const updateOutput = updateMaker('output'); +export function addInputAttributes(inputs, data) { + const index = inputs.length - 1; + const input = checkForInput(inputs, index); + updateInput(data, input); +} +export function addOutputAttributes(outputs, data) { + const index = outputs.length - 1; + const output = checkForOutput(outputs, index); + updateOutput(data, output); +} +export function defaultVersionSetter(version, txBuf) { + if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) { + throw new Error('Set Version: Invalid Transaction'); + } + tools.writeUInt32(txBuf, 0, version, 'LE'); + return txBuf; +} +export function defaultLocktimeSetter(locktime, txBuf) { + if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) { + throw new Error('Set Locktime: Invalid Transaction'); + } + tools.writeUInt32(txBuf, txBuf.length - 4, locktime, 'LE'); + return txBuf; +} diff --git a/src/esm/tests/addInputOutput.d.ts b/src/esm/tests/addInputOutput.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/addInputOutput.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/addInputOutput.js b/src/esm/tests/addInputOutput.js similarity index 64% rename from src/tests/addInputOutput.js rename to src/esm/tests/addInputOutput.js index f1e2f15..eb778c1 100644 --- a/src/tests/addInputOutput.js +++ b/src/esm/tests/addInputOutput.js @@ -1,10 +1,8 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../lib/psbt'); -const txTools_1 = require('./utils/txTools'); +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { getDefaultTx, transactionFromBuffer } from './utils/txTools.js'; tape('Test: add Input Output', t => { - const psbt = new psbt_1.Psbt(txTools_1.getDefaultTx()); + const psbt = new Psbt(getDefaultTx()); psbt.addInput({ hash: '865dce988413971fd812d0e81a3395ed916a87ea533e1a16c0f4e15df96fa7d4', index: 3, @@ -28,10 +26,7 @@ tape('Test: add Input Output', t => { value: 987654321, }); const hex = psbt.toHex(); - const hex2 = psbt_1.Psbt.fromHex( - hex, - txTools_1.transactionFromBuffer, - ).toHex(); + const hex2 = Psbt.fromHex(hex, transactionFromBuffer).toHex(); t.equal( hex, '70736274ff01009c0100000002d4a76ff95de1f4c0161a3e53ea876a91ed95331ae8d01' + @@ -41,11 +36,5 @@ tape('Test: add Input Output', t => { 'e18870f2c297fbfca54c5c6f645c7745a5b66eda87000000000000000000', ); t.equal(hex, hex2); - // console.log(jsonA1); - // console.log(jsonA2); - // console.log(jsonB1); - // console.log(jsonB2); - // t.notDeepEqual(JSON.parse(jsonA1), JSON.parse(jsonB1)); - // t.deepEqual(JSON.parse(jsonA2), JSON.parse(jsonB2)); t.end(); }); diff --git a/src/esm/tests/combine.d.ts b/src/esm/tests/combine.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/combine.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/combine.js b/src/esm/tests/combine.js similarity index 56% rename from src/tests/combine.js rename to src/esm/tests/combine.js index 12df0f1..f5c1191 100644 --- a/src/tests/combine.js +++ b/src/esm/tests/combine.js @@ -1,23 +1,15 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../lib/psbt'); -const combine_1 = require('./fixtures/combine'); -const txTools_1 = require('./utils/txTools'); -for (const f of combine_1.fixtures) { +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/combine.js'; +import { transactionFromBuffer } from './utils/txTools.js'; +for (const f of fixtures) { tape('Test: ' + f.description, t => { - const psbts = f.psbts.map(p => - psbt_1.Psbt.fromHex(p, txTools_1.transactionFromBuffer), - ); + const psbts = f.psbts.map(p => Psbt.fromHex(p, transactionFromBuffer)); const jsonA1 = jsonify(psbts[0]); const jsonA2 = jsonify(psbts[1]); psbts[0].combine(psbts[1]); const jsonB1 = jsonify(psbts[0]); const jsonB2 = jsonify(psbts[1]); - // console.log(jsonA1); - // console.log(jsonA2); - // console.log(jsonB1); - // console.log(jsonB2); t.notDeepEqual(JSON.parse(jsonA1), JSON.parse(jsonB1)); t.deepEqual(JSON.parse(jsonA2), JSON.parse(jsonB2)); t.equal(psbts[0].toHex(), f.result); @@ -30,6 +22,8 @@ function jsonify(parsed) { (key, value) => { return key !== undefined && value.type === 'Buffer' ? Buffer.from(value.data).toString('hex') + : typeof value === 'bigint' + ? value.toString() : value; }, 2, diff --git a/src/esm/tests/create.d.ts b/src/esm/tests/create.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/create.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/create.js b/src/esm/tests/create.js similarity index 61% rename from src/tests/create.js rename to src/esm/tests/create.js index fa34dca..5f7bd00 100644 --- a/src/tests/create.js +++ b/src/esm/tests/create.js @@ -1,12 +1,10 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../lib/psbt'); -const create_1 = require('./fixtures/create'); -const txTools_1 = require('./utils/txTools'); -for (const f of create_1.fixtures) { +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/create.js'; +import { getDefaultTx } from './utils/txTools.js'; +for (const f of fixtures) { tape('Test: ' + f.description, t => { - const psbt = new psbt_1.Psbt(txTools_1.getDefaultTx(2)); + const psbt = new Psbt(getDefaultTx(2)); for (const input of f.input.addInputs) { psbt.addInput(input); } diff --git a/src/esm/tests/first.d.ts b/src/esm/tests/first.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/first.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/esm/tests/first.js b/src/esm/tests/first.js new file mode 100644 index 0000000..8cb4852 --- /dev/null +++ b/src/esm/tests/first.js @@ -0,0 +1,36 @@ +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/first.js'; +import { transactionFromBuffer } from './utils/txTools.js'; +import * as tools from 'uint8array-tools'; +for (const f of fixtures) { + tape('Test: ' + f.description, t => { + const parsed = Psbt.fromHex(f.input, transactionFromBuffer); + const hex = parsed.toHex(); + const parsed2 = Psbt.fromHex(hex, transactionFromBuffer); + const hex2 = parsed2.toHex(); + const parsed3 = Psbt.fromHex(hex2, transactionFromBuffer); + t.strictEqual(parsed.toHex(), parsed2.toHex()); + t.strictEqual(parsed.toHex(), parsed3.toHex()); + // @ts-ignore + parsed3.globalMap.unsignedTx = parsed3.globalMap.unsignedTx.toBuffer(); + t.deepEqual(JSON.parse(jsonify(parsed3)), f.output); + t.equal(hex, hex2); + t.end(); + }); +} +function jsonify(parsed) { + return JSON.stringify( + parsed, + (key, value) => { + return key !== undefined && + value !== undefined && + (value.type === 'Buffer' || value instanceof Uint8Array) + ? tools.toHex(value) + : typeof value === 'bigint' + ? Number(value) + : value; + }, + 2, + ); +} diff --git a/src/esm/tests/fixtures/combine.d.ts b/src/esm/tests/fixtures/combine.d.ts new file mode 100644 index 0000000..eabaf64 --- /dev/null +++ b/src/esm/tests/fixtures/combine.d.ts @@ -0,0 +1,5 @@ +export declare const fixtures: { + description: string; + psbts: string[]; + result: string; +}[]; diff --git a/src/tests/fixtures/combine.js b/src/esm/tests/fixtures/combine.js similarity index 99% rename from src/tests/fixtures/combine.js rename to src/esm/tests/fixtures/combine.js index 0102abe..4e22500 100644 --- a/src/tests/fixtures/combine.js +++ b/src/esm/tests/fixtures/combine.js @@ -1,6 +1,4 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -exports.fixtures = [ +export const fixtures = [ { description: 'Combines two PSBTs', psbts: [ diff --git a/src/esm/tests/fixtures/create.d.ts b/src/esm/tests/fixtures/create.d.ts new file mode 100644 index 0000000..716102b --- /dev/null +++ b/src/esm/tests/fixtures/create.d.ts @@ -0,0 +1,47 @@ +/// +export declare const fixtures: { + description: string; + input: { + addInputs: { + hash: string; + index: number; + }[]; + addOutputs: { + script: Buffer; + value: bigint; + }[]; + updateInputData: ({ + nonWitnessUtxo: Buffer; + redeemScript: Buffer; + bip32Derivation: { + masterFingerprint: Buffer; + pubkey: Buffer; + path: string; + }[]; + witnessUtxo?: undefined; + witnessScript?: undefined; + } | { + witnessUtxo: { + script: Buffer; + value: bigint; + }; + redeemScript: Buffer; + witnessScript: Buffer; + bip32Derivation: { + masterFingerprint: Buffer; + pubkey: Buffer; + path: string; + }[]; + nonWitnessUtxo?: undefined; + })[]; + updateOutputData: { + bip32Derivation: { + masterFingerprint: Buffer; + pubkey: Buffer; + path: string; + }[]; + }[]; + }; + expectedBeforeUpdate: string; + expectedAfterUpdate: string; +}[]; diff --git a/src/tests/fixtures/create.js b/src/esm/tests/fixtures/create.js similarity index 96% rename from src/tests/fixtures/create.js rename to src/esm/tests/fixtures/create.js index 96ae9b2..8ce4482 100644 --- a/src/tests/fixtures/create.js +++ b/src/esm/tests/fixtures/create.js @@ -1,7 +1,5 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); const b = hex => Buffer.from(hex, 'hex'); -exports.fixtures = [ +export const fixtures = [ { description: 'Should create a psbt', input: { @@ -20,11 +18,11 @@ exports.fixtures = [ addOutputs: [ { script: b('0014d85c2b71d0060b09c9886aeb815e50991dda124d'), - value: 149990000, + value: 149990000n, }, { script: b('001400aea9a2e5f0f876a588df5546e8742d1d87008f'), - value: 100000000, + value: 100000000n, }, ], updateInputData: [ @@ -62,7 +60,7 @@ exports.fixtures = [ { witnessUtxo: { script: b('a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887'), - value: 200000000, + value: 200000000n, }, redeemScript: b( '00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903', diff --git a/src/esm/tests/fixtures/first.d.ts b/src/esm/tests/fixtures/first.d.ts new file mode 100644 index 0000000..cff4de4 --- /dev/null +++ b/src/esm/tests/fixtures/first.d.ts @@ -0,0 +1,27 @@ +export declare const fixtures: { + description: string; + input: string; + output: { + globalMap: { + unsignedTx: string; + }; + inputs: { + witnessUtxo: { + script: string; + value: number; + }; + partialSig: { + pubkey: string; + signature: string; + }[]; + redeemScript: string; + witnessScript: string; + bip32Derivation: { + masterFingerprint: string; + pubkey: string; + path: string; + }[]; + }[]; + outputs: {}[]; + }; +}[]; diff --git a/src/tests/fixtures/first.js b/src/esm/tests/fixtures/first.js similarity index 96% rename from src/tests/fixtures/first.js rename to src/esm/tests/fixtures/first.js index 8f1b773..6e45806 100644 --- a/src/tests/fixtures/first.js +++ b/src/esm/tests/fixtures/first.js @@ -1,6 +1,4 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -exports.fixtures = [ +export const fixtures = [ { description: 'Check one fixture', input: diff --git a/src/esm/tests/fixtures/fromBuffer.d.ts b/src/esm/tests/fixtures/fromBuffer.d.ts new file mode 100644 index 0000000..b66b977 --- /dev/null +++ b/src/esm/tests/fixtures/fromBuffer.d.ts @@ -0,0 +1,4 @@ +export declare const fixtures: { + hex: string; + exception: string; +}[]; diff --git a/src/tests/fixtures/fromBuffer.js b/src/esm/tests/fixtures/fromBuffer.js similarity index 80% rename from src/tests/fixtures/fromBuffer.js rename to src/esm/tests/fixtures/fromBuffer.js index 272d9f8..1d1ca9b 100644 --- a/src/tests/fixtures/fromBuffer.js +++ b/src/esm/tests/fixtures/fromBuffer.js @@ -1,6 +1,4 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -exports.fixtures = [ +export const fixtures = [ { hex: '70736274fe', exception: 'Format Error: Magic Number must be followed by 0xff separator', diff --git a/src/esm/tests/fixtures/invalid.d.ts b/src/esm/tests/fixtures/invalid.d.ts new file mode 100644 index 0000000..7d2eb76 --- /dev/null +++ b/src/esm/tests/fixtures/invalid.d.ts @@ -0,0 +1,4 @@ +export declare const fixtures: { + exception: string; + b64: string; +}[]; diff --git a/src/tests/fixtures/invalid.js b/src/esm/tests/fixtures/invalid.js similarity index 99% rename from src/tests/fixtures/invalid.js rename to src/esm/tests/fixtures/invalid.js index e2b66ee..291d8b0 100644 --- a/src/tests/fixtures/invalid.js +++ b/src/esm/tests/fixtures/invalid.js @@ -1,6 +1,4 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -exports.fixtures = [ +export const fixtures = [ { exception: 'Format Error: Invalid Magic Number', b64: diff --git a/src/esm/tests/fixtures/keyValsToPsbt.d.ts b/src/esm/tests/fixtures/keyValsToPsbt.d.ts new file mode 100644 index 0000000..afbbaca --- /dev/null +++ b/src/esm/tests/fixtures/keyValsToPsbt.d.ts @@ -0,0 +1,38 @@ +/// +export declare const fixtures: ({ + data: { + globalMapKeyVals: { + key: Buffer; + value: Buffer; + }[]; + inputKeyVals: { + key: Buffer; + value: Buffer; + }[][]; + outputKeyVals: never[]; + }; + exception: string; + expected?: undefined; +} | { + data: { + globalMapKeyVals: never[]; + inputKeyVals: never[]; + outputKeyVals: { + key: Buffer; + value: Buffer; + }[][]; + }; + exception: string; + expected?: undefined; +} | { + data: { + globalMapKeyVals: { + key: Buffer; + value: Buffer; + }[]; + inputKeyVals: never[]; + outputKeyVals: never[]; + }; + expected: string; + exception?: undefined; +})[]; diff --git a/src/tests/fixtures/keyValsToPsbt.js b/src/esm/tests/fixtures/keyValsToPsbt.js similarity index 98% rename from src/tests/fixtures/keyValsToPsbt.js rename to src/esm/tests/fixtures/keyValsToPsbt.js index 8eb10c2..e4b4571 100644 --- a/src/tests/fixtures/keyValsToPsbt.js +++ b/src/esm/tests/fixtures/keyValsToPsbt.js @@ -1,7 +1,5 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); const b = hex => Buffer.from(hex, 'hex'); -exports.fixtures = [ +export const fixtures = [ { data: { globalMapKeyVals: [ diff --git a/src/esm/tests/fixtures/methods.d.ts b/src/esm/tests/fixtures/methods.d.ts new file mode 100644 index 0000000..3c47cbf --- /dev/null +++ b/src/esm/tests/fixtures/methods.d.ts @@ -0,0 +1,406 @@ +/// +export declare const fixtures: { + valid: ({ + method: string; + addInputOutput: boolean; + args: { + globalXpub: { + masterFingerprint: Buffer; + extendedPubkey: Buffer; + path: string; + }[]; + }[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + nonWitnessUtxo: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + witnessUtxo: { + script: Buffer; + value: bigint; + }; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + partialSig: { + pubkey: Buffer; + signature: Buffer; + }[]; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapInternalKey: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapMerkleRoot: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapKeySig: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapScriptSig: { + pubkey: Buffer; + leafHash: Buffer; + signature: Buffer; + }[]; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapLeafScript: { + controlBlock: Buffer; + script: Buffer; + leafVersion: number; + }[]; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + sighashType: number; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + redeemScript: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + witnessScript: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + bip32Derivation: { + masterFingerprint: Buffer; + path: string; + pubkey: Buffer; + }[]; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapBip32Derivation: { + leafHashes: Buffer[]; + masterFingerprint: Buffer; + path: string; + pubkey: Buffer; + }[]; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + finalScriptSig: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + finalScriptWitness: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + porCommitment: string; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + tapTree: { + leaves: { + depth: number; + script: Buffer; + leafVersion: number; + }[]; + }; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + key: Buffer; + value: Buffer; + })[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: { + hash: string; + index: number; + }[]; + expected: string; + } | { + method: string; + addInputOutput: boolean; + args: { + script: Buffer; + value: number; + }[]; + expected: string; + })[]; + invalid: ({ + method: string; + addInputOutput: boolean; + args: { + globalXpub: number; + }[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: { + globalXpub: number[]; + }[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + nonWitnessUtxo: string; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + twice: boolean; + args: (number | { + nonWitnessUtxo: Buffer; + })[]; + exception: string; + } | { + method: string; + addInputOutput: boolean; + twice: boolean; + args: (number | { + partialSig: { + pubkey: Buffer; + signature: Buffer; + }[]; + })[]; + exception: string; + } | { + method: string; + addInputOutput: boolean; + twice: boolean; + args: (number | { + tapScriptSig: { + pubkey: Buffer; + leafHash: Buffer; + signature: Buffer; + }[]; + })[]; + exception: string; + } | { + method: string; + addInputOutput: boolean; + twice: boolean; + args: (number | { + tapLeafScript: { + controlBlock: Buffer; + script: Buffer; + leafVersion: number; + }[]; + })[]; + exception: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + witnessUtxo: { + scripty: Buffer; + vyalue: number; + }; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + twice: boolean; + args: (number | { + witnessUtxo: { + script: Buffer; + value: bigint; + }; + })[]; + exception: string; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + partialSig: { + pubkdey: Buffer; + signdature: Buffer; + }[]; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + sighashType: string; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + redeemScript: string; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + witnessScript: string; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + bip32Derivation: { + a: number; + }[]; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + finalScriptSig: number; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + finalScriptWitness: number; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + porCommitment: number; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + redeemScript: number; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | { + witnessScript: number; + })[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: (number | Buffer)[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: { + hash: string; + index: number; + unknownKeyVals: number; + }[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: { + script: Buffer; + value: number; + unknownKeyVals: number; + }[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + args: { + key: Buffer; + value: Buffer; + }[]; + exception: string; + twice?: undefined; + } | { + method: string; + addInputOutput: boolean; + twice: boolean; + args: { + key: Buffer; + value: Buffer; + }[]; + exception: string; + })[]; +}; diff --git a/src/tests/fixtures/methods.js b/src/esm/tests/fixtures/methods.js similarity index 97% rename from src/tests/fixtures/methods.js rename to src/esm/tests/fixtures/methods.js index 7136636..56351a4 100644 --- a/src/tests/fixtures/methods.js +++ b/src/esm/tests/fixtures/methods.js @@ -1,5 +1,3 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); const b = h => Buffer.from(h, 'hex'); const dummyPubkeys = [ '03b1341ccba7683b6af4f1238cd6e97e7167d569fac47f1e48d47541844355bd46', @@ -30,7 +28,7 @@ const dummySchnorrSig = 'a251221c339a7129dd0b769698aca40d8d9da9570ab796a1820b91ab7dbf5acb' + 'ea21c88ba8f1e9308a21729baf080734beaf97023882d972f75e380d480fd704'; const dummy4Byte = '01020304'; -exports.fixtures = { +export const fixtures = { valid: [ { method: 'updateGlobal', @@ -73,7 +71,7 @@ exports.fixtures = { addInputOutput: true, args: [ 0, - { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890 } }, + { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890n } }, ], expected: 'cHNidP8BAFMBAAAAAdSnb/ld4fTAFho+U+qHapHtlTMa6NAS2B+XE4SYzl2GAwAAAAD/' + @@ -434,14 +432,14 @@ exports.fixtures = { ], exception: 'Data for global key globalXpub is incorrect: Expected { ' + - 'masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; } and got', + 'masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; } and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { nonWitnessUtxo: 'blah' }], exception: - 'Data for input key nonWitnessUtxo is incorrect: Expected Buffer and got', + 'Data for input key nonWitnessUtxo is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', @@ -509,7 +507,7 @@ exports.fixtures = { ], exception: 'Data for input key witnessUtxo is incorrect: Expected { ' + - 'script: Buffer; value: number; } and got', + 'script: Uint8Array; value: bigint; } and got', }, { method: 'updateInput', @@ -517,7 +515,7 @@ exports.fixtures = { twice: true, args: [ 0, - { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890 } }, + { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890n } }, ], exception: 'Can not add duplicate data to input', }, @@ -534,7 +532,7 @@ exports.fixtures = { ], exception: 'Data for input key partialSig is incorrect: Expected { pubkey: ' + - 'Buffer; signature: Buffer; } and got', + 'Uint8Array; signature: Uint8Array; } and got', }, { method: 'updateInput', @@ -548,14 +546,14 @@ exports.fixtures = { addInputOutput: true, args: [0, { redeemScript: 'a' }], exception: - 'Data for input key redeemScript is incorrect: Expected Buffer and got', + 'Data for input key redeemScript is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { witnessScript: 'a' }], exception: - 'Data for input key witnessScript is incorrect: Expected Buffer and got', + 'Data for input key witnessScript is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', @@ -572,21 +570,21 @@ exports.fixtures = { ], exception: 'Data for input key bip32Derivation is incorrect: Expected { ' + - 'masterFingerprint: Buffer; pubkey: Buffer; path: string; } and got', + 'masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; } and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { finalScriptSig: 8 }], exception: - 'Data for input key finalScriptSig is incorrect: Expected Buffer and got', + 'Data for input key finalScriptSig is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { finalScriptWitness: 8 }], exception: - 'Data for input key finalScriptWitness is incorrect: Expected Buffer and got', + 'Data for input key finalScriptWitness is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', @@ -600,14 +598,14 @@ exports.fixtures = { addInputOutput: true, args: [0, { redeemScript: 8 }], exception: - 'Data for output key redeemScript is incorrect: Expected Buffer and got', + 'Data for output key redeemScript is incorrect: Expected Uint8Array and got', }, { method: 'updateOutput', addInputOutput: true, args: [0, { witnessScript: 8 }], exception: - 'Data for output key witnessScript is incorrect: Expected Buffer and got', + 'Data for output key witnessScript is incorrect: Expected Uint8Array and got', }, { method: 'updateOutput', @@ -624,7 +622,7 @@ exports.fixtures = { ], exception: 'Data for output key bip32Derivation is incorrect: Expected { ' + - 'masterFingerprint: Buffer; pubkey: Buffer; path: string; } and got', + 'masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; } and got', }, { method: 'updateInput', diff --git a/src/esm/tests/fixtures/update.d.ts b/src/esm/tests/fixtures/update.d.ts new file mode 100644 index 0000000..1cc0435 --- /dev/null +++ b/src/esm/tests/fixtures/update.d.ts @@ -0,0 +1,87 @@ +/// +export declare const fixtures: ({ + description: string; + before: string; + inputData: ({ + nonWitnessUtxo: Buffer; + witnessUtxo: { + script: Buffer; + value: bigint; + }; + redeemScript: Buffer; + bip32Derivation: { + masterFingerprint: Buffer; + pubkey: Buffer; + path: string; + }[]; + witnessScript?: undefined; + } | { + witnessUtxo: { + script: Buffer; + value: bigint; + }; + redeemScript: Buffer; + witnessScript: Buffer; + bip32Derivation: { + masterFingerprint: Buffer; + pubkey: Buffer; + path: string; + }[]; + nonWitnessUtxo?: undefined; + })[]; + outputData: { + bip32Derivation: { + masterFingerprint: Buffer; + pubkey: Buffer; + path: string; + }[]; + }[]; + after: string; + cleanForFinalize?: undefined; +} | { + description: string; + inputData: { + sighashType: number; + }[]; + outputData: never[]; + after: string; + before?: undefined; + cleanForFinalize?: undefined; +} | { + description: string; + inputData: { + partialSig: { + pubkey: Buffer; + signature: Buffer; + }[]; + }[]; + outputData: never[]; + after: string; + before?: undefined; + cleanForFinalize?: undefined; +} | { + description: string; + before: string; + inputData: { + partialSig: { + pubkey: Buffer; + signature: Buffer; + }[]; + }[]; + outputData: never[]; + after: string; + cleanForFinalize?: undefined; +} | { + description: string; + cleanForFinalize: boolean; + before: string; + inputData: ({ + finalScriptSig: Buffer; + finalScriptWitness?: undefined; + } | { + finalScriptSig: Buffer; + finalScriptWitness: Buffer; + })[]; + outputData: never[]; + after: string; +})[]; diff --git a/src/tests/fixtures/update.js b/src/esm/tests/fixtures/update.js similarity index 99% rename from src/tests/fixtures/update.js rename to src/esm/tests/fixtures/update.js index 6595e8f..fe23e0c 100644 --- a/src/tests/fixtures/update.js +++ b/src/esm/tests/fixtures/update.js @@ -1,7 +1,5 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); const b = hex => Buffer.from(hex, 'hex'); -exports.fixtures = [ +export const fixtures = [ { description: 'Step 1: From 2 empty inputs and 2 empty outputs, add set of info.', @@ -22,7 +20,7 @@ exports.fixtures = [ ), witnessUtxo: { script: b('0014ce2ef55e561be15ef65dcc79f998117e142d6016'), - value: 10413, + value: 10413n, }, redeemScript: b( '5221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96' + @@ -49,7 +47,7 @@ exports.fixtures = [ { witnessUtxo: { script: b('a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887'), - value: 200000000, + value: 200000000n, }, redeemScript: b( '00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903', diff --git a/src/esm/tests/fixtures/valid.d.ts b/src/esm/tests/fixtures/valid.d.ts new file mode 100644 index 0000000..e465142 --- /dev/null +++ b/src/esm/tests/fixtures/valid.d.ts @@ -0,0 +1 @@ +export declare const fixtures: string[]; diff --git a/src/tests/fixtures/valid.js b/src/esm/tests/fixtures/valid.js similarity index 99% rename from src/tests/fixtures/valid.js rename to src/esm/tests/fixtures/valid.js index f60a37c..5509f0a 100644 --- a/src/tests/fixtures/valid.js +++ b/src/esm/tests/fixtures/valid.js @@ -1,6 +1,4 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -exports.fixtures = [ +export const fixtures = [ 'cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapF' + 'NDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAA' + 'AAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF///' + diff --git a/src/esm/tests/fixtures/varint.d.ts b/src/esm/tests/fixtures/varint.d.ts new file mode 100644 index 0000000..2d3ce76 --- /dev/null +++ b/src/esm/tests/fixtures/varint.d.ts @@ -0,0 +1,15 @@ +export declare const fixtures: { + valid: { + dec: number; + hex: string; + }[]; + invalid: ({ + dec: number; + msg: string; + hex?: undefined; + } | { + dec: number; + hex: string; + msg: string; + })[]; +}; diff --git a/src/tests/fixtures/varint.js b/src/esm/tests/fixtures/varint.js similarity index 91% rename from src/tests/fixtures/varint.js rename to src/esm/tests/fixtures/varint.js index 12a9e6a..7fc6c6d 100644 --- a/src/tests/fixtures/varint.js +++ b/src/esm/tests/fixtures/varint.js @@ -1,6 +1,4 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -exports.fixtures = { +export const fixtures = { valid: [ { dec: 0, diff --git a/src/esm/tests/fromBIP/invalid.d.ts b/src/esm/tests/fromBIP/invalid.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/fromBIP/invalid.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/fromBIP/invalid.js b/src/esm/tests/fromBIP/invalid.js similarity index 63% rename from src/tests/fromBIP/invalid.js rename to src/esm/tests/fromBIP/invalid.js index 99bfb54..4c49346 100644 --- a/src/tests/fromBIP/invalid.js +++ b/src/esm/tests/fromBIP/invalid.js @@ -1,14 +1,12 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../../lib/psbt'); -const invalid_1 = require('../fixtures/invalid'); -const txTools_1 = require('../utils/txTools'); +import tape from 'tape'; +import { Psbt } from '../../lib/psbt.js'; +import { fixtures } from '../fixtures/invalid.js'; +import { transactionFromBuffer } from '../utils/txTools.js'; // const res: any[] = []; -for (const f of invalid_1.fixtures) { +for (const f of fixtures) { tape(`Test: Should throw "${f.exception}"`, t => { t.throws(() => { - psbt_1.Psbt.fromBase64(f.b64, txTools_1.transactionFromBuffer); + Psbt.fromBase64(f.b64, transactionFromBuffer); }, new RegExp(f.exception)); t.end(); }); diff --git a/src/esm/tests/fromBIP/update.d.ts b/src/esm/tests/fromBIP/update.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/fromBIP/update.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/fromBIP/update.js b/src/esm/tests/fromBIP/update.js similarity index 54% rename from src/tests/fromBIP/update.js rename to src/esm/tests/fromBIP/update.js index c024f73..ce72c2d 100644 --- a/src/tests/fromBIP/update.js +++ b/src/esm/tests/fromBIP/update.js @@ -1,17 +1,12 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../../lib/psbt'); -const update_1 = require('../fixtures/update'); -const txTools_1 = require('../utils/txTools'); +import tape from 'tape'; +import { Psbt } from '../../lib/psbt.js'; +import { fixtures } from '../fixtures/update.js'; +import { transactionFromBuffer } from '../utils/txTools.js'; let lastAfter; -for (const f of update_1.fixtures) { +for (const f of fixtures) { tape(f.description, t => { const before = f.before || lastAfter; - const psbt = psbt_1.Psbt.fromBase64( - before, - txTools_1.transactionFromBuffer, - ); + const psbt = Psbt.fromBase64(before, transactionFromBuffer); for (const [i, input] of f.inputData.entries()) { psbt.updateInput(i, input); if (f.cleanForFinalize) psbt.clearFinalizedInput(i); diff --git a/src/esm/tests/fromBIP/valid.d.ts b/src/esm/tests/fromBIP/valid.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/fromBIP/valid.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/esm/tests/fromBIP/valid.js b/src/esm/tests/fromBIP/valid.js new file mode 100644 index 0000000..6ba7992 --- /dev/null +++ b/src/esm/tests/fromBIP/valid.js @@ -0,0 +1,17 @@ +import tape from 'tape'; +import { Psbt } from '../../lib/psbt.js'; +import { fixtures } from '../fixtures/valid.js'; +import { transactionFromBuffer } from '../utils/txTools.js'; +for (const f of fixtures) { + tape(`Test: Should not throw`, t => { + let psbt; + t.doesNotThrow(() => { + psbt = Psbt.fromBase64(f, transactionFromBuffer); + }, 'fromBase64'); + t.doesNotThrow(() => { + const out = psbt.toBase64(); + t.equal(out, f); + }, 'toBase64'); + t.end(); + }); +} diff --git a/src/esm/tests/fromBuffer.d.ts b/src/esm/tests/fromBuffer.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/fromBuffer.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/fromBuffer.js b/src/esm/tests/fromBuffer.js similarity index 60% rename from src/tests/fromBuffer.js rename to src/esm/tests/fromBuffer.js index 649bbab..73b573f 100644 --- a/src/tests/fromBuffer.js +++ b/src/esm/tests/fromBuffer.js @@ -1,8 +1,6 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../lib/psbt'); -const fromBuffer_1 = require('./fixtures/fromBuffer'); +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/fromBuffer.js'; class Blah { constructor(buf) { this.buf = buf; @@ -24,10 +22,10 @@ class Blah { } } const fromBuf = b => new Blah(b); -for (const f of fromBuffer_1.fixtures) { +for (const f of fixtures) { tape('From Buffer should throw:', t => { t.throws(() => { - psbt_1.Psbt.fromHex(f.hex, fromBuf); + Psbt.fromHex(f.hex, fromBuf); }, new RegExp(f.exception)); t.end(); }); diff --git a/src/esm/tests/keyValsToPsbt.d.ts b/src/esm/tests/keyValsToPsbt.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/keyValsToPsbt.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/esm/tests/keyValsToPsbt.js b/src/esm/tests/keyValsToPsbt.js new file mode 100644 index 0000000..360c992 --- /dev/null +++ b/src/esm/tests/keyValsToPsbt.js @@ -0,0 +1,26 @@ +import tape from 'tape'; +import { psbtFromKeyVals } from '../lib/parser/fromBuffer.js'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/keyValsToPsbt.js'; +import { getDefaultTx, transactionFromBuffer } from './utils/txTools.js'; +for (const f of fixtures) { + if (f.exception) { + tape('From keyVals should throw:', t => { + t.throws(() => { + psbtFromKeyVals(getDefaultTx(), f.data); + }, new RegExp(f.exception)); + t.end(); + }); + } else { + const tx = transactionFromBuffer( + f.data.globalMapKeyVals.filter(kv => kv.key[0] === 0)[0].value, + ); + tape('From keyVals should not throw:', t => { + const data = psbtFromKeyVals(tx, f.data); + const psbt = new Psbt(tx); + Object.assign(psbt, data); + t.strictEqual(psbt.toBase64(), f.expected); + t.end(); + }); + } +} diff --git a/src/esm/tests/methods.d.ts b/src/esm/tests/methods.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/methods.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/methods.js b/src/esm/tests/methods.js similarity index 71% rename from src/tests/methods.js rename to src/esm/tests/methods.js index 71e6600..28e6f9b 100644 --- a/src/tests/methods.js +++ b/src/esm/tests/methods.js @@ -1,18 +1,16 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../lib/psbt'); -const methods_1 = require('./fixtures/methods'); -const txTools_1 = require('./utils/txTools'); +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/methods.js'; +import { getDefaultTx } from './utils/txTools.js'; function run(f, typ) { tape(`check ${typ} method: ${f.method}`, t => { let func; let psbt; if (!f.addInputOutput) { // @ts-ignore - func = psbt_1.Psbt[f.method].bind(psbt_1.Psbt); + func = Psbt[f.method].bind(Psbt); } else { - psbt = new psbt_1.Psbt(txTools_1.getDefaultTx()); + psbt = new Psbt(getDefaultTx()); addInputOutput(psbt); // @ts-ignore func = psbt[f.method].bind(psbt); @@ -38,10 +36,10 @@ function run(f, typ) { t.end(); }); } -for (const f of methods_1.fixtures.valid) { +for (const f of fixtures.valid) { run(f, 'valid'); } -for (const f of methods_1.fixtures.invalid) { +for (const f of fixtures.invalid) { run(f, 'invalid'); } function addInputOutput(psbt) { diff --git a/src/esm/tests/utils/txTools.d.ts b/src/esm/tests/utils/txTools.d.ts new file mode 100644 index 0000000..50ad818 --- /dev/null +++ b/src/esm/tests/utils/txTools.d.ts @@ -0,0 +1,16 @@ +/// +import { Transaction as BTransaction } from 'bitcoinjs-lib'; +import { Transaction as ITransaction, TransactionFromBuffer } from '../../lib/interfaces'; +export declare function getDefaultTx(version?: number): Transaction; +export declare const transactionFromBuffer: TransactionFromBuffer; +export declare class Transaction implements ITransaction { + tx: BTransaction; + constructor(buffer: Uint8Array); + getInputOutputCounts(): { + inputCount: number; + outputCount: number; + }; + addInput(input: any): void; + addOutput(output: any): void; + toBuffer(): Buffer; +} diff --git a/src/tests/utils/txTools.js b/src/esm/tests/utils/txTools.js similarity index 54% rename from src/tests/utils/txTools.js rename to src/esm/tests/utils/txTools.js index 03dea88..68ea078 100644 --- a/src/tests/utils/txTools.js +++ b/src/esm/tests/utils/txTools.js @@ -1,17 +1,14 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const bitcoinjs_lib_1 = require('bitcoinjs-lib'); -const tools_1 = require('../../lib/converter/tools'); -function getDefaultTx(version = 1) { +import { Transaction as BTransaction } from 'bitcoinjs-lib'; +import { reverseBuffer } from '../../lib/converter/tools.js'; +export function getDefaultTx(version = 1) { const TX = new Transaction(Buffer.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0])); TX.tx.version = version; return TX; } -exports.getDefaultTx = getDefaultTx; -exports.transactionFromBuffer = buffer => new Transaction(buffer); -class Transaction { +export const transactionFromBuffer = buffer => new Transaction(buffer); +export class Transaction { constructor(buffer) { - this.tx = bitcoinjs_lib_1.Transaction.fromBuffer(buffer); + this.tx = BTransaction.fromBuffer(Buffer.from(buffer)); if (this.tx.ins.some(input => input.script.length !== 0)) { throw new Error('Format Error: Transaction ScriptSigs are not empty'); } @@ -25,15 +22,14 @@ class Transaction { addInput(input) { const hash = typeof input.hash === 'string' - ? tools_1.reverseBuffer(Buffer.from(input.hash, 'hex')) + ? reverseBuffer(Buffer.from(input.hash, 'hex')) : input.hash; this.tx.addInput(hash, input.index, input.sequence); } addOutput(output) { - this.tx.addOutput(output.script, output.value); + this.tx.addOutput(output.script, Number(output.value)); } toBuffer() { return this.tx.toBuffer(); } } -exports.Transaction = Transaction; diff --git a/src/esm/tests/validation.d.ts b/src/esm/tests/validation.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/esm/tests/validation.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/tests/validation.js b/src/esm/tests/validation.js similarity index 68% rename from src/tests/validation.js rename to src/esm/tests/validation.js index 2ce6c2c..cfe3993 100644 --- a/src/tests/validation.js +++ b/src/esm/tests/validation.js @@ -1,9 +1,11 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const combiner_1 = require('../lib/combiner'); -const converter_1 = require('../lib/converter'); -const txTools_1 = require('./utils/txTools'); +import tape from 'tape'; +import { combine } from '../lib/combiner/index.js'; +import { + globals as convertGlobal, + inputs as convertInputs, +} from '../lib/converter/index.js'; +import { getDefaultTx } from './utils/txTools.js'; +import * as tools from 'uint8array-tools'; const b = hex => Buffer.from(hex, 'hex'); tape('should not pass isPartialSig with invalid DER signature', t => { const data = { @@ -24,49 +26,49 @@ tape('should not pass isPartialSig with invalid DER signature', t => { ]; for (const sig of sigs) { data.signature = sig; - t.assert(converter_1.inputs.partialSig.check(data) === false); + t.assert(convertInputs.partialSig.check(data) === false); } const keyVal = { key: b('ff'), value: b('ff'), }; t.throws(() => { - converter_1.inputs.nonWitnessUtxo.decode(keyVal); + convertInputs.nonWitnessUtxo.decode(keyVal); }, new RegExp('Decode Error: could not decode nonWitnessUtxo with key 0xff')); t.throws(() => { - converter_1.inputs.witnessUtxo.decode(keyVal); + convertInputs.witnessUtxo.decode(keyVal); }, new RegExp('Decode Error: could not decode witnessUtxo with key 0xff')); t.throws(() => { - converter_1.inputs.finalScriptSig.decode(keyVal); + convertInputs.finalScriptSig.decode(keyVal); }, new RegExp('Decode Error: could not decode finalScriptSig with key 0xff')); t.throws(() => { - converter_1.inputs.finalScriptWitness.decode(keyVal); + convertInputs.finalScriptWitness.decode(keyVal); }, new RegExp('Decode Error: could not decode finalScriptWitness with key 0xff')); t.throws(() => { - converter_1.inputs.porCommitment.decode(keyVal); + convertInputs.porCommitment.decode(keyVal); }, new RegExp('Decode Error: could not decode porCommitment with key 0xff')); t.throws(() => { - converter_1.inputs.sighashType.decode(keyVal); + convertInputs.sighashType.decode(keyVal); }, new RegExp('Decode Error: could not decode sighashType with key 0xff')); t.throws(() => { - converter_1.inputs.redeemScript.decode(keyVal); + convertInputs.redeemScript.decode(keyVal); }, new RegExp('Decode Error: could not decode redeemScript with key 0xff')); t.throws(() => { - converter_1.inputs.witnessScript.decode(keyVal); + convertInputs.witnessScript.decode(keyVal); }, new RegExp('Decode Error: could not decode witnessScript with key 0xff')); t.throws(() => { - converter_1.inputs.bip32Derivation.decode(keyVal); + convertInputs.bip32Derivation.decode(keyVal); }, new RegExp('Decode Error: could not decode bip32Derivation with key 0xff')); t.throws(() => { - converter_1.inputs.partialSig.decode(keyVal); + convertInputs.partialSig.decode(keyVal); }, new RegExp('Decode Error: could not decode partialSig with key 0xff')); keyVal.key = b('02ff'); t.throws(() => { - converter_1.inputs.partialSig.decode(keyVal); + convertInputs.partialSig.decode(keyVal); }, new RegExp('Decode Error: partialSig has invalid pubkey in key 0x02ff')); keyVal.key = Buffer.concat([b('02'), data.pubkey, data.pubkey.slice(1)]); - const result = converter_1.inputs.partialSig.decode(keyVal); - t.assert(result.pubkey.equals(keyVal.key.slice(1))); + const result = convertInputs.partialSig.decode(keyVal); + t.assert(tools.compare(result.pubkey, keyVal.key.slice(1)) === 0); const psbt1 = { globalMap: { unknownKeyVals: [], @@ -82,15 +84,15 @@ tape('should not pass isPartialSig with invalid DER signature', t => { outputs: [], }; t.throws(() => { - combiner_1.combine([psbt1]); + combine([psbt1]); }, new RegExp('Combine: Nothing to combine')); t.throws(() => { - combiner_1.combine([psbt1, psbt2]); + combine([psbt1, psbt2]); }, new RegExp('Combine: Self missing transaction')); - psbt1.globalMap.unsignedTx = txTools_1.getDefaultTx(1); - psbt2.globalMap.unsignedTx = txTools_1.getDefaultTx(2); + psbt1.globalMap.unsignedTx = getDefaultTx(1); + psbt2.globalMap.unsignedTx = getDefaultTx(2); t.throws(() => { - combiner_1.combine([psbt1, psbt2]); + combine([psbt1, psbt2]); }, new RegExp('Combine: One of the Psbts does not have the same transaction.')); psbt1.globalMap.unknownKeyVals.push({ key: b('09'), @@ -101,10 +103,10 @@ tape('should not pass isPartialSig with invalid DER signature', t => { value: b('ff'), }); t.throws(() => { - combiner_1.combine([psbt1, psbt2]); + combine([psbt1, psbt2]); }, new RegExp('Combine: KeyValue Map keys should be unique')); t.ok( - converter_1.globals.globalXpub.check({ + convertGlobal.globalXpub.check({ masterFingerprint: b('3442193e'), extendedPubkey: b( // tslint:disable-next-line:max-line-length diff --git a/src/lib/converter/index.d.ts b/src/lib/converter/index.d.ts deleted file mode 100644 index 074eb3d..0000000 --- a/src/lib/converter/index.d.ts +++ /dev/null @@ -1,109 +0,0 @@ -/// -import * as globalXpub from './global/globalXpub'; -import * as unsignedTx from './global/unsignedTx'; -import * as finalScriptSig from './input/finalScriptSig'; -import * as finalScriptWitness from './input/finalScriptWitness'; -import * as nonWitnessUtxo from './input/nonWitnessUtxo'; -import * as partialSig from './input/partialSig'; -import * as porCommitment from './input/porCommitment'; -import * as sighashType from './input/sighashType'; -import * as tapKeySig from './input/tapKeySig'; -import * as tapLeafScript from './input/tapLeafScript'; -import * as tapMerkleRoot from './input/tapMerkleRoot'; -import * as tapScriptSig from './input/tapScriptSig'; -import * as witnessUtxo from './input/witnessUtxo'; -import * as tapTree from './output/tapTree'; -declare const globals: { - unsignedTx: typeof unsignedTx; - globalXpub: typeof globalXpub; - checkPubkey: (keyVal: import("../interfaces").KeyValue) => Buffer | undefined; -}; -declare const inputs: { - nonWitnessUtxo: typeof nonWitnessUtxo; - partialSig: typeof partialSig; - sighashType: typeof sighashType; - finalScriptSig: typeof finalScriptSig; - finalScriptWitness: typeof finalScriptWitness; - porCommitment: typeof porCommitment; - witnessUtxo: typeof witnessUtxo; - bip32Derivation: { - decode: (keyVal: import("../interfaces").KeyValue) => import("../interfaces").Bip32Derivation; - encode: (data: import("../interfaces").Bip32Derivation) => import("../interfaces").KeyValue; - check: (data: any) => data is import("../interfaces").Bip32Derivation; - expected: string; - canAddToArray: (array: import("../interfaces").Bip32Derivation[], item: import("../interfaces").Bip32Derivation, dupeSet: Set) => boolean; - }; - redeemScript: { - decode: (keyVal: import("../interfaces").KeyValue) => Buffer; - encode: (data: Buffer) => import("../interfaces").KeyValue; - check: (data: any) => data is Buffer; - expected: string; - canAdd: (currentData: any, newData: any) => boolean; - }; - witnessScript: { - decode: (keyVal: import("../interfaces").KeyValue) => Buffer; - encode: (data: Buffer) => import("../interfaces").KeyValue; - check: (data: any) => data is Buffer; - expected: string; - canAdd: (currentData: any, newData: any) => boolean; - }; - checkPubkey: (keyVal: import("../interfaces").KeyValue) => Buffer | undefined; - tapKeySig: typeof tapKeySig; - tapScriptSig: typeof tapScriptSig; - tapLeafScript: typeof tapLeafScript; - tapBip32Derivation: { - decode: (keyVal: import("../interfaces").KeyValue) => import("../interfaces").TapBip32Derivation; - encode: (data: import("../interfaces").TapBip32Derivation) => import("../interfaces").KeyValue; - check: (data: any) => data is import("../interfaces").TapBip32Derivation; - expected: string; - canAddToArray: (array: import("../interfaces").TapBip32Derivation[], item: import("../interfaces").TapBip32Derivation, dupeSet: Set) => boolean; - }; - tapInternalKey: { - decode: (keyVal: import("../interfaces").KeyValue) => Buffer; - encode: (data: Buffer) => import("../interfaces").KeyValue; - check: (data: any) => data is Buffer; - expected: string; - canAdd: (currentData: any, newData: any) => boolean; - }; - tapMerkleRoot: typeof tapMerkleRoot; -}; -declare const outputs: { - bip32Derivation: { - decode: (keyVal: import("../interfaces").KeyValue) => import("../interfaces").Bip32Derivation; - encode: (data: import("../interfaces").Bip32Derivation) => import("../interfaces").KeyValue; - check: (data: any) => data is import("../interfaces").Bip32Derivation; - expected: string; - canAddToArray: (array: import("../interfaces").Bip32Derivation[], item: import("../interfaces").Bip32Derivation, dupeSet: Set) => boolean; - }; - redeemScript: { - decode: (keyVal: import("../interfaces").KeyValue) => Buffer; - encode: (data: Buffer) => import("../interfaces").KeyValue; - check: (data: any) => data is Buffer; - expected: string; - canAdd: (currentData: any, newData: any) => boolean; - }; - witnessScript: { - decode: (keyVal: import("../interfaces").KeyValue) => Buffer; - encode: (data: Buffer) => import("../interfaces").KeyValue; - check: (data: any) => data is Buffer; - expected: string; - canAdd: (currentData: any, newData: any) => boolean; - }; - checkPubkey: (keyVal: import("../interfaces").KeyValue) => Buffer | undefined; - tapBip32Derivation: { - decode: (keyVal: import("../interfaces").KeyValue) => import("../interfaces").TapBip32Derivation; - encode: (data: import("../interfaces").TapBip32Derivation) => import("../interfaces").KeyValue; - check: (data: any) => data is import("../interfaces").TapBip32Derivation; - expected: string; - canAddToArray: (array: import("../interfaces").TapBip32Derivation[], item: import("../interfaces").TapBip32Derivation, dupeSet: Set) => boolean; - }; - tapTree: typeof tapTree; - tapInternalKey: { - decode: (keyVal: import("../interfaces").KeyValue) => Buffer; - encode: (data: Buffer) => import("../interfaces").KeyValue; - check: (data: any) => data is Buffer; - expected: string; - canAdd: (currentData: any, newData: any) => boolean; - }; -}; -export { globals, inputs, outputs }; diff --git a/src/lib/converter/index.js b/src/lib/converter/index.js deleted file mode 100644 index 729d05d..0000000 --- a/src/lib/converter/index.js +++ /dev/null @@ -1,85 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../typeFields'); -const globalXpub = require('./global/globalXpub'); -const unsignedTx = require('./global/unsignedTx'); -const finalScriptSig = require('./input/finalScriptSig'); -const finalScriptWitness = require('./input/finalScriptWitness'); -const nonWitnessUtxo = require('./input/nonWitnessUtxo'); -const partialSig = require('./input/partialSig'); -const porCommitment = require('./input/porCommitment'); -const sighashType = require('./input/sighashType'); -const tapKeySig = require('./input/tapKeySig'); -const tapLeafScript = require('./input/tapLeafScript'); -const tapMerkleRoot = require('./input/tapMerkleRoot'); -const tapScriptSig = require('./input/tapScriptSig'); -const witnessUtxo = require('./input/witnessUtxo'); -const tapTree = require('./output/tapTree'); -const bip32Derivation = require('./shared/bip32Derivation'); -const checkPubkey = require('./shared/checkPubkey'); -const redeemScript = require('./shared/redeemScript'); -const tapBip32Derivation = require('./shared/tapBip32Derivation'); -const tapInternalKey = require('./shared/tapInternalKey'); -const witnessScript = require('./shared/witnessScript'); -const globals = { - unsignedTx, - globalXpub, - // pass an Array of key bytes that require pubkey beside the key - checkPubkey: checkPubkey.makeChecker([]), -}; -exports.globals = globals; -const inputs = { - nonWitnessUtxo, - partialSig, - sighashType, - finalScriptSig, - finalScriptWitness, - porCommitment, - witnessUtxo, - bip32Derivation: bip32Derivation.makeConverter( - typeFields_1.InputTypes.BIP32_DERIVATION, - ), - redeemScript: redeemScript.makeConverter( - typeFields_1.InputTypes.REDEEM_SCRIPT, - ), - witnessScript: witnessScript.makeConverter( - typeFields_1.InputTypes.WITNESS_SCRIPT, - ), - checkPubkey: checkPubkey.makeChecker([ - typeFields_1.InputTypes.PARTIAL_SIG, - typeFields_1.InputTypes.BIP32_DERIVATION, - ]), - tapKeySig, - tapScriptSig, - tapLeafScript, - tapBip32Derivation: tapBip32Derivation.makeConverter( - typeFields_1.InputTypes.TAP_BIP32_DERIVATION, - ), - tapInternalKey: tapInternalKey.makeConverter( - typeFields_1.InputTypes.TAP_INTERNAL_KEY, - ), - tapMerkleRoot, -}; -exports.inputs = inputs; -const outputs = { - bip32Derivation: bip32Derivation.makeConverter( - typeFields_1.OutputTypes.BIP32_DERIVATION, - ), - redeemScript: redeemScript.makeConverter( - typeFields_1.OutputTypes.REDEEM_SCRIPT, - ), - witnessScript: witnessScript.makeConverter( - typeFields_1.OutputTypes.WITNESS_SCRIPT, - ), - checkPubkey: checkPubkey.makeChecker([ - typeFields_1.OutputTypes.BIP32_DERIVATION, - ]), - tapBip32Derivation: tapBip32Derivation.makeConverter( - typeFields_1.OutputTypes.TAP_BIP32_DERIVATION, - ), - tapTree, - tapInternalKey: tapInternalKey.makeConverter( - typeFields_1.OutputTypes.TAP_INTERNAL_KEY, - ), -}; -exports.outputs = outputs; diff --git a/src/lib/converter/input/finalScriptSig.js b/src/lib/converter/input/finalScriptSig.js deleted file mode 100644 index d41e7b1..0000000 --- a/src/lib/converter/input/finalScriptSig.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.FINAL_SCRIPTSIG) { - throw new Error( - 'Decode Error: could not decode finalScriptSig with key 0x' + - keyVal.key.toString('hex'), - ); - } - return keyVal.value; -} -exports.decode = decode; -function encode(data) { - const key = Buffer.from([typeFields_1.InputTypes.FINAL_SCRIPTSIG]); - return { - key, - value: data, - }; -} -exports.encode = encode; -exports.expected = 'Buffer'; -function check(data) { - return Buffer.isBuffer(data); -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.finalScriptSig === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/finalScriptWitness.js b/src/lib/converter/input/finalScriptWitness.js deleted file mode 100644 index 450c71d..0000000 --- a/src/lib/converter/input/finalScriptWitness.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.FINAL_SCRIPTWITNESS) { - throw new Error( - 'Decode Error: could not decode finalScriptWitness with key 0x' + - keyVal.key.toString('hex'), - ); - } - return keyVal.value; -} -exports.decode = decode; -function encode(data) { - const key = Buffer.from([typeFields_1.InputTypes.FINAL_SCRIPTWITNESS]); - return { - key, - value: data, - }; -} -exports.encode = encode; -exports.expected = 'Buffer'; -function check(data) { - return Buffer.isBuffer(data); -} -exports.check = check; -function canAdd(currentData, newData) { - return ( - !!currentData && !!newData && currentData.finalScriptWitness === undefined - ); -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/nonWitnessUtxo.js b/src/lib/converter/input/nonWitnessUtxo.js deleted file mode 100644 index c69bc6c..0000000 --- a/src/lib/converter/input/nonWitnessUtxo.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.NON_WITNESS_UTXO) { - throw new Error( - 'Decode Error: could not decode nonWitnessUtxo with key 0x' + - keyVal.key.toString('hex'), - ); - } - return keyVal.value; -} -exports.decode = decode; -function encode(data) { - return { - key: Buffer.from([typeFields_1.InputTypes.NON_WITNESS_UTXO]), - value: data, - }; -} -exports.encode = encode; -exports.expected = 'Buffer'; -function check(data) { - return Buffer.isBuffer(data); -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.nonWitnessUtxo === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/porCommitment.js b/src/lib/converter/input/porCommitment.js deleted file mode 100644 index 9b97253..0000000 --- a/src/lib/converter/input/porCommitment.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.POR_COMMITMENT) { - throw new Error( - 'Decode Error: could not decode porCommitment with key 0x' + - keyVal.key.toString('hex'), - ); - } - return keyVal.value.toString('utf8'); -} -exports.decode = decode; -function encode(data) { - const key = Buffer.from([typeFields_1.InputTypes.POR_COMMITMENT]); - return { - key, - value: Buffer.from(data, 'utf8'), - }; -} -exports.encode = encode; -exports.expected = 'string'; -function check(data) { - return typeof data === 'string'; -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.porCommitment === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/sighashType.js b/src/lib/converter/input/sighashType.js deleted file mode 100644 index 9f90c1b..0000000 --- a/src/lib/converter/input/sighashType.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.SIGHASH_TYPE) { - throw new Error( - 'Decode Error: could not decode sighashType with key 0x' + - keyVal.key.toString('hex'), - ); - } - return keyVal.value.readUInt32LE(0); -} -exports.decode = decode; -function encode(data) { - const key = Buffer.from([typeFields_1.InputTypes.SIGHASH_TYPE]); - const value = Buffer.allocUnsafe(4); - value.writeUInt32LE(data, 0); - return { - key, - value, - }; -} -exports.encode = encode; -exports.expected = 'number'; -function check(data) { - return typeof data === 'number'; -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.sighashType === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/tapKeySig.js b/src/lib/converter/input/tapKeySig.js deleted file mode 100644 index a55a0a1..0000000 --- a/src/lib/converter/input/tapKeySig.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if ( - keyVal.key[0] !== typeFields_1.InputTypes.TAP_KEY_SIG || - keyVal.key.length !== 1 - ) { - throw new Error( - 'Decode Error: could not decode tapKeySig with key 0x' + - keyVal.key.toString('hex'), - ); - } - if (!check(keyVal.value)) { - throw new Error( - 'Decode Error: tapKeySig not a valid 64-65-byte BIP340 signature', - ); - } - return keyVal.value; -} -exports.decode = decode; -function encode(value) { - const key = Buffer.from([typeFields_1.InputTypes.TAP_KEY_SIG]); - return { key, value }; -} -exports.encode = encode; -exports.expected = 'Buffer'; -function check(data) { - return Buffer.isBuffer(data) && (data.length === 64 || data.length === 65); -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.tapKeySig === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/tapMerkleRoot.js b/src/lib/converter/input/tapMerkleRoot.js deleted file mode 100644 index c7c2697..0000000 --- a/src/lib/converter/input/tapMerkleRoot.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if ( - keyVal.key[0] !== typeFields_1.InputTypes.TAP_MERKLE_ROOT || - keyVal.key.length !== 1 - ) { - throw new Error( - 'Decode Error: could not decode tapMerkleRoot with key 0x' + - keyVal.key.toString('hex'), - ); - } - if (!check(keyVal.value)) { - throw new Error('Decode Error: tapMerkleRoot not a 32-byte hash'); - } - return keyVal.value; -} -exports.decode = decode; -function encode(value) { - const key = Buffer.from([typeFields_1.InputTypes.TAP_MERKLE_ROOT]); - return { key, value }; -} -exports.encode = encode; -exports.expected = 'Buffer'; -function check(data) { - return Buffer.isBuffer(data) && data.length === 32; -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.tapMerkleRoot === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/input/tapScriptSig.js b/src/lib/converter/input/tapScriptSig.js deleted file mode 100644 index 7180d32..0000000 --- a/src/lib/converter/input/tapScriptSig.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.TAP_SCRIPT_SIG) { - throw new Error( - 'Decode Error: could not decode tapScriptSig with key 0x' + - keyVal.key.toString('hex'), - ); - } - if (keyVal.key.length !== 65) { - throw new Error( - 'Decode Error: tapScriptSig has invalid key 0x' + - keyVal.key.toString('hex'), - ); - } - if (keyVal.value.length !== 64 && keyVal.value.length !== 65) { - throw new Error( - 'Decode Error: tapScriptSig has invalid signature in key 0x' + - keyVal.key.toString('hex'), - ); - } - const pubkey = keyVal.key.slice(1, 33); - const leafHash = keyVal.key.slice(33); - return { - pubkey, - leafHash, - signature: keyVal.value, - }; -} -exports.decode = decode; -function encode(tSig) { - const head = Buffer.from([typeFields_1.InputTypes.TAP_SCRIPT_SIG]); - return { - key: Buffer.concat([head, tSig.pubkey, tSig.leafHash]), - value: tSig.signature, - }; -} -exports.encode = encode; -exports.expected = '{ pubkey: Buffer; leafHash: Buffer; signature: Buffer; }'; -function check(data) { - return ( - Buffer.isBuffer(data.pubkey) && - Buffer.isBuffer(data.leafHash) && - Buffer.isBuffer(data.signature) && - data.pubkey.length === 32 && - data.leafHash.length === 32 && - (data.signature.length === 64 || data.signature.length === 65) - ); -} -exports.check = check; -function canAddToArray(array, item, dupeSet) { - const dupeString = - item.pubkey.toString('hex') + item.leafHash.toString('hex'); - if (dupeSet.has(dupeString)) return false; - dupeSet.add(dupeString); - return ( - array.filter( - v => v.pubkey.equals(item.pubkey) && v.leafHash.equals(item.leafHash), - ).length === 0 - ); -} -exports.canAddToArray = canAddToArray; diff --git a/src/lib/converter/input/witnessUtxo.js b/src/lib/converter/input/witnessUtxo.js deleted file mode 100644 index fad8ae5..0000000 --- a/src/lib/converter/input/witnessUtxo.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const typeFields_1 = require('../../typeFields'); -const tools_1 = require('../tools'); -const varuint = require('../varint'); -function decode(keyVal) { - if (keyVal.key[0] !== typeFields_1.InputTypes.WITNESS_UTXO) { - throw new Error( - 'Decode Error: could not decode witnessUtxo with key 0x' + - keyVal.key.toString('hex'), - ); - } - const value = tools_1.readUInt64LE(keyVal.value, 0); - let _offset = 8; - const scriptLen = varuint.decode(keyVal.value, _offset); - _offset += varuint.encodingLength(scriptLen); - const script = keyVal.value.slice(_offset); - if (script.length !== scriptLen) { - throw new Error('Decode Error: WITNESS_UTXO script is not proper length'); - } - return { - script, - value, - }; -} -exports.decode = decode; -function encode(data) { - const { script, value } = data; - const varintLen = varuint.encodingLength(script.length); - const result = Buffer.allocUnsafe(8 + varintLen + script.length); - tools_1.writeUInt64LE(result, value, 0); - varuint.encode(script.length, result, 8); - script.copy(result, 8 + varintLen); - return { - key: Buffer.from([typeFields_1.InputTypes.WITNESS_UTXO]), - value: result, - }; -} -exports.encode = encode; -exports.expected = '{ script: Buffer; value: number; }'; -function check(data) { - return Buffer.isBuffer(data.script) && typeof data.value === 'number'; -} -exports.check = check; -function canAdd(currentData, newData) { - return !!currentData && !!newData && currentData.witnessUtxo === undefined; -} -exports.canAdd = canAdd; diff --git a/src/lib/converter/tools.d.ts b/src/lib/converter/tools.d.ts deleted file mode 100644 index 53866c8..0000000 --- a/src/lib/converter/tools.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// -import { KeyValue } from '../interfaces'; -export declare const range: (n: number) => number[]; -export declare function reverseBuffer(buffer: Buffer): Buffer; -export declare function keyValsToBuffer(keyVals: KeyValue[]): Buffer; -export declare function keyValToBuffer(keyVal: KeyValue): Buffer; -export declare function readUInt64LE(buffer: Buffer, offset: number): number; -export declare function writeUInt64LE(buffer: Buffer, value: number, offset: number): number; diff --git a/src/lib/converter/tools.js b/src/lib/converter/tools.js deleted file mode 100644 index 1d5a86a..0000000 --- a/src/lib/converter/tools.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const varuint = require('./varint'); -exports.range = n => [...Array(n).keys()]; -function reverseBuffer(buffer) { - if (buffer.length < 1) return buffer; - let j = buffer.length - 1; - let tmp = 0; - for (let i = 0; i < buffer.length / 2; i++) { - tmp = buffer[i]; - buffer[i] = buffer[j]; - buffer[j] = tmp; - j--; - } - return buffer; -} -exports.reverseBuffer = reverseBuffer; -function keyValsToBuffer(keyVals) { - const buffers = keyVals.map(keyValToBuffer); - buffers.push(Buffer.from([0])); - return Buffer.concat(buffers); -} -exports.keyValsToBuffer = keyValsToBuffer; -function keyValToBuffer(keyVal) { - const keyLen = keyVal.key.length; - const valLen = keyVal.value.length; - const keyVarIntLen = varuint.encodingLength(keyLen); - const valVarIntLen = varuint.encodingLength(valLen); - const buffer = Buffer.allocUnsafe( - keyVarIntLen + keyLen + valVarIntLen + valLen, - ); - varuint.encode(keyLen, buffer, 0); - keyVal.key.copy(buffer, keyVarIntLen); - varuint.encode(valLen, buffer, keyVarIntLen + keyLen); - keyVal.value.copy(buffer, keyVarIntLen + keyLen + valVarIntLen); - return buffer; -} -exports.keyValToBuffer = keyValToBuffer; -// https://github.com/feross/buffer/blob/master/index.js#L1127 -function verifuint(value, max) { - if (typeof value !== 'number') - throw new Error('cannot write a non-number as a number'); - if (value < 0) - throw new Error('specified a negative value for writing an unsigned value'); - if (value > max) throw new Error('RangeError: value out of range'); - if (Math.floor(value) !== value) - throw new Error('value has a fractional component'); -} -function readUInt64LE(buffer, offset) { - const a = buffer.readUInt32LE(offset); - let b = buffer.readUInt32LE(offset + 4); - b *= 0x100000000; - verifuint(b + a, 0x001fffffffffffff); - return b + a; -} -exports.readUInt64LE = readUInt64LE; -function writeUInt64LE(buffer, value, offset) { - verifuint(value, 0x001fffffffffffff); - buffer.writeInt32LE(value & -1, offset); - buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4); - return offset + 8; -} -exports.writeUInt64LE = writeUInt64LE; diff --git a/src/lib/converter/varint.d.ts b/src/lib/converter/varint.d.ts deleted file mode 100644 index cff1d08..0000000 --- a/src/lib/converter/varint.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -/// -export declare function encode(_number: number, buffer?: Buffer, offset?: number): Buffer; -export declare function decode(buffer: Buffer, offset?: number): number; -export declare function encodingLength(_number: number): number; diff --git a/src/lib/converter/varint.js b/src/lib/converter/varint.js deleted file mode 100644 index 72a4393..0000000 --- a/src/lib/converter/varint.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -// Number.MAX_SAFE_INTEGER -const MAX_SAFE_INTEGER = 9007199254740991; -function checkUInt53(n) { - if (n < 0 || n > MAX_SAFE_INTEGER || n % 1 !== 0) - throw new RangeError('value out of range'); -} -function encode(_number, buffer, offset) { - checkUInt53(_number); - if (!buffer) buffer = Buffer.allocUnsafe(encodingLength(_number)); - if (!Buffer.isBuffer(buffer)) - throw new TypeError('buffer must be a Buffer instance'); - if (!offset) offset = 0; - // 8 bit - if (_number < 0xfd) { - buffer.writeUInt8(_number, offset); - Object.assign(encode, { bytes: 1 }); - // 16 bit - } else if (_number <= 0xffff) { - buffer.writeUInt8(0xfd, offset); - buffer.writeUInt16LE(_number, offset + 1); - Object.assign(encode, { bytes: 3 }); - // 32 bit - } else if (_number <= 0xffffffff) { - buffer.writeUInt8(0xfe, offset); - buffer.writeUInt32LE(_number, offset + 1); - Object.assign(encode, { bytes: 5 }); - // 64 bit - } else { - buffer.writeUInt8(0xff, offset); - buffer.writeUInt32LE(_number >>> 0, offset + 1); - buffer.writeUInt32LE((_number / 0x100000000) | 0, offset + 5); - Object.assign(encode, { bytes: 9 }); - } - return buffer; -} -exports.encode = encode; -function decode(buffer, offset) { - if (!Buffer.isBuffer(buffer)) - throw new TypeError('buffer must be a Buffer instance'); - if (!offset) offset = 0; - const first = buffer.readUInt8(offset); - // 8 bit - if (first < 0xfd) { - Object.assign(decode, { bytes: 1 }); - return first; - // 16 bit - } else if (first === 0xfd) { - Object.assign(decode, { bytes: 3 }); - return buffer.readUInt16LE(offset + 1); - // 32 bit - } else if (first === 0xfe) { - Object.assign(decode, { bytes: 5 }); - return buffer.readUInt32LE(offset + 1); - // 64 bit - } else { - Object.assign(decode, { bytes: 9 }); - const lo = buffer.readUInt32LE(offset + 1); - const hi = buffer.readUInt32LE(offset + 5); - const _number = hi * 0x0100000000 + lo; - checkUInt53(_number); - return _number; - } -} -exports.decode = decode; -function encodingLength(_number) { - checkUInt53(_number); - return _number < 0xfd - ? 1 - : _number <= 0xffff - ? 3 - : _number <= 0xffffffff - ? 5 - : 9; -} -exports.encodingLength = encodingLength; diff --git a/src/tests/first.js b/src/tests/first.js deleted file mode 100644 index 58c0255..0000000 --- a/src/tests/first.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../lib/psbt'); -const first_1 = require('./fixtures/first'); -const txTools_1 = require('./utils/txTools'); -for (const f of first_1.fixtures) { - tape('Test: ' + f.description, t => { - const parsed = psbt_1.Psbt.fromHex( - f.input, - txTools_1.transactionFromBuffer, - ); - const hex = parsed.toHex(); - const parsed2 = psbt_1.Psbt.fromHex(hex, txTools_1.transactionFromBuffer); - const hex2 = parsed2.toHex(); - const parsed3 = psbt_1.Psbt.fromHex(hex2, txTools_1.transactionFromBuffer); - t.strictEqual(parsed.toHex(), parsed2.toHex()); - t.strictEqual(parsed.toHex(), parsed3.toHex()); - // @ts-ignore - parsed3.globalMap.unsignedTx = parsed3.globalMap.unsignedTx.toBuffer(); - t.deepEqual(JSON.parse(jsonify(parsed3)), f.output); - t.equal(hex, hex2); - t.end(); - }); -} -function jsonify(parsed) { - return JSON.stringify( - parsed, - (key, value) => { - return key !== undefined && value !== undefined && value.type === 'Buffer' - ? Buffer.from(value.data).toString('hex') - : value; - }, - 2, - ); -} diff --git a/src/tests/fromBIP/valid.js b/src/tests/fromBIP/valid.js deleted file mode 100644 index 7021188..0000000 --- a/src/tests/fromBIP/valid.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const psbt_1 = require('../../lib/psbt'); -const valid_1 = require('../fixtures/valid'); -const txTools_1 = require('../utils/txTools'); -for (const f of valid_1.fixtures) { - tape(`Test: Should not throw`, t => { - let psbt; - t.doesNotThrow(() => { - psbt = psbt_1.Psbt.fromBase64(f, txTools_1.transactionFromBuffer); - }, 'fromBase64'); - t.doesNotThrow(() => { - const out = psbt.toBase64(); - t.equal(out, f); - }, 'toBase64'); - t.end(); - }); -} diff --git a/src/tests/keyValsToPsbt.js b/src/tests/keyValsToPsbt.js deleted file mode 100644 index 2d50a12..0000000 --- a/src/tests/keyValsToPsbt.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const tape = require('tape'); -const fromBuffer_1 = require('../lib/parser/fromBuffer'); -const psbt_1 = require('../lib/psbt'); -const keyValsToPsbt_1 = require('./fixtures/keyValsToPsbt'); -const txTools_1 = require('./utils/txTools'); -for (const f of keyValsToPsbt_1.fixtures) { - if (f.exception) { - tape('From keyVals should throw:', t => { - t.throws(() => { - fromBuffer_1.psbtFromKeyVals(txTools_1.getDefaultTx(), f.data); - }, new RegExp(f.exception)); - t.end(); - }); - } else { - const tx = txTools_1.transactionFromBuffer( - f.data.globalMapKeyVals.filter(kv => kv.key[0] === 0)[0].value, - ); - tape('From keyVals should not throw:', t => { - const data = fromBuffer_1.psbtFromKeyVals(tx, f.data); - const psbt = new psbt_1.Psbt(tx); - Object.assign(psbt, data); - t.strictEqual(psbt.toBase64(), f.expected); - // else console.log(psbt.toBase64()); - t.end(); - }); - } -} diff --git a/src/tests/varint.js b/src/tests/varint.js deleted file mode 100644 index f74ef0a..0000000 --- a/src/tests/varint.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict'; -Object.defineProperty(exports, '__esModule', { value: true }); -const test = require('tape'); -const varuint = require('../lib/converter/varint'); -const varint_1 = require('./fixtures/varint'); -varint_1.fixtures.valid.forEach((fixture, i) => { - test('valid encode #' + (i + 1), t => { - t.same(varuint.encode(fixture.dec).toString('hex'), fixture.hex); - // @ts-ignore - t.same(varuint.encode.bytes, fixture.hex.length / 2); - t.end(); - }); - test('valid decode #' + (i + 1), t => { - t.same(varuint.decode(Buffer.from(fixture.hex, 'hex')), fixture.dec); - // @ts-ignore - t.same(varuint.decode.bytes, fixture.hex.length / 2); - t.end(); - }); - test('valid encodingLength #' + (i + 1), t => { - t.same(varuint.encodingLength(fixture.dec), fixture.hex.length / 2); - t.end(); - }); -}); -varint_1.fixtures.invalid.forEach((fixture, i) => { - test('invalid encode #' + (i + 1), t => { - t.throws(() => { - varuint.encode(fixture.dec); - }, new RegExp(fixture.msg)); - t.end(); - }); - test('invalid encodingLength #' + (i + 1), t => { - t.throws(() => { - varuint.encodingLength(fixture.dec); - }, new RegExp(fixture.msg)); - t.end(); - }); - if (fixture.hex) { - test('invalid decode #' + (i + 1), t => { - t.throws(() => { - // @ts-ignore - t.decode(varuint.decode(Buffer.from(fixture.hex, 'hex'))); - }, new RegExp(fixture.msg)); - t.end(); - }); - } -}); -test('encode', t => { - t.test('write to buffer with offset', _t => { - const buffer = Buffer.from([0x00, 0x00]); - _t.same(varuint.encode(0xfc, buffer, 1).toString('hex'), '00fc'); - // @ts-ignore - _t.same(varuint.encode.bytes, 1); - _t.end(); - }); - t.test('should be a buffer', _t => { - _t.throws(() => { - // @ts-ignore - varuint.encode(0, []); - }, new RegExp('buffer must be a Buffer instance')); - _t.end(); - }); - t.end(); -}); -test('decode', t => { - t.test('read from buffer with offset', _t => { - const buffer = Buffer.from([0x00, 0xfc]); - _t.same(varuint.decode(buffer, 1), 0xfc); - // @ts-ignore - _t.same(varuint.decode.bytes, 1); - _t.end(); - }); - t.test('should be a buffer', _t => { - _t.throws(() => { - // @ts-ignore - varuint.decode([]); - }, new RegExp('buffer must be a Buffer instance')); - _t.end(); - }); - t.end(); -}); diff --git a/ts_src/lib/combiner/index.ts b/ts_src/lib/combiner/index.ts index d008c98..68fde8b 100644 --- a/ts_src/lib/combiner/index.ts +++ b/ts_src/lib/combiner/index.ts @@ -1,5 +1,10 @@ import { KeyValue, Transaction } from '../interfaces'; -import { PsbtAttributes, psbtFromKeyVals, psbtToKeyVals } from '../parser'; +import { + PsbtAttributes, + psbtFromKeyVals, + psbtToKeyVals, +} from '../parser/index.js'; +import * as tools from 'uint8array-tools'; export function combine(psbts: PsbtAttributes[]): PsbtAttributes { const self = psbts[0]; @@ -19,7 +24,7 @@ export function combine(psbts: PsbtAttributes[]): PsbtAttributes { const otherTx = getTx(other); if ( otherTx === undefined || - !otherTx.toBuffer().equals(selfTx.toBuffer()) + tools.compare(otherTx.toBuffer(), selfTx.toBuffer()) !== 0 ) { throw new Error( 'Combine: One of the Psbts does not have the same transaction.', @@ -72,7 +77,7 @@ function keyPusher( ): (key: string) => void { return (key: string): void => { if (selfSet.has(key)) return; - const newKv = otherKeyVals.filter(kv => kv.key.toString('hex') === key)[0]; + const newKv = otherKeyVals.filter(kv => tools.toHex(kv.key) === key)[0]; selfKeyVals.push(newKv); selfSet.add(key); }; @@ -85,7 +90,7 @@ function getTx(psbt: PsbtAttributes): Transaction | undefined { function getKeySet(keyVals: KeyValue[]): Set { const set: Set = new Set(); keyVals.forEach(keyVal => { - const hex = keyVal.key.toString('hex'); + const hex = tools.toHex(keyVal.key); if (set.has(hex)) throw new Error('Combine: KeyValue Map keys should be unique'); set.add(hex); diff --git a/ts_src/lib/converter/global/globalXpub.ts b/ts_src/lib/converter/global/globalXpub.ts index 3f9a70a..54dabce 100644 --- a/ts_src/lib/converter/global/globalXpub.ts +++ b/ts_src/lib/converter/global/globalXpub.ts @@ -1,18 +1,20 @@ import { GlobalXpub, KeyValue } from '../../interfaces'; -import { GlobalTypes } from '../../typeFields'; +import { GlobalTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; + const range = (n: number): number[] => [...Array(n).keys()]; export function decode(keyVal: KeyValue): GlobalXpub { if (keyVal.key[0] !== GlobalTypes.GLOBAL_XPUB) { throw new Error( 'Decode Error: could not decode globalXpub with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (keyVal.key.length !== 79 || ![2, 3].includes(keyVal.key[46])) { throw new Error( 'Decode Error: globalXpub has invalid extended pubkey in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ((keyVal.value.length / 4) % 1 !== 0) { @@ -27,7 +29,7 @@ export function decode(keyVal: KeyValue): GlobalXpub { path: 'm', }; for (const i of range(keyVal.value.length / 4 - 1)) { - const val = keyVal.value.readUInt32LE(i * 4 + 4); + const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE'); const isHard = !!(val & 0x80000000); const idx = val & 0x7fffffff; data.path += '/' + idx.toString(10) + (isHard ? "'" : ''); @@ -36,20 +38,20 @@ export function decode(keyVal: KeyValue): GlobalXpub { } export function encode(data: GlobalXpub): KeyValue { - const head = Buffer.from([GlobalTypes.GLOBAL_XPUB]); - const key = Buffer.concat([head, data.extendedPubkey]); + const head = new Uint8Array([GlobalTypes.GLOBAL_XPUB]); + const key = tools.concat([head, data.extendedPubkey]); const splitPath = data.path.split('/'); - const value = Buffer.allocUnsafe(splitPath.length * 4); + const value = new Uint8Array(splitPath.length * 4); - data.masterFingerprint.copy(value, 0); + value.set(data.masterFingerprint, 0); let offset = 4; splitPath.slice(1).forEach(level => { const isHard = level.slice(-1) === "'"; let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10); if (isHard) num += 0x80000000; - value.writeUInt32LE(num, offset); + tools.writeUInt32(value, offset, num, 'LE'); offset += 4; }); @@ -60,17 +62,17 @@ export function encode(data: GlobalXpub): KeyValue { } export const expected = - '{ masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; }'; + '{ masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; }'; export function check(data: any): data is GlobalXpub { const epk = data.extendedPubkey; const mfp = data.masterFingerprint; const p = data.path; return ( - Buffer.isBuffer(epk) && + epk instanceof Uint8Array && epk.length === 78 && [2, 3].indexOf(epk[45]) > -1 && - Buffer.isBuffer(mfp) && + mfp instanceof Uint8Array && mfp.length === 4 && typeof p === 'string' && !!p.match(/^m(\/\d+'?)*$/) @@ -82,10 +84,11 @@ export function canAddToArray( item: GlobalXpub, dupeSet: Set, ): boolean { - const dupeString = item.extendedPubkey.toString('hex'); + const dupeString = tools.toHex(item.extendedPubkey); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); return ( - array.filter(v => v.extendedPubkey.equals(item.extendedPubkey)).length === 0 + array.filter(v => tools.compare(v.extendedPubkey, item.extendedPubkey)) + .length === 0 ); } diff --git a/ts_src/lib/converter/global/unsignedTx.ts b/ts_src/lib/converter/global/unsignedTx.ts index 29a4017..92d8163 100644 --- a/ts_src/lib/converter/global/unsignedTx.ts +++ b/ts_src/lib/converter/global/unsignedTx.ts @@ -1,9 +1,9 @@ import { KeyValue, Transaction } from '../../interfaces'; -import { GlobalTypes } from '../../typeFields'; +import { GlobalTypes } from '../../typeFields.js'; export function encode(data: Transaction): KeyValue { return { - key: Buffer.from([GlobalTypes.UNSIGNED_TX]), + key: new Uint8Array([GlobalTypes.UNSIGNED_TX]), value: data.toBuffer(), }; } diff --git a/ts_src/lib/converter/index.ts b/ts_src/lib/converter/index.ts index c814073..2cae70f 100644 --- a/ts_src/lib/converter/index.ts +++ b/ts_src/lib/converter/index.ts @@ -1,28 +1,28 @@ -import { InputTypes, OutputTypes } from '../typeFields'; +import { InputTypes, OutputTypes } from '../typeFields.js'; -import * as globalXpub from './global/globalXpub'; -import * as unsignedTx from './global/unsignedTx'; +import * as globalXpub from './global/globalXpub.js'; +import * as unsignedTx from './global/unsignedTx.js'; -import * as finalScriptSig from './input/finalScriptSig'; -import * as finalScriptWitness from './input/finalScriptWitness'; -import * as nonWitnessUtxo from './input/nonWitnessUtxo'; -import * as partialSig from './input/partialSig'; -import * as porCommitment from './input/porCommitment'; -import * as sighashType from './input/sighashType'; -import * as tapKeySig from './input/tapKeySig'; -import * as tapLeafScript from './input/tapLeafScript'; -import * as tapMerkleRoot from './input/tapMerkleRoot'; -import * as tapScriptSig from './input/tapScriptSig'; -import * as witnessUtxo from './input/witnessUtxo'; +import * as finalScriptSig from './input/finalScriptSig.js'; +import * as finalScriptWitness from './input/finalScriptWitness.js'; +import * as nonWitnessUtxo from './input/nonWitnessUtxo.js'; +import * as partialSig from './input/partialSig.js'; +import * as porCommitment from './input/porCommitment.js'; +import * as sighashType from './input/sighashType.js'; +import * as tapKeySig from './input/tapKeySig.js'; +import * as tapLeafScript from './input/tapLeafScript.js'; +import * as tapMerkleRoot from './input/tapMerkleRoot.js'; +import * as tapScriptSig from './input/tapScriptSig.js'; +import * as witnessUtxo from './input/witnessUtxo.js'; -import * as tapTree from './output/tapTree'; +import * as tapTree from './output/tapTree.js'; -import * as bip32Derivation from './shared/bip32Derivation'; -import * as checkPubkey from './shared/checkPubkey'; -import * as redeemScript from './shared/redeemScript'; -import * as tapBip32Derivation from './shared/tapBip32Derivation'; -import * as tapInternalKey from './shared/tapInternalKey'; -import * as witnessScript from './shared/witnessScript'; +import * as bip32Derivation from './shared/bip32Derivation.js'; +import * as checkPubkey from './shared/checkPubkey.js'; +import * as redeemScript from './shared/redeemScript.js'; +import * as tapBip32Derivation from './shared/tapBip32Derivation.js'; +import * as tapInternalKey from './shared/tapInternalKey.js'; +import * as witnessScript from './shared/witnessScript.js'; const globals = { unsignedTx, diff --git a/ts_src/lib/converter/input/finalScriptSig.ts b/ts_src/lib/converter/input/finalScriptSig.ts index 59a17f2..23598c4 100644 --- a/ts_src/lib/converter/input/finalScriptSig.ts +++ b/ts_src/lib/converter/input/finalScriptSig.ts @@ -1,27 +1,28 @@ import { FinalScriptSig, KeyValue } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): FinalScriptSig { if (keyVal.key[0] !== InputTypes.FINAL_SCRIPTSIG) { throw new Error( 'Decode Error: could not decode finalScriptSig with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; } export function encode(data: FinalScriptSig): KeyValue { - const key = Buffer.from([InputTypes.FINAL_SCRIPTSIG]); + const key = new Uint8Array([InputTypes.FINAL_SCRIPTSIG]); return { key, value: data, }; } -export const expected = 'Buffer'; +export const expected = 'Uint8Array'; export function check(data: any): data is FinalScriptSig { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } export function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/input/finalScriptWitness.ts b/ts_src/lib/converter/input/finalScriptWitness.ts index 37f9462..154b9f7 100644 --- a/ts_src/lib/converter/input/finalScriptWitness.ts +++ b/ts_src/lib/converter/input/finalScriptWitness.ts @@ -1,27 +1,28 @@ import { FinalScriptWitness, KeyValue } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): FinalScriptWitness { if (keyVal.key[0] !== InputTypes.FINAL_SCRIPTWITNESS) { throw new Error( 'Decode Error: could not decode finalScriptWitness with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; } export function encode(data: FinalScriptWitness): KeyValue { - const key = Buffer.from([InputTypes.FINAL_SCRIPTWITNESS]); + const key = new Uint8Array([InputTypes.FINAL_SCRIPTWITNESS]); return { key, value: data, }; } -export const expected = 'Buffer'; +export const expected = 'Uint8Array'; export function check(data: any): data is FinalScriptWitness { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } export function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/input/nonWitnessUtxo.ts b/ts_src/lib/converter/input/nonWitnessUtxo.ts index 6b41520..8ba1404 100644 --- a/ts_src/lib/converter/input/nonWitnessUtxo.ts +++ b/ts_src/lib/converter/input/nonWitnessUtxo.ts @@ -1,11 +1,12 @@ import { KeyValue, NonWitnessUtxo } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): NonWitnessUtxo { if (keyVal.key[0] !== InputTypes.NON_WITNESS_UTXO) { throw new Error( 'Decode Error: could not decode nonWitnessUtxo with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; @@ -13,14 +14,14 @@ export function decode(keyVal: KeyValue): NonWitnessUtxo { export function encode(data: NonWitnessUtxo): KeyValue { return { - key: Buffer.from([InputTypes.NON_WITNESS_UTXO]), + key: new Uint8Array([InputTypes.NON_WITNESS_UTXO]), value: data, }; } -export const expected = 'Buffer'; +export const expected = 'Uint8Array'; export function check(data: any): data is NonWitnessUtxo { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } export function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/input/partialSig.ts b/ts_src/lib/converter/input/partialSig.ts index 28a7a5d..04416a0 100644 --- a/ts_src/lib/converter/input/partialSig.ts +++ b/ts_src/lib/converter/input/partialSig.ts @@ -1,11 +1,12 @@ import { KeyValue, PartialSig } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): PartialSig { if (keyVal.key[0] !== InputTypes.PARTIAL_SIG) { throw new Error( 'Decode Error: could not decode partialSig with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ( @@ -14,7 +15,7 @@ export function decode(keyVal: KeyValue): PartialSig { ) { throw new Error( 'Decode Error: partialSig has invalid pubkey in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const pubkey = keyVal.key.slice(1); @@ -25,26 +26,26 @@ export function decode(keyVal: KeyValue): PartialSig { } export function encode(pSig: PartialSig): KeyValue { - const head = Buffer.from([InputTypes.PARTIAL_SIG]); + const head = new Uint8Array([InputTypes.PARTIAL_SIG]); return { - key: Buffer.concat([head, pSig.pubkey]), + key: tools.concat([head, pSig.pubkey]), value: pSig.signature, }; } -export const expected = '{ pubkey: Buffer; signature: Buffer; }'; +export const expected = '{ pubkey: Uint8Array; signature: Uint8Array; }'; export function check(data: any): data is PartialSig { return ( - Buffer.isBuffer(data.pubkey) && - Buffer.isBuffer(data.signature) && + data.pubkey instanceof Uint8Array && + data.signature instanceof Uint8Array && [33, 65].includes(data.pubkey.length) && [2, 3, 4].includes(data.pubkey[0]) && isDerSigWithSighash(data.signature) ); } -function isDerSigWithSighash(buf: Buffer): boolean { - if (!Buffer.isBuffer(buf) || buf.length < 9) return false; +function isDerSigWithSighash(buf: Uint8Array): boolean { + if (!(buf instanceof Uint8Array) || buf.length < 9) return false; if (buf[0] !== 0x30) return false; if (buf.length !== buf[1] + 3) return false; if (buf[2] !== 0x02) return false; @@ -62,8 +63,10 @@ export function canAddToArray( item: PartialSig, dupeSet: Set, ): boolean { - const dupeString = item.pubkey.toString('hex'); + const dupeString = tools.toHex(item.pubkey); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); - return array.filter(v => v.pubkey.equals(item.pubkey)).length === 0; + return ( + array.filter(v => tools.compare(v.pubkey, item.pubkey) === 0).length === 0 + ); } diff --git a/ts_src/lib/converter/input/porCommitment.ts b/ts_src/lib/converter/input/porCommitment.ts index 751fcde..33f1f20 100644 --- a/ts_src/lib/converter/input/porCommitment.ts +++ b/ts_src/lib/converter/input/porCommitment.ts @@ -1,21 +1,22 @@ import { KeyValue, PorCommitment } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): PorCommitment { if (keyVal.key[0] !== InputTypes.POR_COMMITMENT) { throw new Error( 'Decode Error: could not decode porCommitment with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } - return keyVal.value.toString('utf8'); + return tools.toUtf8(keyVal.value); } export function encode(data: PorCommitment): KeyValue { - const key = Buffer.from([InputTypes.POR_COMMITMENT]); + const key = new Uint8Array([InputTypes.POR_COMMITMENT]); return { key, - value: Buffer.from(data, 'utf8'), + value: tools.fromUtf8(data), }; } diff --git a/ts_src/lib/converter/input/sighashType.ts b/ts_src/lib/converter/input/sighashType.ts index 38e606c..8ef5ced 100644 --- a/ts_src/lib/converter/input/sighashType.ts +++ b/ts_src/lib/converter/input/sighashType.ts @@ -1,20 +1,21 @@ import { KeyValue, SighashType } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): SighashType { if (keyVal.key[0] !== InputTypes.SIGHASH_TYPE) { throw new Error( 'Decode Error: could not decode sighashType with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } - return keyVal.value.readUInt32LE(0); + return Number(tools.readUInt32(keyVal.value, 0, 'LE')); } export function encode(data: SighashType): KeyValue { - const key = Buffer.from([InputTypes.SIGHASH_TYPE]); - const value = Buffer.allocUnsafe(4); - value.writeUInt32LE(data, 0); + const key = Uint8Array.from([InputTypes.SIGHASH_TYPE]); + const value = new Uint8Array(4); + tools.writeUInt32(value, 0, data, 'LE'); return { key, value, diff --git a/ts_src/lib/converter/input/tapKeySig.ts b/ts_src/lib/converter/input/tapKeySig.ts index 2381088..18bda77 100644 --- a/ts_src/lib/converter/input/tapKeySig.ts +++ b/ts_src/lib/converter/input/tapKeySig.ts @@ -1,11 +1,12 @@ import { KeyValue, TapKeySig } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): TapKeySig { if (keyVal.key[0] !== InputTypes.TAP_KEY_SIG || keyVal.key.length !== 1) { throw new Error( 'Decode Error: could not decode tapKeySig with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (!check(keyVal.value)) { @@ -17,13 +18,15 @@ export function decode(keyVal: KeyValue): TapKeySig { } export function encode(value: TapKeySig): KeyValue { - const key = Buffer.from([InputTypes.TAP_KEY_SIG]); + const key = Uint8Array.from([InputTypes.TAP_KEY_SIG]); return { key, value }; } -export const expected = 'Buffer'; +export const expected = 'Uint8Array'; export function check(data: any): data is TapKeySig { - return Buffer.isBuffer(data) && (data.length === 64 || data.length === 65); + return ( + data instanceof Uint8Array && (data.length === 64 || data.length === 65) + ); } export function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/input/tapLeafScript.ts b/ts_src/lib/converter/input/tapLeafScript.ts index 4938a33..1f04d25 100644 --- a/ts_src/lib/converter/input/tapLeafScript.ts +++ b/ts_src/lib/converter/input/tapLeafScript.ts @@ -1,17 +1,18 @@ import { KeyValue, TapLeafScript } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): TapLeafScript { if (keyVal.key[0] !== InputTypes.TAP_LEAF_SCRIPT) { throw new Error( 'Decode Error: could not decode tapLeafScript with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ((keyVal.key.length - 2) % 32 !== 0) { throw new Error( 'Decode Error: tapLeafScript has invalid control block in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } @@ -19,7 +20,7 @@ export function decode(keyVal: KeyValue): TapLeafScript { if ((keyVal.key[1] & 0xfe) !== leafVersion) { throw new Error( 'Decode Error: tapLeafScript bad leaf version in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } @@ -29,23 +30,23 @@ export function decode(keyVal: KeyValue): TapLeafScript { } export function encode(tScript: TapLeafScript): KeyValue { - const head = Buffer.from([InputTypes.TAP_LEAF_SCRIPT]); - const verBuf = Buffer.from([tScript.leafVersion]); + const head = Uint8Array.from([InputTypes.TAP_LEAF_SCRIPT]); + const verBuf = Uint8Array.from([tScript.leafVersion]); return { - key: Buffer.concat([head, tScript.controlBlock]), - value: Buffer.concat([tScript.script, verBuf]), + key: tools.concat([head, tScript.controlBlock]), + value: tools.concat([tScript.script, verBuf]), }; } export const expected = - '{ controlBlock: Buffer; leafVersion: number, script: Buffer; }'; + '{ controlBlock: Uint8Array; leafVersion: number, script: Uint8Array; }'; export function check(data: any): data is TapLeafScript { return ( - Buffer.isBuffer(data.controlBlock) && + data.controlBlock instanceof Uint8Array && (data.controlBlock.length - 1) % 32 === 0 && (data.controlBlock[0] & 0xfe) === data.leafVersion && - Buffer.isBuffer(data.script) + data.script instanceof Uint8Array ); } @@ -54,10 +55,11 @@ export function canAddToArray( item: TapLeafScript, dupeSet: Set, ): boolean { - const dupeString = item.controlBlock.toString('hex'); + const dupeString = tools.toHex(item.controlBlock); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); return ( - array.filter(v => v.controlBlock.equals(item.controlBlock)).length === 0 + array.filter(v => tools.compare(v.controlBlock, item.controlBlock) === 0) + .length === 0 ); } diff --git a/ts_src/lib/converter/input/tapMerkleRoot.ts b/ts_src/lib/converter/input/tapMerkleRoot.ts index 009453e..09dbdb1 100644 --- a/ts_src/lib/converter/input/tapMerkleRoot.ts +++ b/ts_src/lib/converter/input/tapMerkleRoot.ts @@ -1,11 +1,12 @@ import { KeyValue, TapMerkleRoot } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): TapMerkleRoot { if (keyVal.key[0] !== InputTypes.TAP_MERKLE_ROOT || keyVal.key.length !== 1) { throw new Error( 'Decode Error: could not decode tapMerkleRoot with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (!check(keyVal.value)) { @@ -15,13 +16,13 @@ export function decode(keyVal: KeyValue): TapMerkleRoot { } export function encode(value: TapMerkleRoot): KeyValue { - const key = Buffer.from([InputTypes.TAP_MERKLE_ROOT]); + const key = Uint8Array.from([InputTypes.TAP_MERKLE_ROOT]); return { key, value }; } -export const expected = 'Buffer'; +export const expected = 'Uint8Array'; export function check(data: any): data is TapMerkleRoot { - return Buffer.isBuffer(data) && data.length === 32; + return data instanceof Uint8Array && data.length === 32; } export function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/input/tapScriptSig.ts b/ts_src/lib/converter/input/tapScriptSig.ts index 4c02989..2be9e8a 100644 --- a/ts_src/lib/converter/input/tapScriptSig.ts +++ b/ts_src/lib/converter/input/tapScriptSig.ts @@ -1,23 +1,23 @@ import { KeyValue, TapScriptSig } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): TapScriptSig { if (keyVal.key[0] !== InputTypes.TAP_SCRIPT_SIG) { throw new Error( 'Decode Error: could not decode tapScriptSig with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (keyVal.key.length !== 65) { throw new Error( - 'Decode Error: tapScriptSig has invalid key 0x' + - keyVal.key.toString('hex'), + 'Decode Error: tapScriptSig has invalid key 0x' + tools.toHex(keyVal.key), ); } if (keyVal.value.length !== 64 && keyVal.value.length !== 65) { throw new Error( 'Decode Error: tapScriptSig has invalid signature in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const pubkey = keyVal.key.slice(1, 33); @@ -30,20 +30,20 @@ export function decode(keyVal: KeyValue): TapScriptSig { } export function encode(tSig: TapScriptSig): KeyValue { - const head = Buffer.from([InputTypes.TAP_SCRIPT_SIG]); + const head = Uint8Array.from([InputTypes.TAP_SCRIPT_SIG]); return { - key: Buffer.concat([head, tSig.pubkey, tSig.leafHash]), + key: tools.concat([head, tSig.pubkey, tSig.leafHash]), value: tSig.signature, }; } export const expected = - '{ pubkey: Buffer; leafHash: Buffer; signature: Buffer; }'; + '{ pubkey: Uint8Array; leafHash: Uint8Array; signature: Uint8Array; }'; export function check(data: any): data is TapScriptSig { return ( - Buffer.isBuffer(data.pubkey) && - Buffer.isBuffer(data.leafHash) && - Buffer.isBuffer(data.signature) && + data.pubkey instanceof Uint8Array && + data.leafHash instanceof Uint8Array && + data.signature instanceof Uint8Array && data.pubkey.length === 32 && data.leafHash.length === 32 && (data.signature.length === 64 || data.signature.length === 65) @@ -55,13 +55,14 @@ export function canAddToArray( item: TapScriptSig, dupeSet: Set, ): boolean { - const dupeString = - item.pubkey.toString('hex') + item.leafHash.toString('hex'); + const dupeString = tools.toHex(item.pubkey) + tools.toHex(item.leafHash); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); return ( array.filter( - v => v.pubkey.equals(item.pubkey) && v.leafHash.equals(item.leafHash), + v => + tools.compare(v.pubkey, item.pubkey) === 0 && + tools.compare(v.leafHash, item.leafHash) === 0, ).length === 0 ); } diff --git a/ts_src/lib/converter/input/witnessUtxo.ts b/ts_src/lib/converter/input/witnessUtxo.ts index e55f331..8f9d632 100644 --- a/ts_src/lib/converter/input/witnessUtxo.ts +++ b/ts_src/lib/converter/input/witnessUtxo.ts @@ -1,19 +1,22 @@ import { KeyValue, WitnessUtxo } from '../../interfaces'; -import { InputTypes } from '../../typeFields'; -import { readUInt64LE, writeUInt64LE } from '../tools'; -import * as varuint from '../varint'; +import { InputTypes } from '../../typeFields.js'; +import * as tools from 'uint8array-tools'; +import * as varuint from 'varuint-bitcoin'; export function decode(keyVal: KeyValue): WitnessUtxo { if (keyVal.key[0] !== InputTypes.WITNESS_UTXO) { throw new Error( 'Decode Error: could not decode witnessUtxo with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } - const value = readUInt64LE(keyVal.value, 0); + const value = tools.readInt64(keyVal.value, 0, 'LE'); let _offset = 8; - const scriptLen = varuint.decode(keyVal.value, _offset); - _offset += varuint.encodingLength(scriptLen); + const { numberValue: scriptLen, bytes } = varuint.decode( + keyVal.value, + _offset, + ); + _offset += bytes; const script = keyVal.value.slice(_offset); if (script.length !== scriptLen) { throw new Error('Decode Error: WITNESS_UTXO script is not proper length'); @@ -26,23 +29,23 @@ export function decode(keyVal: KeyValue): WitnessUtxo { export function encode(data: WitnessUtxo): KeyValue { const { script, value } = data; - const varintLen = varuint.encodingLength(script.length); + const varuintlen = varuint.encodingLength(script.length); - const result = Buffer.allocUnsafe(8 + varintLen + script.length); + const result = new Uint8Array(8 + varuintlen + script.length); - writeUInt64LE(result, value, 0); + tools.writeInt64(result, 0, BigInt(value), 'LE'); varuint.encode(script.length, result, 8); - script.copy(result, 8 + varintLen); + result.set(script, 8 + varuintlen); return { - key: Buffer.from([InputTypes.WITNESS_UTXO]), + key: Uint8Array.from([InputTypes.WITNESS_UTXO]), value: result, }; } -export const expected = '{ script: Buffer; value: number; }'; +export const expected = '{ script: Uint8Array; value: bigint; }'; export function check(data: any): data is WitnessUtxo { - return Buffer.isBuffer(data.script) && typeof data.value === 'number'; + return data.script instanceof Uint8Array && typeof data.value === 'bigint'; } export function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/output/tapTree.ts b/ts_src/lib/converter/output/tapTree.ts index 6f8edea..11e262d 100644 --- a/ts_src/lib/converter/output/tapTree.ts +++ b/ts_src/lib/converter/output/tapTree.ts @@ -1,12 +1,13 @@ import { KeyValue, TapLeaf, TapTree } from '../../interfaces'; -import { OutputTypes } from '../../typeFields'; -import * as varuint from '../varint'; +import { OutputTypes } from '../../typeFields.js'; +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; export function decode(keyVal: KeyValue): TapTree { if (keyVal.key[0] !== OutputTypes.TAP_TREE || keyVal.key.length !== 1) { throw new Error( 'Decode Error: could not decode tapTree with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } let _offset = 0; @@ -14,35 +15,39 @@ export function decode(keyVal: KeyValue): TapTree { while (_offset < keyVal.value.length) { const depth = keyVal.value[_offset++]; const leafVersion = keyVal.value[_offset++]; - const scriptLen = varuint.decode(keyVal.value, _offset); - _offset += varuint.encodingLength(scriptLen); + const { numberValue: scriptLen, bytes } = varuint.decode( + keyVal.value, + _offset, + ); + _offset += bytes; data.push({ depth, leafVersion, - script: keyVal.value.slice(_offset, _offset + scriptLen), + script: keyVal.value.slice(_offset, _offset + scriptLen!), }); - _offset += scriptLen; + _offset += scriptLen!; } return { leaves: data }; } export function encode(tree: TapTree): KeyValue { - const key = Buffer.from([OutputTypes.TAP_TREE]); - const bufs = ([] as Buffer[]).concat( + const key = Uint8Array.from([OutputTypes.TAP_TREE]); + + const bufs = ([] as Uint8Array[]).concat( ...tree.leaves.map(tapLeaf => [ - Buffer.of(tapLeaf.depth, tapLeaf.leafVersion), - varuint.encode(tapLeaf.script.length), + Uint8Array.of(tapLeaf.depth, tapLeaf.leafVersion), + varuint.encode(BigInt(tapLeaf.script.length)).buffer, tapLeaf.script, ]), ); return { key, - value: Buffer.concat(bufs), + value: tools.concat(bufs), }; } export const expected = - '{ leaves: [{ depth: number; leafVersion: number, script: Buffer; }] }'; + '{ leaves: [{ depth: number; leafVersion: number, script: Uint8Array; }] }'; export function check(data: any): data is TapTree { return ( Array.isArray(data.leaves) && @@ -51,7 +56,7 @@ export function check(data: any): data is TapTree { tapLeaf.depth >= 0 && tapLeaf.depth <= 128 && (tapLeaf.leafVersion & 0xfe) === tapLeaf.leafVersion && - Buffer.isBuffer(tapLeaf.script), + tapLeaf.script instanceof Uint8Array, ) ); } diff --git a/ts_src/lib/converter/shared/bip32Derivation.ts b/ts_src/lib/converter/shared/bip32Derivation.ts index 5f07a24..fc9afd1 100644 --- a/ts_src/lib/converter/shared/bip32Derivation.ts +++ b/ts_src/lib/converter/shared/bip32Derivation.ts @@ -1,7 +1,8 @@ import { Bip32Derivation, KeyValue } from '../../interfaces'; +import * as tools from 'uint8array-tools'; const range = (n: number): number[] => [...Array(n).keys()]; -const isValidDERKey = (pubkey: Buffer): boolean => +const isValidDERKey = (pubkey: Uint8Array): boolean => (pubkey.length === 33 && [2, 3].includes(pubkey[0])) || (pubkey.length === 65 && 4 === pubkey[0]); @@ -23,14 +24,14 @@ export function makeConverter( if (keyVal.key[0] !== TYPE_BYTE) { throw new Error( 'Decode Error: could not decode bip32Derivation with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } const pubkey = keyVal.key.slice(1); if (!isValidPubkey(pubkey)) { throw new Error( 'Decode Error: bip32Derivation has invalid pubkey in key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if ((keyVal.value.length / 4) % 1 !== 0) { @@ -44,7 +45,7 @@ export function makeConverter( path: 'm', }; for (const i of range(keyVal.value.length / 4 - 1)) { - const val = keyVal.value.readUInt32LE(i * 4 + 4); + const val = tools.readUInt32(keyVal.value, i * 4 + 4, 'LE'); const isHard = !!(val & 0x80000000); const idx = val & 0x7fffffff; data.path += '/' + idx.toString(10) + (isHard ? "'" : ''); @@ -53,20 +54,20 @@ export function makeConverter( } function encode(data: Bip32Derivation): KeyValue { - const head = Buffer.from([TYPE_BYTE]); - const key = Buffer.concat([head, data.pubkey]); + const head = Uint8Array.from([TYPE_BYTE]); + const key = tools.concat([head, data.pubkey]); const splitPath = data.path.split('/'); - const value = Buffer.allocUnsafe(splitPath.length * 4); + const value = new Uint8Array(splitPath.length * 4); - data.masterFingerprint.copy(value, 0); + value.set(data.masterFingerprint, 0); let offset = 4; splitPath.slice(1).forEach(level => { const isHard = level.slice(-1) === "'"; let num = 0x7fffffff & parseInt(isHard ? level.slice(0, -1) : level, 10); if (isHard) num += 0x80000000; - value.writeUInt32LE(num, offset); + tools.writeUInt32(value, offset, num, 'LE'); offset += 4; }); @@ -77,11 +78,11 @@ export function makeConverter( } const expected = - '{ masterFingerprint: Buffer; pubkey: Buffer; path: string; }'; + '{ masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; }'; function check(data: any): data is Bip32Derivation { return ( - Buffer.isBuffer(data.pubkey) && - Buffer.isBuffer(data.masterFingerprint) && + data.pubkey instanceof Uint8Array && + data.masterFingerprint instanceof Uint8Array && typeof data.path === 'string' && isValidPubkey(data.pubkey) && data.masterFingerprint.length === 4 @@ -93,10 +94,12 @@ export function makeConverter( item: Bip32Derivation, dupeSet: Set, ): boolean { - const dupeString = item.pubkey.toString('hex'); + const dupeString = tools.toHex(item.pubkey); if (dupeSet.has(dupeString)) return false; dupeSet.add(dupeString); - return array.filter(v => v.pubkey.equals(item.pubkey)).length === 0; + return ( + array.filter(v => tools.compare(v.pubkey, item.pubkey) === 0).length === 0 + ); } return { diff --git a/ts_src/lib/converter/shared/checkPubkey.ts b/ts_src/lib/converter/shared/checkPubkey.ts index 6d79ada..7eb7f53 100644 --- a/ts_src/lib/converter/shared/checkPubkey.ts +++ b/ts_src/lib/converter/shared/checkPubkey.ts @@ -1,11 +1,11 @@ import { KeyValue } from '../../interfaces'; - +import * as tools from 'uint8array-tools'; export function makeChecker( pubkeyTypes: number[], -): (keyVal: KeyValue) => Buffer | undefined { +): (keyVal: KeyValue) => Uint8Array | undefined { return checkPubkey; - function checkPubkey(keyVal: KeyValue): Buffer | undefined { - let pubkey: Buffer | undefined; + function checkPubkey(keyVal: KeyValue): Uint8Array | undefined { + let pubkey: Uint8Array | undefined; if (pubkeyTypes.includes(keyVal.key[0])) { pubkey = keyVal.key.slice(1); if ( @@ -13,7 +13,7 @@ export function makeChecker( ![2, 3, 4].includes(pubkey[0]) ) { throw new Error( - 'Format Error: invalid pubkey in key 0x' + keyVal.key.toString('hex'), + 'Format Error: invalid pubkey in key 0x' + tools.toHex(keyVal.key), ); } } diff --git a/ts_src/lib/converter/shared/redeemScript.ts b/ts_src/lib/converter/shared/redeemScript.ts index 691f988..bf3d592 100644 --- a/ts_src/lib/converter/shared/redeemScript.ts +++ b/ts_src/lib/converter/shared/redeemScript.ts @@ -1,4 +1,5 @@ import { KeyValue, RedeemScript } from '../../interfaces'; +import * as tools from 'uint8array-tools'; export function makeConverter( TYPE_BYTE: number, @@ -13,23 +14,23 @@ export function makeConverter( if (keyVal.key[0] !== TYPE_BYTE) { throw new Error( 'Decode Error: could not decode redeemScript with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; } function encode(data: RedeemScript): KeyValue { - const key = Buffer.from([TYPE_BYTE]); + const key = Uint8Array.from([TYPE_BYTE]); return { key, value: data, }; } - const expected = 'Buffer'; + const expected = 'Uint8Array'; function check(data: any): data is RedeemScript { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/shared/tapBip32Derivation.ts b/ts_src/lib/converter/shared/tapBip32Derivation.ts index 25ac61c..6463239 100644 --- a/ts_src/lib/converter/shared/tapBip32Derivation.ts +++ b/ts_src/lib/converter/shared/tapBip32Derivation.ts @@ -1,8 +1,9 @@ import { KeyValue, TapBip32Derivation } from '../../interfaces'; -import * as varuint from '../varint'; -import * as bip32Derivation from './bip32Derivation'; +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; +import * as bip32Derivation from './bip32Derivation.js'; -const isValidBIP340Key = (pubkey: Buffer): boolean => pubkey.length === 32; +const isValidBIP340Key = (pubkey: Uint8Array): boolean => pubkey.length === 32; export function makeConverter( TYPE_BYTE: number, @@ -19,14 +20,15 @@ export function makeConverter( } { const parent = bip32Derivation.makeConverter(TYPE_BYTE, isValidBIP340Key); function decode(keyVal: KeyValue): TapBip32Derivation { - const nHashes = varuint.decode(keyVal.value); - const nHashesLen = varuint.encodingLength(nHashes); + const { numberValue: nHashes, bytes: nHashesLen } = varuint.decode( + keyVal.value, + ); const base = parent.decode({ key: keyVal.key, - value: keyVal.value.slice(nHashesLen + nHashes * 32), + value: keyVal.value.slice(nHashesLen + Number(nHashes) * 32), }); - const leafHashes: Buffer[] = new Array(nHashes); - for (let i = 0, _offset = nHashesLen; i < nHashes; i++, _offset += 32) { + const leafHashes: Uint8Array[] = new Array(Number(nHashes)); + for (let i = 0, _offset = nHashesLen; i < nHashes!; i++, _offset += 32) { leafHashes[i] = keyVal.value.slice(_offset, _offset + 32); } return { ...base, leafHashes }; @@ -35,24 +37,25 @@ export function makeConverter( function encode(data: TapBip32Derivation): KeyValue { const base = parent.encode(data); const nHashesLen = varuint.encodingLength(data.leafHashes.length); - const nHashesBuf = Buffer.allocUnsafe(nHashesLen); + const nHashesBuf = new Uint8Array(nHashesLen); varuint.encode(data.leafHashes.length, nHashesBuf); - const value = Buffer.concat([nHashesBuf, ...data.leafHashes, base.value]); + const value = tools.concat([nHashesBuf, ...data.leafHashes, base.value]); return { ...base, value }; } const expected = '{ ' + - 'masterFingerprint: Buffer; ' + - 'pubkey: Buffer; ' + + 'masterFingerprint: Uint8Array; ' + + 'pubkey: Uint8Array; ' + 'path: string; ' + - 'leafHashes: Buffer[]; ' + + 'leafHashes: Uint8Array[]; ' + '}'; function check(data: any): data is TapBip32Derivation { return ( Array.isArray(data.leafHashes) && data.leafHashes.every( - (leafHash: any) => Buffer.isBuffer(leafHash) && leafHash.length === 32, + (leafHash: any) => + leafHash instanceof Uint8Array && leafHash.length === 32, ) && parent.check(data) ); diff --git a/ts_src/lib/converter/shared/tapInternalKey.ts b/ts_src/lib/converter/shared/tapInternalKey.ts index 5265568..a99e587 100644 --- a/ts_src/lib/converter/shared/tapInternalKey.ts +++ b/ts_src/lib/converter/shared/tapInternalKey.ts @@ -1,4 +1,5 @@ import { KeyValue, TapInternalKey } from '../../interfaces'; +import * as tools from 'uint8array-tools'; export function makeConverter( TYPE_BYTE: number, @@ -13,7 +14,7 @@ export function makeConverter( if (keyVal.key[0] !== TYPE_BYTE || keyVal.key.length !== 1) { throw new Error( 'Decode Error: could not decode tapInternalKey with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } if (keyVal.value.length !== 32) { @@ -25,13 +26,13 @@ export function makeConverter( } function encode(value: TapInternalKey): KeyValue { - const key = Buffer.from([TYPE_BYTE]); + const key = Uint8Array.from([TYPE_BYTE]); return { key, value }; } - const expected = 'Buffer'; + const expected = 'Uint8Array'; function check(data: any): data is TapInternalKey { - return Buffer.isBuffer(data) && data.length === 32; + return data instanceof Uint8Array && data.length === 32; } function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/shared/witnessScript.ts b/ts_src/lib/converter/shared/witnessScript.ts index 3ab2f71..0770503 100644 --- a/ts_src/lib/converter/shared/witnessScript.ts +++ b/ts_src/lib/converter/shared/witnessScript.ts @@ -1,4 +1,5 @@ import { KeyValue, WitnessScript } from '../../interfaces'; +import * as tools from 'uint8array-tools'; export function makeConverter( TYPE_BYTE: number, @@ -13,23 +14,23 @@ export function makeConverter( if (keyVal.key[0] !== TYPE_BYTE) { throw new Error( 'Decode Error: could not decode witnessScript with key 0x' + - keyVal.key.toString('hex'), + tools.toHex(keyVal.key), ); } return keyVal.value; } function encode(data: WitnessScript): KeyValue { - const key = Buffer.from([TYPE_BYTE]); + const key = Uint8Array.from([TYPE_BYTE]); return { key, value: data, }; } - const expected = 'Buffer'; + const expected = 'Uint8Array'; function check(data: any): data is WitnessScript { - return Buffer.isBuffer(data); + return data instanceof Uint8Array; } function canAdd(currentData: any, newData: any): boolean { diff --git a/ts_src/lib/converter/tools.ts b/ts_src/lib/converter/tools.ts index 95db97f..db61bc6 100644 --- a/ts_src/lib/converter/tools.ts +++ b/ts_src/lib/converter/tools.ts @@ -1,9 +1,10 @@ import { KeyValue } from '../interfaces'; -import * as varuint from './varint'; +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; export const range = (n: number): number[] => [...Array(n).keys()]; -export function reverseBuffer(buffer: Buffer): Buffer { +export function reverseBuffer(buffer: Uint8Array): Uint8Array { if (buffer.length < 1) return buffer; let j = buffer.length - 1; let tmp = 0; @@ -16,58 +17,24 @@ export function reverseBuffer(buffer: Buffer): Buffer { return buffer; } -export function keyValsToBuffer(keyVals: KeyValue[]): Buffer { +export function keyValsToBuffer(keyVals: KeyValue[]): Uint8Array { const buffers = keyVals.map(keyValToBuffer); - buffers.push(Buffer.from([0])); - return Buffer.concat(buffers); + buffers.push(Uint8Array.from([0])); + return tools.concat(buffers); } -export function keyValToBuffer(keyVal: KeyValue): Buffer { +export function keyValToBuffer(keyVal: KeyValue): Uint8Array { const keyLen = keyVal.key.length; const valLen = keyVal.value.length; const keyVarIntLen = varuint.encodingLength(keyLen); const valVarIntLen = varuint.encodingLength(valLen); - const buffer = Buffer.allocUnsafe( - keyVarIntLen + keyLen + valVarIntLen + valLen, - ); + const buffer = new Uint8Array(keyVarIntLen + keyLen + valVarIntLen + valLen); varuint.encode(keyLen, buffer, 0); - keyVal.key.copy(buffer, keyVarIntLen); + buffer.set(keyVal.key, keyVarIntLen); varuint.encode(valLen, buffer, keyVarIntLen + keyLen); - keyVal.value.copy(buffer, keyVarIntLen + keyLen + valVarIntLen); + buffer.set(keyVal.value, keyVarIntLen + keyLen + valVarIntLen); return buffer; } - -// https://github.com/feross/buffer/blob/master/index.js#L1127 -function verifuint(value: number, max: number): void { - if (typeof value !== 'number') - throw new Error('cannot write a non-number as a number'); - if (value < 0) - throw new Error('specified a negative value for writing an unsigned value'); - if (value > max) throw new Error('RangeError: value out of range'); - if (Math.floor(value) !== value) - throw new Error('value has a fractional component'); -} - -export function readUInt64LE(buffer: Buffer, offset: number): number { - const a = buffer.readUInt32LE(offset); - let b = buffer.readUInt32LE(offset + 4); - b *= 0x100000000; - - verifuint(b + a, 0x001fffffffffffff); - return b + a; -} - -export function writeUInt64LE( - buffer: Buffer, - value: number, - offset: number, -): number { - verifuint(value, 0x001fffffffffffff); - - buffer.writeInt32LE(value & -1, offset); - buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4); - return offset + 8; -} diff --git a/ts_src/lib/converter/varint.ts b/ts_src/lib/converter/varint.ts deleted file mode 100644 index b692128..0000000 --- a/ts_src/lib/converter/varint.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Number.MAX_SAFE_INTEGER -const MAX_SAFE_INTEGER = 9007199254740991; - -function checkUInt53(n: number): void { - if (n < 0 || n > MAX_SAFE_INTEGER || n % 1 !== 0) - throw new RangeError('value out of range'); -} - -export function encode( - _number: number, - buffer?: Buffer, - offset?: number, -): Buffer { - checkUInt53(_number); - - if (!buffer) buffer = Buffer.allocUnsafe(encodingLength(_number)); - if (!Buffer.isBuffer(buffer)) - throw new TypeError('buffer must be a Buffer instance'); - if (!offset) offset = 0; - - // 8 bit - if (_number < 0xfd) { - buffer.writeUInt8(_number, offset); - Object.assign(encode, { bytes: 1 }); - - // 16 bit - } else if (_number <= 0xffff) { - buffer.writeUInt8(0xfd, offset); - buffer.writeUInt16LE(_number, offset + 1); - Object.assign(encode, { bytes: 3 }); - - // 32 bit - } else if (_number <= 0xffffffff) { - buffer.writeUInt8(0xfe, offset); - buffer.writeUInt32LE(_number, offset + 1); - Object.assign(encode, { bytes: 5 }); - - // 64 bit - } else { - buffer.writeUInt8(0xff, offset); - buffer.writeUInt32LE(_number >>> 0, offset + 1); - buffer.writeUInt32LE((_number / 0x100000000) | 0, offset + 5); - Object.assign(encode, { bytes: 9 }); - } - - return buffer; -} - -export function decode(buffer: Buffer, offset?: number): number { - if (!Buffer.isBuffer(buffer)) - throw new TypeError('buffer must be a Buffer instance'); - if (!offset) offset = 0; - - const first = buffer.readUInt8(offset); - - // 8 bit - if (first < 0xfd) { - Object.assign(decode, { bytes: 1 }); - return first; - - // 16 bit - } else if (first === 0xfd) { - Object.assign(decode, { bytes: 3 }); - return buffer.readUInt16LE(offset + 1); - - // 32 bit - } else if (first === 0xfe) { - Object.assign(decode, { bytes: 5 }); - return buffer.readUInt32LE(offset + 1); - - // 64 bit - } else { - Object.assign(decode, { bytes: 9 }); - const lo = buffer.readUInt32LE(offset + 1); - const hi = buffer.readUInt32LE(offset + 5); - const _number = hi * 0x0100000000 + lo; - checkUInt53(_number); - - return _number; - } -} - -export function encodingLength(_number: number): number { - checkUInt53(_number); - - return _number < 0xfd - ? 1 - : _number <= 0xffff - ? 3 - : _number <= 0xffffffff - ? 5 - : 9; -} diff --git a/ts_src/lib/interfaces.ts b/ts_src/lib/interfaces.ts index d7c344e..d01e834 100644 --- a/ts_src/lib/interfaces.ts +++ b/ts_src/lib/interfaces.ts @@ -1,7 +1,7 @@ // This function should throw if the scriptSig or scriptWitness section for // any input is not empty. And it should throw if the transaction is segwit // format. As per the BIP. -export type TransactionFromBuffer = (buffer: Buffer) => Transaction; +export type TransactionFromBuffer = (buffer: Uint8Array) => Transaction; // This is a light wrapper that will give the information needed for parsing // and modifying the Transaction internally. // This library will have no logical understanding of the Transaction format, @@ -19,12 +19,12 @@ export interface Transaction { // This is primarily used when serializing the PSBT to a binary. // You can implement caching behind the scenes if needed and clear the cache // when addInput or addOutput are called. - toBuffer(): Buffer; + toBuffer(): Uint8Array; } export interface KeyValue { - key: Buffer; - value: Buffer; + key: Uint8Array; + value: Uint8Array; } export interface PsbtGlobal extends PsbtGlobalUpdate { @@ -81,65 +81,65 @@ export interface PsbtOutputExtended extends PsbtOutput { } export interface GlobalXpub { - extendedPubkey: Buffer; - masterFingerprint: Buffer; + extendedPubkey: Uint8Array; + masterFingerprint: Uint8Array; path: string; } export interface PartialSig { - pubkey: Buffer; - signature: Buffer; + pubkey: Uint8Array; + signature: Uint8Array; } export interface Bip32Derivation { - masterFingerprint: Buffer; - pubkey: Buffer; + masterFingerprint: Uint8Array; + pubkey: Uint8Array; path: string; } export interface WitnessUtxo { - script: Buffer; - value: number; + script: Uint8Array; + value: bigint; } -export type NonWitnessUtxo = Buffer; +export type NonWitnessUtxo = Uint8Array; export type SighashType = number; -export type RedeemScript = Buffer; +export type RedeemScript = Uint8Array; -export type WitnessScript = Buffer; +export type WitnessScript = Uint8Array; -export type FinalScriptSig = Buffer; +export type FinalScriptSig = Uint8Array; -export type FinalScriptWitness = Buffer; +export type FinalScriptWitness = Uint8Array; export type PorCommitment = string; -export type TapKeySig = Buffer; +export type TapKeySig = Uint8Array; export interface TapScriptSig extends PartialSig { - leafHash: Buffer; + leafHash: Uint8Array; } interface TapScript { leafVersion: number; - script: Buffer; + script: Uint8Array; } -export type ControlBlock = Buffer; +export type ControlBlock = Uint8Array; export interface TapLeafScript extends TapScript { controlBlock: ControlBlock; } export interface TapBip32Derivation extends Bip32Derivation { - leafHashes: Buffer[]; + leafHashes: Uint8Array[]; } -export type TapInternalKey = Buffer; +export type TapInternalKey = Uint8Array; -export type TapMerkleRoot = Buffer; +export type TapMerkleRoot = Uint8Array; export interface TapLeaf extends TapScript { depth: number; @@ -150,7 +150,7 @@ export interface TapTree { } export type TransactionIOCountGetter = ( - txBuffer: Buffer, + txBuffer: Uint8Array, ) => { inputCount: number; outputCount: number; @@ -158,10 +158,10 @@ export type TransactionIOCountGetter = ( export type TransactionVersionSetter = ( version: number, - txBuffer: Buffer, -) => Buffer; + txBuffer: Uint8Array, +) => Uint8Array; export type TransactionLocktimeSetter = ( locktime: number, - txBuffer: Buffer, -) => Buffer; + txBuffer: Uint8Array, +) => Uint8Array; diff --git a/ts_src/lib/parser/fromBuffer.ts b/ts_src/lib/parser/fromBuffer.ts index 52c64ff..14a0e62 100644 --- a/ts_src/lib/parser/fromBuffer.ts +++ b/ts_src/lib/parser/fromBuffer.ts @@ -1,6 +1,7 @@ -import * as convert from '../converter'; -import { range } from '../converter/tools'; -import * as varuint from '../converter/varint'; +import * as convert from '../converter/index.js'; +import { range } from '../converter/tools.js'; +import * as varuint from 'varuint-bitcoin'; +import * as tools from 'uint8array-tools'; import { KeyValue, PsbtGlobal, @@ -9,31 +10,31 @@ import { Transaction, TransactionFromBuffer, } from '../interfaces'; -import { GlobalTypes, InputTypes, OutputTypes } from '../typeFields'; -import { PsbtAttributes } from './index'; +import { GlobalTypes, InputTypes, OutputTypes } from '../typeFields.js'; +import { PsbtAttributes } from './index.js'; export function psbtFromBuffer( - buffer: Buffer, + buffer: Uint8Array, txGetter: TransactionFromBuffer, ): PsbtAttributes { let offset = 0; - function varSlice(): Buffer { - const keyLen = varuint.decode(buffer, offset); - offset += varuint.encodingLength(keyLen); - const key = buffer.slice(offset, offset + keyLen); - offset += keyLen; + function varSlice(): Uint8Array { + const { numberValue: keyLen, bytes } = varuint.decode(buffer, offset); + offset += bytes; + const key = buffer.slice(offset, offset + Number(keyLen)); + offset += Number(keyLen); return key; } function readUInt32BE(): number { - const num = buffer.readUInt32BE(offset); + const num = tools.readUInt32(buffer, offset, 'BE'); offset += 4; return num; } function readUInt8(): number { - const num = buffer.readUInt8(offset); + const num = tools.readUInt8(buffer, offset); offset += 1; return num; } @@ -51,7 +52,7 @@ export function psbtFromBuffer( if (offset >= buffer.length) { throw new Error('Format Error: Unexpected End of PSBT'); } - const isEnd = buffer.readUInt8(offset) === 0; + const isEnd = tools.readUInt8(buffer, offset) === 0; if (isEnd) { offset++; } @@ -71,7 +72,7 @@ export function psbtFromBuffer( const globalKeyIndex: { [index: string]: number } = {}; while (!checkEndOfKeyValPairs()) { const keyVal = getKeyValue(); - const hexKey = keyVal.key.toString('hex'); + const hexKey = tools.toHex(keyVal.key); if (globalKeyIndex[hexKey]) { throw new Error( 'Format Error: Keys must be unique for global keymap: key ' + hexKey, @@ -102,7 +103,7 @@ export function psbtFromBuffer( const input = [] as KeyValue[]; while (!checkEndOfKeyValPairs()) { const keyVal = getKeyValue(); - const hexKey = keyVal.key.toString('hex'); + const hexKey = tools.toHex(keyVal.key); if (inputKeyIndex[hexKey]) { throw new Error( 'Format Error: Keys must be unique for each input: ' + @@ -123,7 +124,7 @@ export function psbtFromBuffer( const output = [] as KeyValue[]; while (!checkEndOfKeyValPairs()) { const keyVal = getKeyValue(); - const hexKey = keyVal.key.toString('hex'); + const hexKey = tools.toHex(keyVal.key); if (outputKeyIndex[hexKey]) { throw new Error( 'Format Error: Keys must be unique for each output: ' + @@ -154,12 +155,13 @@ interface PsbtFromKeyValsArg { export function checkKeyBuffer( type: string, - keyBuf: Buffer, + keyBuf: Uint8Array, keyNum: number, ): void { - if (!keyBuf.equals(Buffer.from([keyNum]))) { + if (tools.compare(keyBuf, Uint8Array.from([keyNum]))) { throw new Error( - `Format Error: Invalid ${type} key: ${keyBuf.toString('hex')}`, + // `Format Error: Invalid ${type} key: ${keyBuf.toString('hex')}`, + `Format Error: Invalid ${type} key: ${tools.toHex(keyBuf)}`, ); } } diff --git a/ts_src/lib/parser/index.ts b/ts_src/lib/parser/index.ts index 5965b5f..d56b9b6 100644 --- a/ts_src/lib/parser/index.ts +++ b/ts_src/lib/parser/index.ts @@ -1,7 +1,7 @@ import { PsbtGlobal, PsbtInput, PsbtOutput } from '../interfaces'; -export * from './fromBuffer'; -export * from './toBuffer'; +export * from './fromBuffer.js'; +export * from './toBuffer.js'; export interface PsbtAttributes { globalMap: PsbtGlobal; diff --git a/ts_src/lib/parser/toBuffer.ts b/ts_src/lib/parser/toBuffer.ts index a304aa9..71df564 100644 --- a/ts_src/lib/parser/toBuffer.ts +++ b/ts_src/lib/parser/toBuffer.ts @@ -1,13 +1,14 @@ -import * as convert from '../converter'; -import { keyValsToBuffer } from '../converter/tools'; +import * as convert from '../converter/index.js'; +import { keyValsToBuffer } from '../converter/tools.js'; import { KeyValue, PsbtGlobal, PsbtInput, PsbtOutput } from '../interfaces'; -import { PsbtAttributes } from './index'; +import { PsbtAttributes } from './index.js'; +import * as tools from 'uint8array-tools'; export function psbtToBuffer({ globalMap, inputs, outputs, -}: PsbtAttributes): Buffer { +}: PsbtAttributes): Uint8Array { const { globalKeyVals, inputKeyVals, outputKeyVals } = psbtToKeyVals({ globalMap, inputs, @@ -16,21 +17,23 @@ export function psbtToBuffer({ const globalBuffer = keyValsToBuffer(globalKeyVals); - const keyValsOrEmptyToBuffer = (keyVals: KeyValue[][]): Buffer[] => - keyVals.length === 0 ? [Buffer.from([0])] : keyVals.map(keyValsToBuffer); + const keyValsOrEmptyToBuffer = (keyVals: KeyValue[][]): Uint8Array[] => + keyVals.length === 0 + ? [Uint8Array.from([0])] + : keyVals.map(keyValsToBuffer); const inputBuffers = keyValsOrEmptyToBuffer(inputKeyVals); const outputBuffers = keyValsOrEmptyToBuffer(outputKeyVals); - const header = Buffer.allocUnsafe(5); - header.writeUIntBE(0x70736274ff, 0, 5); - return Buffer.concat( + const header = new Uint8Array(5); + header.set([0x70, 0x73, 0x62, 0x74, 0xff], 0); + return tools.concat( [header, globalBuffer].concat(inputBuffers, outputBuffers), ); } const sortKeyVals = (a: KeyValue, b: KeyValue): number => { - return a.key.compare(b.key); + return tools.compare(a.key, b.key); }; function keyValsFromMap( @@ -50,7 +53,7 @@ function keyValsFromMap( converter.encode, ) as KeyValue[]; - const keyHexes = encodedKeyVals.map(kv => kv.key.toString('hex')); + const keyHexes = encodedKeyVals.map(kv => tools.toHex(kv.key)); keyHexes.forEach(hex => { if (keyHexSet.has(hex)) throw new Error('Serialize Error: Duplicate key: ' + hex); @@ -63,7 +66,7 @@ function keyValsFromMap( // Get other keyVals that have not yet been gotten const otherKeyVals = keyValMap.unknownKeyVals ? keyValMap.unknownKeyVals.filter((keyVal: KeyValue) => { - return !keyHexSet.has(keyVal.key.toString('hex')); + return !keyHexSet.has(tools.toHex(keyVal.key)); }) : []; diff --git a/ts_src/lib/psbt.ts b/ts_src/lib/psbt.ts index 59c6ed9..8d7aaa7 100644 --- a/ts_src/lib/psbt.ts +++ b/ts_src/lib/psbt.ts @@ -1,4 +1,4 @@ -import { combine } from './combiner'; +import { combine } from './combiner/index.js'; import { KeyValue, PsbtGlobal, @@ -11,9 +11,9 @@ import { PsbtOutputUpdate, Transaction, TransactionFromBuffer, -} from './interfaces'; -import { psbtFromBuffer, psbtToBuffer } from './parser'; -import { GlobalTypes, InputTypes, OutputTypes } from './typeFields'; +} from './interfaces.js'; +import { psbtFromBuffer, psbtToBuffer } from './parser/index.js'; +import { GlobalTypes, InputTypes, OutputTypes } from './typeFields.js'; import { addInputAttributes, addOutputAttributes, @@ -25,7 +25,9 @@ import { updateGlobal, updateInput, updateOutput, -} from './utils'; +} from './utils.js'; + +import * as tools from 'uint8array-tools'; export class Psbt { static fromBase64( @@ -33,7 +35,7 @@ export class Psbt { data: string, txFromBuffer: TransactionFromBuffer, ): InstanceType { - const buffer = Buffer.from(data, 'base64'); + const buffer = tools.fromBase64(data); return this.fromBuffer(buffer, txFromBuffer); } static fromHex( @@ -41,12 +43,12 @@ export class Psbt { data: string, txFromBuffer: TransactionFromBuffer, ): InstanceType { - const buffer = Buffer.from(data, 'hex'); + const buffer = tools.fromHex(data); return this.fromBuffer(buffer, txFromBuffer); } static fromBuffer( this: T, - buffer: Buffer, + buffer: Uint8Array, txFromBuffer: TransactionFromBuffer, ): InstanceType { const results = psbtFromBuffer(buffer, txFromBuffer); @@ -67,15 +69,15 @@ export class Psbt { toBase64(): string { const buffer = this.toBuffer(); - return buffer.toString('base64'); + return tools.toBase64(buffer); } toHex(): string { const buffer = this.toBuffer(); - return buffer.toString('hex'); + return tools.toHex(buffer); } - toBuffer(): Buffer { + toBuffer(): Uint8Array { return psbtToBuffer(this); } @@ -185,7 +187,46 @@ export class Psbt { return this; } - getTransaction(): Buffer { + getTransaction(): Uint8Array { return this.globalMap.unsignedTx.toBuffer(); } } + +export { + Bip32Derivation, + NonWitnessUtxo, + ControlBlock, + FinalScriptSig, + FinalScriptWitness, + GlobalXpub, + KeyValue, + PartialSig, + PorCommitment, + PsbtGlobal, + PsbtGlobalUpdate, + PsbtInput, + PsbtInputExtended, + PsbtInputUpdate, + PsbtOutput, + PsbtOutputExtended, + PsbtOutputUpdate, + RedeemScript, + SighashType, + TapBip32Derivation, + TapInternalKey, + TapKeySig, + TapLeaf, + TapLeafScript, + TapMerkleRoot, + TapScriptSig, + TapTree, + Transaction, + TransactionFromBuffer, + TransactionIOCountGetter, + TransactionLocktimeSetter, + TransactionVersionSetter, + WitnessScript, + WitnessUtxo, +} from './interfaces.js'; + +export { checkForInput, checkForOutput } from './utils.js'; diff --git a/ts_src/lib/utils.ts b/ts_src/lib/utils.ts index c2fa3a0..7862371 100644 --- a/ts_src/lib/utils.ts +++ b/ts_src/lib/utils.ts @@ -1,4 +1,4 @@ -import * as converter from './converter'; +import * as converter from './converter/index.js'; import { KeyValue, PsbtGlobal, @@ -7,7 +7,8 @@ import { PsbtInputUpdate, PsbtOutput, PsbtOutputUpdate, -} from './interfaces'; +} from './interfaces.js'; +import * as tools from 'uint8array-tools'; export function checkForInput( inputs: PsbtInput[], @@ -39,9 +40,10 @@ export function checkHasKey( } if ( keyVals && - keyVals.filter(kv => kv.key.equals(checkKeyVal.key)).length !== 0 + keyVals.filter(kv => tools.compare(kv.key, checkKeyVal.key) === 0) + .length !== 0 ) { - throw new Error(`Duplicate Key: ${checkKeyVal.key.toString('hex')}`); + throw new Error(`Duplicate Key: ${tools.toHex(checkKeyVal.key)}`); } } @@ -91,6 +93,7 @@ function updateMaker( typeName: string, ): (updateData: T, mainData: Y) => void { return (updateData: T, mainData: Y): void => { + // @ts-ignore for (const name of Object.keys(updateData)) { // @ts-ignore const data = updateData[name]; @@ -150,18 +153,24 @@ export function addOutputAttributes(outputs: PsbtOutput[], data: any): void { updateOutput(data, output); } -export function defaultVersionSetter(version: number, txBuf: Buffer): Buffer { - if (!Buffer.isBuffer(txBuf) || txBuf.length < 4) { +export function defaultVersionSetter( + version: number, + txBuf: Uint8Array, +): Uint8Array { + if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) { throw new Error('Set Version: Invalid Transaction'); } - txBuf.writeUInt32LE(version, 0); + tools.writeUInt32(txBuf, 0, version, 'LE'); return txBuf; } -export function defaultLocktimeSetter(locktime: number, txBuf: Buffer): Buffer { - if (!Buffer.isBuffer(txBuf) || txBuf.length < 4) { +export function defaultLocktimeSetter( + locktime: number, + txBuf: Uint8Array, +): Uint8Array { + if (!(txBuf instanceof Uint8Array) || txBuf.length < 4) { throw new Error('Set Locktime: Invalid Transaction'); } - txBuf.writeUInt32LE(locktime, txBuf.length - 4); + tools.writeUInt32(txBuf, txBuf.length - 4, locktime, 'LE'); return txBuf; } diff --git a/ts_src/tests/addInputOutput.ts b/ts_src/tests/addInputOutput.ts index f49d5ab..2ce4d76 100644 --- a/ts_src/tests/addInputOutput.ts +++ b/ts_src/tests/addInputOutput.ts @@ -1,6 +1,6 @@ -import * as tape from 'tape'; -import { Psbt } from '../lib/psbt'; -import { getDefaultTx, transactionFromBuffer } from './utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { getDefaultTx, transactionFromBuffer } from './utils/txTools.js'; tape('Test: add Input Output', t => { const psbt = new Psbt(getDefaultTx()); @@ -37,13 +37,5 @@ tape('Test: add Input Output', t => { 'e18870f2c297fbfca54c5c6f645c7745a5b66eda87000000000000000000', ); t.equal(hex, hex2); - - // console.log(jsonA1); - // console.log(jsonA2); - // console.log(jsonB1); - // console.log(jsonB2); - - // t.notDeepEqual(JSON.parse(jsonA1), JSON.parse(jsonB1)); - // t.deepEqual(JSON.parse(jsonA2), JSON.parse(jsonB2)); t.end(); }); diff --git a/ts_src/tests/combine.ts b/ts_src/tests/combine.ts index c6e881c..6272a53 100644 --- a/ts_src/tests/combine.ts +++ b/ts_src/tests/combine.ts @@ -1,7 +1,7 @@ -import * as tape from 'tape'; -import { Psbt } from '../lib/psbt'; -import { fixtures } from './fixtures/combine'; -import { transactionFromBuffer } from './utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/combine.js'; +import { transactionFromBuffer } from './utils/txTools.js'; for (const f of fixtures) { tape('Test: ' + f.description, t => { @@ -12,11 +12,6 @@ for (const f of fixtures) { const jsonB1 = jsonify(psbts[0]); const jsonB2 = jsonify(psbts[1]); - // console.log(jsonA1); - // console.log(jsonA2); - // console.log(jsonB1); - // console.log(jsonB2); - t.notDeepEqual(JSON.parse(jsonA1), JSON.parse(jsonB1)); t.deepEqual(JSON.parse(jsonA2), JSON.parse(jsonB2)); t.equal(psbts[0].toHex(), f.result); @@ -30,6 +25,8 @@ function jsonify(parsed: any): string { (key, value) => { return key !== undefined && value.type === 'Buffer' ? Buffer.from(value.data).toString('hex') + : typeof value === 'bigint' + ? value.toString() : value; }, 2, diff --git a/ts_src/tests/create.ts b/ts_src/tests/create.ts index 15eb4e1..7a0b217 100644 --- a/ts_src/tests/create.ts +++ b/ts_src/tests/create.ts @@ -1,7 +1,7 @@ -import * as tape from 'tape'; -import { Psbt } from '../lib/psbt'; -import { fixtures } from './fixtures/create'; -import { getDefaultTx } from './utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/create.js'; +import { getDefaultTx } from './utils/txTools.js'; for (const f of fixtures) { tape('Test: ' + f.description, t => { diff --git a/ts_src/tests/first.ts b/ts_src/tests/first.ts index 6d8a46f..18beed0 100644 --- a/ts_src/tests/first.ts +++ b/ts_src/tests/first.ts @@ -1,7 +1,8 @@ -import * as tape from 'tape'; -import { Psbt } from '../lib/psbt'; -import { fixtures } from './fixtures/first'; -import { transactionFromBuffer } from './utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/first.js'; +import { transactionFromBuffer } from './utils/txTools.js'; +import * as tools from 'uint8array-tools'; for (const f of fixtures) { tape('Test: ' + f.description, t => { @@ -24,8 +25,12 @@ function jsonify(parsed: any): string { return JSON.stringify( parsed, (key, value) => { - return key !== undefined && value !== undefined && value.type === 'Buffer' - ? Buffer.from(value.data).toString('hex') + return key !== undefined && + value !== undefined && + (value.type === 'Buffer' || value instanceof Uint8Array) + ? tools.toHex(value) + : typeof value === 'bigint' + ? Number(value) : value; }, 2, diff --git a/ts_src/tests/fixtures/create.ts b/ts_src/tests/fixtures/create.ts index bb516a9..996412f 100644 --- a/ts_src/tests/fixtures/create.ts +++ b/ts_src/tests/fixtures/create.ts @@ -19,11 +19,11 @@ export const fixtures = [ addOutputs: [ { script: b('0014d85c2b71d0060b09c9886aeb815e50991dda124d'), - value: 149990000, + value: 149990000n, }, { script: b('001400aea9a2e5f0f876a588df5546e8742d1d87008f'), - value: 100000000, + value: 100000000n, }, ], updateInputData: [ @@ -61,7 +61,7 @@ export const fixtures = [ { witnessUtxo: { script: b('a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887'), - value: 200000000, + value: 200000000n, }, redeemScript: b( '00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903', diff --git a/ts_src/tests/fixtures/methods.ts b/ts_src/tests/fixtures/methods.ts index 9eb1dba..606aee3 100644 --- a/ts_src/tests/fixtures/methods.ts +++ b/ts_src/tests/fixtures/methods.ts @@ -72,7 +72,7 @@ export const fixtures = { addInputOutput: true, args: [ 0, - { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890 } }, + { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890n } }, ], expected: 'cHNidP8BAFMBAAAAAdSnb/ld4fTAFho+U+qHapHtlTMa6NAS2B+XE4SYzl2GAwAAAAD/' + @@ -433,14 +433,14 @@ export const fixtures = { ], exception: 'Data for global key globalXpub is incorrect: Expected { ' + - 'masterFingerprint: Buffer; extendedPubkey: Buffer; path: string; } and got', + 'masterFingerprint: Uint8Array; extendedPubkey: Uint8Array; path: string; } and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { nonWitnessUtxo: 'blah' }], exception: - 'Data for input key nonWitnessUtxo is incorrect: Expected Buffer and got', + 'Data for input key nonWitnessUtxo is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', @@ -508,7 +508,7 @@ export const fixtures = { ], exception: 'Data for input key witnessUtxo is incorrect: Expected { ' + - 'script: Buffer; value: number; } and got', + 'script: Uint8Array; value: bigint; } and got', }, { method: 'updateInput', @@ -516,7 +516,7 @@ export const fixtures = { twice: true, args: [ 0, - { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890 } }, + { witnessUtxo: { script: Buffer.from([1, 2, 3]), value: 1234567890n } }, ], exception: 'Can not add duplicate data to input', }, @@ -533,7 +533,7 @@ export const fixtures = { ], exception: 'Data for input key partialSig is incorrect: Expected { pubkey: ' + - 'Buffer; signature: Buffer; } and got', + 'Uint8Array; signature: Uint8Array; } and got', }, { method: 'updateInput', @@ -547,14 +547,14 @@ export const fixtures = { addInputOutput: true, args: [0, { redeemScript: 'a' }], exception: - 'Data for input key redeemScript is incorrect: Expected Buffer and got', + 'Data for input key redeemScript is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { witnessScript: 'a' }], exception: - 'Data for input key witnessScript is incorrect: Expected Buffer and got', + 'Data for input key witnessScript is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', @@ -571,21 +571,21 @@ export const fixtures = { ], exception: 'Data for input key bip32Derivation is incorrect: Expected { ' + - 'masterFingerprint: Buffer; pubkey: Buffer; path: string; } and got', + 'masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; } and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { finalScriptSig: 8 }], exception: - 'Data for input key finalScriptSig is incorrect: Expected Buffer and got', + 'Data for input key finalScriptSig is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', addInputOutput: true, args: [0, { finalScriptWitness: 8 }], exception: - 'Data for input key finalScriptWitness is incorrect: Expected Buffer and got', + 'Data for input key finalScriptWitness is incorrect: Expected Uint8Array and got', }, { method: 'updateInput', @@ -599,14 +599,14 @@ export const fixtures = { addInputOutput: true, args: [0, { redeemScript: 8 }], exception: - 'Data for output key redeemScript is incorrect: Expected Buffer and got', + 'Data for output key redeemScript is incorrect: Expected Uint8Array and got', }, { method: 'updateOutput', addInputOutput: true, args: [0, { witnessScript: 8 }], exception: - 'Data for output key witnessScript is incorrect: Expected Buffer and got', + 'Data for output key witnessScript is incorrect: Expected Uint8Array and got', }, { method: 'updateOutput', @@ -623,7 +623,7 @@ export const fixtures = { ], exception: 'Data for output key bip32Derivation is incorrect: Expected { ' + - 'masterFingerprint: Buffer; pubkey: Buffer; path: string; } and got', + 'masterFingerprint: Uint8Array; pubkey: Uint8Array; path: string; } and got', }, { method: 'updateInput', diff --git a/ts_src/tests/fixtures/update.ts b/ts_src/tests/fixtures/update.ts index ec5c495..c68523f 100644 --- a/ts_src/tests/fixtures/update.ts +++ b/ts_src/tests/fixtures/update.ts @@ -20,7 +20,7 @@ export const fixtures = [ ), witnessUtxo: { script: b('0014ce2ef55e561be15ef65dcc79f998117e142d6016'), - value: 10413, + value: 10413n, }, redeemScript: b( '5221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96' + @@ -47,7 +47,7 @@ export const fixtures = [ { witnessUtxo: { script: b('a914b7f5faf40e3d40a5a459b1db3535f2b72fa921e887'), - value: 200000000, + value: 200000000n, }, redeemScript: b( '00208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903', diff --git a/ts_src/tests/fromBIP/invalid.ts b/ts_src/tests/fromBIP/invalid.ts index c851f49..44144da 100644 --- a/ts_src/tests/fromBIP/invalid.ts +++ b/ts_src/tests/fromBIP/invalid.ts @@ -1,7 +1,7 @@ -import * as tape from 'tape'; -import { Psbt } from '../../lib/psbt'; -import { fixtures } from '../fixtures/invalid'; -import { transactionFromBuffer } from '../utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../../lib/psbt.js'; +import { fixtures } from '../fixtures/invalid.js'; +import { transactionFromBuffer } from '../utils/txTools.js'; // const res: any[] = []; diff --git a/ts_src/tests/fromBIP/update.ts b/ts_src/tests/fromBIP/update.ts index b37d932..b713129 100644 --- a/ts_src/tests/fromBIP/update.ts +++ b/ts_src/tests/fromBIP/update.ts @@ -1,7 +1,7 @@ -import * as tape from 'tape'; -import { Psbt } from '../../lib/psbt'; -import { fixtures } from '../fixtures/update'; -import { transactionFromBuffer } from '../utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../../lib/psbt.js'; +import { fixtures } from '../fixtures/update.js'; +import { transactionFromBuffer } from '../utils/txTools.js'; let lastAfter: any; diff --git a/ts_src/tests/fromBIP/valid.ts b/ts_src/tests/fromBIP/valid.ts index 616dd43..7b1a9ad 100644 --- a/ts_src/tests/fromBIP/valid.ts +++ b/ts_src/tests/fromBIP/valid.ts @@ -1,7 +1,7 @@ -import * as tape from 'tape'; -import { Psbt } from '../../lib/psbt'; -import { fixtures } from '../fixtures/valid'; -import { transactionFromBuffer } from '../utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../../lib/psbt.js'; +import { fixtures } from '../fixtures/valid.js'; +import { transactionFromBuffer } from '../utils/txTools.js'; for (const f of fixtures) { tape(`Test: Should not throw`, t => { diff --git a/ts_src/tests/fromBuffer.ts b/ts_src/tests/fromBuffer.ts index 8a8787a..70ddc2d 100644 --- a/ts_src/tests/fromBuffer.ts +++ b/ts_src/tests/fromBuffer.ts @@ -1,9 +1,9 @@ -import * as tape from 'tape'; -import { Psbt } from '../lib/psbt'; -import { fixtures } from './fixtures/fromBuffer'; +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/fromBuffer.js'; class Blah { - constructor(public buf: Buffer) {} + constructor(public buf: Uint8Array) {} getInputOutputCounts(): { inputCount: number; @@ -21,12 +21,12 @@ class Blah { addOutput(): void { return; } - toBuffer(): Buffer { + toBuffer(): Uint8Array { return this.buf; } } -const fromBuf = (b: Buffer): Blah => new Blah(b); +const fromBuf = (b: Uint8Array): Blah => new Blah(b); for (const f of fixtures) { tape('From Buffer should throw:', t => { diff --git a/ts_src/tests/keyValsToPsbt.ts b/ts_src/tests/keyValsToPsbt.ts index c0ef22c..26540ed 100644 --- a/ts_src/tests/keyValsToPsbt.ts +++ b/ts_src/tests/keyValsToPsbt.ts @@ -1,8 +1,8 @@ -import * as tape from 'tape'; -import { psbtFromKeyVals } from '../lib/parser/fromBuffer'; -import { Psbt } from '../lib/psbt'; -import { fixtures } from './fixtures/keyValsToPsbt'; -import { getDefaultTx, transactionFromBuffer } from './utils/txTools'; +import tape from 'tape'; +import { psbtFromKeyVals } from '../lib/parser/fromBuffer.js'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/keyValsToPsbt.js'; +import { getDefaultTx, transactionFromBuffer } from './utils/txTools.js'; for (const f of fixtures) { if (f.exception) { @@ -21,7 +21,6 @@ for (const f of fixtures) { const psbt = new Psbt(tx); Object.assign(psbt, data); t.strictEqual(psbt.toBase64(), f.expected); - // else console.log(psbt.toBase64()); t.end(); }); } diff --git a/ts_src/tests/methods.ts b/ts_src/tests/methods.ts index 7133cbc..5c6e4c1 100644 --- a/ts_src/tests/methods.ts +++ b/ts_src/tests/methods.ts @@ -1,7 +1,7 @@ -import * as tape from 'tape'; -import { Psbt } from '../lib/psbt'; -import { fixtures } from './fixtures/methods'; -import { getDefaultTx } from './utils/txTools'; +import tape from 'tape'; +import { Psbt } from '../lib/psbt.js'; +import { fixtures } from './fixtures/methods.js'; +import { getDefaultTx } from './utils/txTools.js'; function run(f: any, typ: string): void { tape(`check ${typ} method: ${f.method}`, t => { diff --git a/ts_src/tests/utils/txTools.ts b/ts_src/tests/utils/txTools.ts index dc68fe9..d0a50f7 100644 --- a/ts_src/tests/utils/txTools.ts +++ b/ts_src/tests/utils/txTools.ts @@ -1,5 +1,5 @@ import { Transaction as BTransaction } from 'bitcoinjs-lib'; -import { reverseBuffer } from '../../lib/converter/tools'; +import { reverseBuffer } from '../../lib/converter/tools.js'; import { Transaction as ITransaction, TransactionFromBuffer, @@ -12,13 +12,13 @@ export function getDefaultTx(version: number = 1): Transaction { } export const transactionFromBuffer: TransactionFromBuffer = ( - buffer: Buffer, + buffer: Uint8Array, ): Transaction => new Transaction(buffer); export class Transaction implements ITransaction { tx: BTransaction; - constructor(buffer: Buffer) { - this.tx = BTransaction.fromBuffer(buffer); + constructor(buffer: Uint8Array) { + this.tx = BTransaction.fromBuffer(Buffer.from(buffer)); if (this.tx.ins.some(input => input.script.length !== 0)) { throw new Error('Format Error: Transaction ScriptSigs are not empty'); } @@ -43,7 +43,7 @@ export class Transaction implements ITransaction { } addOutput(output: any): void { - this.tx.addOutput(output.script, output.value); + this.tx.addOutput(output.script, Number(output.value)); } toBuffer(): Buffer { diff --git a/ts_src/tests/validation.ts b/ts_src/tests/validation.ts index 0da1ece..8f2724f 100644 --- a/ts_src/tests/validation.ts +++ b/ts_src/tests/validation.ts @@ -1,10 +1,11 @@ -import * as tape from 'tape'; -import { combine } from '../lib/combiner'; +import tape from 'tape'; +import { combine } from '../lib/combiner/index.js'; import { globals as convertGlobal, inputs as convertInputs, -} from '../lib/converter'; -import { getDefaultTx } from './utils/txTools'; +} from '../lib/converter/index.js'; +import { getDefaultTx } from './utils/txTools.js'; +import * as tools from 'uint8array-tools'; const b = (hex: string): Buffer => Buffer.from(hex, 'hex'); @@ -72,7 +73,7 @@ tape('should not pass isPartialSig with invalid DER signature', t => { }, new RegExp('Decode Error: partialSig has invalid pubkey in key 0x02ff')); keyVal.key = Buffer.concat([b('02'), data.pubkey, data.pubkey.slice(1)]); const result = convertInputs.partialSig.decode(keyVal); - t.assert(result.pubkey.equals(keyVal.key.slice(1))); + t.assert(tools.compare(result.pubkey, keyVal.key.slice(1)) === 0); const psbt1: any = { globalMap: { diff --git a/ts_src/tests/varint.ts b/ts_src/tests/varint.ts deleted file mode 100644 index 7858e8b..0000000 --- a/ts_src/tests/varint.ts +++ /dev/null @@ -1,91 +0,0 @@ -import * as test from 'tape'; -import * as varuint from '../lib/converter/varint'; - -import { fixtures } from './fixtures/varint'; - -fixtures.valid.forEach((fixture, i) => { - test('valid encode #' + (i + 1), t => { - t.same(varuint.encode(fixture.dec).toString('hex'), fixture.hex); - // @ts-ignore - t.same(varuint.encode.bytes, fixture.hex.length / 2); - t.end(); - }); - - test('valid decode #' + (i + 1), t => { - t.same(varuint.decode(Buffer.from(fixture.hex, 'hex')), fixture.dec); - // @ts-ignore - t.same(varuint.decode.bytes, fixture.hex.length / 2); - t.end(); - }); - - test('valid encodingLength #' + (i + 1), t => { - t.same(varuint.encodingLength(fixture.dec), fixture.hex.length / 2); - t.end(); - }); -}); - -fixtures.invalid.forEach((fixture, i) => { - test('invalid encode #' + (i + 1), t => { - t.throws(() => { - varuint.encode(fixture.dec); - }, new RegExp(fixture.msg)); - t.end(); - }); - - test('invalid encodingLength #' + (i + 1), t => { - t.throws(() => { - varuint.encodingLength(fixture.dec); - }, new RegExp(fixture.msg)); - t.end(); - }); - - if (fixture.hex) { - test('invalid decode #' + (i + 1), t => { - t.throws(() => { - // @ts-ignore - t.decode(varuint.decode(Buffer.from(fixture.hex, 'hex'))); - }, new RegExp(fixture.msg)); - t.end(); - }); - } -}); - -test('encode', t => { - t.test('write to buffer with offset', _t => { - const buffer = Buffer.from([0x00, 0x00]); - _t.same(varuint.encode(0xfc, buffer, 1).toString('hex'), '00fc'); - // @ts-ignore - _t.same(varuint.encode.bytes, 1); - _t.end(); - }); - - t.test('should be a buffer', _t => { - _t.throws(() => { - // @ts-ignore - varuint.encode(0, []); - }, new RegExp('buffer must be a Buffer instance')); - _t.end(); - }); - - t.end(); -}); - -test('decode', t => { - t.test('read from buffer with offset', _t => { - const buffer = Buffer.from([0x00, 0xfc]); - _t.same(varuint.decode(buffer, 1), 0xfc); - // @ts-ignore - _t.same(varuint.decode.bytes, 1); - _t.end(); - }); - - t.test('should be a buffer', _t => { - _t.throws(() => { - // @ts-ignore - varuint.decode([]); - }, new RegExp('buffer must be a Buffer instance')); - _t.end(); - }); - - t.end(); -}); diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..212658d --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + "target": "ESNext", + "outDir": "./src", + "declaration": true, + "rootDir": "./ts_src", + "types": ["node"], + "allowJs": false, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "moduleResolution": "Node", + "module": "ESNext", + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "skipLibCheck": true + }, + "include": ["ts_src/**/*.ts"], + "exclude": ["**/*.spec.ts", "node_modules/**/*"] +} diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 0000000..c93762f --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": false, + "outDir": "src/cjs", + "module": "commonjs" + }, + "exclude": ["ts_src/tests/**/*"] +} diff --git a/tsconfig.json b/tsconfig.json index 0da8441..0d9e728 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,31 +1,8 @@ { + "extends": "./tsconfig.base.json", "compilerOptions": { - "target": "ES2015", - "module": "commonjs", - "outDir": "./src", - "declaration": true, - "rootDir": "./ts_src", - "types": [ - "node" - ], - "allowJs": false, - "strict": true, - "noImplicitAny": true, - "strictNullChecks": true, - "strictFunctionTypes": true, - "strictBindCallApply": true, - "strictPropertyInitialization": true, - "noImplicitThis": true, - "alwaysStrict": true, - "esModuleInterop": false, - "noUnusedLocals": true, - "noUnusedParameters": true - }, - "include": [ - "ts_src/**/*.ts" - ], - "exclude": [ - "**/*.spec.ts", - "node_modules/**/*" - ] + "outDir": "src/esm", + "esModuleInterop": true, + "module": "ESNext" + } } diff --git a/tslint.json b/tslint.json index 6f10eef..80d3c6f 100644 --- a/tslint.json +++ b/tslint.json @@ -4,11 +4,7 @@ "rules": { "arrow-parens": [true, "ban-single-arg-parens"], "curly": false, - "indent": [ - true, - "spaces", - 2 - ], + "indent": [true, "spaces", 2], "interface-name": [false], "match-default-export-name": true, "max-classes-per-file": [false], @@ -19,6 +15,7 @@ "no-implicit-dependencies": [true, "dev"], "no-return-await": true, "no-var-requires": false, + "ordered-imports": false, "no-unnecessary-callback-wrapper": true, "no-unused-expression": false, "object-literal-sort-keys": false,