duck typing.

This commit is contained in:
Christopher Jeffrey 2016-03-24 13:28:24 -07:00
parent 1db0954c83
commit 6ce950d081
16 changed files with 153 additions and 34 deletions

View File

@ -54,6 +54,12 @@ function Address(options) {
}, this);
}
Address.isAddress = function isAddress(obj) {
return obj
&& Array.isArray(obj.keys)
&& typeof obj._getAddressMap === 'function';
};
Address.prototype.getID = function getID() {
return this.getKeyAddress();
};

View File

@ -420,6 +420,12 @@ Block.fromCompact = function fromCompact(buf) {
};
};
Block.isBlock = function isBlock(obj) {
return obj
&& typeof obj.merkleRoot === 'string'
&& typeof obj.toCompact === 'function';
};
/**
* Expose
*/

View File

@ -302,6 +302,12 @@ ChainBlock.prototype.inspect = function inspect() {
return json;
};
ChainBlock.isChainBlock = function isChainBlock(obj) {
return obj
&& bn.isBN(obj.chainwork)
&& typeof obj.getMedianTime === 'function';
};
/**
* Expose
*/

View File

@ -54,7 +54,7 @@ function Coin(tx, index) {
assert(typeof this.version === 'number');
assert(utils.isFinite(this.height));
assert(this.value instanceof bn);
assert(bn.isBN(this.value));
assert(this.script instanceof bcoin.script);
assert(typeof this.coinbase === 'boolean');
// assert(typeof this.hash === 'string');
@ -198,6 +198,13 @@ Coin.fromExtended = function fromExtended(data, enc) {
return new Coin(Coin._fromExtended(data, enc));
};
Coin.isCoin = function isCoin(obj) {
return obj
&& typeof obj.version === 'number'
&& typeof obj.script === 'object'
&& typeof obj.getConfirmations === 'function';
};
/**
* Expose
*/

View File

@ -112,6 +112,12 @@ HDSeed.prototype.createMnemonic = function createMnemonic(entropy) {
return mnemonic.join(' ');
};
HDSeed.isHDSeed = function isHDSeed(obj) {
return obj
&& typeof obj.bits === 'number'
&& typeof obj.createSeed === 'function';
};
/**
* Abstract
*/
@ -130,6 +136,10 @@ HD.fromSeed = function fromSeed(options) {
HD.cache = new LRU(500);
HD.isHD = function isHD(obj) {
return HDPrivateKey.isHDPrivateKey(obj) || HDPublicKey.isHDPublicKey(obj);
};
/**
* HD Private Key
*/
@ -184,6 +194,10 @@ function HDPrivateKey(options) {
this.isPublic = false;
}
HDPublicKey.isHDPrivateKey = function isHDPrivateKey(obj) {
return obj && obj.isPrivate && typeof obj._unbuild === 'function';
};
utils.inherits(HDPrivateKey, HD);
HDPrivateKey.prototype.deriveAccount44 = function deriveAccount44(options) {
@ -809,6 +823,10 @@ function HDPublicKey(options) {
utils.inherits(HDPublicKey, HD);
HDPublicKey.isHDPublicKey = function isHDPublicKey(obj) {
return obj && obj.isPublic && typeof obj._unbuild === 'function';
};
HDPublicKey.prototype.scan44 = HDPrivateKey.prototype.scan44;
HDPublicKey.prototype.deriveAccount44 = HDPrivateKey.prototype.deriveAccount44;
HDPublicKey.prototype.deriveBIP44 = HDPrivateKey.prototype.deriveBIP44;

View File

@ -18,26 +18,32 @@ function Headers(data) {
bcoin.abstractblock.call(this, data);
this.type = 'headers';
if (!this._raw)
this._raw = this.render();
if (!this._size)
this._size = this._raw.length;
}
utils.inherits(Headers, bcoin.abstractblock);
Headers.prototype.render = function render() {
if (this._raw)
return this._raw;
return bcoin.protocol.framer.headers(this);
return this.getRaw();
};
Headers.prototype._verify = function _verify() {
return this.verifyHeaders();
};
Headers.prototype.getSize = function getSize() {
if (this._size == null)
this.getRaw();
return this._size;
};
Headers.prototype.getRaw = function getRaw() {
if (!this._raw) {
this._raw = bcoin.protocol.framer.headers(this);
this._size = this._raw.length;
}
return this._raw;
};
Headers.prototype.inspect = function inspect() {
var copy = bcoin.headers(this);
copy.__proto__ = null;
@ -71,6 +77,9 @@ Headers.fromRaw = function fromRaw(data, enc) {
return new Headers(Headers._fromRaw(data, enc));
};
Headers.isHeaders = function isHeaders(obj) {
return obj && obj.type === 'headers' && typeof obj.render === 'function';
};
/**
* Expose

View File

@ -303,6 +303,14 @@ Input.fromExtended = function fromExtended(data, enc) {
return new Input(Input._fromExtended(data, enc));
};
Input.isInput = function isInput(obj) {
return obj
&& obj.prevout
&& obj.script
&& obj.witness
&& typeof obj.getAddress === 'function';
};
/**
* Expose
*/

View File

@ -35,9 +35,21 @@ function MerkleBlock(data) {
utils.inherits(MerkleBlock, bcoin.abstractblock);
MerkleBlock.prototype.render = function render() {
if (this._raw)
return this._raw;
return bcoin.protocol.framer.merkleBlock(this);
return this.getRaw();
};
MerkleBlock.prototype.getSize = function getSize() {
if (this._size == null)
this.getRaw();
return this._size;
};
MerkleBlock.prototype.getRaw = function getRaw() {
if (!this._raw) {
this._raw = bcoin.protocol.framer.merkleBlock(this);
this._size = this._raw.length;
}
return this._raw;
};
MerkleBlock.prototype.hasTX = function hasTX(hash) {
@ -154,6 +166,12 @@ MerkleBlock.fromRaw = function fromRaw(data, enc) {
return new MerkleBlock(MerkleBlock._fromRaw(data, enc));
};
MerkleBlock.isMerkleBlock = function isMerkleBlock(obj) {
return obj
&& Array.isArray(obj.flags)
&& typeof obj._verifyPartial === 'function';
};
/**
* Expose
*/

View File

@ -1118,6 +1118,14 @@ MTX.prototype.toTX = function toTX() {
return new bcoin.tx(this);
};
MTX.isMTX = function isMTX(obj) {
return obj
&& Array.isArray(obj.inputs)
&& typeof obj.ps === 'number'
&& typeof obj.changeIndex === 'number'
&& typeof obj.scriptInput === 'function';
};
/**
* Expose
*/

View File

@ -151,6 +151,13 @@ Output.fromRaw = function fromRaw(data, enc) {
return new Output(Output._fromRaw(data, enc));
};
Output.isOutput = function isOutput(obj) {
return obj
&& obj.value
&& obj.script
&& typeof obj.getAddress === 'function';
};
/**
* Expose
*/

View File

@ -125,6 +125,12 @@ Witness.fromString = function fromString(items) {
return new Witness(items);
};
Witness.isWitness = function isWitness(obj) {
return obj
&& Array.isArray(obj.items)
&& typeof obj.toStack === 'function';
};
function Stack(items) {
this.items = items || [];
this.alt = [];
@ -388,6 +394,10 @@ Stack.prototype.size = function size() {
this.push(Script.array(this.top(-1).length));
};
Stack.isStack = function isStack(obj) {
return obj && Array.isArray(obj.alt) && typeof obj.swap2 === 'function';
};
/**
* Script
*/
@ -1106,7 +1116,7 @@ Script.bool = function bool(value) {
// if (utils.isFinite(value))
// return value !== 0;
if (value instanceof bn)
if (bn.isBN(value))
return value.cmpn(0) !== 0;
assert(Buffer.isBuffer(value));
@ -1174,7 +1184,7 @@ Script.array = function(value) {
if (utils.isFinite(value))
value = new bn(value, 'le');
assert(value instanceof bn);
assert(bn.isBN(value));
// Convert the number to the
// negative byte representation.
@ -1231,7 +1241,7 @@ Script.checkPush = function checkPush(value, flags) {
return true;
};
Script.isScript = function isScript(buf) {
Script.isCode = function isCode(buf) {
var i, b;
if (!buf)
@ -1872,7 +1882,7 @@ Script.isScripthashInput = function isScripthashInput(code, redeem, isWitness) {
if (Script.isKeyEncoding(raw))
return false;
if (!Script.isScript(raw))
if (!Script.isCode(raw))
return false;
return true;
@ -2676,6 +2686,12 @@ Script.encode = function encode(code) {
return p.render();
};
Script.isScript = function isScript(obj) {
return obj
&& Array.isArray(obj.code)
&& typeof obj.getSubscript === 'function';
};
Script.witness = Witness;
Script.stack = Stack;
module.exports = Script;

View File

@ -1259,6 +1259,13 @@ TX.prototype.toCoins = function toCoins() {
return bcoin.coins.fromTX(this);
};
TX.isTX = function isTX(obj) {
return obj
&& Array.isArray(obj.inputs)
&& typeof obj.ps === 'number'
&& typeof obj.getVirtualSize === 'function';
};
/**
* Expose
*/

View File

@ -606,7 +606,7 @@ utils.isFinite = function _isFinite(val) {
};
utils.isSatoshi = function isSatoshi(val) {
if (val instanceof bn)
if (bn.isBN(val))
return val;
if (utils.isInt(val))
return new bn(val, 10);
@ -1192,7 +1192,7 @@ utils.writeU32BE = function writeU32BE(dst, num, off) {
utils.writeU64 = function writeU64(dst, num, off) {
var i;
if (!(num instanceof bn))
if (!bn.isBN(num))
num = new bn(+num);
off = off >>> 0;
@ -1218,7 +1218,7 @@ utils.writeU64 = function writeU64(dst, num, off) {
utils.writeU64BE = function writeU64BE(dst, num, off) {
var i;
if (!(num instanceof bn))
if (!bn.isBN(num))
num = new bn(+num);
off = off >>> 0;
@ -1244,7 +1244,7 @@ utils.writeU64BE = function writeU64BE(dst, num, off) {
utils.writeU256 = function writeU256(dst, num, off) {
var i;
if (!(num instanceof bn))
if (!bn.isBN(num))
num = new bn(+num);
off = off >>> 0;
@ -1267,7 +1267,7 @@ utils.writeU256 = function writeU256(dst, num, off) {
utils.writeU256BE = function writeU256BE(dst, num, off) {
var i;
if (!(num instanceof bn))
if (!bn.isBN(num))
num = new bn(+num);
off = off >>> 0;
@ -1333,7 +1333,7 @@ utils.write32BE = function write32BE(dst, num, off) {
utils.write64 = function write64(dst, num, off) {
var i;
if (!(num instanceof bn))
if (!bn.isBN(num))
num = new bn(+num);
off = off >>> 0;
@ -1363,7 +1363,7 @@ utils.write64 = function write64(dst, num, off) {
utils.write64BE = function write64BE(dst, num, off) {
var i;
if (!(num instanceof bn))
if (!bn.isBN(num))
num = new bn(+num);
off = off >>> 0;
@ -1423,7 +1423,7 @@ utils.readIntv = function readIntv(arr, off) {
utils.writeIntv = function writeIntv(dst, num, off) {
off = off >>> 0;
if (num instanceof bn) {
if (bn.isBN(num)) {
if (num.cmpn(0xffffffff) > 0) {
dst[off] = 0xff;
utils.writeU64(dst, num, off + 1);
@ -1461,7 +1461,7 @@ utils.writeIntv = function writeIntv(dst, num, off) {
};
utils.sizeIntv = function sizeIntv(num) {
if (num instanceof bn) {
if (bn.isBN(num)) {
if (num.cmpn(0xffffffff) > 0)
return 9;
num = num.toNumber();

View File

@ -40,12 +40,8 @@ function Wallet(options) {
this.options = options;
this.provider = options.provider || null;
this.addresses = [];
this.master = options.master || null;
this.addressMap = options.addressMap || {};
this.labelMap = {};
this.change = [];
this.receive = [];
this.witness = options.witness || false;
this.loaded = false;
@ -1091,6 +1087,12 @@ Wallet.setDepth = function setDepth(json, receiveDepth, changeDepth) {
});
};
Wallet.isWallet = function isWallet(obj) {
return obj
&& typeof obj.receiveDepth === 'number'
&& obj.deriveAddress === 'function';
};
/**
* Expose
*/

View File

@ -214,7 +214,7 @@ function frameItem(item, p) {
} else if (item instanceof bcoin.coin) {
p.writeU8(42);
p.writeVarBytes(item.toExtended());
} else if (item instanceof bn) {
} else if (bn.isBN(item)) {
p.writeU8(43);
p.writeVarBytes(item.toBuffer());
} else if (Buffer.isBuffer(item)) {

View File

@ -28,9 +28,10 @@
"node": ">= 0.8.0"
},
"dependencies": {
"bn.js": "4.10.3",
"elliptic": "6.0.2",
"leveldown": "1.4.4"
"bn.js": "4.11.0",
"elliptic": "6.2.3",
"leveldown": "git://github.com/Level/leveldown.git#master",
"memdown": "1.1.2"
},
"optionalDependencies": {
"secp256k1": "3.0.0",