more wallet work.
This commit is contained in:
parent
9c747cde42
commit
3480b8c679
@ -487,10 +487,6 @@ KeyRing.prototype.sign = function sign(tx, key, index, type) {
|
|||||||
return total;
|
return total;
|
||||||
};
|
};
|
||||||
|
|
||||||
KeyRing.prototype.__defineGetter__('privateKey', function() {
|
|
||||||
return this.getPrivateKey();
|
|
||||||
});
|
|
||||||
|
|
||||||
KeyRing.prototype.__defineGetter__('publicKey', function() {
|
KeyRing.prototype.__defineGetter__('publicKey', function() {
|
||||||
return this.getPublicKey();
|
return this.getPublicKey();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -986,7 +986,7 @@ MTX.prototype.selectCoins = function selectCoins(coins, options) {
|
|||||||
if (options.confirmed && coin.height === -1)
|
if (options.confirmed && coin.height === -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (options.height != null && coin.coinbase) {
|
if (options.height >= 0 && coin.coinbase) {
|
||||||
if (options.height + 1 < coin.height + constants.tx.COINBASE_MATURITY)
|
if (options.height + 1 < coin.height + constants.tx.COINBASE_MATURITY)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,44 +45,6 @@ var BufferWriter = require('./writer');
|
|||||||
* (default=account key "address").
|
* (default=account key "address").
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function MasterKey(options) {
|
|
||||||
this.json = options.json;
|
|
||||||
this.key = options.key || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
MasterKey.prototype.decrypt = function decrypt(passphrase) {
|
|
||||||
if (this.key)
|
|
||||||
return this.key;
|
|
||||||
|
|
||||||
if (!this.json.encrypted)
|
|
||||||
return bcoin.hd.fromJSON(this.json);
|
|
||||||
|
|
||||||
return bcoin.hd.fromJSON(this.json, passphrase);
|
|
||||||
};
|
|
||||||
|
|
||||||
MasterKey.prototype.toJSON = function toJSON() {
|
|
||||||
return this.json;
|
|
||||||
};
|
|
||||||
|
|
||||||
MasterKey.fromKey = function fromKey(key) {
|
|
||||||
return new MasterKey({
|
|
||||||
key: key,
|
|
||||||
json: key.toJSON()
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
MasterKey.fromJSON = function fromJSON(json) {
|
|
||||||
var key;
|
|
||||||
|
|
||||||
if (!json.encrypted)
|
|
||||||
key = bcoin.hd.fromJSON(json);
|
|
||||||
|
|
||||||
return new MasterKey({
|
|
||||||
key: key,
|
|
||||||
json: json
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function Wallet(options) {
|
function Wallet(options) {
|
||||||
var i, key;
|
var i, key;
|
||||||
|
|
||||||
@ -129,7 +91,7 @@ function Wallet(options) {
|
|||||||
this.m = options.m || 1;
|
this.m = options.m || 1;
|
||||||
this.n = options.n || 1;
|
this.n = options.n || 1;
|
||||||
|
|
||||||
this.cache = new bcoin.lru(20);
|
this.cache = new bcoin.lru(20, 1);
|
||||||
|
|
||||||
if (this.n > 1)
|
if (this.n > 1)
|
||||||
this.type = 'multisig';
|
this.type = 'multisig';
|
||||||
@ -1114,7 +1076,7 @@ Wallet.prototype.scan = function scan(getByAddress, callback) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var res = false;
|
var res = false;
|
||||||
|
|
||||||
return this._scan({}, getByAddress, function(err, depth, txs) {
|
return this._scan(getByAddress, function(err, depth, txs) {
|
||||||
if (err)
|
if (err)
|
||||||
return callback(err);
|
return callback(err);
|
||||||
|
|
||||||
@ -1124,42 +1086,13 @@ Wallet.prototype.scan = function scan(getByAddress, callback) {
|
|||||||
if (self.setReceiveDepth(depth.receiveDepth + 1))
|
if (self.setReceiveDepth(depth.receiveDepth + 1))
|
||||||
res = true;
|
res = true;
|
||||||
|
|
||||||
if (self.provider && self.provider.addTX) {
|
|
||||||
utils.forEachSerial(txs, function(tx, next) {
|
|
||||||
self.addTX(tx, next);
|
|
||||||
}, function(err) {
|
|
||||||
if (err)
|
|
||||||
return callback(err);
|
|
||||||
return callback(null, res, txs);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(null, res, txs);
|
return callback(null, res, txs);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
Wallet.prototype._scan = function _scan(getByAddress, callback) {
|
||||||
* Clone the wallet (used for scanning).
|
var self = this;
|
||||||
* @returns {Wallet}
|
|
||||||
*/
|
|
||||||
|
|
||||||
Wallet.prototype.clone = function clone() {
|
|
||||||
var passphrase = this.options.passphrase;
|
|
||||||
var wallet;
|
|
||||||
|
|
||||||
delete this.options.passphrase;
|
|
||||||
|
|
||||||
wallet = Wallet.fromJSON(this.toJSON());
|
|
||||||
|
|
||||||
this.options.passphrase = passphrase;
|
|
||||||
|
|
||||||
return wallet;
|
|
||||||
};
|
|
||||||
|
|
||||||
Wallet.prototype._scan = function _scan(options, getByAddress, callback) {
|
|
||||||
var depth = { changeDepth: 0, receiveDepth: 0 };
|
var depth = { changeDepth: 0, receiveDepth: 0 };
|
||||||
var wallet = this.clone();
|
|
||||||
var all = [];
|
var all = [];
|
||||||
|
|
||||||
assert(this._initialized);
|
assert(this._initialized);
|
||||||
@ -1170,7 +1103,7 @@ Wallet.prototype._scan = function _scan(options, getByAddress, callback) {
|
|||||||
var gap = 0;
|
var gap = 0;
|
||||||
|
|
||||||
(function next() {
|
(function next() {
|
||||||
var address = wallet.deriveAddress(change, addressIndex++);
|
var address = self.deriveAddress(change, addressIndex++);
|
||||||
|
|
||||||
getByAddress(address.getAddress(), function(err, txs) {
|
getByAddress(address.getAddress(), function(err, txs) {
|
||||||
var result;
|
var result;
|
||||||
@ -1250,10 +1183,15 @@ Wallet.prototype.scriptInputs = function scriptInputs(tx, index) {
|
|||||||
|
|
||||||
Wallet.prototype.sign = function sign(tx, passphrase, index, type) {
|
Wallet.prototype.sign = function sign(tx, passphrase, index, type) {
|
||||||
var addresses = this.deriveInputs(tx, index);
|
var addresses = this.deriveInputs(tx, index);
|
||||||
var key = this.master.decrypt(passphrase);
|
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var i, address, key;
|
var i, address, key;
|
||||||
|
|
||||||
|
try {
|
||||||
|
key = this.master.decrypt(passphrase);
|
||||||
|
} catch (e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < addresses.length; i++) {
|
for (i = 0; i < addresses.length; i++) {
|
||||||
address = addresses[i];
|
address = addresses[i];
|
||||||
|
|
||||||
@ -1499,10 +1437,6 @@ Wallet.prototype.getAddress = function getAddress() {
|
|||||||
return this.receiveAddress.getAddress();
|
return this.receiveAddress.getAddress();
|
||||||
};
|
};
|
||||||
|
|
||||||
Wallet.prototype.__defineGetter__('privateKey', function() {
|
|
||||||
return this.getPrivateKey();
|
|
||||||
});
|
|
||||||
|
|
||||||
Wallet.prototype.__defineGetter__('publicKey', function() {
|
Wallet.prototype.__defineGetter__('publicKey', function() {
|
||||||
return this.getPublicKey();
|
return this.getPublicKey();
|
||||||
});
|
});
|
||||||
@ -1681,6 +1615,45 @@ Wallet.isWallet = function isWallet(obj) {
|
|||||||
&& obj.deriveAddress === 'function';
|
&& obj.deriveAddress === 'function';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function MasterKey(options) {
|
||||||
|
this.json = options.json;
|
||||||
|
this.key = options.key || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
MasterKey.prototype.decrypt = function decrypt(passphrase) {
|
||||||
|
if (this.key)
|
||||||
|
return this.key;
|
||||||
|
|
||||||
|
if (!this.json.encrypted)
|
||||||
|
return bcoin.hd.fromJSON(this.json);
|
||||||
|
|
||||||
|
return bcoin.hd.fromJSON(this.json, passphrase);
|
||||||
|
};
|
||||||
|
|
||||||
|
MasterKey.prototype.toJSON = function toJSON() {
|
||||||
|
return this.json;
|
||||||
|
};
|
||||||
|
|
||||||
|
MasterKey.fromKey = function fromKey(key) {
|
||||||
|
return new MasterKey({
|
||||||
|
key: key,
|
||||||
|
json: key.toJSON()
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
MasterKey.fromJSON = function fromJSON(json) {
|
||||||
|
var key;
|
||||||
|
|
||||||
|
if (!json.encrypted)
|
||||||
|
key = bcoin.hd.fromJSON(json);
|
||||||
|
|
||||||
|
return new MasterKey({
|
||||||
|
key: key,
|
||||||
|
json: json
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expose
|
* Expose
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -252,6 +252,37 @@ WalletDB.prototype.syncOutputDepth = function syncOutputDepth(id, tx, callback)
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive an address.
|
||||||
|
* @param {WalletID} id
|
||||||
|
* @param {Boolean} change
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
WalletDB.prototype.createAddress = function createAddress(id, change, callback) {
|
||||||
|
var self = this;
|
||||||
|
var address;
|
||||||
|
|
||||||
|
callback = utils.ensure(callback);
|
||||||
|
|
||||||
|
this.get(id, function(err, json) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
if (!wallet)
|
||||||
|
return callback(new Error('No wallet.'));
|
||||||
|
|
||||||
|
address = wallet.createAddress(change);
|
||||||
|
|
||||||
|
self.save(wallet, function(err) {
|
||||||
|
if (err)
|
||||||
|
return callback(err);
|
||||||
|
|
||||||
|
return callback(null, address);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a public account/purpose key to the wallet for multisig.
|
* Add a public account/purpose key to the wallet for multisig.
|
||||||
* @param {WalletID} id
|
* @param {WalletID} id
|
||||||
@ -260,7 +291,7 @@ WalletDB.prototype.syncOutputDepth = function syncOutputDepth(id, tx, callback)
|
|||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
|
|
||||||
WalletDB.prototype.addKey = function addKey(id, key, callback) {
|
WalletDB.prototype.modifyKey = function modifyKey(id, key, remove, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
callback = utils.ensure(callback);
|
callback = utils.ensure(callback);
|
||||||
@ -273,37 +304,10 @@ WalletDB.prototype.addKey = function addKey(id, key, callback) {
|
|||||||
return callback(new Error('No wallet.'));
|
return callback(new Error('No wallet.'));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
wallet.addKey(key);
|
if (!remove)
|
||||||
} catch (e) {
|
wallet.addKey(key);
|
||||||
return callback(e);
|
else
|
||||||
}
|
wallet.removeKey(key);
|
||||||
|
|
||||||
self.save(wallet, callback);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove a public account/purpose key to the wallet for multisig.
|
|
||||||
* @param {WalletID} id
|
|
||||||
* @param {HDPublicKey|Base58String} key - Account (bip44) or Purpose
|
|
||||||
* (bip45) key (can be in base58 form).
|
|
||||||
* @param {Function} callback
|
|
||||||
*/
|
|
||||||
|
|
||||||
WalletDB.prototype.removeKey = function removeKey(id, key, callback) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
callback = utils.ensure(callback);
|
|
||||||
|
|
||||||
this.get(id, function(err, wallet) {
|
|
||||||
if (err)
|
|
||||||
return callback(err);
|
|
||||||
|
|
||||||
if (!wallet)
|
|
||||||
return callback(new Error('No wallet.'));
|
|
||||||
|
|
||||||
try {
|
|
||||||
wallet.removeKey(key);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return callback(e);
|
return callback(e);
|
||||||
}
|
}
|
||||||
@ -698,6 +702,41 @@ WalletDB.prototype.provider = function provider() {
|
|||||||
return new Provider(this);
|
return new Provider(this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
WalletDB.prototype.register = function register(id, provider) {
|
||||||
|
if (!this.listeners[id])
|
||||||
|
this.listeners[id] = [];
|
||||||
|
|
||||||
|
if (this.listeners[id].indexOf(provider) !== -1)
|
||||||
|
this.listeners[id].push(provider);
|
||||||
|
};
|
||||||
|
|
||||||
|
WalletDB.prototype.unregister = function unregister(id, provider) {
|
||||||
|
var listeners = this.listeners[id];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
if (!listeners)
|
||||||
|
return;
|
||||||
|
|
||||||
|
i = listeners.indexOf(provider);
|
||||||
|
if (i !== -1)
|
||||||
|
listeners.splice(i, 1);
|
||||||
|
|
||||||
|
if (listeners.length === 0)
|
||||||
|
delete this.listeners[id];
|
||||||
|
};
|
||||||
|
|
||||||
|
WalletDB.prototype.fire = function fire(id) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
var listeners = this.listeners[id];
|
||||||
|
var i;
|
||||||
|
|
||||||
|
if (!listeners)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < listeners.length; i++)
|
||||||
|
listeners.emit.apply(listener, args);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents {@link Wallet} Provider. This is what
|
* Represents {@link Wallet} Provider. This is what
|
||||||
* allows the {@link Wallet} object to access
|
* allows the {@link Wallet} object to access
|
||||||
@ -959,6 +998,66 @@ Provider.prototype.save = function save(wallet, callback) {
|
|||||||
return this.db.save(wallet, callback);
|
return this.db.save(wallet, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the provider backend that a new address was
|
||||||
|
* derived (not technically necessary if you're
|
||||||
|
* implementing a provider).
|
||||||
|
* @param {Wallet} wallet
|
||||||
|
* @param {Address} address
|
||||||
|
*/
|
||||||
|
|
||||||
|
Provider.prototype.addKey = function addKey(key, callback) {
|
||||||
|
return this.db.addKey(this.id, key, false, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the provider backend that a new address was
|
||||||
|
* derived (not technically necessary if you're
|
||||||
|
* implementing a provider).
|
||||||
|
* @param {Wallet} wallet
|
||||||
|
* @param {Address} address
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Provider.prototype.deriveInputs = function deriveInputs(tx, index, callback) {
|
||||||
|
// return this.db.deriveInputs(this.id, tx, index, callback);
|
||||||
|
// };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the provider backend that a new address was
|
||||||
|
* derived (not technically necessary if you're
|
||||||
|
* implementing a provider).
|
||||||
|
* @param {Wallet} wallet
|
||||||
|
* @param {Address} address
|
||||||
|
*/
|
||||||
|
|
||||||
|
Provider.prototype.removeKey = function removeKey(key, callback) {
|
||||||
|
return this.db.addKey(this.id, key, true, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the provider backend that a new address was
|
||||||
|
* derived (not technically necessary if you're
|
||||||
|
* implementing a provider).
|
||||||
|
* @param {Wallet} wallet
|
||||||
|
* @param {Address} address
|
||||||
|
*/
|
||||||
|
|
||||||
|
Provider.prototype.createReceive = function createReceive(callback) {
|
||||||
|
return this.db.createAddress(this.id, false, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the provider backend that a new address was
|
||||||
|
* derived (not technically necessary if you're
|
||||||
|
* implementing a provider).
|
||||||
|
* @param {Wallet} wallet
|
||||||
|
* @param {Address} address
|
||||||
|
*/
|
||||||
|
|
||||||
|
Provider.prototype.createChange = function createChange(callback) {
|
||||||
|
return this.db.createAddress(this.id, true, callback);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zap stale transactions.
|
* Zap stale transactions.
|
||||||
* @param {Number} now - Current time.
|
* @param {Number} now - Current time.
|
||||||
|
|||||||
@ -486,134 +486,165 @@ describe('Wallet', function() {
|
|||||||
n: 3
|
n: 3
|
||||||
};
|
};
|
||||||
|
|
||||||
wdb.create(utils.merge({}, options), function(err, w1) {
|
var w1, w2, w3, receive;
|
||||||
assert.ifError(err);
|
|
||||||
wdb.create(utils.merge({}, options), function(err, w2) {
|
utils.serial([
|
||||||
assert.ifError(err);
|
function(next) {
|
||||||
wdb.create(utils.merge({}, options), function(err, w3) {
|
wdb.create(utils.merge({}, options), function(err, w1_) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
wdb.create({}, function(err, receive) {
|
w1 = w1_;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
wdb.create(utils.merge({}, options), function(err, w2_) {
|
||||||
|
assert.ifError(err);
|
||||||
|
w2 = w2_;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
wdb.create(utils.merge({}, options), function(err, w3_) {
|
||||||
|
assert.ifError(err);
|
||||||
|
w3 = w3_;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(next) {
|
||||||
|
wdb.create({}, function(err, receive_) {
|
||||||
|
assert.ifError(err);
|
||||||
|
receive = receive_;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
], function(err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
|
||||||
|
w1.addKey(w2);
|
||||||
|
w1.addKey(w3);
|
||||||
|
w2.addKey(w1);
|
||||||
|
w2.addKey(w3);
|
||||||
|
w3.addKey(w1);
|
||||||
|
w3.addKey(w2);
|
||||||
|
|
||||||
|
utils.serial([
|
||||||
|
wdb.save.bind(wdb, w1),
|
||||||
|
wdb.save.bind(wdb, w2),
|
||||||
|
wdb.save.bind(wdb, w3),
|
||||||
|
wdb.save.bind(wdb, receive)
|
||||||
|
], function(err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
|
||||||
|
// w3 = bcoin.wallet.fromJSON(w3.toJSON());
|
||||||
|
|
||||||
|
// Our p2sh address
|
||||||
|
var addr = w1.getAddress();
|
||||||
|
|
||||||
|
if (witness)
|
||||||
|
assert(bcoin.address.parseBase58(addr).type === 'witnessscripthash');
|
||||||
|
else
|
||||||
|
assert(bcoin.address.parseBase58(addr).type === 'scripthash');
|
||||||
|
|
||||||
|
assert.equal(w1.getAddress(), addr);
|
||||||
|
assert.equal(w2.getAddress(), addr);
|
||||||
|
assert.equal(w3.getAddress(), addr);
|
||||||
|
|
||||||
|
var paddr = w1.getProgramAddress();
|
||||||
|
assert.equal(w1.getProgramAddress(), paddr);
|
||||||
|
assert.equal(w2.getProgramAddress(), paddr);
|
||||||
|
assert.equal(w3.getProgramAddress(), paddr);
|
||||||
|
|
||||||
|
// Add a shared unspent transaction to our wallets
|
||||||
|
var utx = bcoin.mtx();
|
||||||
|
if (bullshitNesting)
|
||||||
|
utx.addOutput({ address: paddr, value: 5460 * 10 });
|
||||||
|
else
|
||||||
|
utx.addOutput({ address: addr, value: 5460 * 10 });
|
||||||
|
|
||||||
|
utx.addInput(dummyInput);
|
||||||
|
|
||||||
|
assert(w1.ownOutput(utx.outputs[0]));
|
||||||
|
|
||||||
|
// Simulate a confirmation
|
||||||
|
utx.ps = 0;
|
||||||
|
utx.ts = 1;
|
||||||
|
utx.height = 1;
|
||||||
|
|
||||||
|
assert.equal(w1.receiveDepth, 1);
|
||||||
|
|
||||||
|
wdb.addTX(utx, function(err) {
|
||||||
|
assert.ifError(err);
|
||||||
|
wdb.addTX(utx, function(err) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
|
||||||
w1.addKey(w2);
|
|
||||||
w1.addKey(w3);
|
|
||||||
w2.addKey(w1);
|
|
||||||
w2.addKey(w3);
|
|
||||||
w3.addKey(w1);
|
|
||||||
w3.addKey(w2);
|
|
||||||
|
|
||||||
// w3 = bcoin.wallet.fromJSON(w3.toJSON());
|
|
||||||
|
|
||||||
// Our p2sh address
|
|
||||||
var addr = w1.getAddress();
|
|
||||||
|
|
||||||
if (witness)
|
|
||||||
assert(bcoin.address.parseBase58(addr).type === 'witnessscripthash');
|
|
||||||
else
|
|
||||||
assert(bcoin.address.parseBase58(addr).type === 'scripthash');
|
|
||||||
|
|
||||||
assert.equal(w1.getAddress(), addr);
|
|
||||||
assert.equal(w2.getAddress(), addr);
|
|
||||||
assert.equal(w3.getAddress(), addr);
|
|
||||||
|
|
||||||
var paddr = w1.getProgramAddress();
|
|
||||||
assert.equal(w1.getProgramAddress(), paddr);
|
|
||||||
assert.equal(w2.getProgramAddress(), paddr);
|
|
||||||
assert.equal(w3.getProgramAddress(), paddr);
|
|
||||||
|
|
||||||
// Add a shared unspent transaction to our wallets
|
|
||||||
var utx = bcoin.mtx();
|
|
||||||
if (bullshitNesting)
|
|
||||||
utx.addOutput({ address: paddr, value: 5460 * 10 });
|
|
||||||
else
|
|
||||||
utx.addOutput({ address: addr, value: 5460 * 10 });
|
|
||||||
|
|
||||||
utx.addInput(dummyInput);
|
|
||||||
|
|
||||||
assert(w1.ownOutput(utx.outputs[0]));
|
|
||||||
|
|
||||||
// Simulate a confirmation
|
|
||||||
utx.ps = 0;
|
|
||||||
utx.ts = 1;
|
|
||||||
utx.height = 1;
|
|
||||||
|
|
||||||
assert.equal(w1.receiveDepth, 1);
|
|
||||||
|
|
||||||
wdb.addTX(utx, function(err) {
|
wdb.addTX(utx, function(err) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
wdb.addTX(utx, function(err) {
|
|
||||||
|
assert.equal(w1.receiveDepth, 2);
|
||||||
|
assert.equal(w1.changeDepth, 1);
|
||||||
|
|
||||||
|
assert(w1.getAddress() !== addr);
|
||||||
|
addr = w1.getAddress();
|
||||||
|
assert.equal(w1.getAddress(), addr);
|
||||||
|
assert.equal(w2.getAddress(), addr);
|
||||||
|
assert.equal(w3.getAddress(), addr);
|
||||||
|
|
||||||
|
// Create a tx requiring 2 signatures
|
||||||
|
var send = bcoin.mtx();
|
||||||
|
send.addOutput({ address: receive.getAddress(), value: 5460 });
|
||||||
|
assert(!send.verify(null, true, flags));
|
||||||
|
w1.fill(send, { rate: 10000, round: true }, function(err) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
wdb.addTX(utx, function(err) {
|
|
||||||
|
w1.sign(send);
|
||||||
|
|
||||||
|
assert(!send.verify(null, true, flags));
|
||||||
|
w2.sign(send);
|
||||||
|
|
||||||
|
assert(send.verify(null, true, flags));
|
||||||
|
|
||||||
|
assert.equal(w1.changeDepth, 1);
|
||||||
|
var change = w1.changeAddress.getAddress();
|
||||||
|
assert.equal(w1.changeAddress.getAddress(), change);
|
||||||
|
assert.equal(w2.changeAddress.getAddress(), change);
|
||||||
|
assert.equal(w3.changeAddress.getAddress(), change);
|
||||||
|
|
||||||
|
// Simulate a confirmation
|
||||||
|
send.ps = 0;
|
||||||
|
send.ts = 1;
|
||||||
|
send.height = 1;
|
||||||
|
|
||||||
|
wdb.addTX(send, function(err) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
wdb.addTX(send, function(err) {
|
||||||
assert.equal(w1.receiveDepth, 2);
|
|
||||||
assert.equal(w1.changeDepth, 1);
|
|
||||||
|
|
||||||
assert(w1.getAddress() !== addr);
|
|
||||||
addr = w1.getAddress();
|
|
||||||
assert.equal(w1.getAddress(), addr);
|
|
||||||
assert.equal(w2.getAddress(), addr);
|
|
||||||
assert.equal(w3.getAddress(), addr);
|
|
||||||
|
|
||||||
// Create a tx requiring 2 signatures
|
|
||||||
var send = bcoin.mtx();
|
|
||||||
send.addOutput({ address: receive.getAddress(), value: 5460 });
|
|
||||||
assert(!send.verify(null, true, flags));
|
|
||||||
w1.fill(send, { rate: 10000, round: true }, function(err) {
|
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
|
|
||||||
w1.sign(send);
|
|
||||||
|
|
||||||
assert(!send.verify(null, true, flags));
|
|
||||||
w2.sign(send);
|
|
||||||
|
|
||||||
assert(send.verify(null, true, flags));
|
|
||||||
|
|
||||||
assert.equal(w1.changeDepth, 1);
|
|
||||||
var change = w1.changeAddress.getAddress();
|
|
||||||
assert.equal(w1.changeAddress.getAddress(), change);
|
|
||||||
assert.equal(w2.changeAddress.getAddress(), change);
|
|
||||||
assert.equal(w3.changeAddress.getAddress(), change);
|
|
||||||
|
|
||||||
// Simulate a confirmation
|
|
||||||
send.ps = 0;
|
|
||||||
send.ts = 1;
|
|
||||||
send.height = 1;
|
|
||||||
|
|
||||||
wdb.addTX(send, function(err) {
|
wdb.addTX(send, function(err) {
|
||||||
assert.ifError(err);
|
assert.ifError(err);
|
||||||
wdb.addTX(send, function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
wdb.addTX(send, function(err) {
|
|
||||||
assert.ifError(err);
|
|
||||||
|
|
||||||
assert.equal(w1.receiveDepth, 2);
|
assert.equal(w1.receiveDepth, 2);
|
||||||
assert.equal(w1.changeDepth, 2);
|
assert.equal(w1.changeDepth, 2);
|
||||||
|
|
||||||
assert(w1.getAddress() === addr);
|
assert(w1.getAddress() === addr);
|
||||||
assert(w1.changeAddress.getAddress() !== change);
|
assert(w1.changeAddress.getAddress() !== change);
|
||||||
change = w1.changeAddress.getAddress();
|
change = w1.changeAddress.getAddress();
|
||||||
assert.equal(w1.changeAddress.getAddress(), change);
|
assert.equal(w1.changeAddress.getAddress(), change);
|
||||||
assert.equal(w2.changeAddress.getAddress(), change);
|
assert.equal(w2.changeAddress.getAddress(), change);
|
||||||
assert.equal(w3.changeAddress.getAddress(), change);
|
assert.equal(w3.changeAddress.getAddress(), change);
|
||||||
|
|
||||||
if (witness)
|
if (witness)
|
||||||
send.inputs[0].witness.items[2] = new Buffer([]);
|
send.inputs[0].witness.items[2] = new Buffer([]);
|
||||||
else
|
else
|
||||||
send.inputs[0].script.code[2] = 0;
|
send.inputs[0].script.code[2] = 0;
|
||||||
|
|
||||||
assert(!send.verify(null, true, flags));
|
assert(!send.verify(null, true, flags));
|
||||||
assert.equal(send.getFee(), 10000);
|
assert.equal(send.getFee(), 10000);
|
||||||
|
|
||||||
w3 = bcoin.wallet.fromJSON(w3.toJSON());
|
w3 = bcoin.wallet.fromJSON(w3.toJSON());
|
||||||
assert.equal(w3.receiveDepth, 2);
|
assert.equal(w3.receiveDepth, 2);
|
||||||
assert.equal(w3.changeDepth, 2);
|
assert.equal(w3.changeDepth, 2);
|
||||||
assert.equal(w3.getAddress(), addr);
|
assert.equal(w3.getAddress(), addr);
|
||||||
assert.equal(w3.changeAddress.getAddress(), change);
|
assert.equal(w3.changeAddress.getAddress(), change);
|
||||||
|
|
||||||
cb();
|
cb();
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user