Update TypeScript to use ! instead of casting

This commit is contained in:
junderw 2019-01-15 17:47:30 +09:00
parent bc28949056
commit 1732bafbc1
No known key found for this signature in database
GPG key ID: B256185D3A971908
17 changed files with 99 additions and 97 deletions

View file

@ -50,7 +50,7 @@ function p2pkh(a, opts) {
if (a.address) if (a.address)
return _address().hash; return _address().hash;
if (a.pubkey || o.pubkey) if (a.pubkey || o.pubkey)
return bcrypto.hash160(a.pubkey || o.pubkey); // eslint-disable-line return bcrypto.hash160(a.pubkey || o.pubkey);
}); });
lazy.prop(o, 'output', function () { lazy.prop(o, 'output', function () {
if (!o.hash) if (!o.hash)

View file

@ -55,7 +55,7 @@ function p2wpkh(a, opts) {
if (a.address) if (a.address)
return _address().data; return _address().data;
if (a.pubkey || o.pubkey) if (a.pubkey || o.pubkey)
return bcrypto.hash160(a.pubkey || o.pubkey); // eslint-disable-line return bcrypto.hash160(a.pubkey || o.pubkey);
}); });
lazy.prop(o, 'output', function () { lazy.prop(o, 'output', function () {
if (!o.hash) if (!o.hash)

View file

@ -369,13 +369,13 @@ class Transaction {
offset += slice.copy(buffer, offset); offset += slice.copy(buffer, offset);
} }
function writeUInt8(i) { function writeUInt8(i) {
offset = buffer.writeUInt8(i, offset); offset = (buffer).writeUInt8(i, offset);
} }
function writeUInt32(i) { function writeUInt32(i) {
offset = buffer.writeUInt32LE(i, offset); offset = (buffer).writeUInt32LE(i, offset);
} }
function writeInt32(i) { function writeInt32(i) {
offset = buffer.writeInt32LE(i, offset); offset = (buffer).writeInt32LE(i, offset);
} }
function writeUInt64(i) { function writeUInt64(i) {
offset = bufferutils.writeUInt64LE(buffer, i, offset); offset = bufferutils.writeUInt64LE(buffer, i, offset);

View file

@ -270,7 +270,7 @@ class TransactionBuilder {
return this.__inputs.every(input => { return this.__inputs.every(input => {
if (input.signatures === undefined) if (input.signatures === undefined)
return true; return true;
return input.signatures.every((signature => { return input.signatures.every(signature => {
if (!signature) if (!signature)
return true; return true;
const hashType = signatureHashType(signature); const hashType = signatureHashType(signature);
@ -283,7 +283,8 @@ class TransactionBuilder {
// of more outputs // of more outputs
return nInputs <= nOutputs; return nInputs <= nOutputs;
} }
})); return false;
});
}); });
} }
__overMaximumFees(bytes) { __overMaximumFees(bytes) {

View file

@ -129,7 +129,7 @@ export class Block {
if (transactions.length === 0) throw errorMerkleNoTxes if (transactions.length === 0) throw errorMerkleNoTxes
if (forWitness && !txesHaveWitness(transactions)) throw errorWitnessNotSegwit if (forWitness && !txesHaveWitness(transactions)) throw errorWitnessNotSegwit
const hashes = transactions.map(transaction => transaction.getHash((<boolean>forWitness))) const hashes = transactions.map(transaction => transaction.getHash(forWitness!))
const rootHash = fastMerkleRoot(hashes, bcrypto.hash256) const rootHash = fastMerkleRoot(hashes, bcrypto.hash256)
@ -139,7 +139,7 @@ export class Block {
} }
hasWitnessCommit (): boolean { hasWitnessCommit (): boolean {
return txesHaveWitness(<Array<Transaction>>this.transactions) return txesHaveWitness(this.transactions!)
} }
byteLength (headersOnly: boolean): number { byteLength (headersOnly: boolean): number {
@ -184,8 +184,8 @@ export class Block {
} }
writeInt32(this.version) writeInt32(this.version)
writeSlice(<Buffer>this.prevHash) writeSlice(this.prevHash!)
writeSlice(<Buffer>this.merkleRoot) writeSlice(this.merkleRoot!)
writeUInt32(this.timestamp) writeUInt32(this.timestamp)
writeUInt32(this.bits) writeUInt32(this.bits)
writeUInt32(this.nonce) writeUInt32(this.nonce)
@ -212,7 +212,7 @@ export class Block {
if (!this.transactions) throw errorMerkleNoTxes if (!this.transactions) throw errorMerkleNoTxes
const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions) const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
return (<Buffer>this.merkleRoot).compare(actualMerkleRoot) === 0 return this.merkleRoot!.compare(actualMerkleRoot) === 0
} }
checkWitnessCommit (): boolean { checkWitnessCommit (): boolean {
@ -220,7 +220,7 @@ export class Block {
if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit
const actualWitnessCommit = Block.calculateMerkleRoot(this.transactions, true) const actualWitnessCommit = Block.calculateMerkleRoot(this.transactions, true)
return (<Buffer>this.witnessCommit).compare(actualWitnessCommit) === 0 return this.witnessCommit!.compare(actualWitnessCommit) === 0
} }
checkProofOfWork (): boolean { checkProofOfWork (): boolean {

View file

@ -36,15 +36,15 @@ export function p2data (a: Payment, opts?: PaymentOpts): Payment {
}) })
lazy.prop(o, 'data', function () { lazy.prop(o, 'data', function () {
if (!a.output) return if (!a.output) return
return (<Array<Buffer | number>>bscript.decompile(a.output)).slice(1) return bscript.decompile(a.output)!.slice(1)
}) })
// extended validation // extended validation
if (opts.validate) { if (opts.validate) {
if (a.output) { if (a.output) {
const chunks = bscript.decompile(a.output) const chunks = bscript.decompile(a.output)
if ((<Array<Buffer | number>>chunks)[0] !== OPS.OP_RETURN) throw new TypeError('Output is invalid') if (chunks![0] !== OPS.OP_RETURN) throw new TypeError('Output is invalid')
if (!(<Array<Buffer | number>>chunks).slice(1).every(typef.Buffer)) throw new TypeError('Output is invalid') if (!chunks!.slice(1).every(typef.Buffer)) throw new TypeError('Output is invalid')
if (a.data && !stacksEqual(a.data, <Array<Buffer>>o.data)) throw new TypeError('Data mismatch') if (a.data && !stacksEqual(a.data, <Array<Buffer>>o.data)) throw new TypeError('Data mismatch')
} }

View file

@ -29,7 +29,7 @@ export function p2ms (a: Payment, opts?: PaymentOpts): Payment {
function isAcceptableSignature (x: Buffer | number) { function isAcceptableSignature (x: Buffer | number) {
return bscript.isCanonicalScriptSignature(<Buffer>x) || return bscript.isCanonicalScriptSignature(<Buffer>x) ||
((<PaymentOpts>opts).allowIncomplete && (opts!.allowIncomplete &&
(<number> x === OPS.OP_0)) !== undefined // eslint-disable-line (<number> x === OPS.OP_0)) !== undefined // eslint-disable-line
} }
@ -85,7 +85,7 @@ export function p2ms (a: Payment, opts?: PaymentOpts): Payment {
}) })
lazy.prop(o, 'signatures', function () { lazy.prop(o, 'signatures', function () {
if (!a.input) return if (!a.input) return
return (<Array<Buffer | number>>bscript.decompile(a.input)).slice(1) return bscript.decompile(a.input)!.slice(1)
}) })
lazy.prop(o, 'input', function () { lazy.prop(o, 'input', function () {
if (!a.signatures) return if (!a.signatures) return
@ -105,35 +105,35 @@ export function p2ms (a: Payment, opts?: PaymentOpts): Payment {
if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) throw new TypeError('Output is invalid') if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) throw new TypeError('Output is invalid')
if ( if (
<number>(<Payment>o).m <= 0 || // eslint-disable-line o.m! <= 0 || // eslint-disable-line
<number>(<Payment>o).n > 16 || // eslint-disable-line o.n! > 16 || // eslint-disable-line
<number>(<Payment>o).m > <number>(<Payment>o).n || // eslint-disable-line o.m! > o.n! || // eslint-disable-line
o.n !== chunks.length - 3) throw new TypeError('Output is invalid') o.n !== chunks.length - 3) throw new TypeError('Output is invalid')
if (!(<Array<Buffer>>o.pubkeys).every(x => ecc.isPoint(x))) throw new TypeError('Output is invalid') if (!o.pubkeys!.every(x => ecc.isPoint(x))) throw new TypeError('Output is invalid')
if (a.m !== undefined && a.m !== o.m) throw new TypeError('m mismatch') if (a.m !== undefined && a.m !== o.m) throw new TypeError('m mismatch')
if (a.n !== undefined && a.n !== o.n) throw new TypeError('n mismatch') if (a.n !== undefined && a.n !== o.n) throw new TypeError('n mismatch')
if (a.pubkeys && !stacksEqual(a.pubkeys, (<Array<Buffer>>o.pubkeys))) throw new TypeError('Pubkeys mismatch') if (a.pubkeys && !stacksEqual(a.pubkeys, o.pubkeys!)) throw new TypeError('Pubkeys mismatch')
} }
if (a.pubkeys) { if (a.pubkeys) {
if (a.n !== undefined && a.n !== a.pubkeys.length) throw new TypeError('Pubkey count mismatch') if (a.n !== undefined && a.n !== a.pubkeys.length) throw new TypeError('Pubkey count mismatch')
o.n = a.pubkeys.length o.n = a.pubkeys.length
if (o.n < <number>(<Payment>o).m) throw new TypeError('Pubkey count cannot be less than m') if (o.n < o.m!) throw new TypeError('Pubkey count cannot be less than m')
} }
if (a.signatures) { if (a.signatures) {
if (a.signatures.length < <number>(<Payment>o).m) throw new TypeError('Not enough signatures provided') if (a.signatures.length < o.m!) throw new TypeError('Not enough signatures provided')
if (a.signatures.length > <number>(<Payment>o).m) throw new TypeError('Too many signatures provided') if (a.signatures.length > o.m!) throw new TypeError('Too many signatures provided')
} }
if (a.input) { if (a.input) {
if (a.input[0] !== OPS.OP_0) throw new TypeError('Input is invalid') if (a.input[0] !== OPS.OP_0) throw new TypeError('Input is invalid')
if ((<Array<Buffer>>o.signatures).length === 0 || !(<Array<Buffer>>o.signatures).every(isAcceptableSignature)) throw new TypeError('Input has invalid signature(s)') if (o.signatures!.length === 0 || !o.signatures!.every(isAcceptableSignature)) throw new TypeError('Input has invalid signature(s)')
if (a.signatures && !stacksEqual(a.signatures, (<Array<Buffer>>o.signatures))) throw new TypeError('Signature mismatch') if (a.signatures && !stacksEqual(a.signatures, o.signatures!)) throw new TypeError('Signature mismatch')
if (a.m !== undefined && a.m !== (<Array<Buffer>>a.signatures).length) throw new TypeError('Signature count mismatch') if (a.m !== undefined && a.m !== a.signatures!.length) throw new TypeError('Signature count mismatch')
} }
} }

View file

@ -27,7 +27,7 @@ export function p2pk (a: Payment, opts?: PaymentOpts): Payment {
input: typef.maybe(typef.Buffer) input: typef.maybe(typef.Buffer)
}, a) }, a)
const _chunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(<Buffer>a.input) }) const _chunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(a.input!) })
const network = a.network || BITCOIN_NETWORK const network = a.network || BITCOIN_NETWORK
const o: Payment = { network } const o: Payment = { network }
@ -61,16 +61,16 @@ export function p2pk (a: Payment, opts?: PaymentOpts): Payment {
if (a.output) { if (a.output) {
if (a.output[a.output.length - 1] !== OPS.OP_CHECKSIG) throw new TypeError('Output is invalid') if (a.output[a.output.length - 1] !== OPS.OP_CHECKSIG) throw new TypeError('Output is invalid')
if (!ecc.isPoint(o.pubkey)) throw new TypeError('Output pubkey is invalid') if (!ecc.isPoint(o.pubkey)) throw new TypeError('Output pubkey is invalid')
if (a.pubkey && !a.pubkey.equals(<Buffer>o.pubkey)) throw new TypeError('Pubkey mismatch') if (a.pubkey && !a.pubkey.equals(o.pubkey!)) throw new TypeError('Pubkey mismatch')
} }
if (a.signature) { if (a.signature) {
if (a.input && !a.input.equals(<Buffer>o.input)) throw new TypeError('Signature mismatch') if (a.input && !a.input.equals(o.input!)) throw new TypeError('Signature mismatch')
} }
if (a.input) { if (a.input) {
if (_chunks().length !== 1) throw new TypeError('Input is invalid') if (_chunks().length !== 1) throw new TypeError('Input is invalid')
if (!bscript.isCanonicalScriptSignature(<Buffer>o.signature)) throw new TypeError('Input has invalid signature') if (!bscript.isCanonicalScriptSignature(o.signature!)) throw new TypeError('Input has invalid signature')
} }
} }

