Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Code coverage
.nyc_output
coverage

# Dependencies
node_modules

# Outputs
dist

# ide
.idea

# github
.github

# WebAssembly
wasm

# prose
*.md
21 changes: 12 additions & 9 deletions classes/address.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ const PUBLIC_KEY_TO_ADDRESS_CACHE = new WeakMap() // Cached to reduce ripemd160
const ADDRESS_TO_STRING_CACHE = new WeakMap() // Cached to reduce sha256 hashing

class Address {
constructor (pubkeyhash, testnet, validate = true) {
constructor(pubkeyhash, testnet, validate = true) {
if (validate) {
if (!isBuffer(pubkeyhash) || pubkeyhash.length !== 20) throw new Error('bad pubkeyhash')
if (!isBuffer(pubkeyhash) || pubkeyhash.length !== 20)
throw new Error('bad pubkeyhash')
if (typeof testnet !== 'boolean') throw new Error('bad testnet flag')
}

Expand All @@ -20,15 +21,16 @@ class Address {
Object.freeze(this)
}

static fromString (s) {
static fromString(s) {
const { pubkeyhash, testnet } = decodeAddress(s)
const address = new Address(pubkeyhash, testnet, false)
ADDRESS_TO_STRING_CACHE.set(address, s)
return address
}

static fromPublicKey (publicKey) {
if (PUBLIC_KEY_TO_ADDRESS_CACHE.has(publicKey)) return PUBLIC_KEY_TO_ADDRESS_CACHE.get(publicKey)
static fromPublicKey(publicKey) {
if (PUBLIC_KEY_TO_ADDRESS_CACHE.has(publicKey))
return PUBLIC_KEY_TO_ADDRESS_CACHE.get(publicKey)

const testnet = publicKey.testnet
const pubkeyhash = calculatePublicKeyHash(publicKey.point)
Expand All @@ -39,7 +41,7 @@ class Address {
return address
}

static from (x) {
static from(x) {
if (x instanceof Address) return x
const PublicKey = require('./public-key')
if (x instanceof PublicKey) return Address.fromPublicKey(x)
Expand All @@ -48,14 +50,15 @@ class Address {
throw new Error('unsupported type')
}

toString () {
if (ADDRESS_TO_STRING_CACHE.has(this)) return ADDRESS_TO_STRING_CACHE.get(this)
toString() {
if (ADDRESS_TO_STRING_CACHE.has(this))
return ADDRESS_TO_STRING_CACHE.get(this)
const address = encodeAddress(this.pubkeyhash, this.testnet)
ADDRESS_TO_STRING_CACHE.set(this, address)
return address
}

toScript () {
toScript() {
const Script = require('./script')
return Script.templates.P2PKHLockScript.fromAddress(this)
}
Expand Down
11 changes: 6 additions & 5 deletions classes/buffer-reader.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class BufferReader {
constructor (buffer, pos = 0) {
constructor(buffer, pos = 0) {
this.buffer = buffer
this.pos = pos
}

read (length) {
read(length) {
this.checkRemaining(length)

const start = this.pos
Expand All @@ -16,12 +16,13 @@ class BufferReader {
return buffer
}

close () {
close() {
if (this.pos !== this.buffer.length) throw new Error('unconsumed data')
}

checkRemaining (length) {
if (this.buffer.length - this.pos < length) throw new Error('not enough data')
checkRemaining(length) {
if (this.buffer.length - this.pos < length)
throw new Error('not enough data')
}
}

Expand Down
8 changes: 4 additions & 4 deletions classes/buffer-writer.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
class BufferWriter {
constructor () {
constructor() {
this.buffers = []
this.length = 0
}

write (buffer) {
write(buffer) {
this.buffers.push(buffer)
this.length += buffer.length
return this
}

toBuffer () {
toBuffer() {
if (this.buffers.length === 1) {
return this.buffers[0]
}

const whole = new Uint8Array(this.length)

let offset = 0
this.buffers.forEach(part => {
this.buffers.forEach((part) => {
whole.set(part, offset)
offset += part.length
})
Expand Down
2 changes: 1 addition & 1 deletion classes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ module.exports = {
PrivateKey: require('./private-key'),
PublicKey: require('./public-key'),
Script: require('./script'),
Transaction: require('./transaction')
Transaction: require('./transaction'),
}
23 changes: 13 additions & 10 deletions classes/private-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ const verifyPrivateKey = require('../functions/verify-private-key')
const PRIVATE_KEY_TO_WIF_CACHE = new WeakMap() // Cached to reduce sha256

class PrivateKey {
constructor (number, testnet, compressed, validate = true) {
constructor(number, testnet, compressed, validate = true) {
if (validate) {
if (!isBuffer(number)) throw new Error('bad number')
if (typeof testnet !== 'boolean') throw new Error('bad testnet flag')
if (typeof compressed !== 'boolean') throw new Error('bad compressed flag')
if (typeof compressed !== 'boolean')
throw new Error('bad compressed flag')
verifyPrivateKey(number)
}

Expand All @@ -23,39 +24,41 @@ class PrivateKey {
Object.freeze(this)
}

static fromString (wif) {
static fromString(wif) {
const { number, testnet, compressed } = decodeWIF(wif)
const privateKey = new PrivateKey(number, testnet, compressed, false)
PRIVATE_KEY_TO_WIF_CACHE.set(privateKey, wif)
return privateKey
}

static fromRandom (testnet = require('../index').testnet) {
static fromRandom(testnet = require('../index').testnet) {
const number = generatePrivateKey()
const compressed = true
return new PrivateKey(number, testnet, compressed, false)
}

static from (privateKey) {
static from(privateKey) {
if (privateKey instanceof PrivateKey) return privateKey
if (typeof privateKey === 'object' && privateKey) privateKey = privateKey.toString()
if (typeof privateKey === 'object' && privateKey)
privateKey = privateKey.toString()
if (typeof privateKey === 'string') return PrivateKey.fromString(privateKey)
throw new Error('unsupported type')
}

toString () {
if (PRIVATE_KEY_TO_WIF_CACHE.has(this)) return PRIVATE_KEY_TO_WIF_CACHE.get(this)
toString() {
if (PRIVATE_KEY_TO_WIF_CACHE.has(this))
return PRIVATE_KEY_TO_WIF_CACHE.get(this)
const wif = encodeWIF(this.number, this.testnet, this.compressed)
PRIVATE_KEY_TO_WIF_CACHE.set(this, wif)
return wif
}

toPublicKey () {
toPublicKey() {
const PublicKey = require('./public-key')
return PublicKey.fromPrivateKey(this)
}

toAddress () {
toAddress() {
return this.toPublicKey().toAddress()
}
}
Expand Down
26 changes: 15 additions & 11 deletions classes/public-key.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ const verifyPoint = require('../functions/verify-point')
const PRIVATE_KEY_TO_PUBLIC_KEY_CACHE = new WeakMap() // Cached to reduce secp256k1 multiplication

class PublicKey {
constructor (point, testnet, compressed, validate = true) {
constructor(point, testnet, compressed, validate = true) {
if (validate) {
if (typeof point !== 'object' || !isBuffer(point.x) || !isBuffer(point.y)) throw new Error('bad point')
if (typeof point !== 'object' || !isBuffer(point.x) || !isBuffer(point.y))
throw new Error('bad point')
if (typeof testnet !== 'boolean') throw new Error('bad testnet flag')
if (typeof compressed !== 'boolean') throw new Error('bad compressed flag')
if (typeof compressed !== 'boolean')
throw new Error('bad compressed flag')
verifyPoint(point)
}

Expand All @@ -25,18 +27,20 @@ class PublicKey {
Object.freeze(this)
}

static fromString (pubkey) {
static fromString(pubkey) {
const point = decodePublicKey(decodeHex(pubkey))
const testnet = require('../index').testnet
const compressed = pubkey.length === 66
return new PublicKey(point, testnet, compressed, false)
}

static fromPrivateKey (privateKey) {
if (PRIVATE_KEY_TO_PUBLIC_KEY_CACHE.has(privateKey)) return PRIVATE_KEY_TO_PUBLIC_KEY_CACHE.get(privateKey)
static fromPrivateKey(privateKey) {
if (PRIVATE_KEY_TO_PUBLIC_KEY_CACHE.has(privateKey))
return PRIVATE_KEY_TO_PUBLIC_KEY_CACHE.get(privateKey)

const PrivateKey = require('./private-key')
if (!(privateKey instanceof PrivateKey)) throw new Error(`not a PrivateKey: ${privateKey}`)
if (!(privateKey instanceof PrivateKey))
throw new Error(`not a PrivateKey: ${privateKey}`)

const point = calculatePublicKey(privateKey.number)
const testnet = privateKey.testnet
Expand All @@ -48,7 +52,7 @@ class PublicKey {
return publicKey
}

static from (x) {
static from(x) {
if (x instanceof PublicKey) return x
const PrivateKey = require('./private-key')
if (x instanceof PrivateKey) return PublicKey.fromPrivateKey(x)
Expand All @@ -57,15 +61,15 @@ class PublicKey {
throw new Error('unsupported type')
}

toString () {
toString() {
return encodeHex(this.toBuffer())
}

toBuffer () {
toBuffer() {
return encodePublicKey(this.point, this.compressed)
}

toAddress () {
toAddress() {
const Address = require('./address')
return Address.fromPublicKey(this)
}
Expand Down
Loading