From 037fbd898427926b83609473cd2420e4ee6469fd Mon Sep 17 00:00:00 2001 From: junderw Date: Wed, 26 Dec 2018 16:13:43 +0900 Subject: [PATCH] # This is a combination of 2 commits. # The first commit's message is: Add types to Networks and Addresses # This is the 2nd commit message: Added types --- src/address.ts | 48 +++++++++++++++++---------- src/bufferutils.ts | 12 ++----- src/classify.ts | 35 ++++++++++---------- src/crypto.ts | 19 +++-------- src/networks.ts | 82 ++++++++++++++++++++++++++-------------------- 5 files changed, 102 insertions(+), 94 deletions(-) diff --git a/src/address.ts b/src/address.ts index e6f60fc..b758a66 100644 --- a/src/address.ts +++ b/src/address.ts @@ -6,8 +6,21 @@ const networks = require('./networks') const typeforce = require('typeforce') const types = require('./types') const payments = require('./payments') +import * as Networks from './networks' +import { Network } from './networks' -function fromBase58Check (address) { +export declare type Base58CheckResult = { + hash: Buffer; + version: number; +} + +export declare type Bech32Result = { + version: number; + prefix: string; + data: Buffer; +} + +function fromBase58Check (address: string): Base58CheckResult { const payload = bs58check.decode(address) // TODO: 4.0.0, move to "toOutputScript" @@ -20,7 +33,7 @@ function fromBase58Check (address) { return { version: version, hash: hash } } -function fromBech32 (address) { +function fromBech32 (address: string): Bech32Result { const result = bech32.decode(address) const data = bech32.fromWords(result.words.slice(1)) @@ -31,7 +44,7 @@ function fromBech32 (address) { } } -function toBase58Check (hash, version) { +function toBase58Check (hash: Buffer, version: number): string { typeforce(types.tuple(types.Hash160bit, types.UInt8), arguments) const payload = Buffer.allocUnsafe(21) @@ -41,14 +54,14 @@ function toBase58Check (hash, version) { return bs58check.encode(payload) } -function toBech32 (data, version, prefix) { +function toBech32 (data: Buffer, version: number, prefix: string): string { const words = bech32.toWords(data) words.unshift(version) return bech32.encode(prefix, words) } -function fromOutputScript (output, network) { +function fromOutputScript (output: Buffer, network: Network): string { //TODO: Network network = network || networks.bitcoin try { return payments.p2pkh({ output, network }).address } catch (e) {} @@ -59,27 +72,28 @@ function fromOutputScript (output, network) { throw new Error(bscript.toASM(output) + ' has no matching Address') } -function toOutputScript (address, network) { +function toOutputScript (address: string, network: Network): Buffer { network = network || networks.bitcoin - let decode + let decodeBase58: Base58CheckResult + let decodeBech32: Bech32Result try { - decode = fromBase58Check(address) + decodeBase58 = fromBase58Check(address) } catch (e) {} - if (decode) { - if (decode.version === network.pubKeyHash) return payments.p2pkh({ hash: decode.hash }).output - if (decode.version === network.scriptHash) return payments.p2sh({ hash: decode.hash }).output + if (decodeBase58) { + if (decodeBase58.version === network.pubKeyHash) return payments.p2pkh({ hash: decodeBase58.hash }).output + if (decodeBase58.version === network.scriptHash) return payments.p2sh({ hash: decodeBase58.hash }).output } else { try { - decode = fromBech32(address) + decodeBech32 = fromBech32(address) } catch (e) {} - if (decode) { - if (decode.prefix !== network.bech32) throw new Error(address + ' has an invalid prefix') - if (decode.version === 0) { - if (decode.data.length === 20) return payments.p2wpkh({ hash: decode.data }).output - if (decode.data.length === 32) return payments.p2wsh({ hash: decode.data }).output + if (decodeBech32) { + if (decodeBech32.prefix !== network.bech32) throw new Error(address + ' has an invalid prefix') + if (decodeBech32.version === 0) { + if (decodeBech32.data.length === 20) return payments.p2wpkh({ hash: decodeBech32.data }).output + if (decodeBech32.data.length === 32) return payments.p2wsh({ hash: decodeBech32.data }).output } } } diff --git a/src/bufferutils.ts b/src/bufferutils.ts index a78b07b..b66c84a 100644 --- a/src/bufferutils.ts +++ b/src/bufferutils.ts @@ -1,12 +1,12 @@ // https://github.com/feross/buffer/blob/master/index.js#L1127 -function verifuint (value, max) { +function verifuint (value: number, max: number): void { if (typeof value !== 'number') throw new Error('cannot write a non-number as a number') if (value < 0) throw new Error('specified a negative value for writing an unsigned value') if (value > max) throw new Error('RangeError: value out of range') if (Math.floor(value) !== value) throw new Error('value has a fractional component') } -function readUInt64LE (buffer, offset) { +export function readUInt64LE (buffer: Buffer, offset: number): number { const a = buffer.readUInt32LE(offset) let b = buffer.readUInt32LE(offset + 4) b *= 0x100000000 @@ -15,16 +15,10 @@ function readUInt64LE (buffer, offset) { return b + a } -function writeUInt64LE (buffer, value, offset) { +export function writeUInt64LE (buffer: Buffer, value: number, offset: number): number { verifuint(value, 0x001fffffffffffff) buffer.writeInt32LE(value & -1, offset) buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4) return offset + 8 } - -module.exports = { - readUInt64LE: readUInt64LE, - writeUInt64LE: writeUInt64LE -} -export {} diff --git a/src/classify.ts b/src/classify.ts index 3f824c4..5eabc7e 100644 --- a/src/classify.ts +++ b/src/classify.ts @@ -9,18 +9,18 @@ const witnessScriptHash = require('./templates/witnessscripthash') const witnessCommitment = require('./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', + NONSTANDARD: 'nonstandard', + NULLDATA: 'nulldata', + P2PK: 'pubkey', + P2PKH: 'pubkeyhash', + P2SH: 'scripthash', + P2WPKH: 'witnesspubkeyhash', + P2WSH: 'witnessscripthash', + WITNESS_COMMITMENT: 'witnesscommitment' } -function classifyOutput (script) { +function classifyOutput (script: Buffer): string { if (witnessPubKeyHash.output.check(script)) return types.P2WPKH if (witnessScriptHash.output.check(script)) return types.P2WSH if (pubKeyHash.output.check(script)) return types.P2PKH @@ -38,7 +38,7 @@ function classifyOutput (script) { return types.NONSTANDARD } -function classifyInput (script, allowIncomplete) { +function classifyInput (script: Buffer, allowIncomplete: boolean): string { // XXX: optimization, below functions .decompile before use const chunks = decompile(script) if (!chunks) throw new TypeError('Invalid script') @@ -51,7 +51,7 @@ function classifyInput (script, allowIncomplete) { return types.NONSTANDARD } -function classifyWitness (script, allowIncomplete) { +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') @@ -62,10 +62,9 @@ function classifyWitness (script, allowIncomplete) { return types.NONSTANDARD } -module.exports = { - input: classifyInput, - output: classifyOutput, - witness: classifyWitness, - types: types +export { + classifyInput as input, + classifyOutput as output, + classifyWitness as witness, + types, } -export {} diff --git a/src/crypto.ts b/src/crypto.ts index a04c67f..6aabb5b 100644 --- a/src/crypto.ts +++ b/src/crypto.ts @@ -1,30 +1,21 @@ const createHash = require('create-hash') -function ripemd160 (buffer) { +export function ripemd160 (buffer: Buffer): Buffer { return createHash('rmd160').update(buffer).digest() } -function sha1 (buffer) { +export function sha1 (buffer: Buffer): Buffer { return createHash('sha1').update(buffer).digest() } -function sha256 (buffer) { +export function sha256 (buffer: Buffer): Buffer { return createHash('sha256').update(buffer).digest() } -function hash160 (buffer) { +export function hash160 (buffer: Buffer): Buffer { return ripemd160(sha256(buffer)) } -function hash256 (buffer) { +export function hash256 (buffer: Buffer): Buffer { return sha256(sha256(buffer)) } - -module.exports = { - hash160: hash160, - hash256: hash256, - ripemd160: ripemd160, - sha1: sha1, - sha256: sha256 -} -export {} diff --git a/src/networks.ts b/src/networks.ts index 0aac048..f8ee1aa 100644 --- a/src/networks.ts +++ b/src/networks.ts @@ -1,39 +1,49 @@ // https://en.bitcoin.it/wiki/List_of_address_prefixes // Dogecoin BIP32 is a proposed standard: https://bitcointalk.org/index.php?topic=409731 - -module.exports = { - bitcoin: { - messagePrefix: '\x18Bitcoin Signed Message:\n', - bech32: 'bc', - bip32: { - public: 0x0488b21e, - private: 0x0488ade4 - }, - pubKeyHash: 0x00, - scriptHash: 0x05, - wif: 0x80 - }, - regtest: { - messagePrefix: '\x18Bitcoin Signed Message:\n', - bech32: 'bcrt', - bip32: { - public: 0x043587cf, - private: 0x04358394 - }, - pubKeyHash: 0x6f, - scriptHash: 0xc4, - wif: 0xef - }, - testnet: { - messagePrefix: '\x18Bitcoin Signed Message:\n', - bech32: 'tb', - bip32: { - public: 0x043587cf, - private: 0x04358394 - }, - pubKeyHash: 0x6f, - scriptHash: 0xc4, - wif: 0xef - } +export declare type Network = { + messagePrefix: string; + bech32: string; + bip32: bip32; + pubKeyHash: number; + scriptHash: number; + wif: number; +} + +declare type bip32 = { + public: number; + private: number; +} + +export const bitcoin: Network = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bech32: 'bc', + bip32: { + public: 0x0488b21e, + private: 0x0488ade4 + }, + pubKeyHash: 0x00, + scriptHash: 0x05, + wif: 0x80 +} +export const regtest: Network = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bech32: 'bcrt', + bip32: { + public: 0x043587cf, + private: 0x04358394 + }, + pubKeyHash: 0x6f, + scriptHash: 0xc4, + wif: 0xef +} +export const testnet: Network = { + messagePrefix: '\x18Bitcoin Signed Message:\n', + bech32: 'tb', + bip32: { + public: 0x043587cf, + private: 0x04358394 + }, + pubKeyHash: 0x6f, + scriptHash: 0xc4, + wif: 0xef } -export {}