View file

@ -38,7 +38,7 @@ export function p2pkh (a: Payment, opts?: PaymentOpts): Payment {
const hash = payload.slice(1) const hash = payload.slice(1)
return { version, hash } return { version, hash }
}) })
const _chunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(<Buffer>a.input) }) const _chunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(a.input!) })
const network = a.network || BITCOIN_NETWORK const network = a.network || BITCOIN_NETWORK
const o: Payment = { network } const o: Payment = { network }
@ -54,7 +54,7 @@ export function p2pkh (a: Payment, opts?: PaymentOpts): Payment {
lazy.prop(o, 'hash', function () { lazy.prop(o, 'hash', function () {
if (a.output) return a.output.slice(3, 23) if (a.output) return a.output.slice(3, 23)
if (a.address) return _address().hash if (a.address) return _address().hash
if (a.pubkey || o.pubkey) return bcrypto.hash160(<Buffer> a.pubkey || <Buffer>o.pubkey) // eslint-disable-line if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey! || o.pubkey!)
}) })
lazy.prop(o, 'output', function () { lazy.prop(o, 'output', function () {
if (!o.hash) return if (!o.hash) return

View file

@ -59,7 +59,7 @@ export function p2sh (a: Payment, opts?: PaymentOpts): Payment {
const hash = payload.slice(1) const hash = payload.slice(1)
return { version, hash } return { version, hash }
}) })
const _chunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(<Buffer>a.input) }) const _chunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(a.input!) })
const _redeem = lazy.value(function (): Payment { const _redeem = lazy.value(function (): Payment {
const chunks = _chunks() const chunks = _chunks()
return { return {
@ -75,7 +75,7 @@ export function p2sh (a: Payment, opts?: PaymentOpts): Payment {
if (!o.hash) return if (!o.hash) return
const payload = Buffer.allocUnsafe(21) const payload = Buffer.allocUnsafe(21)
payload.writeUInt8((<Network>o.network).scriptHash, 0) payload.writeUInt8(o.network!.scriptHash, 0)
o.hash.copy(payload, 1) o.hash.copy(payload, 1)
return bs58check.encode(payload) return bs58check.encode(payload)
}) })
@ -173,8 +173,8 @@ export function p2sh (a: Payment, opts?: PaymentOpts): Payment {
if (a.redeem.network && a.redeem.network !== network) throw new TypeError('Network mismatch') if (a.redeem.network && a.redeem.network !== network) throw new TypeError('Network mismatch')
if (a.input) { if (a.input) {
const redeem = _redeem() const redeem = _redeem()
if (a.redeem.output && !a.redeem.output.equals(<Buffer>redeem.output)) throw new TypeError('Redeem.output mismatch') if (a.redeem.output && !a.redeem.output.equals(redeem.output!)) throw new TypeError('Redeem.output mismatch')
if (a.redeem.input && !a.redeem.input.equals(<Buffer>redeem.input)) throw new TypeError('Redeem.input mismatch') if (a.redeem.input && !a.redeem.input.equals(redeem.input!)) throw new TypeError('Redeem.input mismatch')
} }
checkRedeem(a.redeem) checkRedeem(a.redeem)

View file

@ -59,7 +59,7 @@ export function p2wpkh (a: Payment, opts?: PaymentOpts): Payment {
lazy.prop(o, 'hash', function () { lazy.prop(o, 'hash', function () {
if (a.output) return a.output.slice(2, 22) if (a.output) return a.output.slice(2, 22)
if (a.address) return _address().data if (a.address) return _address().data
if (a.pubkey || o.pubkey) return bcrypto.hash160(<Buffer> a.pubkey || <Buffer>o.pubkey) // eslint-disable-line if (a.pubkey || o.pubkey) return bcrypto.hash160(a.pubkey! || o.pubkey!)
}) })
lazy.prop(o, 'output', function () { lazy.prop(o, 'output', function () {
if (!o.hash) return if (!o.hash) return

View file

@ -58,7 +58,7 @@ export function p2wsh (a: Payment, opts?: PaymentOpts): Payment {
data: Buffer.from(data) data: Buffer.from(data)
} }
}) })
const _rchunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(<Buffer>(<Payment>a.redeem).input) }) const _rchunks = <()=>Array<Buffer | number>>lazy.value(function () { return bscript.decompile(a.redeem!.input!) })
let network = a.network let network = a.network
if (!network) { if (!network) {
@ -71,7 +71,7 @@ export function p2wsh (a: Payment, opts?: PaymentOpts): Payment {
if (!o.hash) return if (!o.hash) return
const words = bech32.toWords(o.hash) const words = bech32.toWords(o.hash)
words.unshift(0x00) words.unshift(0x00)
return bech32.encode((<Network>network).bech32, words) return bech32.encode(network!.bech32, words)
}) })
lazy.prop(o, 'hash', function () { lazy.prop(o, 'hash', function () {
if (a.output) return a.output.slice(2) if (a.output) return a.output.slice(2)
@ -158,7 +158,7 @@ export function p2wsh (a: Payment, opts?: PaymentOpts): Payment {
// is the redeem output non-empty? // is the redeem output non-empty?
if (a.redeem.output) { if (a.redeem.output) {
if ((<Array<Buffer | number>>bscript.decompile(a.redeem.output)).length === 0) throw new TypeError('Redeem.output is invalid') if (bscript.decompile(a.redeem.output)!.length === 0) throw new TypeError('Redeem.output is invalid')
// match hash against other sources // match hash against other sources
const hash2 = bcrypto.sha256(a.redeem.output) const hash2 = bcrypto.sha256(a.redeem.output)

View file

@ -125,7 +125,7 @@ export function decompile (buffer: Buffer | Array<number | Buffer>): Array<numbe
// decompile minimally // decompile minimally
const op = asMinimalOP(data) const op = asMinimalOP(data)
if (op !== undefined) { if (op !== undefined) {
chunks.push(<number>op) chunks.push(op)
} else { } else {
chunks.push(data) chunks.push(data)
} }

View file

@ -10,14 +10,14 @@ import * as p2wsho from '../witnessscripthash/output'
export function check (script: Buffer | Array<number | Buffer>, allowIncomplete?: boolean): boolean { export function check (script: Buffer | Array<number | Buffer>, allowIncomplete?: boolean): boolean {
const chunks = <Array<number | Buffer>>bscript.decompile(script) const chunks = bscript.decompile(script)!
if (chunks.length < 1) return false if (chunks.length < 1) return false
const lastChunk = chunks[chunks.length - 1] const lastChunk = chunks[chunks.length - 1]
if (!Buffer.isBuffer(lastChunk)) return false if (!Buffer.isBuffer(lastChunk)) return false
const scriptSigChunks = <Array<number | Buffer>>bscript.decompile(bscript.compile(chunks.slice(0, -1))) const scriptSigChunks = bscript.decompile(bscript.compile(chunks.slice(0, -1)))!
const redeemScriptChunks = bscript.decompile(<Buffer>lastChunk) const redeemScriptChunks = bscript.decompile(lastChunk)
// is redeemScript a valid script? // is redeemScript a valid script?
if (!redeemScriptChunks) return false if (!redeemScriptChunks) return false

View file

@ -32,5 +32,5 @@ export function encode (commitment: Buffer): Buffer {
export function decode (buffer: Buffer): Buffer { export function decode (buffer: Buffer): Buffer {
typeforce(check, buffer) typeforce(check, buffer)
return (<Buffer>(<Array<number | Buffer>>bscript.decompile(buffer))[1]).slice(4, 36) return (<Buffer>bscript.decompile(buffer)![1]).slice(4, 36)
} }

View file

@ -294,8 +294,8 @@ export class Transaction {
if (inIndex >= this.ins.length) return ONE if (inIndex >= this.ins.length) return ONE
// ignore OP_CODESEPARATOR // ignore OP_CODESEPARATOR
const ourScript = bscript.compile((<Array<Buffer | number>>bscript.decompile(prevOutScript)).filter((x) => { const ourScript = bscript.compile(bscript.decompile(prevOutScript)!.filter((x) => {
return x !== <number>opcodes.OP_CODESEPARATOR return x !== opcodes.OP_CODESEPARATOR
})) }))
const txTmp = this.clone() const txTmp = this.clone()
@ -471,28 +471,28 @@ export class Transaction {
} }
private __toBuffer (buffer?: Buffer, initialOffset?: number, __allowWitness?: boolean): Buffer { private __toBuffer (buffer?: Buffer, initialOffset?: number, __allowWitness?: boolean): Buffer {
if (!buffer) buffer = <Buffer> Buffer.allocUnsafe(this.__byteLength((<boolean>__allowWitness))) if (!buffer) buffer = <Buffer> Buffer.allocUnsafe(this.__byteLength(__allowWitness!))
let offset = initialOffset || 0 let offset = initialOffset || 0
function writeSlice (slice: Buffer): void { function writeSlice (slice: Buffer): void {
offset += slice.copy(<Buffer>buffer, offset) offset += slice.copy(buffer!, offset)
} }
function writeUInt8 (i: number) { function writeUInt8 (i: number) {
offset = (<Buffer>buffer).writeUInt8(i, offset) offset = (buffer!).writeUInt8(i, offset)
} }
function writeUInt32 (i: number) { function writeUInt32 (i: number) {
offset = (<Buffer>buffer).writeUInt32LE(i, offset) offset = (buffer!).writeUInt32LE(i, offset)
} }
function writeInt32 (i: number) { function writeInt32 (i: number) {
offset = (<Buffer>buffer).writeInt32LE(i, offset) offset = (buffer!).writeInt32LE(i, offset)
} }
function writeUInt64 (i: number) { function writeUInt64 (i: number) {
offset = bufferutils.writeUInt64LE(<Buffer>buffer, i, offset) offset = bufferutils.writeUInt64LE(buffer!, i, offset)
} }
function writeVarInt (i: number) { function writeVarInt (i: number) {
@ -548,7 +548,7 @@ export class Transaction {
writeUInt32(this.locktime) writeUInt32(this.locktime)
// avoid slicing unless necessary // avoid slicing unless necessary
if (initialOffset !== undefined) return buffer.slice((<number>initialOffset), offset) if (initialOffset !== undefined) return buffer.slice(initialOffset, offset)
return buffer return buffer
} }

View file

@ -50,11 +50,11 @@ interface TxbOutput {
} }
function txIsString(tx: Buffer | string | Transaction): tx is string { function txIsString(tx: Buffer | string | Transaction): tx is string {
return typeof (<string>tx) === 'string' || tx instanceof String return typeof tx === 'string' || tx instanceof String
} }
function txIsTransaction(tx: Buffer | string | Transaction): tx is Transaction { function txIsTransaction(tx: Buffer | string | Transaction): tx is Transaction {
return (<Transaction>tx) instanceof Transaction return tx instanceof Transaction
} }
export class TransactionBuilder { export class TransactionBuilder {
@ -209,7 +209,7 @@ export class TransactionBuilder {
scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network) scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network)
} }
return this.__tx.addOutput(<Buffer>scriptPubKey, value) return this.__tx.addOutput(scriptPubKey, value)
} }
build (): Transaction { build (): Transaction {
@ -232,15 +232,15 @@ export class TransactionBuilder {
this.__inputs.forEach((input, i) => { this.__inputs.forEach((input, i) => {
if (!input.prevOutType && !allowIncomplete) throw new Error('Transaction is not complete') if (!input.prevOutType && !allowIncomplete) throw new Error('Transaction is not complete')
const result = build(<string>input.prevOutType, input, allowIncomplete) const result = build(input.prevOutType!, input, allowIncomplete)
if (!result) { if (!result) {
if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) throw new Error('Unknown input type') if (!allowIncomplete && input.prevOutType === SCRIPT_TYPES.NONSTANDARD) throw new Error('Unknown input type')
if (!allowIncomplete) throw new Error('Not enough information') if (!allowIncomplete) throw new Error('Not enough information')
return return
} }
tx.setInputScript(i, <Buffer>result.input) tx.setInputScript(i, result.input!)
tx.setWitness(i, <Array<Buffer>>result.witness) tx.setWitness(i, result.witness!)
}) })
if (!allowIncomplete) { if (!allowIncomplete) {
@ -270,7 +270,7 @@ export class TransactionBuilder {
throw new Error('Inconsistent redeemScript') throw new Error('Inconsistent redeemScript')
} }
const ourPubKey = keyPair.publicKey || (<()=>Buffer>keyPair.getPublicKey)() const ourPubKey = keyPair.publicKey || keyPair.getPublicKey!()
if (!canSign(input)) { if (!canSign(input)) {
if (witnessValue !== undefined) { if (witnessValue !== undefined) {
if (input.value !== undefined && input.value !== witnessValue) throw new Error('Input didn\'t match witnessValue') if (input.value !== undefined && input.value !== witnessValue) throw new Error('Input didn\'t match witnessValue')
@ -297,9 +297,9 @@ export class TransactionBuilder {
} }
// enforce in order signing of public keys // enforce in order signing of public keys
const signed = (<Array<Buffer>>input.pubkeys).some((pubKey, i) => { const signed = input.pubkeys!.some((pubKey, i) => {
if (!ourPubKey.equals(pubKey)) return false if (!ourPubKey.equals(pubKey!)) return false
if ((<Array<Buffer>>input.signatures)[i]) throw new Error('Signature already exists') if (input.signatures![i]) throw new Error('Signature already exists')
// TODO: add tests // TODO: add tests
if (ourPubKey.length !== 33 && input.hasWitness) { if (ourPubKey.length !== 33 && input.hasWitness) {
@ -307,7 +307,7 @@ export class TransactionBuilder {
} }
const signature = keyPair.sign(signatureHash) const signature = keyPair.sign(signatureHash)
;(<Array<Buffer>>input.signatures)[i] = bscript.signature.encode(signature, hashType) input.signatures![i] = bscript.signature.encode(signature, hashType)
return true return true
}) })
@ -355,7 +355,7 @@ export class TransactionBuilder {
return this.__inputs.every(input => { return this.__inputs.every(input => {
if (input.signatures === undefined) return true if (input.signatures === undefined) return true
return input.signatures.every(<(signature: Buffer | undefined)=>boolean>(signature => { return input.signatures.every(signature => {
if (!signature) return true if (!signature) return true
const hashType = signatureHashType(signature) const hashType = signatureHashType(signature)
@ -367,13 +367,14 @@ export class TransactionBuilder {
// of more outputs // of more outputs
return nInputs <= nOutputs return nInputs <= nOutputs
} }
})) return false
})
}) })
} }
private __overMaximumFees (bytes: number): boolean { private __overMaximumFees (bytes: number): boolean {
// not all inputs will have .value defined // not all inputs will have .value defined
const incoming = this.__inputs.reduce((a, x) => a + (<number>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 // but all outputs do, and if we have any input value
// we can immediately determine if the outputs are too small // we can immediately determine if the outputs are too small
@ -449,14 +450,14 @@ function expandInput (scriptSig: Buffer, witnessStack: Array<Buffer>, type?: str
witness: witnessStack witness: witnessStack
}) })
const outputType = classify.output(<Buffer>(<Payment>redeem).output) const outputType = classify.output(redeem!.output!)
const expanded = expandInput(<Buffer>(<Payment>redeem).input, <Array<Buffer>>(<Payment>redeem).witness, outputType, (<Payment>redeem).output) const expanded = expandInput(redeem!.input!, redeem!.witness!, outputType, redeem!.output)
if (!expanded.prevOutType) return {} if (!expanded.prevOutType) return {}
return { return {
prevOutScript: output, prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2SH, prevOutType: SCRIPT_TYPES.P2SH,
redeemScript: (<Payment>redeem).output, redeemScript: redeem!.output,
redeemScriptType: expanded.prevOutType, redeemScriptType: expanded.prevOutType,
witnessScript: expanded.witnessScript, witnessScript: expanded.witnessScript,
witnessScriptType: expanded.witnessScriptType, witnessScriptType: expanded.witnessScriptType,
@ -471,19 +472,19 @@ function expandInput (scriptSig: Buffer, witnessStack: Array<Buffer>, type?: str
input: scriptSig, input: scriptSig,
witness: witnessStack witness: witnessStack
}) })
const outputType = classify.output(<Buffer>(<Payment>redeem).output) const outputType = classify.output(redeem!.output!)
let expanded let expanded
if (outputType === SCRIPT_TYPES.P2WPKH) { if (outputType === SCRIPT_TYPES.P2WPKH) {
expanded = expandInput(<Buffer>(<Payment>redeem).input, <Array<Buffer>>(<Payment>redeem).witness, outputType) expanded = expandInput(redeem!.input!, redeem!.witness!, outputType)
} else { } else {
expanded = expandInput(bscript.compile(<Array<Buffer>>(<Payment>redeem).witness), [], outputType, (<Payment>redeem).output) expanded = expandInput(bscript.compile(redeem!.witness!), [], outputType, redeem!.output)
} }
if (!expanded.prevOutType) return {} if (!expanded.prevOutType) return {}
return { return {
prevOutScript: output, prevOutScript: output,
prevOutType: SCRIPT_TYPES.P2WSH, prevOutType: SCRIPT_TYPES.P2WSH,
witnessScript: (<Payment>redeem).output, witnessScript: redeem!.output,
witnessScriptType: expanded.prevOutType, witnessScriptType: expanded.prevOutType,
pubkeys: expanded.pubkeys, pubkeys: expanded.pubkeys,
@ -500,12 +501,12 @@ function expandInput (scriptSig: Buffer, witnessStack: Array<Buffer>, type?: str
// could be done in expandInput, but requires the original Transaction for hashForSignature // could be done in expandInput, but requires the original Transaction for hashForSignature
function fixMultisigOrder (input: TxbInput, transaction: Transaction, vin: number): void { function fixMultisigOrder (input: TxbInput, transaction: Transaction, vin: number): void {
if (input.redeemScriptType !== SCRIPT_TYPES.P2MS || !input.redeemScript) return if (input.redeemScriptType !== SCRIPT_TYPES.P2MS || !input.redeemScript) return
if ((<Array<Buffer>>input.pubkeys).length === (<Array<Buffer>>input.signatures).length) return if (input.pubkeys!.length === input.signatures!.length) return
const unmatched = (<Array<Buffer | undefined>>input.signatures).concat() const unmatched = input.signatures!.concat()
input.signatures = <Array<Buffer | undefined>>(<Array<Buffer>>input.pubkeys).map(pubKey => { input.signatures = input.pubkeys!.map(pubKey => {
const keyPair = ECPair.fromPublicKey(pubKey) const keyPair = ECPair.fromPublicKey(pubKey!)
let match: Buffer | undefined let match: Buffer | undefined
// check for a signature // check for a signature
@ -515,7 +516,7 @@ function fixMultisigOrder (input: TxbInput, transaction: Transaction, vin: numbe
// TODO: avoid O(n) hashForSignature // TODO: avoid O(n) hashForSignature
const parsed = bscript.signature.decode(signature) const parsed = bscript.signature.decode(signature)
const hash = transaction.hashForSignature(vin, (<Buffer>input.redeemScript), parsed.hashType) const hash = transaction.hashForSignature(vin, input.redeemScript!, parsed.hashType)
// skip if signature does not match pubKey // skip if signature does not match pubKey
if (!keyPair.verify(hash, parsed.signature)) return false if (!keyPair.verify(hash, parsed.signature)) return false
@ -542,7 +543,7 @@ function expandOutput (script: Buffer, ourPubKey?: Buffer): TxbOutput {
// does our hash160(pubKey) match the output scripts? // does our hash160(pubKey) match the output scripts?
const pkh1 = payments.p2pkh({ output: script }).hash const pkh1 = payments.p2pkh({ output: script }).hash
const pkh2 = bcrypto.hash160(ourPubKey) const pkh2 = bcrypto.hash160(ourPubKey)
if (!(<Buffer>pkh1).equals(pkh2)) return { type } if (!pkh1!.equals(pkh2)) return { type }
return { return {
type, type,
@ -557,7 +558,7 @@ function expandOutput (script: Buffer, ourPubKey?: Buffer): TxbOutput {
// does our hash160(pubKey) match the output scripts? // does our hash160(pubKey) match the output scripts?
const wpkh1 = payments.p2wpkh({ output: script }).hash const wpkh1 = payments.p2wpkh({ output: script }).hash
const wpkh2 = bcrypto.hash160(ourPubKey) const wpkh2 = bcrypto.hash160(ourPubKey)
if (!(<Buffer>wpkh1).equals(wpkh2)) return { type } if (!wpkh1!.equals(wpkh2)) return { type }
return { return {
type, type,
@ -580,7 +581,7 @@ function expandOutput (script: Buffer, ourPubKey?: Buffer): TxbOutput {
return { return {
type, type,
pubkeys: p2ms.pubkeys, pubkeys: p2ms.pubkeys,
signatures: (<Array<Buffer>>p2ms.pubkeys).map((): undefined => undefined), signatures: p2ms.pubkeys!.map((): undefined => undefined),
maxSignatures: p2ms.m maxSignatures: p2ms.m
} }
} }
@ -597,10 +598,10 @@ function prepareInput (input: TxbInput, ourPubKey: Buffer, redeemScript: Buffer,
const p2shAlt = <Payment> payments.p2sh({ redeem: p2wsh }) const p2shAlt = <Payment> payments.p2sh({ redeem: p2wsh })
// enforces P2SH(P2WSH(...)) // enforces P2SH(P2WSH(...))
if (!(<Buffer>p2wsh.hash).equals(<Buffer>p2wshAlt.hash)) throw new Error('Witness script inconsistent with prevOutScript') if (!p2wsh.hash!.equals(p2wshAlt.hash!)) throw new Error('Witness script inconsistent with prevOutScript')
if (!(<Buffer>p2sh.hash).equals(<Buffer>p2shAlt.hash)) throw new Error('Redeem script inconsistent with prevOutScript') if (!p2sh.hash!.equals(p2shAlt.hash!)) throw new Error('Redeem script inconsistent with prevOutScript')
const expanded = expandOutput(<Buffer>(<Payment>p2wsh.redeem).output, ourPubKey) const expanded = expandOutput(p2wsh.redeem!.output!, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')') if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')')
if (input.signatures && input.signatures.some(x => x !== undefined)) { if (input.signatures && input.signatures.some(x => x !== undefined)) {
expanded.signatures = input.signatures expanded.signatures = input.signatures
@ -637,10 +638,10 @@ function prepareInput (input: TxbInput, ourPubKey: Buffer, redeemScript: Buffer,
try { try {
p2shAlt = <Payment> payments.p2sh({ output: input.prevOutScript }) p2shAlt = <Payment> payments.p2sh({ output: input.prevOutScript })
} catch (e) { throw new Error('PrevOutScript must be P2SH') } } catch (e) { throw new Error('PrevOutScript must be P2SH') }
if (!(<Buffer>p2sh.hash).equals(<Buffer>p2shAlt.hash)) throw new Error('Redeem script inconsistent with prevOutScript') if (!p2sh.hash!.equals(p2shAlt.hash!)) throw new Error('Redeem script inconsistent with prevOutScript')
} }
const expanded = expandOutput(<Buffer>(<Payment>p2sh.redeem).output, ourPubKey) const expanded = expandOutput(p2sh.redeem!.output!, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as redeemScript (' + bscript.toASM(redeemScript) + ')') if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as redeemScript (' + bscript.toASM(redeemScript) + ')')
if (input.signatures && input.signatures.some(x => x !== undefined)) { if (input.signatures && input.signatures.some(x => x !== undefined)) {
expanded.signatures = input.signatures expanded.signatures = input.signatures
@ -648,7 +649,7 @@ function prepareInput (input: TxbInput, ourPubKey: Buffer, redeemScript: Buffer,
let signScript = redeemScript let signScript = redeemScript
if (expanded.type === SCRIPT_TYPES.P2WPKH) { if (expanded.type === SCRIPT_TYPES.P2WPKH) {
signScript = <Buffer> payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output!
} }
return { return {
@ -669,14 +670,14 @@ function prepareInput (input: TxbInput, ourPubKey: Buffer, redeemScript: Buffer,
} }
if (witnessScript) { if (witnessScript) {
const p2wsh = <Payment> payments.p2wsh({ redeem: { output: witnessScript } }) const p2wsh = payments.p2wsh({ redeem: { output: witnessScript } })
if (input.prevOutScript) { if (input.prevOutScript) {
const p2wshAlt = payments.p2wsh({ output: input.prevOutScript }) const p2wshAlt = payments.p2wsh({ output: input.prevOutScript })
if (!(<Buffer>p2wsh.hash).equals(<Buffer>p2wshAlt.hash)) throw new Error('Witness script inconsistent with prevOutScript') if (!p2wsh.hash!.equals(p2wshAlt.hash!)) throw new Error('Witness script inconsistent with prevOutScript')
} }
const expanded = expandOutput(<Buffer>(<Payment>p2wsh.redeem).output, ourPubKey) const expanded = expandOutput(p2wsh.redeem!.output!, ourPubKey)
if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')') if (!expanded.pubkeys) throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')')
if (input.signatures && input.signatures.some(x => x !== undefined)) { if (input.signatures && input.signatures.some(x => x !== undefined)) {
expanded.signatures = input.signatures expanded.signatures = input.signatures
@ -784,7 +785,7 @@ function build (type: string, input: TxbInput, allowIncomplete?: boolean): Payme
return payments.p2ms({ m, pubkeys, signatures }, { allowIncomplete, validate }) return payments.p2ms({ m, pubkeys, signatures }, { allowIncomplete, validate })
} }
case SCRIPT_TYPES.P2SH: { case SCRIPT_TYPES.P2SH: {
const redeem = build(<string>input.redeemScriptType, input, allowIncomplete) const redeem = build(input.redeemScriptType!, input, allowIncomplete)
if (!redeem) return if (!redeem) return
return payments.p2sh({ return payments.p2sh({
@ -796,7 +797,7 @@ function build (type: string, input: TxbInput, allowIncomplete?: boolean): Payme
}) })
} }
case SCRIPT_TYPES.P2WSH: { case SCRIPT_TYPES.P2WSH: {
const redeem = build(<string>input.witnessScriptType, input, allowIncomplete) const redeem = build(input.witnessScriptType!, input, allowIncomplete)
if (!redeem) return if (!redeem) return
return payments.p2wsh({ return payments.p2wsh({