From f084439054543ee058f1e3c839daa121a20b6bb9 Mon Sep 17 00:00:00 2001 From: d-yokoi Date: Tue, 5 Mar 2019 23:51:45 +0900 Subject: [PATCH 01/22] ci: add tslint --- package-lock.json | 249 +++++++++++++++++++++++++++++++++------------- package.json | 8 +- tslint.json | 31 ++++++ 3 files changed, 214 insertions(+), 74 deletions(-) create mode 100644 tslint.json diff --git a/package-lock.json b/package-lock.json index 4af2f69..cbbf172 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,59 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.18.tgz", "integrity": "sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==" }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -130,6 +183,34 @@ "safe-buffer": "^5.1.2" } }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -139,6 +220,21 @@ "safe-buffer": "^5.0.1" } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", @@ -220,44 +316,16 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "eslint-plugin-typescript": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-typescript/-/eslint-plugin-typescript-0.14.0.tgz", - "integrity": "sha512-2u1WnnDF2mkWWgU1lFQ2RjypUlmRoBEvQN02y9u+IL12mjWlkKFGEBnVsjs9Y8190bfPQCvWly1c2rYYUSOxWw==", - "dev": true, - "requires": { - "requireindex": "~1.1.0" - } - }, - "eslint-scope": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.2.tgz", - "integrity": "sha512-5q1+B/ogmHl8+paxtOKx38Z8LtWkVGuNt3+GQNErqwLl6ViNp/gdJGMCjZNxZ8j/VYjDNZ2Fo+eQc1TAVPIzbg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "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 }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, "file-uri-to-path": { @@ -301,6 +369,15 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -368,12 +445,22 @@ "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", "dev": true }, - "lodash.unescape": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", - "integrity": "sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw=", + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, + "js-yaml": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -514,7 +601,6 @@ "version": "0.1.4", "bundled": true, "dev": true, - "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -1697,8 +1783,7 @@ "longest": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "loose-envify": { "version": "1.3.1", @@ -3174,12 +3259,6 @@ "safe-buffer": "^5.1.0" } }, - "requireindex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.1.0.tgz", - "integrity": "sha1-5UBLgVV+91225JxacgBIk/4D4WI=", - "dev": true - }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -3218,12 +3297,27 @@ "safe-buffer": "^5.0.1" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", @@ -3245,6 +3339,42 @@ "nan": "^2.10.0" } }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.13.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.13.1.tgz", + "integrity": "sha512-fplQqb2miLbcPhyHoMV4FU9PtNRbgmm/zI5d3SZwwmJQM6V0eodju+hplpyfhLWpmwrDNfNYU57uYRb8s0zZoQ==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.27.2" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, "typeforce": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.18.0.tgz", @@ -3256,27 +3386,6 @@ "integrity": "sha512-VCj5UiSyHBjwfYacmDuc/NOk4QQixbE+Wn7MFJuS0nRuPQbof132Pw4u53dm264O8LPc2MVsc7RJNml5szurkg==", "dev": true }, - "typescript-eslint-parser": { - "version": "21.0.2", - "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-21.0.2.tgz", - "integrity": "sha512-u+pj4RVJBr4eTzj0n5npoXD/oRthvfUCjSKndhNI714MG0mQq2DJw5WP7qmonRNIFgmZuvdDOH3BHm9iOjIAfg==", - "dev": true, - "requires": { - "eslint-scope": "^4.0.0", - "eslint-visitor-keys": "^1.0.0", - "typescript-estree": "5.3.0" - } - }, - "typescript-estree": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/typescript-estree/-/typescript-estree-5.3.0.tgz", - "integrity": "sha512-Vu0KmYdSCkpae+J48wsFC1ti19Hq3Wi/lODUaE+uesc3gzqhWbZ5itWbsjylLVbjNW4K41RqDzSfnaYNbmEiMQ==", - "dev": true, - "requires": { - "lodash.unescape": "4.0.1", - "semver": "5.5.0" - } - }, "unorm": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.5.0.tgz", diff --git a/package.json b/package.json index b98f412..898fac8 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "format": "npm run prettier -- --write", "format:ci": "npm run prettier -- --check", "integration": "npm run build && npm run nobuild:integration", + "lint": "tslint -p tsconfig.json -c tslint.json", "nobuild:coverage-report": "nyc report --reporter=lcov", "nobuild:coverage-html": "nyc report --reporter=html", "nobuild:coverage": "nyc --check-coverage --branches 90 --functions 90 --lines 90 mocha", @@ -29,7 +30,7 @@ "nobuild:unit": "mocha", "prepare": "npm run build", "prettier": "prettier 'ts_src/**/*.ts' --ignore-path ./.prettierignore", - "test": "npm run build && npm run format:ci && npm run nobuild:coverage", + "test": "npm run build && npm run format:ci && npm run lint && npm run nobuild:coverage", "unit": "npm run build && npm run nobuild:unit" }, "repository": { @@ -64,15 +65,14 @@ "bn.js": "^4.11.8", "bs58": "^4.0.0", "dhttp": "^3.0.0", - "eslint-plugin-typescript": "^0.14.0", "hoodwink": "^2.0.0", "minimaldata": "^1.0.2", "mocha": "^5.2.0", "nyc": "^11.8.0", "prettier": "^1.16.4", "proxyquire": "^2.0.1", - "typescript": "3.2.2", - "typescript-eslint-parser": "^21.0.2" + "tslint": "^5.13.1", + "typescript": "3.2.2" }, "license": "MIT" } diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..18bf61d --- /dev/null +++ b/tslint.json @@ -0,0 +1,31 @@ +{ + "defaultSeverity": "error", + "extends": ["tslint:recommended"], + "rules": { + "curly": false, + "indent": [ + true, + "spaces", + 2 + ], + "interface-name": [false], + "match-default-export-name": true, + "max-classes-per-file": [false], + "member-access": [true, "no-public"], + "no-empty": [true, "allow-empty-catch"], + "no-implicit-dependencies": true, + "no-return-await": true, + "no-var-requires": false, + "no-unused-expression": false, + "object-literal-sort-keys": false, + "quotemark": [true, "single"], + "variable-name": [ + true, + "ban-keywords", + "check-format", + "allow-leading-underscore", + "allow-pascal-case" + ] + }, + "rulesDirectory": [] +} From 99d0de8b3d9bff5c0ba57af9b98c299b2f602c4f Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 11:22:04 +0900 Subject: [PATCH 02/22] update package-lock --- package-lock.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index cbbf172..9de2ff5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -601,6 +601,7 @@ "version": "0.1.4", "bundled": true, "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2", "longest": "^1.0.1", @@ -1783,7 +1784,8 @@ "longest": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "loose-envify": { "version": "1.3.1", From d9cba6f176931833a8a3fd8cc26af3a160c820e7 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 11:32:06 +0900 Subject: [PATCH 03/22] Fixed address.ts lint --- src/address.js | 12 ++++++------ ts_src/address.ts | 36 ++++++++++++++++++------------------ types/address.d.ts | 8 ++++---- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/address.js b/src/address.js index f12cd8d..b0be0e1 100644 --- a/src/address.js +++ b/src/address.js @@ -1,9 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const types = require("./types"); -const bscript = require("./script"); const networks = require("./networks"); const payments = require("./payments"); +const bscript = require("./script"); +const types = require("./types"); const bech32 = require('bech32'); const bs58check = require('bs58check'); const typeforce = require('typeforce'); @@ -16,7 +16,7 @@ function fromBase58Check(address) { throw new TypeError(address + ' is too long'); const version = payload.readUInt8(0); const hash = payload.slice(1); - return { version: version, hash: hash }; + return { version, hash }; } exports.fromBase58Check = fromBase58Check; function fromBech32(address) { @@ -44,7 +44,7 @@ function toBech32(data, version, prefix) { } exports.toBech32 = toBech32; function fromOutputScript(output, network) { - //TODO: Network + // TODO: Network network = network || networks.bitcoin; try { return payments.p2pkh({ output, network }).address; @@ -67,8 +67,8 @@ function fromOutputScript(output, network) { exports.fromOutputScript = fromOutputScript; function toOutputScript(address, network) { network = network || networks.bitcoin; - let decodeBase58 = undefined; - let decodeBech32 = undefined; + let decodeBase58; + let decodeBech32; try { decodeBase58 = fromBase58Check(address); } diff --git a/ts_src/address.ts b/ts_src/address.ts index d547e78..0c0cda5 100644 --- a/ts_src/address.ts +++ b/ts_src/address.ts @@ -1,23 +1,23 @@ import { Network } from './networks'; -import * as types from './types'; -import * as bscript from './script'; import * as networks from './networks'; import * as payments from './payments'; +import * as bscript from './script'; +import * as types from './types'; const bech32 = require('bech32'); const bs58check = require('bs58check'); const typeforce = require('typeforce'); -export type Base58CheckResult = { +export interface Base58CheckResult { hash: Buffer; version: number; -}; +} -export type Bech32Result = { +export interface Bech32Result { version: number; prefix: string; data: Buffer; -}; +} export function fromBase58Check(address: string): Base58CheckResult { const payload = bs58check.decode(address); @@ -29,7 +29,7 @@ export function fromBase58Check(address: string): Base58CheckResult { const version = payload.readUInt8(0); const hash = payload.slice(1); - return { version: version, hash: hash }; + return { version, hash }; } export function fromBech32(address: string): Bech32Result { @@ -65,20 +65,20 @@ export function toBech32( } export function fromOutputScript(output: Buffer, network: Network): string { - //TODO: Network + // TODO: Network network = network || networks.bitcoin; try { - return payments.p2pkh({ output, network }).address; + return payments.p2pkh({ output, network }).address as string; } catch (e) {} try { - return payments.p2sh({ output, network }).address; + return payments.p2sh({ output, network }).address as string; } catch (e) {} try { - return payments.p2wpkh({ output, network }).address; + return payments.p2wpkh({ output, network }).address as string; } catch (e) {} try { - return payments.p2wsh({ output, network }).address; + return payments.p2wsh({ output, network }).address as string; } catch (e) {} throw new Error(bscript.toASM(output) + ' has no matching Address'); @@ -87,17 +87,17 @@ export function fromOutputScript(output: Buffer, network: Network): string { export function toOutputScript(address: string, network: Network): Buffer { network = network || networks.bitcoin; - let decodeBase58: Base58CheckResult | undefined = undefined; - let decodeBech32: Bech32Result | undefined = undefined; + let decodeBase58: Base58CheckResult | undefined; + let decodeBech32: Bech32Result | undefined; try { decodeBase58 = fromBase58Check(address); } catch (e) {} if (decodeBase58) { if (decodeBase58.version === network.pubKeyHash) - return payments.p2pkh({ hash: decodeBase58.hash }).output; + return payments.p2pkh({ hash: decodeBase58.hash }).output as Buffer; if (decodeBase58.version === network.scriptHash) - return payments.p2sh({ hash: decodeBase58.hash }).output; + return payments.p2sh({ hash: decodeBase58.hash }).output as Buffer; } else { try { decodeBech32 = fromBech32(address); @@ -108,9 +108,9 @@ export function toOutputScript(address: string, network: Network): Buffer { throw new Error(address + ' has an invalid prefix'); if (decodeBech32.version === 0) { if (decodeBech32.data.length === 20) - return payments.p2wpkh({ hash: decodeBech32.data }).output; + return payments.p2wpkh({ hash: decodeBech32.data }).output as Buffer; if (decodeBech32.data.length === 32) - return payments.p2wsh({ hash: decodeBech32.data }).output; + return payments.p2wsh({ hash: decodeBech32.data }).output as Buffer; } } } diff --git a/types/address.d.ts b/types/address.d.ts index 68fbedd..1da68ac 100644 --- a/types/address.d.ts +++ b/types/address.d.ts @@ -1,14 +1,14 @@ /// import { Network } from './networks'; -export declare type Base58CheckResult = { +export interface Base58CheckResult { hash: Buffer; version: number; -}; -export declare type Bech32Result = { +} +export interface Bech32Result { version: number; prefix: string; data: Buffer; -}; +} export declare function fromBase58Check(address: string): Base58CheckResult; export declare function fromBech32(address: string): Bech32Result; export declare function toBase58Check(hash: Buffer, version: number): string; From 51d078cbcedd378e02870c65b51b9bcb4aee5924 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 11:47:00 +0900 Subject: [PATCH 04/22] Fix block.ts lint --- src/block.js | 44 +++++++++++++-------------- ts_src/block.ts | 78 ++++++++++++++++++++++++------------------------ tslint.json | 3 ++ types/block.d.ts | 14 ++++----- 4 files changed, 71 insertions(+), 68 deletions(-) diff --git a/src/block.js b/src/block.js index eb3fb8b..9419989 100644 --- a/src/block.js +++ b/src/block.js @@ -1,9 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const bufferutils_1 = require("./bufferutils"); +const bcrypto = require("./crypto"); const transaction_1 = require("./transaction"); const types = require("./types"); -const bcrypto = require("./crypto"); -const bufferutils_1 = require("./bufferutils"); const fastMerkleRoot = require('merkle-lib/fastRoot'); const typeforce = require('typeforce'); const varuint = require('varuint-bitcoin'); @@ -28,16 +28,6 @@ function anyTxHasWitness(transactions) { input.witness.length > 0))); } class Block { - constructor() { - this.version = 1; - this.timestamp = 0; - this.bits = 0; - this.nonce = 0; - this.prevHash = undefined; - this.merkleRoot = undefined; - this.witnessCommit = undefined; - this.transactions = undefined; - } static fromBuffer(buffer) { if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)'); @@ -77,11 +67,11 @@ class Block { }; const nTransactions = readVarInt(); block.transactions = []; - for (var i = 0; i < nTransactions; ++i) { + for (let i = 0; i < nTransactions; ++i) { const tx = readTransaction(); block.transactions.push(tx); } - let witnessCommit = block.getWitnessCommit(); + const witnessCommit = block.getWitnessCommit(); // This Block contains a witness commit if (witnessCommit) block.witnessCommit = witnessCommit; @@ -109,6 +99,16 @@ class Block { ? bcrypto.hash256(Buffer.concat([rootHash, transactions[0].ins[0].witness[0]])) : rootHash; } + constructor() { + this.version = 1; + this.timestamp = 0; + this.bits = 0; + this.nonce = 0; + this.prevHash = undefined; + this.merkleRoot = undefined; + this.witnessCommit = undefined; + this.transactions = undefined; + } getWitnessCommit() { if (!txesHaveWitnessCommit(this.transactions)) return null; @@ -116,11 +116,11 @@ class Block { // There is no rule for the index of the output, so use filter to find it. // The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed // If multiple commits are found, the output with highest index is assumed. - let witnessCommits = this.transactions[0].outs.filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex'))).map(out => out.script.slice(6, 38)); + const witnessCommits = this.transactions[0].outs.filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex'))).map(out => out.script.slice(6, 38)); if (witnessCommits.length === 0) return null; // Use the commit with the highest output (should only be one though) - let result = witnessCommits[witnessCommits.length - 1]; + const result = witnessCommits[witnessCommits.length - 1]; if (!(result instanceof Buffer && result.length === 32)) return null; return result; @@ -193,7 +193,7 @@ class Block { checkTxRoots() { // If the Block has segwit transactions but no witness commit, // there's no way it can be valid, so fail the check. - let hasWitnessCommit = this.hasWitnessCommit(); + const hasWitnessCommit = this.hasWitnessCommit(); if (!hasWitnessCommit && this.hasWitness()) return false; return (this.__checkMerkleRoot() && @@ -204,6 +204,11 @@ class Block { 'deprecated in v5. Please use checkTxRoots instead.'); return this.checkTxRoots(); } + checkProofOfWork() { + const hash = bufferutils_1.reverseBuffer(this.getHash()); + const target = Block.calculateTarget(this.bits); + return hash.compare(target) <= 0; + } __checkMerkleRoot() { if (!this.transactions) throw errorMerkleNoTxes; @@ -218,10 +223,5 @@ class Block { const actualWitnessCommit = Block.calculateMerkleRoot(this.transactions, true); return this.witnessCommit.compare(actualWitnessCommit) === 0; } - checkProofOfWork() { - const hash = bufferutils_1.reverseBuffer(this.getHash()); - const target = Block.calculateTarget(this.bits); - return hash.compare(target) <= 0; - } } exports.Block = Block; diff --git a/ts_src/block.ts b/ts_src/block.ts index feb141e..888337d 100644 --- a/ts_src/block.ts +++ b/ts_src/block.ts @@ -1,7 +1,7 @@ +import { reverseBuffer } from './bufferutils'; +import * as bcrypto from './crypto'; import { Transaction } from './transaction'; import * as types from './types'; -import * as bcrypto from './crypto'; -import { reverseBuffer } from './bufferutils'; const fastMerkleRoot = require('merkle-lib/fastRoot'); const typeforce = require('typeforce'); @@ -14,7 +14,7 @@ const errorWitnessNotSegwit = new TypeError( 'Cannot compute witness commit for non-segwit block', ); -function txesHaveWitnessCommit(transactions: Array): boolean { +function txesHaveWitnessCommit(transactions: Transaction[]): boolean { return ( transactions instanceof Array && transactions[0] && @@ -27,7 +27,7 @@ function txesHaveWitnessCommit(transactions: Array): boolean { ); } -function anyTxHasWitness(transactions: Array): boolean { +function anyTxHasWitness(transactions: Transaction[]): boolean { return ( transactions instanceof Array && transactions.some( @@ -45,26 +45,6 @@ function anyTxHasWitness(transactions: Array): boolean { } export class Block { - version: number; - prevHash?: Buffer; - merkleRoot?: Buffer; - timestamp: number; - witnessCommit?: Buffer; - bits: number; - nonce: number; - transactions?: Array; - - constructor() { - this.version = 1; - this.timestamp = 0; - this.bits = 0; - this.nonce = 0; - this.prevHash = undefined; - this.merkleRoot = undefined; - this.witnessCommit = undefined; - this.transactions = undefined; - } - static fromBuffer(buffer: Buffer): Block { if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)'); @@ -111,12 +91,12 @@ export class Block { const nTransactions = readVarInt(); block.transactions = []; - for (var i = 0; i < nTransactions; ++i) { + for (let i = 0; i < nTransactions; ++i) { const tx = readTransaction(); block.transactions.push(tx); } - let witnessCommit = block.getWitnessCommit(); + const witnessCommit = block.getWitnessCommit(); // This Block contains a witness commit if (witnessCommit) block.witnessCommit = witnessCommit; @@ -136,7 +116,7 @@ export class Block { } static calculateMerkleRoot( - transactions: Array, + transactions: Transaction[], forWitness?: boolean, ): Buffer { typeforce([{ getHash: types.Function }], transactions); @@ -157,6 +137,26 @@ export class Block { : rootHash; } + version: number; + prevHash?: Buffer; + merkleRoot?: Buffer; + timestamp: number; + witnessCommit?: Buffer; + bits: number; + nonce: number; + transactions?: Transaction[]; + + constructor() { + this.version = 1; + this.timestamp = 0; + this.bits = 0; + this.nonce = 0; + this.prevHash = undefined; + this.merkleRoot = undefined; + this.witnessCommit = undefined; + this.transactions = undefined; + } + getWitnessCommit(): Buffer | null { if (!txesHaveWitnessCommit(this.transactions!)) return null; @@ -164,12 +164,12 @@ export class Block { // There is no rule for the index of the output, so use filter to find it. // The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed // If multiple commits are found, the output with highest index is assumed. - let witnessCommits = this.transactions![0].outs.filter(out => + const witnessCommits = this.transactions![0].outs.filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex')), ).map(out => out.script.slice(6, 38)); if (witnessCommits.length === 0) return null; // Use the commit with the highest output (should only be one though) - let result = witnessCommits[witnessCommits.length - 1]; + const result = witnessCommits[witnessCommits.length - 1]; if (!(result instanceof Buffer && result.length === 32)) return null; return result; @@ -261,7 +261,7 @@ export class Block { checkTxRoots(): boolean { // If the Block has segwit transactions but no witness commit, // there's no way it can be valid, so fail the check. - let hasWitnessCommit = this.hasWitnessCommit(); + const hasWitnessCommit = this.hasWitnessCommit(); if (!hasWitnessCommit && this.hasWitness()) return false; return ( this.__checkMerkleRoot() && @@ -277,14 +277,21 @@ export class Block { return this.checkTxRoots(); } - __checkMerkleRoot(): boolean { + checkProofOfWork(): boolean { + const hash: Buffer = reverseBuffer(this.getHash()); + const target = Block.calculateTarget(this.bits); + + return hash.compare(target) <= 0; + } + + private __checkMerkleRoot(): boolean { if (!this.transactions) throw errorMerkleNoTxes; const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions); return this.merkleRoot!.compare(actualMerkleRoot) === 0; } - __checkWitnessCommit(): boolean { + private __checkWitnessCommit(): boolean { if (!this.transactions) throw errorMerkleNoTxes; if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit; @@ -294,11 +301,4 @@ export class Block { ); return this.witnessCommit!.compare(actualWitnessCommit) === 0; } - - checkProofOfWork(): boolean { - const hash: Buffer = reverseBuffer(this.getHash()); - const target = Block.calculateTarget(this.bits); - - return hash.compare(target) <= 0; - } } diff --git a/tslint.json b/tslint.json index 18bf61d..9708e8b 100644 --- a/tslint.json +++ b/tslint.json @@ -2,6 +2,7 @@ "defaultSeverity": "error", "extends": ["tslint:recommended"], "rules": { + "arrow-parens": [true, "ban-single-arg-parens"], "curly": false, "indent": [ true, @@ -12,6 +13,8 @@ "match-default-export-name": true, "max-classes-per-file": [false], "member-access": [true, "no-public"], + "no-bitwise": false, + "no-console": false, "no-empty": [true, "allow-empty-catch"], "no-implicit-dependencies": true, "no-return-await": true, diff --git a/types/block.d.ts b/types/block.d.ts index 8b4f2f1..6f2d5b9 100644 --- a/types/block.d.ts +++ b/types/block.d.ts @@ -1,6 +1,10 @@ /// import { Transaction } from './transaction'; export declare class Block { + static fromBuffer(buffer: Buffer): Block; + static fromHex(hex: string): Block; + static calculateTarget(bits: number): Buffer; + static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Buffer; version: number; prevHash?: Buffer; merkleRoot?: Buffer; @@ -8,12 +12,8 @@ export declare class Block { witnessCommit?: Buffer; bits: number; nonce: number; - transactions?: Array; + transactions?: Transaction[]; constructor(); - static fromBuffer(buffer: Buffer): Block; - static fromHex(hex: string): Block; - static calculateTarget(bits: number): Buffer; - static calculateMerkleRoot(transactions: Array, forWitness?: boolean): Buffer; getWitnessCommit(): Buffer | null; hasWitnessCommit(): boolean; hasWitness(): boolean; @@ -25,7 +25,7 @@ export declare class Block { toHex(headersOnly: boolean): string; checkTxRoots(): boolean; checkMerkleRoot(): boolean; - __checkMerkleRoot(): boolean; - __checkWitnessCommit(): boolean; checkProofOfWork(): boolean; + private __checkMerkleRoot; + private __checkWitnessCommit; } From cb5ab7684e04d7add2ecc78d3749089a7f1b53b4 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 11:54:37 +0900 Subject: [PATCH 05/22] Fix classify.ts lint --- src/classify.js | 2 +- ts_src/classify.ts | 27 ++++++++++++--------------- types/classify.d.ts | 2 +- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/classify.js b/src/classify.js index 0aec5c4..7d8e57d 100644 --- a/src/classify.js +++ b/src/classify.js @@ -6,9 +6,9 @@ const nullData = require("./templates/nulldata"); const pubKey = require("./templates/pubkey"); const pubKeyHash = require("./templates/pubkeyhash"); const scriptHash = require("./templates/scripthash"); +const witnessCommitment = require("./templates/witnesscommitment"); const witnessPubKeyHash = require("./templates/witnesspubkeyhash"); const witnessScriptHash = require("./templates/witnessscripthash"); -const witnessCommitment = require("./templates/witnesscommitment"); const types = { P2MS: 'multisig', NONSTANDARD: 'nonstandard', diff --git a/ts_src/classify.ts b/ts_src/classify.ts index 0de93f9..a7ec68c 100644 --- a/ts_src/classify.ts +++ b/ts_src/classify.ts @@ -4,20 +4,20 @@ import * as nullData from './templates/nulldata'; import * as pubKey from './templates/pubkey'; import * as pubKeyHash from './templates/pubkeyhash'; import * as scriptHash from './templates/scripthash'; +import * as witnessCommitment from './templates/witnesscommitment'; import * as witnessPubKeyHash from './templates/witnesspubkeyhash'; import * as witnessScriptHash from './templates/witnessscripthash'; -import * as witnessCommitment from './templates/witnesscommitment'; const types = { - P2MS: 'multisig', - NONSTANDARD: 'nonstandard', - NULLDATA: 'nulldata', - P2PK: 'pubkey', - P2PKH: 'pubkeyhash', - P2SH: 'scripthash', - P2WPKH: 'witnesspubkeyhash', - P2WSH: 'witnessscripthash', - WITNESS_COMMITMENT: 'witnesscommitment', + P2MS: 'multisig' as string, + NONSTANDARD: 'nonstandard' as string, + NULLDATA: 'nulldata' as string, + P2PK: 'pubkey' as string, + P2PKH: 'pubkeyhash' as string, + P2SH: 'scripthash' as string, + P2WPKH: 'witnesspubkeyhash' as string, + P2WSH: 'witnessscripthash' as string, + WITNESS_COMMITMENT: 'witnesscommitment' as string, }; function classifyOutput(script: Buffer): string { @@ -51,16 +51,13 @@ function classifyInput(script: Buffer, allowIncomplete: boolean): string { return types.NONSTANDARD; } -function classifyWitness( - script: Array, - allowIncomplete: boolean, -): string { +function classifyWitness(script: Buffer[], allowIncomplete: boolean): string { // XXX: optimization, below functions .decompile before use const chunks = decompile(script); if (!chunks) throw new TypeError('Invalid script'); if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH; - if (witnessScriptHash.input.check(>chunks, allowIncomplete)) + if (witnessScriptHash.input.check(chunks as Buffer[], allowIncomplete)) return types.P2WSH; return types.NONSTANDARD; diff --git a/types/classify.d.ts b/types/classify.d.ts index b394c71..67f913b 100644 --- a/types/classify.d.ts +++ b/types/classify.d.ts @@ -12,5 +12,5 @@ declare const types: { }; declare function classifyOutput(script: Buffer): string; declare function classifyInput(script: Buffer, allowIncomplete: boolean): string; -declare function classifyWitness(script: Array, allowIncomplete: boolean): string; +declare function classifyWitness(script: Buffer[], allowIncomplete: boolean): string; export { classifyInput as input, classifyOutput as output, classifyWitness as witness, types, }; From 6a734aef4c0dfc2503ee67ef878f3296291e0397 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:06:12 +0900 Subject: [PATCH 06/22] Fix lint for ecpair.ts --- src/ecpair.js | 22 +++++++++++----------- test/ecpair.js | 2 +- ts_src/ecpair.ts | 36 ++++++++++++++++++------------------ types/ecpair.d.ts | 4 ++-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/ecpair.js b/src/ecpair.js index 7d376ac..1335014 100644 --- a/src/ecpair.js +++ b/src/ecpair.js @@ -17,30 +17,30 @@ class ECPair { this.compressed = options.compressed === undefined ? true : options.compressed; this.network = options.network || NETWORKS.bitcoin; - this.__d = undefined; + this.__D = undefined; this.__Q = undefined; if (d !== undefined) - this.__d = d; + this.__D = d; if (Q !== undefined) this.__Q = ecc.pointCompress(Q, this.compressed); } get privateKey() { - return this.__d; + return this.__D; } get publicKey() { if (!this.__Q) - this.__Q = ecc.pointFromScalar(this.__d, this.compressed); + this.__Q = ecc.pointFromScalar(this.__D, this.compressed); return this.__Q; } toWIF() { - if (!this.__d) + if (!this.__D) throw new Error('Missing private key'); - return wif.encode(this.network.wif, this.__d, this.compressed); + return wif.encode(this.network.wif, this.__D, this.compressed); } sign(hash) { - if (!this.__d) + if (!this.__D) throw new Error('Missing private key'); - return ecc.sign(hash, this.__d); + return ecc.sign(hash, this.__D); } verify(hash, signature) { return ecc.verify(hash, this.publicKey, signature); @@ -60,13 +60,13 @@ function fromPublicKey(buffer, options) { return new ECPair(undefined, buffer, options); } exports.fromPublicKey = fromPublicKey; -function fromWIF(string, network) { - const decoded = wif.decode(string); +function fromWIF(wifString, network) { + const decoded = wif.decode(wifString); const version = decoded.version; // list of networks? if (types.Array(network)) { network = network - .filter(function (x) { + .filter((x) => { return version === x.wif; }) .pop(); diff --git a/test/ecpair.js b/test/ecpair.js index 0ff0e8b..de5c485 100644 --- a/test/ecpair.js +++ b/test/ecpair.js @@ -238,7 +238,7 @@ describe('ECPair', function () { })) it('throws if no private key is found', function () { - delete keyPair.__d + delete keyPair.__D assert.throws(function () { keyPair.sign(hash) diff --git a/ts_src/ecpair.ts b/ts_src/ecpair.ts index 15ec00a..ec8dc13 100644 --- a/ts_src/ecpair.ts +++ b/ts_src/ecpair.ts @@ -33,7 +33,7 @@ export interface ECPairInterface { class ECPair implements ECPairInterface { compressed: boolean; network: Network; - private __d?: Buffer; + private __D?: Buffer; private __Q?: Buffer; constructor(d?: Buffer, Q?: Buffer, options?: ECPairOptions) { @@ -42,29 +42,29 @@ class ECPair implements ECPairInterface { options.compressed === undefined ? true : options.compressed; this.network = options.network || NETWORKS.bitcoin; - this.__d = undefined; + this.__D = undefined; this.__Q = undefined; - if (d !== undefined) this.__d = d; + if (d !== undefined) this.__D = d; if (Q !== undefined) this.__Q = ecc.pointCompress(Q, this.compressed); } get privateKey(): Buffer | undefined { - return this.__d; + return this.__D; } get publicKey(): Buffer | undefined { - if (!this.__Q) this.__Q = ecc.pointFromScalar(this.__d, this.compressed); + if (!this.__Q) this.__Q = ecc.pointFromScalar(this.__D, this.compressed); return this.__Q; } toWIF(): string { - if (!this.__d) throw new Error('Missing private key'); - return wif.encode(this.network.wif, this.__d, this.compressed); + if (!this.__D) throw new Error('Missing private key'); + return wif.encode(this.network.wif, this.__D, this.compressed); } sign(hash: Buffer): Buffer { - if (!this.__d) throw new Error('Missing private key'); - return ecc.sign(hash, this.__d); + if (!this.__D) throw new Error('Missing private key'); + return ecc.sign(hash, this.__D); } verify(hash: Buffer, signature: Buffer): Buffer { @@ -78,26 +78,26 @@ function fromPrivateKey(buffer: Buffer, options?: ECPairOptions): ECPair { throw new TypeError('Private key not in range [1, n)'); typeforce(isOptions, options); - return new ECPair(buffer, undefined, options); + return new ECPair(buffer, undefined, options as ECPairOptions); } function fromPublicKey(buffer: Buffer, options?: ECPairOptions): ECPair { typeforce(ecc.isPoint, buffer); typeforce(isOptions, options); - return new ECPair(undefined, buffer, options); + return new ECPair(undefined, buffer, options as ECPairOptions); } -function fromWIF(string: string, network?: Network | Array): ECPair { - const decoded = wif.decode(string); +function fromWIF(wifString: string, network?: Network | Network[]): ECPair { + const decoded = wif.decode(wifString); const version = decoded.version; // list of networks? if (types.Array(network)) { - network = (>network) - .filter(function(x: Network) { + network = (network as Network[]) + .filter((x: Network) => { return version === x.wif; }) - .pop(); + .pop() as Network; if (!network) throw new Error('Unknown network version'); @@ -105,13 +105,13 @@ function fromWIF(string: string, network?: Network | Array): ECPair { } else { network = network || NETWORKS.bitcoin; - if (version !== (network).wif) + if (version !== (network as Network).wif) throw new Error('Invalid network version'); } return fromPrivateKey(decoded.privateKey, { compressed: decoded.compressed, - network: network, + network: network as Network, }); } diff --git a/types/ecpair.d.ts b/types/ecpair.d.ts index 58ea4be..674615b 100644 --- a/types/ecpair.d.ts +++ b/types/ecpair.d.ts @@ -18,7 +18,7 @@ export interface ECPairInterface { declare class ECPair implements ECPairInterface { compressed: boolean; network: Network; - private __d?; + private __D?; private __Q?; constructor(d?: Buffer, Q?: Buffer, options?: ECPairOptions); readonly privateKey: Buffer | undefined; @@ -29,6 +29,6 @@ declare class ECPair implements ECPairInterface { } declare function fromPrivateKey(buffer: Buffer, options?: ECPairOptions): ECPair; declare function fromPublicKey(buffer: Buffer, options?: ECPairOptions): ECPair; -declare function fromWIF(string: string, network?: Network | Array): ECPair; +declare function fromWIF(wifString: string, network?: Network | Network[]): ECPair; declare function makeRandom(options?: ECPairOptions): ECPair; export { makeRandom, fromPrivateKey, fromPublicKey, fromWIF }; From 3f34fe457abe6d19688416e566b6b340cfa959c8 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:11:15 +0900 Subject: [PATCH 07/22] Fix index.ts networks.ts lint --- src/index.js | 8 ++++---- ts_src/index.ts | 10 +++++----- ts_src/networks.ts | 10 +++++----- types/index.d.ts | 10 +++++----- types/networks.d.ts | 10 +++++----- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/index.js b/src/index.js index 7455d4a..73ac6f4 100644 --- a/src/index.js +++ b/src/index.js @@ -2,12 +2,12 @@ Object.defineProperty(exports, "__esModule", { value: true }); const bip32 = require("bip32"); exports.bip32 = bip32; -const ECPair = require("./ecpair"); -exports.ECPair = ECPair; const address = require("./address"); exports.address = address; const crypto = require("./crypto"); exports.crypto = crypto; +const ECPair = require("./ecpair"); +exports.ECPair = ECPair; const networks = require("./networks"); exports.networks = networks; const payments = require("./payments"); @@ -16,9 +16,9 @@ const script = require("./script"); exports.script = script; var block_1 = require("./block"); exports.Block = block_1.Block; +var script_1 = require("./script"); +exports.opcodes = script_1.OPS; var transaction_1 = require("./transaction"); exports.Transaction = transaction_1.Transaction; var transaction_builder_1 = require("./transaction_builder"); exports.TransactionBuilder = transaction_builder_1.TransactionBuilder; -var script_1 = require("./script"); -exports.opcodes = script_1.OPS; diff --git a/ts_src/index.ts b/ts_src/index.ts index fce7304..4e76c96 100644 --- a/ts_src/index.ts +++ b/ts_src/index.ts @@ -1,7 +1,7 @@ import * as bip32 from 'bip32'; -import * as ECPair from './ecpair'; import * as address from './address'; import * as crypto from './crypto'; +import * as ECPair from './ecpair'; import * as networks from './networks'; import * as payments from './payments'; import * as script from './script'; @@ -9,12 +9,12 @@ import * as script from './script'; export { ECPair, address, bip32, crypto, networks, payments, script }; export { Block } from './block'; +export { OPS as opcodes } from './script'; export { Transaction } from './transaction'; export { TransactionBuilder } from './transaction_builder'; -export { OPS as opcodes } from './script'; -export { Payment, PaymentOpts } from './payments'; -export { Input as TxInput, Output as TxOutput } from './transaction'; +export { BIP32Interface } from 'bip32'; export { Network } from './networks'; +export { Payment, PaymentOpts } from './payments'; export { OpCode } from './script'; -export { BIP32Interface } from 'bip32'; +export { Input as TxInput, Output as TxOutput } from './transaction'; diff --git a/ts_src/networks.ts b/ts_src/networks.ts index 0212a44..e66b08c 100644 --- a/ts_src/networks.ts +++ b/ts_src/networks.ts @@ -1,18 +1,18 @@ // https://en.bitcoin.it/wiki/List_of_address_prefixes // Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731 -export type Network = { +export interface Network { messagePrefix: string; bech32: string; - bip32: bip32; + bip32: Bip32; pubKeyHash: number; scriptHash: number; wif: number; -}; +} -type bip32 = { +interface Bip32 { public: number; private: number; -}; +} export const bitcoin: Network = { messagePrefix: '\x18Bitcoin Signed Message:\n', diff --git a/types/index.d.ts b/types/index.d.ts index 3512872..d21454a 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -1,17 +1,17 @@ import * as bip32 from 'bip32'; -import * as ECPair from './ecpair'; import * as address from './address'; import * as crypto from './crypto'; +import * as ECPair from './ecpair'; import * as networks from './networks'; import * as payments from './payments'; import * as script from './script'; export { ECPair, address, bip32, crypto, networks, payments, script }; export { Block } from './block'; +export { OPS as opcodes } from './script'; export { Transaction } from './transaction'; export { TransactionBuilder } from './transaction_builder'; -export { OPS as opcodes } from './script'; -export { Payment, PaymentOpts } from './payments'; -export { Input as TxInput, Output as TxOutput } from './transaction'; +export { BIP32Interface } from 'bip32'; export { Network } from './networks'; +export { Payment, PaymentOpts } from './payments'; export { OpCode } from './script'; -export { BIP32Interface } from 'bip32'; +export { Input as TxInput, Output as TxOutput } from './transaction'; diff --git a/types/networks.d.ts b/types/networks.d.ts index e402873..d5590fd 100644 --- a/types/networks.d.ts +++ b/types/networks.d.ts @@ -1,15 +1,15 @@ -export declare type Network = { +export interface Network { messagePrefix: string; bech32: string; - bip32: bip32; + bip32: Bip32; pubKeyHash: number; scriptHash: number; wif: number; -}; -declare type bip32 = { +} +interface Bip32 { public: number; private: number; -}; +} export declare const bitcoin: Network; export declare const regtest: Network; export declare const testnet: Network; From 389ec8cb33710d534d813a90cf7129b2f4e0dad4 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:29:24 +0900 Subject: [PATCH 08/22] Fix embed.ts and index.ts for payments lint --- src/payments/embed.js | 8 ++++---- ts_src/payments/embed.ts | 21 ++++++++++----------- ts_src/payments/index.ts | 11 +++++++---- types/payments/index.d.ts | 10 ++++++---- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/payments/embed.js b/src/payments/embed.js index 0e2a0ae..800c8de 100644 --- a/src/payments/embed.js +++ b/src/payments/embed.js @@ -1,14 +1,14 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const networks_1 = require("../networks"); const bscript = require("../script"); const lazy = require("./lazy"); -const networks_1 = require("../networks"); const typef = require('typeforce'); const OPS = bscript.OPS; function stacksEqual(a, b) { if (a.length !== b.length) return false; - return a.every(function (x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -24,12 +24,12 @@ function p2data(a, opts) { }, a); const network = a.network || networks_1.bitcoin; const o = { network }; - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!a.data) return; return bscript.compile([OPS.OP_RETURN].concat(a.data)); }); - lazy.prop(o, 'data', function () { + lazy.prop(o, 'data', () => { if (!a.output) return; return bscript.decompile(a.output).slice(1); diff --git a/ts_src/payments/embed.ts b/ts_src/payments/embed.ts index d7a2b0f..38a8162 100644 --- a/ts_src/payments/embed.ts +++ b/ts_src/payments/embed.ts @@ -1,14 +1,15 @@ -import { Payment, PaymentOpts } from './index'; +import { bitcoin as BITCOIN_NETWORK } from '../networks'; import * as bscript from '../script'; +import { Payment, PaymentOpts, Stack } from './index'; import * as lazy from './lazy'; -import { bitcoin as BITCOIN_NETWORK } from '../networks'; + const typef = require('typeforce'); const OPS = bscript.OPS; -function stacksEqual(a: Array, b: Array): boolean { +function stacksEqual(a: Buffer[], b: Buffer[]): boolean { if (a.length !== b.length) return false; - return a.every(function(x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -28,15 +29,13 @@ export function p2data(a: Payment, opts?: PaymentOpts): Payment { ); const network = a.network || BITCOIN_NETWORK; - const o = { network }; + const o = { network } as Payment; - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!a.data) return; - return bscript.compile( - (>[OPS.OP_RETURN]).concat(a.data), - ); + return bscript.compile(([OPS.OP_RETURN] as Stack).concat(a.data)); }); - lazy.prop(o, 'data', function() { + lazy.prop(o, 'data', () => { if (!a.output) return; return bscript.decompile(a.output)!.slice(1); }); @@ -50,7 +49,7 @@ export function p2data(a: Payment, opts?: PaymentOpts): Payment { if (!chunks!.slice(1).every(typef.Buffer)) throw new TypeError('Output is invalid'); - if (a.data && !stacksEqual(a.data, >o.data)) + if (a.data && !stacksEqual(a.data, o.data as Buffer[])) throw new TypeError('Data mismatch'); } } diff --git a/ts_src/payments/index.ts b/ts_src/payments/index.ts index 6727eeb..4f6eb75 100644 --- a/ts_src/payments/index.ts +++ b/ts_src/payments/index.ts @@ -10,18 +10,18 @@ import { p2wsh } from './p2wsh'; export interface Payment { network?: Network; output?: Buffer; - data?: Array; + data?: Buffer[]; m?: number; n?: number; - pubkeys?: Array; + pubkeys?: Buffer[]; input?: Buffer; - signatures?: Array; + signatures?: Buffer[]; pubkey?: Buffer; signature?: Buffer; address?: string; hash?: Buffer; redeem?: Payment; - witness?: Array; + witness?: Buffer[]; } export interface PaymentOpts { @@ -29,6 +29,9 @@ export interface PaymentOpts { allowIncomplete?: boolean; } +export type StackElement = Buffer | number; +export type Stack = StackElement[]; + export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh }; // TODO diff --git a/types/payments/index.d.ts b/types/payments/index.d.ts index 5afc847..3009bef 100644 --- a/types/payments/index.d.ts +++ b/types/payments/index.d.ts @@ -10,21 +10,23 @@ import { p2wsh } from './p2wsh'; export interface Payment { network?: Network; output?: Buffer; - data?: Array; + data?: Buffer[]; m?: number; n?: number; - pubkeys?: Array; + pubkeys?: Buffer[]; input?: Buffer; - signatures?: Array; + signatures?: Buffer[]; pubkey?: Buffer; signature?: Buffer; address?: string; hash?: Buffer; redeem?: Payment; - witness?: Array; + witness?: Buffer[]; } export interface PaymentOpts { validate?: boolean; allowIncomplete?: boolean; } +export declare type StackElement = Buffer | number; +export declare type Stack = StackElement[]; export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh }; From db937f8110ad9e9f42a5b53922cb2e2d994719a0 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:33:47 +0900 Subject: [PATCH 09/22] Fix lazy.ts in payments lint --- src/payments/lazy.js | 24 ++++++++++++------------ ts_src/payments/lazy.ts | 24 ++++++++++++------------ types/payments/lazy.d.ts | 2 +- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/payments/lazy.js b/src/payments/lazy.js index 9eda8e8..d8494fd 100644 --- a/src/payments/lazy.js +++ b/src/payments/lazy.js @@ -4,16 +4,16 @@ function prop(object, name, f) { Object.defineProperty(object, name, { configurable: true, enumerable: true, - get: function () { - let value = f.call(this); - this[name] = value; - return value; + get() { + const _value = f.call(this); + this[name] = _value; + return _value; }, - set: function (value) { + set(_value) { Object.defineProperty(this, name, { configurable: true, enumerable: true, - value: value, + value: _value, writable: true, }); }, @@ -21,12 +21,12 @@ function prop(object, name, f) { } exports.prop = prop; function value(f) { - let value; - return function () { - if (value !== undefined) - return value; - value = f(); - return value; + let _value; + return () => { + if (_value !== undefined) + return _value; + _value = f(); + return _value; }; } exports.value = value; diff --git a/ts_src/payments/lazy.ts b/ts_src/payments/lazy.ts index 474c8e9..fe0fb6d 100644 --- a/ts_src/payments/lazy.ts +++ b/ts_src/payments/lazy.ts @@ -1,17 +1,17 @@ -export function prop(object: Object, name: string, f: () => any): void { +export function prop(object: {}, name: string, f: () => any): void { Object.defineProperty(object, name, { configurable: true, enumerable: true, - get: function() { - let value = f.call(this); - this[name] = value; - return value; + get() { + const _value = f.call(this); + this[name] = _value; + return _value; }, - set: function(value) { + set(_value) { Object.defineProperty(this, name, { configurable: true, enumerable: true, - value: value, + value: _value, writable: true, }); }, @@ -19,10 +19,10 @@ export function prop(object: Object, name: string, f: () => any): void { } export function value(f: () => T): () => T { - let value: T; - return function(): T { - if (value !== undefined) return value; - value = f(); - return value; + let _value: T; + return (): T => { + if (_value !== undefined) return _value; + _value = f(); + return _value; }; } diff --git a/types/payments/lazy.d.ts b/types/payments/lazy.d.ts index 705f530..3463906 100644 --- a/types/payments/lazy.d.ts +++ b/types/payments/lazy.d.ts @@ -1,2 +1,2 @@ -export declare function prop(object: Object, name: string, f: () => any): void; +export declare function prop(object: {}, name: string, f: () => any): void; export declare function value(f: () => T): () => T; From 4054f3ae879a8840933e622410224d7e5b0a868c Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:40:18 +0900 Subject: [PATCH 10/22] Fix lint for p2ms payment --- src/payments/p2ms.js | 18 ++++++++--------- ts_src/payments/p2ms.ts | 44 ++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/payments/p2ms.js b/src/payments/p2ms.js index 1e51faa..5e48432 100644 --- a/src/payments/p2ms.js +++ b/src/payments/p2ms.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const networks_1 = require("../networks"); const bscript = require("../script"); const lazy = require("./lazy"); -const networks_1 = require("../networks"); const OPS = bscript.OPS; const typef = require('typeforce'); const ecc = require('tiny-secp256k1'); @@ -10,7 +10,7 @@ const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1 function stacksEqual(a, b) { if (a.length !== b.length) return false; - return a.every(function (x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -49,7 +49,7 @@ function p2ms(a, opts) { o.n = chunks[chunks.length - 2] - OP_INT_BASE; o.pubkeys = chunks.slice(1, -2); } - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!a.m) return; if (!o.n) @@ -58,34 +58,34 @@ function p2ms(a, opts) { return; return bscript.compile([].concat(OP_INT_BASE + a.m, a.pubkeys, OP_INT_BASE + o.n, OPS.OP_CHECKMULTISIG)); }); - lazy.prop(o, 'm', function () { + lazy.prop(o, 'm', () => { if (!o.output) return; decode(o.output); return o.m; }); - lazy.prop(o, 'n', function () { + lazy.prop(o, 'n', () => { if (!o.pubkeys) return; return o.pubkeys.length; }); - lazy.prop(o, 'pubkeys', function () { + lazy.prop(o, 'pubkeys', () => { if (!a.output) return; decode(a.output); return o.pubkeys; }); - lazy.prop(o, 'signatures', function () { + lazy.prop(o, 'signatures', () => { if (!a.input) return; return bscript.decompile(a.input).slice(1); }); - lazy.prop(o, 'input', function () { + lazy.prop(o, 'input', () => { if (!a.signatures) return; return bscript.compile([OPS.OP_0].concat(a.signatures)); }); - lazy.prop(o, 'witness', function () { + lazy.prop(o, 'witness', () => { if (!o.input) return; return []; diff --git a/ts_src/payments/p2ms.ts b/ts_src/payments/p2ms.ts index 766f341..b8691c0 100644 --- a/ts_src/payments/p2ms.ts +++ b/ts_src/payments/p2ms.ts @@ -1,17 +1,17 @@ -import { Payment, PaymentOpts } from './index'; +import { bitcoin as BITCOIN_NETWORK } from '../networks'; import * as bscript from '../script'; +import { Payment, PaymentOpts, Stack } from './index'; import * as lazy from './lazy'; -import { bitcoin as BITCOIN_NETWORK } from '../networks'; const OPS = bscript.OPS; const typef = require('typeforce'); const ecc = require('tiny-secp256k1'); const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1 -function stacksEqual(a: Array, b: Array): boolean { +function stacksEqual(a: Buffer[], b: Buffer[]): boolean { if (a.length !== b.length) return false; - return a.every(function(x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -30,8 +30,8 @@ export function p2ms(a: Payment, opts?: PaymentOpts): Payment { function isAcceptableSignature(x: Buffer | number) { return ( - bscript.isCanonicalScriptSignature(x) || - (opts!.allowIncomplete && x === OPS.OP_0) !== undefined + bscript.isCanonicalScriptSignature(x as Buffer) || + (opts!.allowIncomplete && (x as number) === OPS.OP_0) !== undefined ); } @@ -52,23 +52,23 @@ export function p2ms(a: Payment, opts?: PaymentOpts): Payment { const network = a.network || BITCOIN_NETWORK; const o: Payment = { network }; - let chunks: Array = []; + let chunks: Stack = []; let decoded = false; - function decode(output: Buffer | Array): void { + function decode(output: Buffer | Stack): void { if (decoded) return; decoded = true; - chunks = >bscript.decompile(output); - o.m = chunks[0] - OP_INT_BASE; - o.n = chunks[chunks.length - 2] - OP_INT_BASE; - o.pubkeys = >chunks.slice(1, -2); + chunks = bscript.decompile(output) as Stack; + o.m = (chunks[0] as number) - OP_INT_BASE; + o.n = (chunks[chunks.length - 2] as number) - OP_INT_BASE; + o.pubkeys = chunks.slice(1, -2) as Buffer[]; } - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!a.m) return; if (!o.n) return; if (!a.pubkeys) return; return bscript.compile( - (>[]).concat( + ([] as Stack).concat( OP_INT_BASE + a.m, a.pubkeys, OP_INT_BASE + o.n, @@ -76,31 +76,29 @@ export function p2ms(a: Payment, opts?: PaymentOpts): Payment { ), ); }); - lazy.prop(o, 'm', function() { + lazy.prop(o, 'm', () => { if (!o.output) return; decode(o.output); return o.m; }); - lazy.prop(o, 'n', function() { + lazy.prop(o, 'n', () => { if (!o.pubkeys) return; return o.pubkeys.length; }); - lazy.prop(o, 'pubkeys', function() { + lazy.prop(o, 'pubkeys', () => { if (!a.output) return; decode(a.output); return o.pubkeys; }); - lazy.prop(o, 'signatures', function() { + lazy.prop(o, 'signatures', () => { if (!a.input) return; return bscript.decompile(a.input)!.slice(1); }); - lazy.prop(o, 'input', function() { + lazy.prop(o, 'input', () => { if (!a.signatures) return; - return bscript.compile( - (>[OPS.OP_0]).concat(a.signatures), - ); + return bscript.compile(([OPS.OP_0] as Stack).concat(a.signatures)); }); - lazy.prop(o, 'witness', function() { + lazy.prop(o, 'witness', () => { if (!o.input) return; return []; }); From 8d5d78431c8e8b6a5ffbfb167d66cedb63febfd6 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:47:26 +0900 Subject: [PATCH 11/22] Fix P2PK payment lint --- src/payments/p2pk.js | 14 +++++++------- ts_src/payments/index.ts | 1 + ts_src/payments/p2pk.ts | 20 ++++++++++---------- types/payments/index.d.ts | 1 + 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/payments/p2pk.js b/src/payments/p2pk.js index 9c9318f..81fe427 100644 --- a/src/payments/p2pk.js +++ b/src/payments/p2pk.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const networks_1 = require("../networks"); const bscript = require("../script"); const lazy = require("./lazy"); -const networks_1 = require("../networks"); const typef = require('typeforce'); const OPS = bscript.OPS; const ecc = require('tiny-secp256k1'); @@ -19,32 +19,32 @@ function p2pk(a, opts) { signature: typef.maybe(bscript.isCanonicalScriptSignature), input: typef.maybe(typef.Buffer), }, a); - const _chunks = lazy.value(function () { + const _chunks = lazy.value(() => { return bscript.decompile(a.input); }); const network = a.network || networks_1.bitcoin; const o = { network }; - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!a.pubkey) return; return bscript.compile([a.pubkey, OPS.OP_CHECKSIG]); }); - lazy.prop(o, 'pubkey', function () { + lazy.prop(o, 'pubkey', () => { if (!a.output) return; return a.output.slice(1, -1); }); - lazy.prop(o, 'signature', function () { + lazy.prop(o, 'signature', () => { if (!a.input) return; return _chunks()[0]; }); - lazy.prop(o, 'input', function () { + lazy.prop(o, 'input', () => { if (!a.signature) return; return bscript.compile([a.signature]); }); - lazy.prop(o, 'witness', function () { + lazy.prop(o, 'witness', () => { if (!o.input) return; return []; diff --git a/ts_src/payments/index.ts b/ts_src/payments/index.ts index 4f6eb75..0c70fba 100644 --- a/ts_src/payments/index.ts +++ b/ts_src/payments/index.ts @@ -31,6 +31,7 @@ export interface PaymentOpts { export type StackElement = Buffer | number; export type Stack = StackElement[]; +export type StackFunction = () => Stack; export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh }; diff --git a/ts_src/payments/p2pk.ts b/ts_src/payments/p2pk.ts index 69fb404..d14aacf 100644 --- a/ts_src/payments/p2pk.ts +++ b/ts_src/payments/p2pk.ts @@ -1,7 +1,7 @@ -import { Payment, PaymentOpts } from './index'; +import { bitcoin as BITCOIN_NETWORK } from '../networks'; import * as bscript from '../script'; +import { Payment, PaymentOpts, StackFunction } from './index'; import * as lazy from './lazy'; -import { bitcoin as BITCOIN_NETWORK } from '../networks'; const typef = require('typeforce'); const OPS = bscript.OPS; const ecc = require('tiny-secp256k1'); @@ -25,30 +25,30 @@ export function p2pk(a: Payment, opts?: PaymentOpts): Payment { a, ); - const _chunks = <() => Array>lazy.value(function() { + const _chunks = lazy.value(() => { return bscript.decompile(a.input!); - }); + }) as StackFunction; const network = a.network || BITCOIN_NETWORK; const o: Payment = { network }; - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!a.pubkey) return; return bscript.compile([a.pubkey, OPS.OP_CHECKSIG]); }); - lazy.prop(o, 'pubkey', function() { + lazy.prop(o, 'pubkey', () => { if (!a.output) return; return a.output.slice(1, -1); }); - lazy.prop(o, 'signature', function() { + lazy.prop(o, 'signature', () => { if (!a.input) return; - return _chunks()[0]; + return _chunks()[0] as Buffer; }); - lazy.prop(o, 'input', function() { + lazy.prop(o, 'input', () => { if (!a.signature) return; return bscript.compile([a.signature]); }); - lazy.prop(o, 'witness', function() { + lazy.prop(o, 'witness', () => { if (!o.input) return; return []; }); diff --git a/types/payments/index.d.ts b/types/payments/index.d.ts index 3009bef..66654d2 100644 --- a/types/payments/index.d.ts +++ b/types/payments/index.d.ts @@ -29,4 +29,5 @@ export interface PaymentOpts { } export declare type StackElement = Buffer | number; export declare type Stack = StackElement[]; +export declare type StackFunction = () => Stack; export { embed, p2ms, p2pk, p2pkh, p2sh, p2wpkh, p2wsh }; From db0e3f1203ae50ba03a58a19f424a2fe7c75bf75 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:51:22 +0900 Subject: [PATCH 12/22] Fix lint payments p2pkh --- src/payments/p2pkh.js | 22 +++++++++++----------- ts_src/payments/p2pkh.ts | 38 +++++++++++++++++++------------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/payments/p2pkh.js b/src/payments/p2pkh.js index 6b41a77..9f06bde 100644 --- a/src/payments/p2pkh.js +++ b/src/payments/p2pkh.js @@ -1,9 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const bscript = require("../script"); const bcrypto = require("../crypto"); -const lazy = require("./lazy"); const networks_1 = require("../networks"); +const bscript = require("../script"); +const lazy = require("./lazy"); const typef = require('typeforce'); const OPS = bscript.OPS; const ecc = require('tiny-secp256k1'); @@ -23,18 +23,18 @@ function p2pkh(a, opts) { signature: typef.maybe(bscript.isCanonicalScriptSignature), input: typef.maybe(typef.Buffer), }, a); - const _address = lazy.value(function () { + const _address = lazy.value(() => { const payload = bs58check.decode(a.address); const version = payload.readUInt8(0); const hash = payload.slice(1); return { version, hash }; }); - const _chunks = lazy.value(function () { + const _chunks = lazy.value(() => { return bscript.decompile(a.input); }); const network = a.network || networks_1.bitcoin; const o = { network }; - lazy.prop(o, 'address', function () { + lazy.prop(o, 'address', () => { if (!o.hash) return; const payload = Buffer.allocUnsafe(21); @@ -42,7 +42,7 @@ function p2pkh(a, opts) { o.hash.copy(payload, 1); return bs58check.encode(payload); }); - lazy.prop(o, 'hash', function () { + lazy.prop(o, 'hash', () => { if (a.output) return a.output.slice(3, 23); if (a.address) @@ -50,7 +50,7 @@ function p2pkh(a, opts) { if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey || o.pubkey); }); - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([ @@ -61,24 +61,24 @@ function p2pkh(a, opts) { OPS.OP_CHECKSIG, ]); }); - lazy.prop(o, 'pubkey', function () { + lazy.prop(o, 'pubkey', () => { if (!a.input) return; return _chunks()[1]; }); - lazy.prop(o, 'signature', function () { + lazy.prop(o, 'signature', () => { if (!a.input) return; return _chunks()[0]; }); - lazy.prop(o, 'input', function () { + lazy.prop(o, 'input', () => { if (!a.pubkey) return; if (!a.signature) return; return bscript.compile([a.signature, a.pubkey]); }); - lazy.prop(o, 'witness', function () { + lazy.prop(o, 'witness', () => { if (!o.input) return; return []; diff --git a/ts_src/payments/p2pkh.ts b/ts_src/payments/p2pkh.ts index 63594ad..12c9473 100644 --- a/ts_src/payments/p2pkh.ts +++ b/ts_src/payments/p2pkh.ts @@ -1,8 +1,8 @@ -import { Payment, PaymentOpts } from './index'; -import * as bscript from '../script'; import * as bcrypto from '../crypto'; -import * as lazy from './lazy'; import { bitcoin as BITCOIN_NETWORK } from '../networks'; +import * as bscript from '../script'; +import { Payment, PaymentOpts, StackFunction } from './index'; +import * as lazy from './lazy'; const typef = require('typeforce'); const OPS = bscript.OPS; const ecc = require('tiny-secp256k1'); @@ -30,20 +30,20 @@ export function p2pkh(a: Payment, opts?: PaymentOpts): Payment { a, ); - const _address = lazy.value(function() { + const _address = lazy.value(() => { const payload = bs58check.decode(a.address); const version = payload.readUInt8(0); const hash = payload.slice(1); return { version, hash }; }); - const _chunks = <() => Array>lazy.value(function() { + const _chunks = lazy.value(() => { return bscript.decompile(a.input!); - }); + }) as StackFunction; const network = a.network || BITCOIN_NETWORK; const o: Payment = { network }; - lazy.prop(o, 'address', function() { + lazy.prop(o, 'address', () => { if (!o.hash) return; const payload = Buffer.allocUnsafe(21); @@ -51,12 +51,12 @@ export function p2pkh(a: Payment, opts?: PaymentOpts): Payment { o.hash.copy(payload, 1); return bs58check.encode(payload); }); - lazy.prop(o, 'hash', function() { + lazy.prop(o, 'hash', () => { if (a.output) return a.output.slice(3, 23); if (a.address) return _address().hash; if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey! || o.pubkey!); }); - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([ OPS.OP_DUP, @@ -66,20 +66,20 @@ export function p2pkh(a: Payment, opts?: PaymentOpts): Payment { OPS.OP_CHECKSIG, ]); }); - lazy.prop(o, 'pubkey', function() { + lazy.prop(o, 'pubkey', () => { if (!a.input) return; - return _chunks()[1]; + return _chunks()[1] as Buffer; }); - lazy.prop(o, 'signature', function() { + lazy.prop(o, 'signature', () => { if (!a.input) return; - return _chunks()[0]; + return _chunks()[0] as Buffer; }); - lazy.prop(o, 'input', function() { + lazy.prop(o, 'input', () => { if (!a.pubkey) return; if (!a.signature) return; return bscript.compile([a.signature, a.pubkey]); }); - lazy.prop(o, 'witness', function() { + lazy.prop(o, 'witness', () => { if (!o.input) return; return []; }); @@ -127,17 +127,17 @@ export function p2pkh(a: Payment, opts?: PaymentOpts): Payment { if (a.input) { const chunks = _chunks(); if (chunks.length !== 2) throw new TypeError('Input is invalid'); - if (!bscript.isCanonicalScriptSignature(chunks[0])) + if (!bscript.isCanonicalScriptSignature(chunks[0] as Buffer)) throw new TypeError('Input has invalid signature'); if (!ecc.isPoint(chunks[1])) throw new TypeError('Input has invalid pubkey'); - if (a.signature && !a.signature.equals(chunks[0])) + if (a.signature && !a.signature.equals(chunks[0] as Buffer)) throw new TypeError('Signature mismatch'); - if (a.pubkey && !a.pubkey.equals(chunks[1])) + if (a.pubkey && !a.pubkey.equals(chunks[1] as Buffer)) throw new TypeError('Pubkey mismatch'); - const pkh = bcrypto.hash160(chunks[1]); + const pkh = bcrypto.hash160(chunks[1] as Buffer); if (hash.length > 0 && !hash.equals(pkh)) throw new TypeError('Hash mismatch'); } From fe62e130236624d84c7ee78e0679af4fcc7bd136 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 12:59:52 +0900 Subject: [PATCH 13/22] Fix lint payments p2sh --- src/payments/p2sh.js | 26 ++++++++-------- ts_src/payments/index.ts | 2 ++ ts_src/payments/p2sh.ts | 62 +++++++++++++++++++++------------------ types/payments/index.d.ts | 1 + 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/payments/p2sh.js b/src/payments/p2sh.js index f98ef71..e419deb 100644 --- a/src/payments/p2sh.js +++ b/src/payments/p2sh.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const bcrypto = require("../crypto"); const networks_1 = require("../networks"); const bscript = require("../script"); -const bcrypto = require("../crypto"); const lazy = require("./lazy"); const typef = require('typeforce'); const OPS = bscript.OPS; @@ -10,7 +10,7 @@ const bs58check = require('bs58check'); function stacksEqual(a, b) { if (a.length !== b.length) return false; - return a.every(function (x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -40,16 +40,16 @@ function p2sh(a, opts) { network = (a.redeem && a.redeem.network) || networks_1.bitcoin; } const o = { network }; - const _address = lazy.value(function () { + const _address = lazy.value(() => { const payload = bs58check.decode(a.address); const version = payload.readUInt8(0); const hash = payload.slice(1); return { version, hash }; }); - const _chunks = lazy.value(function () { + const _chunks = lazy.value(() => { return bscript.decompile(a.input); }); - const _redeem = lazy.value(function () { + const _redeem = lazy.value(() => { const chunks = _chunks(); return { network, @@ -59,7 +59,7 @@ function p2sh(a, opts) { }; }); // output dependents - lazy.prop(o, 'address', function () { + lazy.prop(o, 'address', () => { if (!o.hash) return; const payload = Buffer.allocUnsafe(21); @@ -67,7 +67,7 @@ function p2sh(a, opts) { o.hash.copy(payload, 1); return bs58check.encode(payload); }); - lazy.prop(o, 'hash', function () { + lazy.prop(o, 'hash', () => { // in order of least effort if (a.output) return a.output.slice(2, 22); @@ -76,23 +76,23 @@ function p2sh(a, opts) { if (o.redeem && o.redeem.output) return bcrypto.hash160(o.redeem.output); }); - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]); }); // input dependents - lazy.prop(o, 'redeem', function () { + lazy.prop(o, 'redeem', () => { if (!a.input) return; return _redeem(); }); - lazy.prop(o, 'input', function () { + lazy.prop(o, 'input', () => { if (!a.redeem || !a.redeem.input || !a.redeem.output) return; return bscript.compile([].concat(bscript.decompile(a.redeem.input), a.redeem.output)); }); - lazy.prop(o, 'witness', function () { + lazy.prop(o, 'witness', () => { if (o.redeem && o.redeem.witness) return o.redeem.witness; if (o.input) @@ -126,7 +126,7 @@ function p2sh(a, opts) { hash = hash2; } // inlined to prevent 'no-inner-declarations' failing - const checkRedeem = function (redeem) { + const checkRedeem = (redeem) => { // is the redeem output empty/invalid? if (redeem.output) { const decompile = bscript.decompile(redeem.output); @@ -147,7 +147,7 @@ function p2sh(a, opts) { if (hasInput && hasWitness) throw new TypeError('Input and witness provided'); if (hasInput) { - const richunks = (bscript.decompile(redeem.input)); + const richunks = bscript.decompile(redeem.input); if (!bscript.isPushOnly(richunks)) throw new TypeError('Non push-only scriptSig'); } diff --git a/ts_src/payments/index.ts b/ts_src/payments/index.ts index 0c70fba..acd6ddb 100644 --- a/ts_src/payments/index.ts +++ b/ts_src/payments/index.ts @@ -24,6 +24,8 @@ export interface Payment { witness?: Buffer[]; } +export type PaymentFunction = () => Payment; + export interface PaymentOpts { validate?: boolean; allowIncomplete?: boolean; diff --git a/ts_src/payments/p2sh.ts b/ts_src/payments/p2sh.ts index b7df1dc..46c11cc 100644 --- a/ts_src/payments/p2sh.ts +++ b/ts_src/payments/p2sh.ts @@ -1,17 +1,23 @@ -import { Payment, PaymentOpts } from './index'; +import * as bcrypto from '../crypto'; import { bitcoin as BITCOIN_NETWORK } from '../networks'; import * as bscript from '../script'; -import * as bcrypto from '../crypto'; +import { + Payment, + PaymentFunction, + PaymentOpts, + Stack, + StackFunction, +} from './index'; import * as lazy from './lazy'; const typef = require('typeforce'); const OPS = bscript.OPS; const bs58check = require('bs58check'); -function stacksEqual(a: Array, b: Array): boolean { +function stacksEqual(a: Buffer[], b: Buffer[]): boolean { if (a.length !== b.length) return false; - return a.every(function(x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -51,27 +57,29 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment { const o: Payment = { network }; - const _address = lazy.value(function() { + const _address = lazy.value(() => { const payload = bs58check.decode(a.address); const version = payload.readUInt8(0); const hash = payload.slice(1); return { version, hash }; }); - const _chunks = <() => Array>lazy.value(function() { + const _chunks = lazy.value(() => { return bscript.decompile(a.input!); - }); - const _redeem = lazy.value(function(): Payment { - const chunks = _chunks(); - return { - network, - output: chunks[chunks.length - 1], - input: bscript.compile(chunks.slice(0, -1)), - witness: a.witness || [], - }; - }); + }) as StackFunction; + const _redeem = lazy.value( + (): Payment => { + const chunks = _chunks(); + return { + network, + output: chunks[chunks.length - 1] as Buffer, + input: bscript.compile(chunks.slice(0, -1)), + witness: a.witness || [], + }; + }, + ) as PaymentFunction; // output dependents - lazy.prop(o, 'address', function() { + lazy.prop(o, 'address', () => { if (!o.hash) return; const payload = Buffer.allocUnsafe(21); @@ -79,32 +87,32 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment { o.hash.copy(payload, 1); return bs58check.encode(payload); }); - lazy.prop(o, 'hash', function() { + lazy.prop(o, 'hash', () => { // in order of least effort if (a.output) return a.output.slice(2, 22); if (a.address) return _address().hash; if (o.redeem && o.redeem.output) return bcrypto.hash160(o.redeem.output); }); - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]); }); // input dependents - lazy.prop(o, 'redeem', function() { + lazy.prop(o, 'redeem', () => { if (!a.input) return; return _redeem(); }); - lazy.prop(o, 'input', function() { + lazy.prop(o, 'input', () => { if (!a.redeem || !a.redeem.input || !a.redeem.output) return; return bscript.compile( - (>[]).concat( - >bscript.decompile(a.redeem.input), + ([] as Stack).concat( + bscript.decompile(a.redeem.input) as Stack, a.redeem.output, ), ); }); - lazy.prop(o, 'witness', function() { + lazy.prop(o, 'witness', () => { if (o.redeem && o.redeem.witness) return o.redeem.witness; if (o.input) return []; }); @@ -140,7 +148,7 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment { } // inlined to prevent 'no-inner-declarations' failing - const checkRedeem = function(redeem: Payment): void { + const checkRedeem = (redeem: Payment): void => { // is the redeem output empty/invalid? if (redeem.output) { const decompile = bscript.decompile(redeem.output); @@ -161,9 +169,7 @@ export function p2sh(a: Payment, opts?: PaymentOpts): Payment { if (hasInput && hasWitness) throw new TypeError('Input and witness provided'); if (hasInput) { - const richunks = >( - bscript.decompile(redeem.input) - ); + const richunks = bscript.decompile(redeem.input) as Stack; if (!bscript.isPushOnly(richunks)) throw new TypeError('Non push-only scriptSig'); } diff --git a/types/payments/index.d.ts b/types/payments/index.d.ts index 66654d2..102f20a 100644 --- a/types/payments/index.d.ts +++ b/types/payments/index.d.ts @@ -23,6 +23,7 @@ export interface Payment { redeem?: Payment; witness?: Buffer[]; } +export declare type PaymentFunction = () => Payment; export interface PaymentOpts { validate?: boolean; allowIncomplete?: boolean; From 3ddb88168d8248f3fb86f5e6a8ced725864b5b70 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 13:01:40 +0900 Subject: [PATCH 14/22] Fix lint payments p2wpkh --- src/payments/p2wpkh.js | 20 ++++++++++---------- ts_src/payments/p2wpkh.ts | 22 +++++++++++----------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/payments/p2wpkh.js b/src/payments/p2wpkh.js index 9165f96..9e99610 100644 --- a/src/payments/p2wpkh.js +++ b/src/payments/p2wpkh.js @@ -1,9 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const bscript = require("../script"); const bcrypto = require("../crypto"); -const lazy = require("./lazy"); const networks_1 = require("../networks"); +const bscript = require("../script"); +const lazy = require("./lazy"); const typef = require('typeforce'); const OPS = bscript.OPS; const ecc = require('tiny-secp256k1'); @@ -26,7 +26,7 @@ function p2wpkh(a, opts) { signature: typef.maybe(bscript.isCanonicalScriptSignature), witness: typef.maybe(typef.arrayOf(typef.Buffer)), }, a); - const _address = lazy.value(function () { + const _address = lazy.value(() => { const result = bech32.decode(a.address); const version = result.words.shift(); const data = bech32.fromWords(result.words); @@ -38,14 +38,14 @@ function p2wpkh(a, opts) { }); const network = a.network || networks_1.bitcoin; const o = { network }; - lazy.prop(o, 'address', function () { + lazy.prop(o, 'address', () => { if (!o.hash) return; const words = bech32.toWords(o.hash); words.unshift(0x00); return bech32.encode(network.bech32, words); }); - lazy.prop(o, 'hash', function () { + lazy.prop(o, 'hash', () => { if (a.output) return a.output.slice(2, 22); if (a.address) @@ -53,29 +53,29 @@ function p2wpkh(a, opts) { if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey || o.pubkey); }); - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([OPS.OP_0, o.hash]); }); - lazy.prop(o, 'pubkey', function () { + lazy.prop(o, 'pubkey', () => { if (a.pubkey) return a.pubkey; if (!a.witness) return; return a.witness[1]; }); - lazy.prop(o, 'signature', function () { + lazy.prop(o, 'signature', () => { if (!a.witness) return; return a.witness[0]; }); - lazy.prop(o, 'input', function () { + lazy.prop(o, 'input', () => { if (!o.witness) return; return EMPTY_BUFFER; }); - lazy.prop(o, 'witness', function () { + lazy.prop(o, 'witness', () => { if (!a.pubkey) return; if (!a.signature) diff --git a/ts_src/payments/p2wpkh.ts b/ts_src/payments/p2wpkh.ts index 04f0e92..7d2748c 100644 --- a/ts_src/payments/p2wpkh.ts +++ b/ts_src/payments/p2wpkh.ts @@ -1,8 +1,8 @@ -import { Payment, PaymentOpts } from './index'; -import * as bscript from '../script'; import * as bcrypto from '../crypto'; -import * as lazy from './lazy'; import { bitcoin as BITCOIN_NETWORK } from '../networks'; +import * as bscript from '../script'; +import { Payment, PaymentOpts } from './index'; +import * as lazy from './lazy'; const typef = require('typeforce'); const OPS = bscript.OPS; const ecc = require('tiny-secp256k1'); @@ -33,7 +33,7 @@ export function p2wpkh(a: Payment, opts?: PaymentOpts): Payment { a, ); - const _address = lazy.value(function() { + const _address = lazy.value(() => { const result = bech32.decode(a.address); const version = result.words.shift(); const data = bech32.fromWords(result.words); @@ -47,36 +47,36 @@ export function p2wpkh(a: Payment, opts?: PaymentOpts): Payment { const network = a.network || BITCOIN_NETWORK; const o: Payment = { network }; - lazy.prop(o, 'address', function() { + lazy.prop(o, 'address', () => { if (!o.hash) return; const words = bech32.toWords(o.hash); words.unshift(0x00); return bech32.encode(network.bech32, words); }); - lazy.prop(o, 'hash', function() { + lazy.prop(o, 'hash', () => { if (a.output) return a.output.slice(2, 22); if (a.address) return _address().data; if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey! || o.pubkey!); }); - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([OPS.OP_0, o.hash]); }); - lazy.prop(o, 'pubkey', function() { + lazy.prop(o, 'pubkey', () => { if (a.pubkey) return a.pubkey; if (!a.witness) return; return a.witness[1]; }); - lazy.prop(o, 'signature', function() { + lazy.prop(o, 'signature', () => { if (!a.witness) return; return a.witness[0]; }); - lazy.prop(o, 'input', function() { + lazy.prop(o, 'input', () => { if (!o.witness) return; return EMPTY_BUFFER; }); - lazy.prop(o, 'witness', function() { + lazy.prop(o, 'witness', () => { if (!a.pubkey) return; if (!a.signature) return; return [a.signature, a.pubkey]; From f058140ea8a0313b319d59b6c17c02d3fa1587cc Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 13:05:04 +0900 Subject: [PATCH 15/22] Fix lint payments p2wsh --- src/payments/p2wsh.js | 20 ++++++++++---------- ts_src/payments/p2wsh.ts | 30 +++++++++++++++--------------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/payments/p2wsh.js b/src/payments/p2wsh.js index 7c71ac3..0def430 100644 --- a/src/payments/p2wsh.js +++ b/src/payments/p2wsh.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const bcrypto = require("../crypto"); const networks_1 = require("../networks"); const bscript = require("../script"); -const bcrypto = require("../crypto"); const lazy = require("./lazy"); const typef = require('typeforce'); const OPS = bscript.OPS; @@ -11,7 +11,7 @@ const EMPTY_BUFFER = Buffer.alloc(0); function stacksEqual(a, b) { if (a.length !== b.length) return false; - return a.every(function (x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -36,7 +36,7 @@ function p2wsh(a, opts) { input: typef.maybe(typef.BufferN(0)), witness: typef.maybe(typef.arrayOf(typef.Buffer)), }, a); - const _address = lazy.value(function () { + const _address = lazy.value(() => { const result = bech32.decode(a.address); const version = result.words.shift(); const data = bech32.fromWords(result.words); @@ -46,7 +46,7 @@ function p2wsh(a, opts) { data: Buffer.from(data), }; }); - const _rchunks = lazy.value(function () { + const _rchunks = lazy.value(() => { return bscript.decompile(a.redeem.input); }); let network = a.network; @@ -54,14 +54,14 @@ function p2wsh(a, opts) { network = (a.redeem && a.redeem.network) || networks_1.bitcoin; } const o = { network }; - lazy.prop(o, 'address', function () { + lazy.prop(o, 'address', () => { if (!o.hash) return; const words = bech32.toWords(o.hash); words.unshift(0x00); return bech32.encode(network.bech32, words); }); - lazy.prop(o, 'hash', function () { + lazy.prop(o, 'hash', () => { if (a.output) return a.output.slice(2); if (a.address) @@ -69,12 +69,12 @@ function p2wsh(a, opts) { if (o.redeem && o.redeem.output) return bcrypto.sha256(o.redeem.output); }); - lazy.prop(o, 'output', function () { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([OPS.OP_0, o.hash]); }); - lazy.prop(o, 'redeem', function () { + lazy.prop(o, 'redeem', () => { if (!a.witness) return; return { @@ -83,12 +83,12 @@ function p2wsh(a, opts) { witness: a.witness.slice(0, -1), }; }); - lazy.prop(o, 'input', function () { + lazy.prop(o, 'input', () => { if (!o.witness) return; return EMPTY_BUFFER; }); - lazy.prop(o, 'witness', function () { + lazy.prop(o, 'witness', () => { // transform redeem input to witness stack? if (a.redeem && a.redeem.input && diff --git a/ts_src/payments/p2wsh.ts b/ts_src/payments/p2wsh.ts index 28a235c..131de45 100644 --- a/ts_src/payments/p2wsh.ts +++ b/ts_src/payments/p2wsh.ts @@ -1,7 +1,7 @@ -import { Payment, PaymentOpts } from './index'; +import * as bcrypto from '../crypto'; import { bitcoin as BITCOIN_NETWORK } from '../networks'; import * as bscript from '../script'; -import * as bcrypto from '../crypto'; +import { Payment, PaymentOpts, StackFunction } from './index'; import * as lazy from './lazy'; const typef = require('typeforce'); const OPS = bscript.OPS; @@ -10,10 +10,10 @@ const bech32 = require('bech32'); const EMPTY_BUFFER = Buffer.alloc(0); -function stacksEqual(a: Array, b: Array): boolean { +function stacksEqual(a: Buffer[], b: Buffer[]): boolean { if (a.length !== b.length) return false; - return a.every(function(x, i) { + return a.every((x, i) => { return x.equals(b[i]); }); } @@ -46,7 +46,7 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment { a, ); - const _address = lazy.value(function() { + const _address = lazy.value(() => { const result = bech32.decode(a.address); const version = result.words.shift(); const data = bech32.fromWords(result.words); @@ -56,9 +56,9 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment { data: Buffer.from(data), }; }); - const _rchunks = <() => Array>lazy.value(function() { + const _rchunks = lazy.value(() => { return bscript.decompile(a.redeem!.input!); - }); + }) as StackFunction; let network = a.network; if (!network) { @@ -67,22 +67,22 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment { const o: Payment = { network }; - lazy.prop(o, 'address', function() { + lazy.prop(o, 'address', () => { if (!o.hash) return; const words = bech32.toWords(o.hash); words.unshift(0x00); return bech32.encode(network!.bech32, words); }); - lazy.prop(o, 'hash', function() { + lazy.prop(o, 'hash', () => { if (a.output) return a.output.slice(2); if (a.address) return _address().data; if (o.redeem && o.redeem.output) return bcrypto.sha256(o.redeem.output); }); - lazy.prop(o, 'output', function() { + lazy.prop(o, 'output', () => { if (!o.hash) return; return bscript.compile([OPS.OP_0, o.hash]); }); - lazy.prop(o, 'redeem', function() { + lazy.prop(o, 'redeem', () => { if (!a.witness) return; return { output: a.witness[a.witness.length - 1], @@ -90,11 +90,11 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment { witness: a.witness.slice(0, -1), }; }); - lazy.prop(o, 'input', function() { + lazy.prop(o, 'input', () => { if (!o.witness) return; return EMPTY_BUFFER; }); - lazy.prop(o, 'witness', function() { + lazy.prop(o, 'witness', () => { // transform redeem input to witness stack? if ( a.redeem && @@ -108,13 +108,13 @@ export function p2wsh(a: Payment, opts?: PaymentOpts): Payment { // assign, and blank the existing input o.redeem = Object.assign({ witness: stack }, a.redeem); o.redeem.input = EMPTY_BUFFER; - return (>[]).concat(stack, a.redeem.output); + return ([] as Buffer[]).concat(stack, a.redeem.output); } if (!a.redeem) return; if (!a.redeem.output) return; if (!a.redeem.witness) return; - return (>[]).concat(a.redeem.witness, a.redeem.output); + return ([] as Buffer[]).concat(a.redeem.witness, a.redeem.output); }); // extended validation From c2c650812e74a150220cdc05475d2c7e95b4d3fd Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 13:17:03 +0900 Subject: [PATCH 16/22] Fix lint script.ts --- src/script.js | 13 +++++++------ ts_src/script.ts | 40 +++++++++++++++++++--------------------- types/script.d.ts | 7 ++++--- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/script.js b/src/script.js index a114d1f..ac334f8 100644 --- a/src/script.js +++ b/src/script.js @@ -1,8 +1,8 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const types = require("./types"); const scriptNumber = require("./script_number"); const scriptSignature = require("./script_signature"); +const types = require("./types"); const bip66 = require('bip66'); const ecc = require('tiny-secp256k1'); const pushdata = require('pushdata-bitcoin'); @@ -47,7 +47,7 @@ function compile(chunks) { if (chunksIsBuffer(chunks)) return chunks; typeforce(types.Array, chunks); - const bufferSize = chunks.reduce(function (accum, chunk) { + const bufferSize = chunks.reduce((accum, chunk) => { // data chunk if (singleChunkIsBuffer(chunk)) { // adhere to BIP62.3, minimal push policy @@ -61,7 +61,7 @@ function compile(chunks) { }, 0.0); const buffer = Buffer.allocUnsafe(bufferSize); let offset = 0; - chunks.forEach(function (chunk) { + chunks.forEach(chunk => { // data chunk if (singleChunkIsBuffer(chunk)) { // adhere to BIP62.3, minimal push policy @@ -130,7 +130,7 @@ function toASM(chunks) { chunks = decompile(chunks); } return chunks - .map(function (chunk) { + .map(chunk => { // data? if (singleChunkIsBuffer(chunk)) { const op = asMinimalOP(chunk); @@ -146,7 +146,7 @@ function toASM(chunks) { exports.toASM = toASM; function fromASM(asm) { typeforce(types.String, asm); - return compile(asm.split(' ').map(function (chunkStr) { + return compile(asm.split(' ').map(chunkStr => { // opcode? if (exports.OPS[chunkStr] !== undefined) return exports.OPS[chunkStr]; @@ -159,7 +159,7 @@ exports.fromASM = fromASM; function toStack(chunks) { chunks = decompile(chunks); typeforce(isPushOnly, chunks); - return chunks.map(function (op) { + return chunks.map(op => { if (singleChunkIsBuffer(op)) return op; if (op === exports.OPS.OP_0) @@ -186,5 +186,6 @@ function isCanonicalScriptSignature(buffer) { return bip66.check(buffer.slice(0, -1)); } exports.isCanonicalScriptSignature = isCanonicalScriptSignature; +// tslint:disable-next-line variable-name exports.number = scriptNumber; exports.signature = scriptSignature; diff --git a/ts_src/script.ts b/ts_src/script.ts index 36fef95..1c705d3 100644 --- a/ts_src/script.ts +++ b/ts_src/script.ts @@ -1,15 +1,16 @@ -import * as types from './types'; +import { Stack } from './payments'; import * as scriptNumber from './script_number'; import * as scriptSignature from './script_signature'; +import * as types from './types'; const bip66 = require('bip66'); const ecc = require('tiny-secp256k1'); const pushdata = require('pushdata-bitcoin'); const typeforce = require('typeforce'); export type OpCode = number; -export const OPS = <{ [index: string]: OpCode }>require('bitcoin-ops'); +export const OPS = require('bitcoin-ops') as { [index: string]: OpCode }; -const REVERSE_OPS = <{ [index: number]: string }>require('bitcoin-ops/map'); +const REVERSE_OPS = require('bitcoin-ops/map') as { [index: number]: string }; const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1 function isOPInt(value: number): boolean { @@ -22,10 +23,10 @@ function isOPInt(value: number): boolean { } function isPushOnlyChunk(value: number | Buffer): boolean { - return types.Buffer(value) || isOPInt(value); + return types.Buffer(value) || isOPInt(value as number); } -export function isPushOnly(value: Array) { +export function isPushOnly(value: Stack) { return types.Array(value) && value.every(isPushOnlyChunk); } @@ -36,13 +37,11 @@ function asMinimalOP(buffer: Buffer): number | void { if (buffer[0] === 0x81) return OPS.OP_1NEGATE; } -function chunksIsBuffer(buf: Buffer | Array): buf is Buffer { +function chunksIsBuffer(buf: Buffer | Stack): buf is Buffer { return Buffer.isBuffer(buf); } -function chunksIsArray( - buf: Buffer | Array, -): buf is Array { +function chunksIsArray(buf: Buffer | Stack): buf is Stack { return types.Array(buf); } @@ -50,13 +49,13 @@ function singleChunkIsBuffer(buf: number | Buffer): buf is Buffer { return Buffer.isBuffer(buf); } -export function compile(chunks: Buffer | Array): Buffer { +export function compile(chunks: Buffer | Stack): Buffer { // TODO: remove me if (chunksIsBuffer(chunks)) return chunks; typeforce(types.Array, chunks); - const bufferSize = chunks.reduce(function(accum: number, chunk) { + const bufferSize = chunks.reduce((accum: number, chunk) => { // data chunk if (singleChunkIsBuffer(chunk)) { // adhere to BIP62.3, minimal push policy @@ -74,7 +73,7 @@ export function compile(chunks: Buffer | Array): Buffer { const buffer = Buffer.allocUnsafe(bufferSize); let offset = 0; - chunks.forEach(function(chunk) { + chunks.forEach(chunk => { // data chunk if (singleChunkIsBuffer(chunk)) { // adhere to BIP62.3, minimal push policy @@ -149,16 +148,16 @@ export function decompile( export function toASM(chunks: Buffer | Array): string { if (chunksIsBuffer(chunks)) { - chunks = >decompile(chunks); + chunks = decompile(chunks) as Stack; } return chunks - .map(function(chunk) { + .map(chunk => { // data? if (singleChunkIsBuffer(chunk)) { const op = asMinimalOP(chunk); if (op === undefined) return chunk.toString('hex'); - chunk = op; + chunk = op as number; } // opcode! @@ -171,7 +170,7 @@ export function fromASM(asm: string): Buffer { typeforce(types.String, asm); return compile( - asm.split(' ').map(function(chunkStr) { + asm.split(' ').map(chunkStr => { // opcode? if (OPS[chunkStr] !== undefined) return OPS[chunkStr]; typeforce(types.Hex, chunkStr); @@ -182,13 +181,11 @@ export function fromASM(asm: string): Buffer { ); } -export function toStack( - chunks: Buffer | Array, -): Array { - chunks = >decompile(chunks); +export function toStack(chunks: Buffer | Array): Buffer[] { + chunks = decompile(chunks) as Stack; typeforce(isPushOnly, chunks); - return chunks.map(function(op) { + return chunks.map(op => { if (singleChunkIsBuffer(op)) return op; if (op === OPS.OP_0) return Buffer.allocUnsafe(0); @@ -214,5 +211,6 @@ export function isCanonicalScriptSignature(buffer: Buffer): boolean { return bip66.check(buffer.slice(0, -1)); } +// tslint:disable-next-line variable-name export const number = scriptNumber; export const signature = scriptSignature; diff --git a/types/script.d.ts b/types/script.d.ts index 702e76b..52ad4dd 100644 --- a/types/script.d.ts +++ b/types/script.d.ts @@ -1,16 +1,17 @@ /// +import { Stack } from './payments'; import * as scriptNumber from './script_number'; import * as scriptSignature from './script_signature'; export declare type OpCode = number; export declare const OPS: { [index: string]: number; }; -export declare function isPushOnly(value: Array): boolean; -export declare function compile(chunks: Buffer | Array): Buffer; +export declare function isPushOnly(value: Stack): boolean; +export declare function compile(chunks: Buffer | Stack): Buffer; export declare function decompile(buffer: Buffer | Array): Array | null; export declare function toASM(chunks: Buffer | Array): string; export declare function fromASM(asm: string): Buffer; -export declare function toStack(chunks: Buffer | Array): Array; +export declare function toStack(chunks: Buffer | Array): Buffer[]; export declare function isCanonicalPubKey(buffer: Buffer): boolean; export declare function isDefinedHashType(hashType: number): boolean; export declare function isCanonicalScriptSignature(buffer: Buffer): boolean; From 94f334851937eed434acf3cf413257394f861f8d Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 13:21:18 +0900 Subject: [PATCH 17/22] Fix lint for script_number.ts script_signature.ts --- src/script_number.js | 10 +++++----- src/script_signature.js | 12 +++++------- ts_src/script_number.ts | 10 +++++----- ts_src/script_signature.ts | 12 +++++------- types/script_number.d.ts | 2 +- 5 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/script_number.js b/src/script_number.js index a8c42d3..3a30a43 100644 --- a/src/script_number.js +++ b/src/script_number.js @@ -24,7 +24,7 @@ function decode(buffer, maxLength, minimal) { } // 32-bit / 24-bit / 16-bit / 8-bit let result = 0; - for (var i = 0; i < length; ++i) { + for (let i = 0; i < length; ++i) { result |= buffer[i] << (8 * i); } if (buffer[length - 1] & 0x80) @@ -45,12 +45,12 @@ function scriptNumSize(i) { ? 1 : 0; } -function encode(number) { - let value = Math.abs(number); +function encode(_number) { + let value = Math.abs(_number); const size = scriptNumSize(value); const buffer = Buffer.allocUnsafe(size); - const negative = number < 0; - for (var i = 0; i < size; ++i) { + const negative = _number < 0; + for (let i = 0; i < size; ++i) { buffer.writeUInt8(value & 0xff, i); value >>= 8; } diff --git a/src/script_signature.js b/src/script_signature.js index c185981..a1f2f22 100644 --- a/src/script_signature.js +++ b/src/script_signature.js @@ -29,13 +29,11 @@ function decode(buffer) { const hashTypeMod = hashType & ~0x80; if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType); - const decode = bip66.decode(buffer.slice(0, -1)); - const r = fromDER(decode.r); - const s = fromDER(decode.s); - return { - signature: Buffer.concat([r, s], 64), - hashType: hashType, - }; + const decoded = bip66.decode(buffer.slice(0, -1)); + const r = fromDER(decoded.r); + const s = fromDER(decoded.s); + const signature = Buffer.concat([r, s], 64); + return { signature, hashType }; } exports.decode = decode; function encode(signature, hashType) { diff --git a/ts_src/script_number.ts b/ts_src/script_number.ts index cd48373..a4c502f 100644 --- a/ts_src/script_number.ts +++ b/ts_src/script_number.ts @@ -27,7 +27,7 @@ export function decode( // 32-bit / 24-bit / 16-bit / 8-bit let result = 0; - for (var i = 0; i < length; ++i) { + for (let i = 0; i < length; ++i) { result |= buffer[i] << (8 * i); } @@ -50,13 +50,13 @@ function scriptNumSize(i: number): number { : 0; } -export function encode(number: number): Buffer { - let value = Math.abs(number); +export function encode(_number: number): Buffer { + let value = Math.abs(_number); const size = scriptNumSize(value); const buffer = Buffer.allocUnsafe(size); - const negative = number < 0; + const negative = _number < 0; - for (var i = 0; i < size; ++i) { + for (let i = 0; i < size; ++i) { buffer.writeUInt8(value & 0xff, i); value >>= 8; } diff --git a/ts_src/script_signature.ts b/ts_src/script_signature.ts index 1f11d00..af9930e 100644 --- a/ts_src/script_signature.ts +++ b/ts_src/script_signature.ts @@ -33,14 +33,12 @@ export function decode(buffer: Buffer): ScriptSignature { if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType); - const decode = bip66.decode(buffer.slice(0, -1)); - const r = fromDER(decode.r); - const s = fromDER(decode.s); + const decoded = bip66.decode(buffer.slice(0, -1)); + const r = fromDER(decoded.r); + const s = fromDER(decoded.s); + const signature = Buffer.concat([r, s], 64); - return { - signature: Buffer.concat([r, s], 64), - hashType: hashType, - }; + return { signature, hashType }; } export function encode(signature: Buffer, hashType: number): Buffer { diff --git a/types/script_number.d.ts b/types/script_number.d.ts index d0b87b1..015bb89 100644 --- a/types/script_number.d.ts +++ b/types/script_number.d.ts @@ -1,3 +1,3 @@ /// export declare function decode(buffer: Buffer, maxLength?: number, minimal?: boolean): number; -export declare function encode(number: number): Buffer; +export declare function encode(_number: number): Buffer; From e6ea0389a2c22c096da0707455735ed7eb8ce36a Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 13:40:23 +0900 Subject: [PATCH 18/22] Fix lint for transaction.ts --- src/transaction.js | 90 +++++++++++----------- ts_src/transaction.ts | 168 +++++++++++++++++++++-------------------- types/transaction.d.ts | 34 +++++---- 3 files changed, 148 insertions(+), 144 deletions(-) diff --git a/src/transaction.js b/src/transaction.js index cfd31fe..c6c847a 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -1,11 +1,11 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const bcrypto = require("./crypto"); -const bscript = require("./script"); -const types = require("./types"); const bufferutils = require("./bufferutils"); const bufferutils_1 = require("./bufferutils"); +const bcrypto = require("./crypto"); +const bscript = require("./script"); const script_1 = require("./script"); +const types = require("./types"); const typeforce = require('typeforce'); const varuint = require('varuint-bitcoin'); function varSliceSize(someScript) { @@ -38,7 +38,7 @@ class Transaction { this.ins = []; this.outs = []; } - static fromBuffer(buffer, __noStrict) { + static fromBuffer(buffer, _NO_STRICT) { let offset = 0; function readSlice(n) { offset += n; @@ -70,7 +70,7 @@ class Transaction { function readVector() { const count = readVarInt(); const vector = []; - for (var i = 0; i < count; i++) + for (let i = 0; i < count; i++) vector.push(readVarSlice()); return vector; } @@ -85,7 +85,7 @@ class Transaction { hasWitnesses = true; } const vinLen = readVarInt(); - for (var i = 0; i < vinLen; ++i) { + for (let i = 0; i < vinLen; ++i) { tx.ins.push({ hash: readSlice(32), index: readUInt32(), @@ -95,14 +95,14 @@ class Transaction { }); } const voutLen = readVarInt(); - for (i = 0; i < voutLen; ++i) { + for (let i = 0; i < voutLen; ++i) { tx.outs.push({ value: readUInt64(), script: readVarSlice(), }); } if (hasWitnesses) { - for (i = 0; i < vinLen; ++i) { + for (let i = 0; i < vinLen; ++i) { tx.ins[i].witness = readVector(); } // was this pointless? @@ -110,7 +110,7 @@ class Transaction { throw new Error('Transaction has superfluous witness data'); } tx.locktime = readUInt32(); - if (__noStrict) + if (_NO_STRICT) return tx; if (offset !== buffer.length) throw new Error('Transaction has unexpected data'); @@ -121,7 +121,7 @@ class Transaction { } static isCoinbaseHash(buffer) { typeforce(types.Hash256bit, buffer); - for (var i = 0; i < 32; ++i) { + for (let i = 0; i < 32; ++i) { if (buffer[i] !== 0) return false; } @@ -137,8 +137,8 @@ class Transaction { } // Add the input and return the input's index return (this.ins.push({ - hash: hash, - index: index, + hash, + index, script: scriptSig || EMPTY_SCRIPT, sequence: sequence, witness: EMPTY_WITNESS, @@ -149,7 +149,7 @@ class Transaction { // Add the output and return the output's index return (this.outs.push({ script: scriptPubKey, - value: value, + value, }) - 1); } hasWitnesses() { @@ -168,23 +168,6 @@ class Transaction { byteLength() { return this.__byteLength(true); } - __byteLength(__allowWitness) { - const hasWitnesses = __allowWitness && this.hasWitnesses(); - return ((hasWitnesses ? 10 : 8) + - varuint.encodingLength(this.ins.length) + - varuint.encodingLength(this.outs.length) + - this.ins.reduce((sum, input) => { - return sum + 40 + varSliceSize(input.script); - }, 0) + - this.outs.reduce((sum, output) => { - return sum + 8 + varSliceSize(output.script); - }, 0) + - (hasWitnesses - ? this.ins.reduce((sum, input) => { - return sum + vectorSize(input.witness); - }, 0) - : 0)); - } clone() { const newTx = new Transaction(); newTx.version = this.version; @@ -242,7 +225,7 @@ class Transaction { // truncate outputs after txTmp.outs.length = inIndex + 1; // "blank" outputs before - for (var i = 0; i < inIndex; i++) { + for (let i = 0; i < inIndex; i++) { txTmp.outs[i] = BLANK_OUTPUT; } // ignore sequence numbers (except at inIndex) @@ -365,9 +348,37 @@ class Transaction { toBuffer(buffer, initialOffset) { return this.__toBuffer(buffer, initialOffset, true); } - __toBuffer(buffer, initialOffset, __allowWitness) { + toHex() { + return this.toBuffer(undefined, undefined).toString('hex'); + } + setInputScript(index, scriptSig) { + typeforce(types.tuple(types.Number, types.Buffer), arguments); + this.ins[index].script = scriptSig; + } + setWitness(index, witness) { + typeforce(types.tuple(types.Number, [types.Buffer]), arguments); + this.ins[index].witness = witness; + } + __byteLength(_ALLOW_WITNESS) { + const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses(); + return ((hasWitnesses ? 10 : 8) + + varuint.encodingLength(this.ins.length) + + varuint.encodingLength(this.outs.length) + + this.ins.reduce((sum, input) => { + return sum + 40 + varSliceSize(input.script); + }, 0) + + this.outs.reduce((sum, output) => { + return sum + 8 + varSliceSize(output.script); + }, 0) + + (hasWitnesses + ? this.ins.reduce((sum, input) => { + return sum + vectorSize(input.witness); + }, 0) + : 0)); + } + __toBuffer(buffer, initialOffset, _ALLOW_WITNESS) { if (!buffer) - buffer = Buffer.allocUnsafe(this.__byteLength(__allowWitness)); + buffer = Buffer.allocUnsafe(this.__byteLength(_ALLOW_WITNESS)); let offset = initialOffset || 0; function writeSlice(slice) { offset += slice.copy(buffer, offset); @@ -397,7 +408,7 @@ class Transaction { vector.forEach(writeVarSlice); } writeInt32(this.version); - const hasWitnesses = __allowWitness && this.hasWitnesses(); + const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses(); if (hasWitnesses) { writeUInt8(Transaction.ADVANCED_TRANSACTION_MARKER); writeUInt8(Transaction.ADVANCED_TRANSACTION_FLAG); @@ -430,17 +441,6 @@ class Transaction { return buffer.slice(initialOffset, offset); return buffer; } - toHex() { - return this.toBuffer(undefined, undefined).toString('hex'); - } - setInputScript(index, scriptSig) { - typeforce(types.tuple(types.Number, types.Buffer), arguments); - this.ins[index].script = scriptSig; - } - setWitness(index, witness) { - typeforce(types.tuple(types.Number, [types.Buffer]), arguments); - this.ins[index].witness = witness; - } } Transaction.DEFAULT_SEQUENCE = 0xffffffff; Transaction.SIGHASH_ALL = 0x01; diff --git a/ts_src/transaction.ts b/ts_src/transaction.ts index a456a32..995f1d7 100644 --- a/ts_src/transaction.ts +++ b/ts_src/transaction.ts @@ -1,9 +1,9 @@ -import * as bcrypto from './crypto'; -import * as bscript from './script'; -import * as types from './types'; import * as bufferutils from './bufferutils'; import { reverseBuffer } from './bufferutils'; +import * as bcrypto from './crypto'; +import * as bscript from './script'; import { OPS as opcodes } from './script'; +import * as types from './types'; const typeforce = require('typeforce'); const varuint = require('varuint-bitcoin'); @@ -14,7 +14,7 @@ function varSliceSize(someScript: Buffer): number { return varuint.encodingLength(length) + length; } -function vectorSize(someVector: Array): number { +function vectorSize(someVector: Buffer[]): number { const length = someVector.length; return ( @@ -26,7 +26,7 @@ function vectorSize(someVector: Array): number { } const EMPTY_SCRIPT: Buffer = Buffer.allocUnsafe(0); -const EMPTY_WITNESS: Array = []; +const EMPTY_WITNESS: Buffer[] = []; const ZERO: Buffer = Buffer.from( '0000000000000000000000000000000000000000000000000000000000000000', 'hex', @@ -42,33 +42,30 @@ const BLANK_OUTPUT: BlankOutput = { }; function isOutput(out: Output | BlankOutput): out is Output { - return (out).value !== undefined; + return (out as Output).value !== undefined; } -export type BlankOutput = { +export interface BlankOutput { script: Buffer; valueBuffer: Buffer; -}; +} -export type Output = { +export interface Output { script: Buffer; value: number; -}; +} -export type Input = { +type OpenOutput = Output | BlankOutput; + +export interface Input { hash: Buffer; index: number; script: Buffer; sequence: number; - witness: Array; -}; + witness: Buffer[]; +} export class Transaction { - version: number; - locktime: number; - ins: Array; - outs: Array; - static readonly DEFAULT_SEQUENCE = 0xffffffff; static readonly SIGHASH_ALL = 0x01; static readonly SIGHASH_NONE = 0x02; @@ -77,14 +74,7 @@ export class Transaction { static readonly ADVANCED_TRANSACTION_MARKER = 0x00; static readonly ADVANCED_TRANSACTION_FLAG = 0x01; - constructor() { - this.version = 1; - this.locktime = 0; - this.ins = []; - this.outs = []; - } - - static fromBuffer(buffer: Buffer, __noStrict?: boolean): Transaction { + static fromBuffer(buffer: Buffer, _NO_STRICT?: boolean): Transaction { let offset: number = 0; function readSlice(n: number): Buffer { @@ -120,10 +110,10 @@ export class Transaction { return readSlice(readVarInt()); } - function readVector(): Array { + function readVector(): Buffer[] { const count = readVarInt(); - const vector: Array = []; - for (var i = 0; i < count; i++) vector.push(readVarSlice()); + const vector: Buffer[] = []; + for (let i = 0; i < count; i++) vector.push(readVarSlice()); return vector; } @@ -143,7 +133,7 @@ export class Transaction { } const vinLen = readVarInt(); - for (var i = 0; i < vinLen; ++i) { + for (let i = 0; i < vinLen; ++i) { tx.ins.push({ hash: readSlice(32), index: readUInt32(), @@ -154,7 +144,7 @@ export class Transaction { } const voutLen = readVarInt(); - for (i = 0; i < voutLen; ++i) { + for (let i = 0; i < voutLen; ++i) { tx.outs.push({ value: readUInt64(), script: readVarSlice(), @@ -162,7 +152,7 @@ export class Transaction { } if (hasWitnesses) { - for (i = 0; i < vinLen; ++i) { + for (let i = 0; i < vinLen; ++i) { tx.ins[i].witness = readVector(); } @@ -173,7 +163,7 @@ export class Transaction { tx.locktime = readUInt32(); - if (__noStrict) return tx; + if (_NO_STRICT) return tx; if (offset !== buffer.length) throw new Error('Transaction has unexpected data'); @@ -186,12 +176,24 @@ export class Transaction { static isCoinbaseHash(buffer: Buffer): boolean { typeforce(types.Hash256bit, buffer); - for (var i = 0; i < 32; ++i) { + for (let i = 0; i < 32; ++i) { if (buffer[i] !== 0) return false; } return true; } + version: number; + locktime: number; + ins: Input[]; + outs: OpenOutput[]; + + constructor() { + this.version = 1; + this.locktime = 0; + this.ins = []; + this.outs = []; + } + isCoinbase(): boolean { return ( this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash) @@ -221,10 +223,10 @@ export class Transaction { // Add the input and return the input's index return ( this.ins.push({ - hash: hash, - index: index, + hash, + index, script: scriptSig || EMPTY_SCRIPT, - sequence: sequence, + sequence: sequence as number, witness: EMPTY_WITNESS, }) - 1 ); @@ -237,7 +239,7 @@ export class Transaction { return ( this.outs.push({ script: scriptPubKey, - value: value, + value, }) - 1 ); } @@ -262,27 +264,6 @@ export class Transaction { return this.__byteLength(true); } - private __byteLength(__allowWitness: boolean): number { - const hasWitnesses = __allowWitness && this.hasWitnesses(); - - return ( - (hasWitnesses ? 10 : 8) + - varuint.encodingLength(this.ins.length) + - varuint.encodingLength(this.outs.length) + - this.ins.reduce((sum, input) => { - return sum + 40 + varSliceSize(input.script); - }, 0) + - this.outs.reduce((sum, output) => { - return sum + 8 + varSliceSize(output.script); - }, 0) + - (hasWitnesses - ? this.ins.reduce((sum, input) => { - return sum + vectorSize(input.witness); - }, 0) - : 0) - ); - } - clone(): Transaction { const newTx = new Transaction(); newTx.version = this.version; @@ -301,7 +282,7 @@ export class Transaction { newTx.outs = this.outs.map(txOut => { return { script: txOut.script, - value: (txOut).value, + value: (txOut as Output).value, }; }); @@ -358,7 +339,7 @@ export class Transaction { txTmp.outs.length = inIndex + 1; // "blank" outputs before - for (var i = 0; i < inIndex; i++) { + for (let i = 0; i < inIndex; i++) { txTmp.outs[i] = BLANK_OUTPUT; } @@ -471,7 +452,7 @@ export class Transaction { toffset = 0; this.outs.forEach(out => { - writeUInt64((out).value); + writeUInt64((out as Output).value); writeVarSlice(out.script); }); @@ -484,7 +465,7 @@ export class Transaction { tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script)); toffset = 0; - writeUInt64((output).value); + writeUInt64((output as Output).value); writeVarSlice(output.script); hashOutputs = bcrypto.hash256(tbuffer); @@ -523,13 +504,50 @@ export class Transaction { return this.__toBuffer(buffer, initialOffset, true); } + toHex() { + return this.toBuffer(undefined, undefined).toString('hex'); + } + + setInputScript(index: number, scriptSig: Buffer) { + typeforce(types.tuple(types.Number, types.Buffer), arguments); + + this.ins[index].script = scriptSig; + } + + setWitness(index: number, witness: Buffer[]) { + typeforce(types.tuple(types.Number, [types.Buffer]), arguments); + + this.ins[index].witness = witness; + } + + private __byteLength(_ALLOW_WITNESS: boolean): number { + const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses(); + + return ( + (hasWitnesses ? 10 : 8) + + varuint.encodingLength(this.ins.length) + + varuint.encodingLength(this.outs.length) + + this.ins.reduce((sum, input) => { + return sum + 40 + varSliceSize(input.script); + }, 0) + + this.outs.reduce((sum, output) => { + return sum + 8 + varSliceSize(output.script); + }, 0) + + (hasWitnesses + ? this.ins.reduce((sum, input) => { + return sum + vectorSize(input.witness); + }, 0) + : 0) + ); + } + private __toBuffer( buffer?: Buffer, initialOffset?: number, - __allowWitness?: boolean, + _ALLOW_WITNESS?: boolean, ): Buffer { if (!buffer) - buffer = Buffer.allocUnsafe(this.__byteLength(__allowWitness!)); + buffer = Buffer.allocUnsafe(this.__byteLength(_ALLOW_WITNESS!)) as Buffer; let offset = initialOffset || 0; @@ -563,14 +581,14 @@ export class Transaction { writeSlice(slice); } - function writeVector(vector: Array) { + function writeVector(vector: Buffer[]) { writeVarInt(vector.length); vector.forEach(writeVarSlice); } writeInt32(this.version); - const hasWitnesses = __allowWitness && this.hasWitnesses(); + const hasWitnesses = _ALLOW_WITNESS && this.hasWitnesses(); if (hasWitnesses) { writeUInt8(Transaction.ADVANCED_TRANSACTION_MARKER); @@ -609,20 +627,4 @@ export class Transaction { if (initialOffset !== undefined) return buffer.slice(initialOffset, offset); return buffer; } - - toHex() { - return this.toBuffer(undefined, undefined).toString('hex'); - } - - setInputScript(index: number, scriptSig: Buffer) { - typeforce(types.tuple(types.Number, types.Buffer), arguments); - - this.ins[index].script = scriptSig; - } - - setWitness(index: number, witness: Array) { - typeforce(types.tuple(types.Number, [types.Buffer]), arguments); - - this.ins[index].witness = witness; - } } diff --git a/types/transaction.d.ts b/types/transaction.d.ts index 60bbf45..4f8a2b9 100644 --- a/types/transaction.d.ts +++ b/types/transaction.d.ts @@ -1,24 +1,21 @@ /// -export declare type BlankOutput = { +export interface BlankOutput { script: Buffer; valueBuffer: Buffer; -}; -export declare type Output = { +} +export interface Output { script: Buffer; value: number; -}; -export declare type Input = { +} +declare type OpenOutput = Output | BlankOutput; +export interface Input { hash: Buffer; index: number; script: Buffer; sequence: number; - witness: Array; -}; + witness: Buffer[]; +} export declare class Transaction { - version: number; - locktime: number; - ins: Array; - outs: Array; static readonly DEFAULT_SEQUENCE = 4294967295; static readonly SIGHASH_ALL = 1; static readonly SIGHASH_NONE = 2; @@ -26,10 +23,14 @@ export declare class Transaction { static readonly SIGHASH_ANYONECANPAY = 128; static readonly ADVANCED_TRANSACTION_MARKER = 0; static readonly ADVANCED_TRANSACTION_FLAG = 1; - constructor(); - static fromBuffer(buffer: Buffer, __noStrict?: boolean): Transaction; + static fromBuffer(buffer: Buffer, _NO_STRICT?: boolean): Transaction; static fromHex(hex: string): Transaction; static isCoinbaseHash(buffer: Buffer): boolean; + version: number; + locktime: number; + ins: Input[]; + outs: OpenOutput[]; + constructor(); isCoinbase(): boolean; addInput(hash: Buffer, index: number, sequence?: number, scriptSig?: Buffer): number; addOutput(scriptPubKey: Buffer, value: number): number; @@ -37,7 +38,6 @@ export declare class Transaction { weight(): number; virtualSize(): number; byteLength(): number; - private __byteLength; clone(): Transaction; /** * Hash transaction for signing a specific input. @@ -52,8 +52,10 @@ export declare class Transaction { getHash(forWitness?: boolean): Buffer; getId(): string; toBuffer(buffer?: Buffer, initialOffset?: number): Buffer; - private __toBuffer; toHex(): string; setInputScript(index: number, scriptSig: Buffer): void; - setWitness(index: number, witness: Array): void; + setWitness(index: number, witness: Buffer[]): void; + private __byteLength; + private __toBuffer; } +export {}; From 512b03e28406a281b37fbe357c303ecfc16915c3 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 14:03:04 +0900 Subject: [PATCH 19/22] Fix lint transaction_builder.ts --- src/transaction_builder.js | 227 ++++++++--------- test/fixtures/transaction_builder.json | 2 +- test/transaction_builder.js | 26 +- ts_src/transaction_builder.ts | 335 +++++++++++++------------ types/transaction_builder.d.ts | 14 +- 5 files changed, 305 insertions(+), 299 deletions(-) diff --git a/src/transaction_builder.js b/src/transaction_builder.js index 540a17a..0b876a7 100644 --- a/src/transaction_builder.js +++ b/src/transaction_builder.js @@ -1,16 +1,16 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const networks = require("./networks"); -const bufferutils_1 = require("./bufferutils"); -const transaction_1 = require("./transaction"); -const ECPair = require("./ecpair"); -const types = require("./types"); const baddress = require("./address"); +const bufferutils_1 = require("./bufferutils"); +const classify = require("./classify"); const bcrypto = require("./crypto"); -const bscript = require("./script"); +const ECPair = require("./ecpair"); +const networks = require("./networks"); const payments = require("./payments"); -const classify = require("./classify"); +const bscript = require("./script"); const script_1 = require("./script"); +const transaction_1 = require("./transaction"); +const types = require("./types"); const typeforce = require('typeforce'); const SCRIPT_TYPES = classify.types; function txIsString(tx) { @@ -20,15 +20,6 @@ function txIsTransaction(tx) { return tx instanceof transaction_1.Transaction; } class TransactionBuilder { - constructor(network, maximumFeeRate) { - this.__prevTxSet = {}; - this.network = network || networks.bitcoin; - // WARNING: This is __NOT__ to be relied on, its just another potential safety mechanism (safety in-depth) - this.maximumFeeRate = maximumFeeRate || 2500; - this.__inputs = []; - this.__tx = new transaction_1.Transaction(); - this.__tx.version = 2; - } static fromTransaction(transaction, network) { const txb = new TransactionBuilder(network); // Copy transaction fields @@ -47,33 +38,42 @@ class TransactionBuilder { }); }); // fix some things not possible through the public API - txb.__inputs.forEach((input, i) => { + txb.__INPUTS.forEach((input, i) => { fixMultisigOrder(input, transaction, i); }); return txb; } + constructor(network, maximumFeeRate) { + this.__PREV_TX_SET = {}; + this.network = network || networks.bitcoin; + // WARNING: This is __NOT__ to be relied on, its just another potential safety mechanism (safety in-depth) + this.maximumFeeRate = maximumFeeRate || 2500; + this.__INPUTS = []; + this.__TX = new transaction_1.Transaction(); + this.__TX.version = 2; + } setLockTime(locktime) { typeforce(types.UInt32, locktime); // if any signatures exist, throw - if (this.__inputs.some(input => { + if (this.__INPUTS.some(input => { if (!input.signatures) return false; return input.signatures.some(s => s !== undefined); })) { throw new Error('No, this would invalidate signatures'); } - this.__tx.locktime = locktime; + this.__TX.locktime = locktime; } setVersion(version) { typeforce(types.UInt32, version); // XXX: this might eventually become more complex depending on what the versions represent - this.__tx.version = version; + this.__TX.version = version; } addInput(txHash, vout, sequence, prevOutScript) { if (!this.__canModifyInputs()) { throw new Error('No, this would invalidate signatures'); } - let value = undefined; + let value; // is it a hex string? if (txIsString(txHash)) { // transaction hashs's are displayed in reverse order, un-reverse it @@ -87,46 +87,11 @@ class TransactionBuilder { txHash = txHash.getHash(false); } return this.__addInputUnsafe(txHash, vout, { - sequence: sequence, - prevOutScript: prevOutScript, - value: value, + sequence, + prevOutScript, + value, }); } - __addInputUnsafe(txHash, vout, options) { - if (transaction_1.Transaction.isCoinbaseHash(txHash)) { - throw new Error('coinbase inputs not supported'); - } - const prevTxOut = txHash.toString('hex') + ':' + vout; - if (this.__prevTxSet[prevTxOut] !== undefined) - throw new Error('Duplicate TxOut: ' + prevTxOut); - let input = {}; - // derive what we can from the scriptSig - if (options.script !== undefined) { - input = expandInput(options.script, options.witness || []); - } - // if an input value was given, retain it - if (options.value !== undefined) { - input.value = options.value; - } - // derive what we can from the previous transactions output script - if (!input.prevOutScript && options.prevOutScript) { - let prevOutType; - if (!input.pubkeys && !input.signatures) { - const expanded = expandOutput(options.prevOutScript); - if (expanded.pubkeys) { - input.pubkeys = expanded.pubkeys; - input.signatures = expanded.signatures; - } - prevOutType = expanded.type; - } - input.prevOutScript = options.prevOutScript; - input.prevOutType = prevOutType || classify.output(options.prevOutScript); - } - const vin = this.__tx.addInput(txHash, vout, options.sequence, options.scriptSig); - this.__inputs[vin] = input; - this.__prevTxSet[prevTxOut] = true; - return vin; - } addOutput(scriptPubKey, value) { if (!this.__canModifyOutputs()) { throw new Error('No, this would invalidate signatures'); @@ -135,7 +100,7 @@ class TransactionBuilder { if (typeof scriptPubKey === 'string') { scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network); } - return this.__tx.addOutput(scriptPubKey, value); + return this.__TX.addOutput(scriptPubKey, value); } build() { return this.__build(false); @@ -143,47 +108,16 @@ class TransactionBuilder { buildIncomplete() { return this.__build(true); } - __build(allowIncomplete) { - if (!allowIncomplete) { - if (!this.__tx.ins.length) - throw new Error('Transaction has no inputs'); - if (!this.__tx.outs.length) - throw new Error('Transaction has no outputs'); - } - const tx = this.__tx.clone(); - // create script signatures from inputs - this.__inputs.forEach((input, i) => { - if (!input.prevOutType && !allowIncomplete) - throw new Error('Transaction is not complete'); - const result = build(input.prevOutType, input, allowIncomplete); - if (!result) { - if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) - throw new Error('Unknown input type'); - if (!allowIncomplete) - throw new Error('Not enough information'); - return; - } - tx.setInputScript(i, result.input); - tx.setWitness(i, result.witness); - }); - if (!allowIncomplete) { - // do not rely on this, its merely a last resort - if (this.__overMaximumFees(tx.virtualSize())) { - throw new Error('Transaction has absurd fees'); - } - } - return tx; - } sign(vin, keyPair, redeemScript, hashType, witnessValue, witnessScript) { // TODO: remove keyPair.network matching in 4.0.0 if (keyPair.network && keyPair.network !== this.network) throw new TypeError('Inconsistent network'); - if (!this.__inputs[vin]) + if (!this.__INPUTS[vin]) throw new Error('No input at index: ' + vin); hashType = hashType || transaction_1.Transaction.SIGHASH_ALL; if (this.__needsOutputs(hashType)) throw new Error('Transaction needs outputs'); - const input = this.__inputs[vin]; + const input = this.__INPUTS[vin]; // if redeemScript was previously provided, enforce consistency if (input.redeemScript !== undefined && redeemScript && @@ -194,7 +128,7 @@ class TransactionBuilder { if (!canSign(input)) { if (witnessValue !== undefined) { if (input.value !== undefined && input.value !== witnessValue) - throw new Error("Input didn't match witnessValue"); + throw new Error('Input did not match witnessValue'); typeforce(types.Satoshi, witnessValue); input.value = witnessValue; } @@ -209,10 +143,10 @@ class TransactionBuilder { // ready to sign let signatureHash; if (input.hasWitness) { - signatureHash = this.__tx.hashForWitnessV0(vin, input.signScript, input.value, hashType); + signatureHash = this.__TX.hashForWitnessV0(vin, input.signScript, input.value, hashType); } else { - signatureHash = this.__tx.hashForSignature(vin, input.signScript, hashType); + signatureHash = this.__TX.hashForSignature(vin, input.signScript, hashType); } // enforce in order signing of public keys const signed = input.pubkeys.some((pubKey, i) => { @@ -231,8 +165,74 @@ class TransactionBuilder { if (!signed) throw new Error('Key pair cannot sign for this input'); } + __addInputUnsafe(txHash, vout, options) { + if (transaction_1.Transaction.isCoinbaseHash(txHash)) { + throw new Error('coinbase inputs not supported'); + } + const prevTxOut = txHash.toString('hex') + ':' + vout; + if (this.__PREV_TX_SET[prevTxOut] !== undefined) + throw new Error('Duplicate TxOut: ' + prevTxOut); + let input = {}; + // derive what we can from the scriptSig + if (options.script !== undefined) { + input = expandInput(options.script, options.witness || []); + } + // if an input value was given, retain it + if (options.value !== undefined) { + input.value = options.value; + } + // derive what we can from the previous transactions output script + if (!input.prevOutScript && options.prevOutScript) { + let prevOutType; + if (!input.pubkeys && !input.signatures) { + const expanded = expandOutput(options.prevOutScript); + if (expanded.pubkeys) { + input.pubkeys = expanded.pubkeys; + input.signatures = expanded.signatures; + } + prevOutType = expanded.type; + } + input.prevOutScript = options.prevOutScript; + input.prevOutType = prevOutType || classify.output(options.prevOutScript); + } + const vin = this.__TX.addInput(txHash, vout, options.sequence, options.scriptSig); + this.__INPUTS[vin] = input; + this.__PREV_TX_SET[prevTxOut] = true; + return vin; + } + __build(allowIncomplete) { + if (!allowIncomplete) { + if (!this.__TX.ins.length) + throw new Error('Transaction has no inputs'); + if (!this.__TX.outs.length) + throw new Error('Transaction has no outputs'); + } + const tx = this.__TX.clone(); + // create script signatures from inputs + this.__INPUTS.forEach((input, i) => { + if (!input.prevOutType && !allowIncomplete) + throw new Error('Transaction is not complete'); + const result = build(input.prevOutType, input, allowIncomplete); + if (!result) { + if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) + throw new Error('Unknown input type'); + if (!allowIncomplete) + throw new Error('Not enough information'); + return; + } + tx.setInputScript(i, result.input); + tx.setWitness(i, result.witness); + }); + if (!allowIncomplete) { + // do not rely on this, its merely a last resort + if (this.__overMaximumFees(tx.virtualSize())) { + throw new Error('Transaction has absurd fees'); + } + } + return tx; + } __canModifyInputs() { - return this.__inputs.every(input => { + return this.__INPUTS.every(input => { if (!input.signatures) return true; return input.signatures.every(signature => { @@ -247,12 +247,12 @@ class TransactionBuilder { } __needsOutputs(signingHashType) { if (signingHashType === transaction_1.Transaction.SIGHASH_ALL) { - return this.__tx.outs.length === 0; + return this.__TX.outs.length === 0; } // if inputs are being signed with SIGHASH_NONE, we don't strictly need outputs // .build() will fail, but .buildIncomplete() is OK - return (this.__tx.outs.length === 0 && - this.__inputs.some(input => { + return (this.__TX.outs.length === 0 && + this.__INPUTS.some(input => { if (!input.signatures) return false; return input.signatures.some(signature => { @@ -266,9 +266,9 @@ class TransactionBuilder { })); } __canModifyOutputs() { - const nInputs = this.__tx.ins.length; - const nOutputs = this.__tx.outs.length; - return this.__inputs.every(input => { + const nInputs = this.__TX.ins.length; + const nOutputs = this.__TX.outs.length; + return this.__INPUTS.every(input => { if (input.signatures === undefined) return true; return input.signatures.every(signature => { @@ -290,10 +290,10 @@ class TransactionBuilder { } __overMaximumFees(bytes) { // not all inputs will have .value defined - const incoming = this.__inputs.reduce((a, x) => a + (x.value >>> 0), 0); + const incoming = this.__INPUTS.reduce((a, x) => a + (x.value >>> 0), 0); // but all outputs do, and if we have any input value // we can immediately determine if the outputs are too small - const outgoing = this.__tx.outs.reduce((a, x) => a + x.value, 0); + const outgoing = this.__TX.outs.reduce((a, x) => a + x.value, 0); const fee = incoming - outgoing; const feeRate = fee / bytes; return feeRate > this.maximumFeeRate; @@ -350,8 +350,8 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) { }, { allowIncomplete: true }); return { prevOutType: SCRIPT_TYPES.P2MS, - pubkeys: pubkeys, - signatures: signatures, + pubkeys, + signatures, maxSignatures: m, }; } @@ -488,7 +488,9 @@ function expandOutput(script, ourPubKey) { } function prepareInput(input, ourPubKey, redeemScript, witnessScript) { if (redeemScript && witnessScript) { - const p2wsh = (payments.p2wsh({ redeem: { output: witnessScript } })); + const p2wsh = payments.p2wsh({ + redeem: { output: witnessScript }, + }); const p2wshAlt = payments.p2wsh({ output: redeemScript }); const p2sh = payments.p2sh({ redeem: { output: redeemScript } }); const p2shAlt = payments.p2sh({ redeem: p2wsh }); @@ -506,7 +508,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { if (input.signatures && input.signatures.some(x => x !== undefined)) { expanded.signatures = input.signatures; } - let signScript = witnessScript; + const signScript = witnessScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2SH(P2WSH(P2WPKH)) is a consensus failure'); return { @@ -579,7 +581,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { if (input.signatures && input.signatures.some(x => x !== undefined)) { expanded.signatures = input.signatures; } - let signScript = witnessScript; + const signScript = witnessScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2WSH(P2WPKH) is a consensus failure'); return { @@ -614,7 +616,8 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { } let signScript = input.prevOutScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) { - signScript = (payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output); + signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }) + .output; } return { prevOutType: expanded.type, @@ -630,7 +633,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { const prevOutScript = payments.p2pkh({ pubkey: ourPubKey }).output; return { prevOutType: SCRIPT_TYPES.P2PKH, - prevOutScript: prevOutScript, + prevOutScript, hasWitness: false, signScript: prevOutScript, signType: SCRIPT_TYPES.P2PKH, diff --git a/test/fixtures/transaction_builder.json b/test/fixtures/transaction_builder.json index a2ca5d7..24be3ba 100644 --- a/test/fixtures/transaction_builder.json +++ b/test/fixtures/transaction_builder.json @@ -1976,7 +1976,7 @@ "sign": [ { "description": "Transaction w/ witness value mismatch", - "exception": "Input didn\\'t match witnessValue", + "exception": "Input did not match witnessValue", "network": "testnet", "inputs": [ { diff --git a/test/transaction_builder.js b/test/transaction_builder.js index 574b669..3f84b19 100644 --- a/test/transaction_builder.js +++ b/test/transaction_builder.js @@ -164,7 +164,7 @@ describe('TransactionBuilder', function () { const tx = Transaction.fromHex(fixtures.valid.classification.hex) const txb = TransactionBuilder.fromTransaction(tx) - txb.__inputs.forEach(function (i) { + txb.__INPUTS.forEach(function (i) { assert.strictEqual(i.prevOutType, 'scripthash') assert.strictEqual(i.redeemScriptType, 'multisig') }) @@ -191,22 +191,22 @@ describe('TransactionBuilder', function () { const vin = txb.addInput(txHash, 1, 54) assert.strictEqual(vin, 0) - const txIn = txb.__tx.ins[0] + const txIn = txb.__TX.ins[0] assert.strictEqual(txIn.hash, txHash) assert.strictEqual(txIn.index, 1) assert.strictEqual(txIn.sequence, 54) - assert.strictEqual(txb.__inputs[0].prevOutScript, undefined) + assert.strictEqual(txb.__INPUTS[0].prevOutScript, undefined) }) it('accepts a txHash, index [, sequence number and scriptPubKey]', function () { const vin = txb.addInput(txHash, 1, 54, scripts[1]) assert.strictEqual(vin, 0) - const txIn = txb.__tx.ins[0] + const txIn = txb.__TX.ins[0] assert.strictEqual(txIn.hash, txHash) assert.strictEqual(txIn.index, 1) assert.strictEqual(txIn.sequence, 54) - assert.strictEqual(txb.__inputs[0].prevOutScript, scripts[1]) + assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1]) }) it('accepts a prevTx, index [and sequence number]', function () { @@ -217,11 +217,11 @@ describe('TransactionBuilder', function () { const vin = txb.addInput(prevTx, 1, 54) assert.strictEqual(vin, 0) - const txIn = txb.__tx.ins[0] + const txIn = txb.__TX.ins[0] assert.deepEqual(txIn.hash, prevTx.getHash()) assert.strictEqual(txIn.index, 1) assert.strictEqual(txIn.sequence, 54) - assert.strictEqual(txb.__inputs[0].prevOutScript, scripts[1]) + assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1]) }) it('returns the input index', function () { @@ -251,7 +251,7 @@ describe('TransactionBuilder', function () { const vout = txb.addOutput(address, 1000) assert.strictEqual(vout, 0) - const txout = txb.__tx.outs[0] + const txout = txb.__TX.outs[0] assert.deepEqual(txout.script, scripts[0]) assert.strictEqual(txout.value, 1000) }) @@ -260,7 +260,7 @@ describe('TransactionBuilder', function () { const vout = txb.addOutput(scripts[0], 1000) assert.strictEqual(vout, 0) - const txout = txb.__tx.outs[0] + const txout = txb.__TX.outs[0] assert.deepEqual(txout.script, scripts[0]) assert.strictEqual(txout.value, 1000) }) @@ -533,10 +533,10 @@ describe('TransactionBuilder', function () { '194a565cd6aa4cc38b8eaffa343402201c5b4b61d73fa38e49c1ee68cc0e6dfd2f5dae453dd86eb142e87a' + '0bafb1bc8401210283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f44800000000' const txb = TransactionBuilder.fromTransaction(Transaction.fromHex(rawtx)) - txb.__inputs[0].value = 241530 - txb.__inputs[1].value = 241530 - txb.__inputs[2].value = 248920 - txb.__inputs[3].value = 248920 + txb.__INPUTS[0].value = 241530 + txb.__INPUTS[1].value = 241530 + txb.__INPUTS[2].value = 248920 + txb.__INPUTS[3].value = 248920 assert.throws(function () { txb.build() diff --git a/ts_src/transaction_builder.ts b/ts_src/transaction_builder.ts index a3bd9e6..4c939e1 100644 --- a/ts_src/transaction_builder.ts +++ b/ts_src/transaction_builder.ts @@ -1,24 +1,25 @@ -import { Network } from './networks'; -import * as networks from './networks'; +import * as baddress from './address'; import { reverseBuffer } from './bufferutils'; -import { Transaction, Output } from './transaction'; +import * as classify from './classify'; +import * as bcrypto from './crypto'; import { ECPairInterface } from './ecpair'; import * as ECPair from './ecpair'; -import * as types from './types'; -import * as baddress from './address'; -import * as bcrypto from './crypto'; -import * as bscript from './script'; +import { Network } from './networks'; +import * as networks from './networks'; import { Payment } from './payments'; import * as payments from './payments'; -import * as classify from './classify'; +import * as bscript from './script'; import { OPS as ops } from './script'; +import { Output, Transaction } from './transaction'; +import * as types from './types'; const typeforce = require('typeforce'); const SCRIPT_TYPES = classify.types; -type TxbSignatures = Array | Array; -type TxbPubkeys = Array; -type TxbWitness = Array; +type MaybeBuffer = Buffer | undefined; +type TxbSignatures = Buffer[] | MaybeBuffer[]; +type TxbPubkeys = MaybeBuffer[]; +type TxbWitness = Buffer[]; type TxbScriptType = string; type TxbScript = Buffer; @@ -58,24 +59,6 @@ function txIsTransaction(tx: Buffer | string | Transaction): tx is Transaction { } export class TransactionBuilder { - network: Network; - maximumFeeRate: number; - private __prevTxSet: { [index: string]: boolean }; - private __inputs: Array; - private __tx: Transaction; - - constructor(network?: Network, maximumFeeRate?: number) { - this.__prevTxSet = {}; - this.network = network || networks.bitcoin; - - // WARNING: This is __NOT__ to be relied on, its just another potential safety mechanism (safety in-depth) - this.maximumFeeRate = maximumFeeRate || 2500; - - this.__inputs = []; - this.__tx = new Transaction(); - this.__tx.version = 2; - } - static fromTransaction( transaction: Transaction, network?: Network, @@ -88,7 +71,7 @@ export class TransactionBuilder { // Copy outputs (done first to avoid signature invalidation) transaction.outs.forEach(txOut => { - txb.addOutput(txOut.script, (txOut).value); + txb.addOutput(txOut.script, (txOut as Output).value); }); // Copy inputs @@ -101,19 +84,37 @@ export class TransactionBuilder { }); // fix some things not possible through the public API - txb.__inputs.forEach((input, i) => { + txb.__INPUTS.forEach((input, i) => { fixMultisigOrder(input, transaction, i); }); return txb; } + network: Network; + maximumFeeRate: number; + private __PREV_TX_SET: { [index: string]: boolean }; + private __INPUTS: TxbInput[]; + private __TX: Transaction; + + constructor(network?: Network, maximumFeeRate?: number) { + this.__PREV_TX_SET = {}; + this.network = network || networks.bitcoin; + + // WARNING: This is __NOT__ to be relied on, its just another potential safety mechanism (safety in-depth) + this.maximumFeeRate = maximumFeeRate || 2500; + + this.__INPUTS = []; + this.__TX = new Transaction(); + this.__TX.version = 2; + } + setLockTime(locktime: number): void { typeforce(types.UInt32, locktime); // if any signatures exist, throw if ( - this.__inputs.some(input => { + this.__INPUTS.some(input => { if (!input.signatures) return false; return input.signatures.some(s => s !== undefined); @@ -122,14 +123,14 @@ export class TransactionBuilder { throw new Error('No, this would invalidate signatures'); } - this.__tx.locktime = locktime; + this.__TX.locktime = locktime; } setVersion(version: number): void { typeforce(types.UInt32, version); // XXX: this might eventually become more complex depending on what the versions represent - this.__tx.version = version; + this.__TX.version = version; } addInput( @@ -142,7 +143,7 @@ export class TransactionBuilder { throw new Error('No, this would invalidate signatures'); } - let value: number | undefined = undefined; + let value: number | undefined; // is it a hex string? if (txIsString(txHash)) { @@ -153,72 +154,18 @@ export class TransactionBuilder { } else if (txIsTransaction(txHash)) { const txOut = txHash.outs[vout]; prevOutScript = txOut.script; - value = (txOut).value; + value = (txOut as Output).value; - txHash = txHash.getHash(false); + txHash = txHash.getHash(false) as Buffer; } return this.__addInputUnsafe(txHash, vout, { - sequence: sequence, - prevOutScript: prevOutScript, - value: value, + sequence, + prevOutScript, + value, }); } - private __addInputUnsafe( - txHash: Buffer, - vout: number, - options: TxbInput, - ): number { - if (Transaction.isCoinbaseHash(txHash)) { - throw new Error('coinbase inputs not supported'); - } - - const prevTxOut = txHash.toString('hex') + ':' + vout; - if (this.__prevTxSet[prevTxOut] !== undefined) - throw new Error('Duplicate TxOut: ' + prevTxOut); - - let input = {}; - - // derive what we can from the scriptSig - if (options.script !== undefined) { - input = expandInput(options.script, options.witness || []); - } - - // if an input value was given, retain it - if (options.value !== undefined) { - input.value = options.value; - } - - // derive what we can from the previous transactions output script - if (!input.prevOutScript && options.prevOutScript) { - let prevOutType; - - if (!input.pubkeys && !input.signatures) { - const expanded = expandOutput(options.prevOutScript); - if (expanded.pubkeys) { - input.pubkeys = expanded.pubkeys; - input.signatures = expanded.signatures; - } - - prevOutType = expanded.type; - } - - input.prevOutScript = options.prevOutScript; - input.prevOutType = prevOutType || classify.output(options.prevOutScript); - } - - const vin = this.__tx.addInput( - txHash, - vout, - options.sequence, - options.scriptSig, - ); - this.__inputs[vin] = input; - this.__prevTxSet[prevTxOut] = true; - return vin; - } - addOutput(scriptPubKey: string | Buffer, value: number): number { if (!this.__canModifyOutputs()) { throw new Error('No, this would invalidate signatures'); @@ -229,7 +176,7 @@ export class TransactionBuilder { scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network); } - return this.__tx.addOutput(scriptPubKey, value); + return this.__TX.addOutput(scriptPubKey, value); } build(): Transaction { @@ -240,41 +187,6 @@ export class TransactionBuilder { return this.__build(true); } - private __build(allowIncomplete?: boolean): Transaction { - if (!allowIncomplete) { - if (!this.__tx.ins.length) throw new Error('Transaction has no inputs'); - if (!this.__tx.outs.length) throw new Error('Transaction has no outputs'); - } - - const tx = this.__tx.clone(); - - // create script signatures from inputs - this.__inputs.forEach((input, i) => { - if (!input.prevOutType && !allowIncomplete) - throw new Error('Transaction is not complete'); - - const result = build(input.prevOutType!, input, allowIncomplete); - if (!result) { - if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) - throw new Error('Unknown input type'); - if (!allowIncomplete) throw new Error('Not enough information'); - return; - } - - tx.setInputScript(i, result.input!); - tx.setWitness(i, result.witness!); - }); - - if (!allowIncomplete) { - // do not rely on this, its merely a last resort - if (this.__overMaximumFees(tx.virtualSize())) { - throw new Error('Transaction has absurd fees'); - } - } - - return tx; - } - sign( vin: number, keyPair: ECPairInterface, @@ -286,13 +198,13 @@ export class TransactionBuilder { // TODO: remove keyPair.network matching in 4.0.0 if (keyPair.network && keyPair.network !== this.network) throw new TypeError('Inconsistent network'); - if (!this.__inputs[vin]) throw new Error('No input at index: ' + vin); + if (!this.__INPUTS[vin]) throw new Error('No input at index: ' + vin); hashType = hashType || Transaction.SIGHASH_ALL; if (this.__needsOutputs(hashType)) throw new Error('Transaction needs outputs'); - const input = this.__inputs[vin]; + const input = this.__INPUTS[vin]; // if redeemScript was previously provided, enforce consistency if ( @@ -307,7 +219,7 @@ export class TransactionBuilder { if (!canSign(input)) { if (witnessValue !== undefined) { if (input.value !== undefined && input.value !== witnessValue) - throw new Error("Input didn't match witnessValue"); + throw new Error('Input did not match witnessValue'); typeforce(types.Satoshi, witnessValue); input.value = witnessValue; } @@ -330,16 +242,16 @@ export class TransactionBuilder { // ready to sign let signatureHash: Buffer; if (input.hasWitness) { - signatureHash = this.__tx.hashForWitnessV0( + signatureHash = this.__TX.hashForWitnessV0( vin, - input.signScript, - input.value, + input.signScript as Buffer, + input.value as number, hashType, ); } else { - signatureHash = this.__tx.hashForSignature( + signatureHash = this.__TX.hashForSignature( vin, - input.signScript, + input.signScript as Buffer, hashType, ); } @@ -364,8 +276,97 @@ export class TransactionBuilder { if (!signed) throw new Error('Key pair cannot sign for this input'); } + private __addInputUnsafe( + txHash: Buffer, + vout: number, + options: TxbInput, + ): number { + if (Transaction.isCoinbaseHash(txHash)) { + throw new Error('coinbase inputs not supported'); + } + + const prevTxOut = txHash.toString('hex') + ':' + vout; + if (this.__PREV_TX_SET[prevTxOut] !== undefined) + throw new Error('Duplicate TxOut: ' + prevTxOut); + + let input: TxbInput = {}; + + // derive what we can from the scriptSig + if (options.script !== undefined) { + input = expandInput(options.script, options.witness || []); + } + + // if an input value was given, retain it + if (options.value !== undefined) { + input.value = options.value; + } + + // derive what we can from the previous transactions output script + if (!input.prevOutScript && options.prevOutScript) { + let prevOutType; + + if (!input.pubkeys && !input.signatures) { + const expanded = expandOutput(options.prevOutScript); + if (expanded.pubkeys) { + input.pubkeys = expanded.pubkeys; + input.signatures = expanded.signatures; + } + + prevOutType = expanded.type; + } + + input.prevOutScript = options.prevOutScript; + input.prevOutType = prevOutType || classify.output(options.prevOutScript); + } + + const vin = this.__TX.addInput( + txHash, + vout, + options.sequence, + options.scriptSig, + ); + this.__INPUTS[vin] = input; + this.__PREV_TX_SET[prevTxOut] = true; + return vin; + } + + private __build(allowIncomplete?: boolean): Transaction { + if (!allowIncomplete) { + if (!this.__TX.ins.length) throw new Error('Transaction has no inputs'); + if (!this.__TX.outs.length) throw new Error('Transaction has no outputs'); + } + + const tx = this.__TX.clone(); + + // create script signatures from inputs + this.__INPUTS.forEach((input, i) => { + if (!input.prevOutType && !allowIncomplete) + throw new Error('Transaction is not complete'); + + const result = build(input.prevOutType!, input, allowIncomplete); + if (!result) { + if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) + throw new Error('Unknown input type'); + if (!allowIncomplete) throw new Error('Not enough information'); + return; + } + + tx.setInputScript(i, result.input!); + tx.setWitness(i, result.witness!); + }); + + if (!allowIncomplete) { + // do not rely on this, its merely a last resort + if (this.__overMaximumFees(tx.virtualSize())) { + throw new Error('Transaction has absurd fees'); + } + } + + return tx; + } + private __canModifyInputs(): boolean { - return this.__inputs.every(input => { + return this.__INPUTS.every(input => { if (!input.signatures) return true; return input.signatures.every(signature => { @@ -381,14 +382,14 @@ export class TransactionBuilder { private __needsOutputs(signingHashType: number): boolean { if (signingHashType === Transaction.SIGHASH_ALL) { - return this.__tx.outs.length === 0; + return this.__TX.outs.length === 0; } // if inputs are being signed with SIGHASH_NONE, we don't strictly need outputs // .build() will fail, but .buildIncomplete() is OK return ( - this.__tx.outs.length === 0 && - this.__inputs.some(input => { + this.__TX.outs.length === 0 && + this.__INPUTS.some(input => { if (!input.signatures) return false; return input.signatures.some(signature => { @@ -402,10 +403,10 @@ export class TransactionBuilder { } private __canModifyOutputs(): boolean { - const nInputs = this.__tx.ins.length; - const nOutputs = this.__tx.outs.length; + const nInputs = this.__TX.ins.length; + const nOutputs = this.__TX.outs.length; - return this.__inputs.every(input => { + return this.__INPUTS.every(input => { if (input.signatures === undefined) return true; return input.signatures.every(signature => { @@ -427,11 +428,14 @@ export class TransactionBuilder { private __overMaximumFees(bytes: number): boolean { // not all inputs will have .value defined - const incoming = this.__inputs.reduce((a, x) => a + (x.value! >>> 0), 0); + const incoming = this.__INPUTS.reduce((a, x) => a + (x.value! >>> 0), 0); // but all outputs do, and if we have any input value // we can immediately determine if the outputs are too small - const outgoing = this.__tx.outs.reduce((a, x) => a + (x).value, 0); + const outgoing = this.__TX.outs.reduce( + (a, x) => a + (x as Output).value, + 0, + ); const fee = incoming - outgoing; const feeRate = fee / bytes; @@ -441,7 +445,7 @@ export class TransactionBuilder { function expandInput( scriptSig: Buffer, - witnessStack: Array, + witnessStack: Buffer[], type?: string, scriptPubKey?: Buffer, ): TxbInput { @@ -502,8 +506,8 @@ function expandInput( return { prevOutType: SCRIPT_TYPES.P2MS, - pubkeys: pubkeys, - signatures: signatures, + pubkeys, + signatures, maxSignatures: m, }; } @@ -681,12 +685,12 @@ function prepareInput( witnessScript: Buffer, ): TxbInput { if (redeemScript && witnessScript) { - const p2wsh = ( - payments.p2wsh({ redeem: { output: witnessScript } }) - ); - const p2wshAlt = payments.p2wsh({ output: redeemScript }); - const p2sh = payments.p2sh({ redeem: { output: redeemScript } }); - const p2shAlt = payments.p2sh({ redeem: p2wsh }); + const p2wsh = payments.p2wsh({ + redeem: { output: witnessScript }, + }) as Payment; + const p2wshAlt = payments.p2wsh({ output: redeemScript }) as Payment; + const p2sh = payments.p2sh({ redeem: { output: redeemScript } }) as Payment; + const p2shAlt = payments.p2sh({ redeem: p2wsh }) as Payment; // enforces P2SH(P2WSH(...)) if (!p2wsh.hash!.equals(p2wshAlt.hash!)) @@ -706,7 +710,7 @@ function prepareInput( expanded.signatures = input.signatures; } - let signScript = witnessScript; + const signScript = witnessScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2SH(P2WSH(P2WPKH)) is a consensus failure'); @@ -731,12 +735,12 @@ function prepareInput( } if (redeemScript) { - const p2sh = payments.p2sh({ redeem: { output: redeemScript } }); + const p2sh = payments.p2sh({ redeem: { output: redeemScript } }) as Payment; if (input.prevOutScript) { let p2shAlt; try { - p2shAlt = payments.p2sh({ output: input.prevOutScript }); + p2shAlt = payments.p2sh({ output: input.prevOutScript }) as Payment; } catch (e) { throw new Error('PrevOutScript must be P2SH'); } @@ -799,7 +803,7 @@ function prepareInput( expanded.signatures = input.signatures; } - let signScript = witnessScript; + const signScript = witnessScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) throw new Error('P2WSH(P2WPKH) is a consensus failure'); @@ -846,9 +850,8 @@ function prepareInput( let signScript = input.prevOutScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) { - signScript = ( - payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output - ); + signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }) + .output as Buffer; } return { @@ -868,7 +871,7 @@ function prepareInput( const prevOutScript = payments.p2pkh({ pubkey: ourPubKey }).output; return { prevOutType: SCRIPT_TYPES.P2PKH, - prevOutScript: prevOutScript, + prevOutScript, hasWitness: false, signScript: prevOutScript, @@ -884,8 +887,8 @@ function build( input: TxbInput, allowIncomplete?: boolean, ): Payment | undefined { - const pubkeys = >(input.pubkeys || []); - let signatures = >(input.signatures || []); + const pubkeys = (input.pubkeys || []) as Buffer[]; + let signatures = (input.signatures || []) as Buffer[]; switch (type) { case SCRIPT_TYPES.P2PKH: { diff --git a/types/transaction_builder.d.ts b/types/transaction_builder.d.ts index 4be5968..b3dedb3 100644 --- a/types/transaction_builder.d.ts +++ b/types/transaction_builder.d.ts @@ -1,24 +1,24 @@ /// +import { ECPairInterface } from './ecpair'; import { Network } from './networks'; import { Transaction } from './transaction'; -import { ECPairInterface } from './ecpair'; export declare class TransactionBuilder { + static fromTransaction(transaction: Transaction, network?: Network): TransactionBuilder; network: Network; maximumFeeRate: number; - private __prevTxSet; - private __inputs; - private __tx; + private __PREV_TX_SET; + private __INPUTS; + private __TX; constructor(network?: Network, maximumFeeRate?: number); - static fromTransaction(transaction: Transaction, network?: Network): TransactionBuilder; setLockTime(locktime: number): void; setVersion(version: number): void; addInput(txHash: Buffer | string | Transaction, vout: number, sequence: number, prevOutScript: Buffer): number; - private __addInputUnsafe; addOutput(scriptPubKey: string | Buffer, value: number): number; build(): Transaction; buildIncomplete(): Transaction; - private __build; sign(vin: number, keyPair: ECPairInterface, redeemScript: Buffer, hashType: number, witnessValue: number, witnessScript: Buffer): void; + private __addInputUnsafe; + private __build; private __canModifyInputs; private __needsOutputs; private __canModifyOutputs; From 08c4d6ac7dae7a8d61ded59f64bab68ad7f39f92 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 14:16:45 +0900 Subject: [PATCH 20/22] Fix lint for templates --- src/templates/multisig/input.js | 2 +- src/templates/multisig/output.js | 4 ++-- src/templates/nulldata.js | 2 +- src/templates/pubkey/input.js | 5 +++-- src/templates/pubkey/output.js | 2 +- src/templates/pubkeyhash/input.js | 2 +- src/templates/pubkeyhash/output.js | 2 +- src/templates/scripthash/input.js | 2 +- src/templates/scripthash/output.js | 2 +- src/templates/witnesscommitment/output.js | 4 ++-- src/templates/witnesspubkeyhash/input.js | 2 +- src/templates/witnesspubkeyhash/output.js | 2 +- src/templates/witnessscripthash/input.js | 2 +- src/templates/witnessscripthash/output.js | 2 +- ts_src/templates/multisig/input.ts | 11 ++++++----- ts_src/templates/multisig/output.ts | 15 ++++++++------- ts_src/templates/nulldata.ts | 2 +- ts_src/templates/pubkey/input.ts | 10 ++++++---- ts_src/templates/pubkey/output.ts | 9 +++++---- ts_src/templates/pubkeyhash/input.ts | 11 ++++++----- ts_src/templates/pubkeyhash/output.ts | 2 +- ts_src/templates/scripthash/input.ts | 2 +- ts_src/templates/scripthash/output.ts | 2 +- ts_src/templates/witnesscommitment/output.ts | 6 +++--- ts_src/templates/witnesspubkeyhash/input.ts | 11 ++++++----- ts_src/templates/witnesspubkeyhash/output.ts | 2 +- ts_src/templates/witnessscripthash/input.ts | 7 ++----- ts_src/templates/witnessscripthash/output.ts | 2 +- types/templates/multisig/input.d.ts | 3 ++- types/templates/multisig/output.d.ts | 3 ++- types/templates/pubkey/input.d.ts | 3 ++- types/templates/pubkey/output.d.ts | 3 ++- types/templates/pubkeyhash/input.d.ts | 3 ++- types/templates/witnesspubkeyhash/input.d.ts | 3 ++- types/templates/witnessscripthash/input.d.ts | 2 +- 35 files changed, 79 insertions(+), 68 deletions(-) diff --git a/src/templates/multisig/input.js b/src/templates/multisig/input.js index 24a9710..4b4f395 100644 --- a/src/templates/multisig/input.js +++ b/src/templates/multisig/input.js @@ -18,6 +18,6 @@ function check(script, allowIncomplete) { return chunks.slice(1).every(bscript.isCanonicalScriptSignature); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'multisig input'; }; diff --git a/src/templates/multisig/output.js b/src/templates/multisig/output.js index 64d07bc..c79fe9b 100644 --- a/src/templates/multisig/output.js +++ b/src/templates/multisig/output.js @@ -2,8 +2,8 @@ // m [pubKeys ...] n OP_CHECKMULTISIG Object.defineProperty(exports, "__esModule", { value: true }); const bscript = require("../../script"); -const types = require("../../types"); const script_1 = require("../../script"); +const types = require("../../types"); const OP_INT_BASE = script_1.OPS.OP_RESERVED; // OP_1 - 1 function check(script, allowIncomplete) { const chunks = bscript.decompile(script); @@ -31,6 +31,6 @@ function check(script, allowIncomplete) { return keys.every(bscript.isCanonicalPubKey); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'multi-sig output'; }; diff --git a/src/templates/nulldata.js b/src/templates/nulldata.js index b5ffdce..29bee7a 100644 --- a/src/templates/nulldata.js +++ b/src/templates/nulldata.js @@ -8,7 +8,7 @@ function check(script) { return buffer.length > 1 && buffer[0] === OPS.OP_RETURN; } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'null data output'; }; const output = { check }; diff --git a/src/templates/pubkey/input.js b/src/templates/pubkey/input.js index 10d3c07..479fdc5 100644 --- a/src/templates/pubkey/input.js +++ b/src/templates/pubkey/input.js @@ -4,9 +4,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); const bscript = require("../../script"); function check(script) { const chunks = bscript.decompile(script); - return (chunks.length === 1 && bscript.isCanonicalScriptSignature(chunks[0])); + return (chunks.length === 1 && + bscript.isCanonicalScriptSignature(chunks[0])); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'pubKey input'; }; diff --git a/src/templates/pubkey/output.js b/src/templates/pubkey/output.js index e2f87c2..1f17990 100644 --- a/src/templates/pubkey/output.js +++ b/src/templates/pubkey/output.js @@ -10,6 +10,6 @@ function check(script) { chunks[1] === script_1.OPS.OP_CHECKSIG); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'pubKey output'; }; diff --git a/src/templates/pubkeyhash/input.js b/src/templates/pubkeyhash/input.js index f03d391..7de30ec 100644 --- a/src/templates/pubkeyhash/input.js +++ b/src/templates/pubkeyhash/input.js @@ -9,6 +9,6 @@ function check(script) { bscript.isCanonicalPubKey(chunks[1])); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'pubKeyHash input'; }; diff --git a/src/templates/pubkeyhash/output.js b/src/templates/pubkeyhash/output.js index 222244b..5ee692b 100644 --- a/src/templates/pubkeyhash/output.js +++ b/src/templates/pubkeyhash/output.js @@ -13,6 +13,6 @@ function check(script) { buffer[24] === script_1.OPS.OP_CHECKSIG); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'pubKeyHash output'; }; diff --git a/src/templates/scripthash/input.js b/src/templates/scripthash/input.js index 5d2b576..488b931 100644 --- a/src/templates/scripthash/input.js +++ b/src/templates/scripthash/input.js @@ -39,6 +39,6 @@ function check(script, allowIncomplete) { return false; } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'scriptHash input'; }; diff --git a/src/templates/scripthash/output.js b/src/templates/scripthash/output.js index 5fd2f65..bf1246a 100644 --- a/src/templates/scripthash/output.js +++ b/src/templates/scripthash/output.js @@ -11,6 +11,6 @@ function check(script) { buffer[22] === script_1.OPS.OP_EQUAL); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'scriptHash output'; }; diff --git a/src/templates/witnesscommitment/output.js b/src/templates/witnesscommitment/output.js index 38f622a..f4d6af0 100644 --- a/src/templates/witnesscommitment/output.js +++ b/src/templates/witnesscommitment/output.js @@ -2,9 +2,9 @@ // OP_RETURN {aa21a9ed} {commitment} Object.defineProperty(exports, "__esModule", { value: true }); const bscript = require("../../script"); +const script_1 = require("../../script"); const types = require("../../types"); const typeforce = require('typeforce'); -const script_1 = require("../../script"); const HEADER = Buffer.from('aa21a9ed', 'hex'); function check(script) { const buffer = bscript.compile(script); @@ -14,7 +14,7 @@ function check(script) { buffer.slice(2, 6).equals(HEADER)); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'Witness commitment output'; }; function encode(commitment) { diff --git a/src/templates/witnesspubkeyhash/input.js b/src/templates/witnesspubkeyhash/input.js index 4585623..3d589e9 100644 --- a/src/templates/witnesspubkeyhash/input.js +++ b/src/templates/witnesspubkeyhash/input.js @@ -12,6 +12,6 @@ function check(script) { isCompressedCanonicalPubKey(chunks[1])); } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'witnessPubKeyHash input'; }; diff --git a/src/templates/witnesspubkeyhash/output.js b/src/templates/witnesspubkeyhash/output.js index 9c508a0..69aab11 100644 --- a/src/templates/witnesspubkeyhash/output.js +++ b/src/templates/witnesspubkeyhash/output.js @@ -8,6 +8,6 @@ function check(script) { return buffer.length === 22 && buffer[0] === script_1.OPS.OP_0 && buffer[1] === 0x14; } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'Witness pubKeyHash output'; }; diff --git a/src/templates/witnessscripthash/input.js b/src/templates/witnessscripthash/input.js index ca8c8b6..3f5c002 100644 --- a/src/templates/witnessscripthash/input.js +++ b/src/templates/witnessscripthash/input.js @@ -31,6 +31,6 @@ function check(chunks, allowIncomplete) { return false; } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'witnessScriptHash input'; }; diff --git a/src/templates/witnessscripthash/output.js b/src/templates/witnessscripthash/output.js index f283b86..a6d4d95 100644 --- a/src/templates/witnessscripthash/output.js +++ b/src/templates/witnessscripthash/output.js @@ -8,6 +8,6 @@ function check(script) { return buffer.length === 34 && buffer[0] === script_1.OPS.OP_0 && buffer[1] === 0x20; } exports.check = check; -check.toJSON = function () { +check.toJSON = () => { return 'Witness scriptHash output'; }; diff --git a/ts_src/templates/multisig/input.ts b/ts_src/templates/multisig/input.ts index 222ff10..57b73d2 100644 --- a/ts_src/templates/multisig/input.ts +++ b/ts_src/templates/multisig/input.ts @@ -1,19 +1,20 @@ // OP_0 [signatures ...] +import { Stack } from '../../payments'; import * as bscript from '../../script'; import { OPS } from '../../script'; function partialSignature(value: number | Buffer): boolean { return ( - value === OPS.OP_0 || bscript.isCanonicalScriptSignature(value) + value === OPS.OP_0 || bscript.isCanonicalScriptSignature(value as Buffer) ); } export function check( - script: Buffer | Array, + script: Buffer | Stack, allowIncomplete?: boolean, ): boolean { - const chunks = >bscript.decompile(script); + const chunks = bscript.decompile(script) as Stack; if (chunks.length < 2) return false; if (chunks[0] !== OPS.OP_0) return false; @@ -21,10 +22,10 @@ export function check( return chunks.slice(1).every(partialSignature); } - return (>chunks.slice(1)).every( + return (chunks.slice(1) as Buffer[]).every( bscript.isCanonicalScriptSignature, ); } -check.toJSON = function() { +check.toJSON = () => { return 'multisig input'; }; diff --git a/ts_src/templates/multisig/output.ts b/ts_src/templates/multisig/output.ts index 040649b..3ee0820 100644 --- a/ts_src/templates/multisig/output.ts +++ b/ts_src/templates/multisig/output.ts @@ -1,22 +1,23 @@ // m [pubKeys ...] n OP_CHECKMULTISIG +import { Stack } from '../../payments'; import * as bscript from '../../script'; -import * as types from '../../types'; import { OPS } from '../../script'; +import * as types from '../../types'; const OP_INT_BASE = OPS.OP_RESERVED; // OP_1 - 1 export function check( - script: Buffer | Array, + script: Buffer | Stack, allowIncomplete?: boolean, ): boolean { - const chunks = >bscript.decompile(script); + const chunks = bscript.decompile(script) as Stack; if (chunks.length < 4) return false; if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) return false; if (!types.Number(chunks[0])) return false; if (!types.Number(chunks[chunks.length - 2])) return false; - const m = chunks[0] - OP_INT_BASE; - const n = chunks[chunks.length - 2] - OP_INT_BASE; + const m = (chunks[0] as number) - OP_INT_BASE; + const n = (chunks[chunks.length - 2] as number) - OP_INT_BASE; if (m <= 0) return false; if (n > 16) return false; @@ -24,9 +25,9 @@ export function check( if (n !== chunks.length - 3) return false; if (allowIncomplete) return true; - const keys = >chunks.slice(1, -2); + const keys = chunks.slice(1, -2) as Buffer[]; return keys.every(bscript.isCanonicalPubKey); } -check.toJSON = function() { +check.toJSON = () => { return 'multi-sig output'; }; diff --git a/ts_src/templates/nulldata.ts b/ts_src/templates/nulldata.ts index f0694a3..bafe4a4 100644 --- a/ts_src/templates/nulldata.ts +++ b/ts_src/templates/nulldata.ts @@ -7,7 +7,7 @@ export function check(script: Buffer | Array): boolean { return buffer.length > 1 && buffer[0] === OPS.OP_RETURN; } -check.toJSON = function() { +check.toJSON = () => { return 'null data output'; }; diff --git a/ts_src/templates/pubkey/input.ts b/ts_src/templates/pubkey/input.ts index e9ea1be..7e07a94 100644 --- a/ts_src/templates/pubkey/input.ts +++ b/ts_src/templates/pubkey/input.ts @@ -1,14 +1,16 @@ // {signature} +import { Stack } from '../../payments'; import * as bscript from '../../script'; -export function check(script: Buffer | Array): boolean { - const chunks = >bscript.decompile(script); +export function check(script: Buffer | Stack): boolean { + const chunks = bscript.decompile(script) as Stack; return ( - chunks.length === 1 && bscript.isCanonicalScriptSignature(chunks[0]) + chunks.length === 1 && + bscript.isCanonicalScriptSignature(chunks[0] as Buffer) ); } -check.toJSON = function() { +check.toJSON = () => { return 'pubKey input'; }; diff --git a/ts_src/templates/pubkey/output.ts b/ts_src/templates/pubkey/output.ts index 8378870..d57422d 100644 --- a/ts_src/templates/pubkey/output.ts +++ b/ts_src/templates/pubkey/output.ts @@ -1,17 +1,18 @@ // {pubKey} OP_CHECKSIG +import { Stack } from '../../payments'; import * as bscript from '../../script'; import { OPS } from '../../script'; -export function check(script: Buffer | Array): boolean { - const chunks = >bscript.decompile(script); +export function check(script: Buffer | Stack): boolean { + const chunks = bscript.decompile(script) as Stack; return ( chunks.length === 2 && - bscript.isCanonicalPubKey(chunks[0]) && + bscript.isCanonicalPubKey(chunks[0] as Buffer) && chunks[1] === OPS.OP_CHECKSIG ); } -check.toJSON = function() { +check.toJSON = () => { return 'pubKey output'; }; diff --git a/ts_src/templates/pubkeyhash/input.ts b/ts_src/templates/pubkeyhash/input.ts index c091764..83da475 100644 --- a/ts_src/templates/pubkeyhash/input.ts +++ b/ts_src/templates/pubkeyhash/input.ts @@ -1,16 +1,17 @@ // {signature} {pubKey} +import { Stack } from '../../payments'; import * as bscript from '../../script'; -export function check(script: Buffer | Array): boolean { - const chunks = >bscript.decompile(script); +export function check(script: Buffer | Stack): boolean { + const chunks = bscript.decompile(script) as Stack; return ( chunks.length === 2 && - bscript.isCanonicalScriptSignature(chunks[0]) && - bscript.isCanonicalPubKey(chunks[1]) + bscript.isCanonicalScriptSignature(chunks[0] as Buffer) && + bscript.isCanonicalPubKey(chunks[1] as Buffer) ); } -check.toJSON = function() { +check.toJSON = () => { return 'pubKeyHash input'; }; diff --git a/ts_src/templates/pubkeyhash/output.ts b/ts_src/templates/pubkeyhash/output.ts index a5c5c9b..37070a3 100644 --- a/ts_src/templates/pubkeyhash/output.ts +++ b/ts_src/templates/pubkeyhash/output.ts @@ -15,6 +15,6 @@ export function check(script: Buffer | Array): boolean { buffer[24] === OPS.OP_CHECKSIG ); } -check.toJSON = function() { +check.toJSON = () => { return 'pubKeyHash output'; }; diff --git a/ts_src/templates/scripthash/input.ts b/ts_src/templates/scripthash/input.ts index 0b86d63..1e3f97d 100644 --- a/ts_src/templates/scripthash/input.ts +++ b/ts_src/templates/scripthash/input.ts @@ -56,6 +56,6 @@ export function check( return false; } -check.toJSON = function() { +check.toJSON = () => { return 'scriptHash input'; }; diff --git a/ts_src/templates/scripthash/output.ts b/ts_src/templates/scripthash/output.ts index 6ff138a..7eac30d 100644 --- a/ts_src/templates/scripthash/output.ts +++ b/ts_src/templates/scripthash/output.ts @@ -13,6 +13,6 @@ export function check(script: Buffer | Array): boolean { buffer[22] === OPS.OP_EQUAL ); } -check.toJSON = function() { +check.toJSON = () => { return 'scriptHash output'; }; diff --git a/ts_src/templates/witnesscommitment/output.ts b/ts_src/templates/witnesscommitment/output.ts index 29beb39..9439e4c 100644 --- a/ts_src/templates/witnesscommitment/output.ts +++ b/ts_src/templates/witnesscommitment/output.ts @@ -1,10 +1,10 @@ // OP_RETURN {aa21a9ed} {commitment} import * as bscript from '../../script'; +import { OPS } from '../../script'; import * as types from '../../types'; const typeforce = require('typeforce'); -import { OPS } from '../../script'; const HEADER: Buffer = Buffer.from('aa21a9ed', 'hex'); @@ -19,7 +19,7 @@ export function check(script: Buffer | Array): boolean { ); } -check.toJSON = function() { +check.toJSON = () => { return 'Witness commitment output'; }; @@ -36,5 +36,5 @@ export function encode(commitment: Buffer): Buffer { export function decode(buffer: Buffer): Buffer { typeforce(check, buffer); - return (bscript.decompile(buffer)![1]).slice(4, 36); + return (bscript.decompile(buffer)![1] as Buffer).slice(4, 36); } diff --git a/ts_src/templates/witnesspubkeyhash/input.ts b/ts_src/templates/witnesspubkeyhash/input.ts index 22fc2cf..aa3bef8 100644 --- a/ts_src/templates/witnesspubkeyhash/input.ts +++ b/ts_src/templates/witnesspubkeyhash/input.ts @@ -1,20 +1,21 @@ // {signature} {pubKey} +import { Stack } from '../../payments'; import * as bscript from '../../script'; function isCompressedCanonicalPubKey(pubKey: Buffer): boolean { return bscript.isCanonicalPubKey(pubKey) && pubKey.length === 33; } -export function check(script: Buffer | Array): boolean { - const chunks = >bscript.decompile(script); +export function check(script: Buffer | Stack): boolean { + const chunks = bscript.decompile(script) as Stack; return ( chunks.length === 2 && - bscript.isCanonicalScriptSignature(chunks[0]) && - isCompressedCanonicalPubKey(chunks[1]) + bscript.isCanonicalScriptSignature(chunks[0] as Buffer) && + isCompressedCanonicalPubKey(chunks[1] as Buffer) ); } -check.toJSON = function() { +check.toJSON = () => { return 'witnessPubKeyHash input'; }; diff --git a/ts_src/templates/witnesspubkeyhash/output.ts b/ts_src/templates/witnesspubkeyhash/output.ts index 09c49d0..0e9432c 100644 --- a/ts_src/templates/witnesspubkeyhash/output.ts +++ b/ts_src/templates/witnesspubkeyhash/output.ts @@ -8,6 +8,6 @@ export function check(script: Buffer | Array): boolean { return buffer.length === 22 && buffer[0] === OPS.OP_0 && buffer[1] === 0x14; } -check.toJSON = function() { +check.toJSON = () => { return 'Witness pubKeyHash output'; }; diff --git a/ts_src/templates/witnessscripthash/input.ts b/ts_src/templates/witnessscripthash/input.ts index 6cf35bf..42a13ac 100644 --- a/ts_src/templates/witnessscripthash/input.ts +++ b/ts_src/templates/witnessscripthash/input.ts @@ -7,10 +7,7 @@ import * as p2ms from '../multisig'; import * as p2pk from '../pubkey'; import * as p2pkh from '../pubkeyhash'; -export function check( - chunks: Array, - allowIncomplete?: boolean, -): boolean { +export function check(chunks: Buffer[], allowIncomplete?: boolean): boolean { typeforce(typeforce.Array, chunks); if (chunks.length < 1) return false; @@ -45,6 +42,6 @@ export function check( return false; } -check.toJSON = function() { +check.toJSON = () => { return 'witnessScriptHash input'; }; diff --git a/ts_src/templates/witnessscripthash/output.ts b/ts_src/templates/witnessscripthash/output.ts index 430cc4f..85034d1 100644 --- a/ts_src/templates/witnessscripthash/output.ts +++ b/ts_src/templates/witnessscripthash/output.ts @@ -8,6 +8,6 @@ export function check(script: Buffer | Array): boolean { return buffer.length === 34 && buffer[0] === OPS.OP_0 && buffer[1] === 0x20; } -check.toJSON = function() { +check.toJSON = () => { return 'Witness scriptHash output'; }; diff --git a/types/templates/multisig/input.d.ts b/types/templates/multisig/input.d.ts index a04d03c..a207dd6 100644 --- a/types/templates/multisig/input.d.ts +++ b/types/templates/multisig/input.d.ts @@ -1,5 +1,6 @@ /// -export declare function check(script: Buffer | Array, allowIncomplete?: boolean): boolean; +import { Stack } from '../../payments'; +export declare function check(script: Buffer | Stack, allowIncomplete?: boolean): boolean; export declare namespace check { var toJSON: () => string; } diff --git a/types/templates/multisig/output.d.ts b/types/templates/multisig/output.d.ts index a04d03c..a207dd6 100644 --- a/types/templates/multisig/output.d.ts +++ b/types/templates/multisig/output.d.ts @@ -1,5 +1,6 @@ /// -export declare function check(script: Buffer | Array, allowIncomplete?: boolean): boolean; +import { Stack } from '../../payments'; +export declare function check(script: Buffer | Stack, allowIncomplete?: boolean): boolean; export declare namespace check { var toJSON: () => string; } diff --git a/types/templates/pubkey/input.d.ts b/types/templates/pubkey/input.d.ts index 091758f..c4ffeab 100644 --- a/types/templates/pubkey/input.d.ts +++ b/types/templates/pubkey/input.d.ts @@ -1,5 +1,6 @@ /// -export declare function check(script: Buffer | Array): boolean; +import { Stack } from '../../payments'; +export declare function check(script: Buffer | Stack): boolean; export declare namespace check { var toJSON: () => string; } diff --git a/types/templates/pubkey/output.d.ts b/types/templates/pubkey/output.d.ts index 091758f..c4ffeab 100644 --- a/types/templates/pubkey/output.d.ts +++ b/types/templates/pubkey/output.d.ts @@ -1,5 +1,6 @@ /// -export declare function check(script: Buffer | Array): boolean; +import { Stack } from '../../payments'; +export declare function check(script: Buffer | Stack): boolean; export declare namespace check { var toJSON: () => string; } diff --git a/types/templates/pubkeyhash/input.d.ts b/types/templates/pubkeyhash/input.d.ts index 091758f..c4ffeab 100644 --- a/types/templates/pubkeyhash/input.d.ts +++ b/types/templates/pubkeyhash/input.d.ts @@ -1,5 +1,6 @@ /// -export declare function check(script: Buffer | Array): boolean; +import { Stack } from '../../payments'; +export declare function check(script: Buffer | Stack): boolean; export declare namespace check { var toJSON: () => string; } diff --git a/types/templates/witnesspubkeyhash/input.d.ts b/types/templates/witnesspubkeyhash/input.d.ts index 091758f..c4ffeab 100644 --- a/types/templates/witnesspubkeyhash/input.d.ts +++ b/types/templates/witnesspubkeyhash/input.d.ts @@ -1,5 +1,6 @@ /// -export declare function check(script: Buffer | Array): boolean; +import { Stack } from '../../payments'; +export declare function check(script: Buffer | Stack): boolean; export declare namespace check { var toJSON: () => string; } diff --git a/types/templates/witnessscripthash/input.d.ts b/types/templates/witnessscripthash/input.d.ts index 7786731..b2a6e8a 100644 --- a/types/templates/witnessscripthash/input.d.ts +++ b/types/templates/witnessscripthash/input.d.ts @@ -1,5 +1,5 @@ /// -export declare function check(chunks: Array, allowIncomplete?: boolean): boolean; +export declare function check(chunks: Buffer[], allowIncomplete?: boolean): boolean; export declare namespace check { var toJSON: () => string; } From 7fb859b1f70f0aab4fe68fe60f85f4aa62689637 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 14:21:11 +0900 Subject: [PATCH 21/22] Fix lint types.ts --- src/types.js | 8 ++++---- ts_src/types.ts | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/types.js b/src/types.js index 76b98cf..dbe7ca5 100644 --- a/src/types.js +++ b/src/types.js @@ -10,7 +10,7 @@ function BIP32Path(value) { return typeforce.String(value) && !!value.match(/^(m\/)?(\d+'?\/)*\d+'?$/); } exports.BIP32Path = BIP32Path; -BIP32Path.toJSON = function () { +BIP32Path.toJSON = () => { return 'BIP32 derivation path'; }; const SATOSHI_MAX = 21 * 1e14; @@ -34,10 +34,10 @@ exports.Network = typeforce.compile({ exports.Buffer256bit = typeforce.BufferN(32); exports.Hash160bit = typeforce.BufferN(20); exports.Hash256bit = typeforce.BufferN(32); -exports.Number = typeforce.Number; +exports.Number = typeforce.Number; // tslint:disable-line variable-name exports.Array = typeforce.Array; -exports.Boolean = typeforce.Boolean; -exports.String = typeforce.String; +exports.Boolean = typeforce.Boolean; // tslint:disable-line variable-name +exports.String = typeforce.String; // tslint:disable-line variable-name exports.Buffer = typeforce.Buffer; exports.Hex = typeforce.Hex; exports.maybe = typeforce.maybe; diff --git a/ts_src/types.ts b/ts_src/types.ts index 42ddb40..033e62a 100644 --- a/ts_src/types.ts +++ b/ts_src/types.ts @@ -8,7 +8,7 @@ export function UInt31(value: number): boolean { export function BIP32Path(value: string): boolean { return typeforce.String(value) && !!value.match(/^(m\/)?(\d+'?\/)*\d+'?$/); } -BIP32Path.toJSON = function() { +BIP32Path.toJSON = () => { return 'BIP32 derivation path'; }; @@ -35,10 +35,10 @@ export const Network = typeforce.compile({ export const Buffer256bit = typeforce.BufferN(32); export const Hash160bit = typeforce.BufferN(20); export const Hash256bit = typeforce.BufferN(32); -export const Number = typeforce.Number; +export const Number = typeforce.Number; // tslint:disable-line variable-name export const Array = typeforce.Array; -export const Boolean = typeforce.Boolean; -export const String = typeforce.String; +export const Boolean = typeforce.Boolean; // tslint:disable-line variable-name +export const String = typeforce.String; // tslint:disable-line variable-name export const Buffer = typeforce.Buffer; export const Hex = typeforce.Hex; export const maybe = typeforce.maybe; From cb21cdb74c398a95b183cc2ed9abb3ffc17c0ac3 Mon Sep 17 00:00:00 2001 From: junderw Date: Thu, 7 Mar 2019 15:54:58 +0900 Subject: [PATCH 22/22] Specify version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 898fac8..ae28889 100644 --- a/package.json +++ b/package.json @@ -69,9 +69,9 @@ "minimaldata": "^1.0.2", "mocha": "^5.2.0", "nyc": "^11.8.0", - "prettier": "^1.16.4", + "prettier": "1.16.4", "proxyquire": "^2.0.1", - "tslint": "^5.13.1", + "tslint": "5.13.1", "typescript": "3.2.2" }, "license": "MIT"