diff --git a/.gitignore b/.gitignore index c1733a6e0..664a5520f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ test/*.js test/integration/*.js !test/ts-node-register.js docs +plugin \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 70bc76251..b4e1324a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -48,7 +48,6 @@ "tiny-secp256k1": "^2.2.0", "ts-node": "^8.3.0", "typedoc": "^0.25.1", - "typedoc-plugin-bitcoinjs-runcase": "^1.0.2", "typescript": "^4.4.4" }, "engines": { @@ -2875,18 +2874,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3670,31 +3657,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, "node_modules/readable-stream": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", @@ -3891,15 +3853,6 @@ } ] }, - "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - } - }, "node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -4354,16 +4307,6 @@ "typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x" } }, - "node_modules/typedoc-plugin-bitcoinjs-runcase": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typedoc-plugin-bitcoinjs-runcase/-/typedoc-plugin-bitcoinjs-runcase-1.0.2.tgz", - "integrity": "sha512-Aa9E6aBXA1CKHIos2NJXWTbn38J6ZBV2saTeWyja489mlUBY6O1gyBIiziDl4R7rS/Vu/9AaRAnWGay42h8bBw==", - "dev": true, - "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, "node_modules/typedoc/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -6768,15 +6711,6 @@ "is-unicode-supported": "^0.1.0" } }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -7372,25 +7306,6 @@ "safe-buffer": "^5.1.0" } }, - "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - } - }, "readable-stream": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.1.tgz", @@ -7524,15 +7439,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, - "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -7892,16 +7798,6 @@ } } }, - "typedoc-plugin-bitcoinjs-runcase": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typedoc-plugin-bitcoinjs-runcase/-/typedoc-plugin-bitcoinjs-runcase-1.0.2.tgz", - "integrity": "sha512-Aa9E6aBXA1CKHIos2NJXWTbn38J6ZBV2saTeWyja489mlUBY6O1gyBIiziDl4R7rS/Vu/9AaRAnWGay42h8bBw==", - "dev": true, - "requires": { - "react": "^18.2.0", - "react-dom": "^18.2.0" - } - }, "typeforce": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", diff --git a/src/psbt.js b/src/psbt.js index 227e29304..cc0e5c8ad 100644 --- a/src/psbt.js +++ b/src/psbt.js @@ -243,7 +243,7 @@ class Psbt { if (typeof address === 'string') { const { network } = this.opts; const script = (0, address_1.toOutputScript)(address, network); - outputData = Object.assign(outputData, { script }); + outputData = Object.assign({}, outputData, { script }); } (0, bip371_1.checkTaprootOutputFields)(outputData, outputData, 'addOutput'); const c = this.__CACHE; diff --git a/src/script.js b/src/script.js index be2805190..c95f0cc67 100644 --- a/src/script.js +++ b/src/script.js @@ -158,6 +158,9 @@ function toASM(chunks) { if (chunksIsBuffer(chunks)) { chunks = decompile(chunks); } + if (!chunks) { + throw new Error('Could not convert invalid chunks to ASM'); + } return chunks .map(chunk => { // data? diff --git a/src/types.d.ts b/src/types.d.ts index b08a1fb6f..31e906a1a 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -13,15 +13,7 @@ export declare function stacksEqual(a: Buffer[], b: Buffer[]): boolean; * @returns True if the value is a valid elliptic curve point, false otherwise. */ export declare function isPoint(p: Buffer | number | undefined | null): boolean; -export declare function UInt31(value: number): boolean; -export declare function BIP32Path(value: string): boolean; -export declare namespace BIP32Path { - var toJSON: () => string; -} -export declare function Signer(obj: any): boolean; export declare function Satoshi(value: number): boolean; -export declare const ECPoint: any; -export declare const Network: any; export interface XOnlyPointAddTweakResult { parity: 1 | 0; xOnlyPubkey: Uint8Array; diff --git a/src/types.js b/src/types.js index 5bcd54c81..bcebef356 100644 --- a/src/types.js +++ b/src/types.js @@ -20,12 +20,7 @@ exports.oneOf = exports.isTaptree = exports.isTapleaf = exports.TAPLEAF_VERSION_MASK = - exports.Network = - exports.ECPoint = exports.Satoshi = - exports.Signer = - exports.BIP32Path = - exports.UInt31 = exports.isPoint = exports.stacksEqual = exports.typeforce = @@ -72,49 +67,11 @@ function isPoint(p) { return false; } exports.isPoint = isPoint; -const UINT31_MAX = Math.pow(2, 31) - 1; -function UInt31(value) { - return exports.typeforce.UInt32(value) && value <= UINT31_MAX; -} -exports.UInt31 = UInt31; -function BIP32Path(value) { - return ( - exports.typeforce.String(value) && !!value.match(/^(m\/)?(\d+'?\/)*\d+'?$/) - ); -} -exports.BIP32Path = BIP32Path; -BIP32Path.toJSON = () => { - return 'BIP32 derivation path'; -}; -function Signer(obj) { - return ( - (exports.typeforce.Buffer(obj.publicKey) || - typeof obj.getPublicKey === 'function') && - typeof obj.sign === 'function' - ); -} -exports.Signer = Signer; const SATOSHI_MAX = 21 * 1e14; function Satoshi(value) { return exports.typeforce.UInt53(value) && value <= SATOSHI_MAX; } exports.Satoshi = Satoshi; -// external dependent types -exports.ECPoint = exports.typeforce.quacksLike('Point'); -// exposed, external API -exports.Network = exports.typeforce.compile({ - messagePrefix: exports.typeforce.oneOf( - exports.typeforce.Buffer, - exports.typeforce.String, - ), - bip32: { - public: exports.typeforce.UInt32, - private: exports.typeforce.UInt32, - }, - pubKeyHash: exports.typeforce.UInt8, - scriptHash: exports.typeforce.UInt8, - wif: exports.typeforce.UInt8, -}); exports.TAPLEAF_VERSION_MASK = 0xfe; function isTapleaf(o) { if (!o || !('output' in o)) return false; diff --git a/test/types.spec.ts b/test/types.spec.ts index 478fd997e..363b83c19 100644 --- a/test/types.spec.ts +++ b/test/types.spec.ts @@ -54,41 +54,4 @@ describe('types', () => { }); }); }); - - describe('UInt31', () => { - const UINT31_MAX = Math.pow(2, 31) - 1; - it('return true for valid values', () => { - assert.strictEqual(types.UInt31(0), true); - assert.strictEqual(types.UInt31(1000), true); - assert.strictEqual(types.UInt31(UINT31_MAX), true); - }); - - it('return false for negative values', () => { - assert.strictEqual(types.UInt31(-1), false); - assert.strictEqual(types.UInt31(-UINT31_MAX), false); - }); - - it(`return false for value > ${UINT31_MAX}`, () => { - assert.strictEqual(types.UInt31(UINT31_MAX + 1), false); - }); - }); - - describe('BIP32Path', () => { - it('return true for valid paths', () => { - assert.strictEqual(types.BIP32Path("m/0'/0'"), true); - assert.strictEqual(types.BIP32Path("m/0'/0"), true); - assert.strictEqual(types.BIP32Path("m/0'/1'/2'/3/4'"), true); - }); - - it('return false for invalid paths', () => { - assert.strictEqual(types.BIP32Path('m'), false); - assert.strictEqual(types.BIP32Path("n/0'/0'"), false); - assert.strictEqual(types.BIP32Path("m/0'/x"), false); - }); - - it('return "BIP32 derivation path" for JSON.strigify()', () => { - const toJsonValue = JSON.stringify(types.BIP32Path); - assert.equal(toJsonValue, '"BIP32 derivation path"'); - }); - }); }); diff --git a/ts_src/psbt.ts b/ts_src/psbt.ts index a44646592..b2aa36f1f 100644 --- a/ts_src/psbt.ts +++ b/ts_src/psbt.ts @@ -331,7 +331,7 @@ export class Psbt { if (typeof address === 'string') { const { network } = this.opts; const script = toOutputScript(address, network); - outputData = Object.assign(outputData, { script }); + outputData = Object.assign({}, outputData, { script }); } checkTaprootOutputFields(outputData, outputData, 'addOutput'); diff --git a/ts_src/script.ts b/ts_src/script.ts index 54ee98fde..c2a033569 100644 --- a/ts_src/script.ts +++ b/ts_src/script.ts @@ -168,7 +168,9 @@ export function toASM(chunks: Buffer | Array): string { if (chunksIsBuffer(chunks)) { chunks = decompile(chunks) as Stack; } - + if (!chunks) { + throw new Error('Could not convert invalid chunks to ASM'); + } return chunks .map(chunk => { // data? diff --git a/ts_src/types.ts b/ts_src/types.ts index 971b42363..f4ce4875d 100644 --- a/ts_src/types.ts +++ b/ts_src/types.ts @@ -46,46 +46,11 @@ export function isPoint(p: Buffer | number | undefined | null): boolean { return false; } -const UINT31_MAX: number = Math.pow(2, 31) - 1; -export function UInt31(value: number): boolean { - return typeforce.UInt32(value) && value <= UINT31_MAX; -} - -export function BIP32Path(value: string): boolean { - return typeforce.String(value) && !!value.match(/^(m\/)?(\d+'?\/)*\d+'?$/); -} -BIP32Path.toJSON = (): string => { - return 'BIP32 derivation path'; -}; - -export function Signer(obj: any): boolean { - return ( - (typeforce.Buffer(obj.publicKey) || - typeof obj.getPublicKey === 'function') && - typeof obj.sign === 'function' - ); -} - const SATOSHI_MAX: number = 21 * 1e14; export function Satoshi(value: number): boolean { return typeforce.UInt53(value) && value <= SATOSHI_MAX; } -// external dependent types -export const ECPoint = typeforce.quacksLike('Point'); - -// exposed, external API -export const Network = typeforce.compile({ - messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String), - bip32: { - public: typeforce.UInt32, - private: typeforce.UInt32, - }, - pubKeyHash: typeforce.UInt8, - scriptHash: typeforce.UInt8, - wif: typeforce.UInt8, -}); - export interface XOnlyPointAddTweakResult { parity: 1 | 0; xOnlyPubkey: Uint8Array;