From aa79d92a8367f91153822b1e40571c0f62c080b8 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 2 Nov 2016 01:53:44 -0700 Subject: [PATCH] http: more wallet api calls. --- bin/cli | 64 ++++++++++++++++++++----- lib/http/client.js | 47 ++++++++++++++++--- lib/http/rpc.js | 8 ++-- lib/http/server.js | 46 ++++++++++++++++-- lib/http/wallet.js | 73 ++++++++++++++++++++++++++--- lib/wallet/account.js | 64 +------------------------ lib/wallet/masterkey.js | 52 +++------------------ lib/wallet/wallet.js | 101 +++++++++++++++++----------------------- test/http-test.js | 2 +- test/wallet-test.js | 14 +++--- 10 files changed, 265 insertions(+), 206 deletions(-) diff --git a/bin/cli b/bin/cli index 167a3752..9d3f3967 100755 --- a/bin/cli +++ b/bin/cli @@ -66,21 +66,44 @@ CLI.prototype.createWallet = co(function* createWallet() { this.log(wallet); }); -CLI.prototype.addKey = co(function* addKey() { +CLI.prototype.getMaster = co(function* getMaster() { + var master = yield this.wallet.getMaster(); + this.log(master); +}); + +CLI.prototype.getKey = co(function* getKey() { + var address = this.argv[0]; + var key = yield this.wallet.getKey(address); + this.log(key); +}); + +CLI.prototype.getWIF = co(function* getWIF() { + var address = this.argv[0]; + var key = yield this.wallet.getWIF(address, this.config.passphrase); + this.log(key.privateKey); +}); + +CLI.prototype.addSharedKey = co(function* addSharedKey() { var key = this.argv[0]; - yield this.wallet.addKey(this.config.account, key); + yield this.wallet.addSharedKey(this.config.account, key); this.log('Added key.'); }); -CLI.prototype.removeKey = co(function* removeKey() { +CLI.prototype.removeSharedKey = co(function* removeSharedKey() { var key = this.argv[0]; - yield this.wallet.removeKey(this.config.account, key); + yield this.wallet.removeSharedKey(this.config.account, key); this.log('Removed key.'); }); +CLI.prototype.getSharedKeys = co(function* getSharedKeys() { + var acct = this.argv[0] || this.config.account; + var account = yield this.wallet.getAccount(acct); + this.log(account.keys); +}); + CLI.prototype.getAccount = co(function* getAccount() { - var account = this.argv[0] || this.config.account; - yield this.wallet.getAccount(account); + var acct = this.argv[0] || this.config.account; + var account = yield this.wallet.getAccount(acct); this.log(account); }); @@ -409,10 +432,20 @@ CLI.prototype.handleWallet = co(function* handleWallet() { return yield this.listenWallet(); case 'get': return yield this.getWallet(); - case 'addkey': - return yield this.addKey(); - case 'rmkey': - return yield this.removeKey(); + case 'master': + return yield this.getMaster(); + case 'shared': + if (this.argv[0] === 'add') { + this.argv.shift(); + return yield this.addSharedKey(); + } + if (this.argv[0] === 'remove') { + this.argv.shift(); + return yield this.removeSharedKey(); + } + if (this.argv[0] === 'list') + this.argv.shift(); + return yield this.getSharedKeys(); case 'balance': return yield this.getBalance(); case 'history': @@ -453,6 +486,10 @@ CLI.prototype.handleWallet = co(function* handleWallet() { return yield this.importKey(); case 'watch': return yield this.importAddress(); + case 'key': + return yield this.getKey(); + case 'dump': + return yield this.getWIF(); case 'lock': return yield this.lock(); case 'unlock': @@ -464,8 +501,9 @@ CLI.prototype.handleWallet = co(function* handleWallet() { this.log('Commands:'); this.log(' $ listen: Listen for events.'); this.log(' $ get: View wallet.'); - this.log(' $ addkey [xpubkey]: Add key to wallet.'); - this.log(' $ rmkey [xpubkey]: Remove key from wallet.'); + this.log(' $ master: View wallet master key.'); + this.log(' $ shared add [xpubkey]: Add key to wallet.'); + this.log(' $ shared remove [xpubkey]: Remove key from wallet.'); this.log(' $ balance: Get wallet balance.'); this.log(' $ history: View wallet TX history.'); this.log(' $ coins: View wallet coins.'); @@ -483,6 +521,8 @@ CLI.prototype.handleWallet = co(function* handleWallet() { this.log(' $ view [tx-hex]: Parse and view transaction.'); this.log(' $ import [wif|hex]: Import private or public key.'); this.log(' $ watch [address]: Import an address.'); + this.log(' $ key [address]: Get wallet key by address.'); + this.log(' $ dump [address]: Get wallet key WIF by address.'); this.log(' $ lock: Lock wallet.'); this.log(' $ unlock [passphrase] [timeout?]: Unlock wallet.'); this.log(' $ resend: Resend pending transactions.'); diff --git a/lib/http/client.js b/lib/http/client.js index 0bcea83d..476ca86e 100644 --- a/lib/http/client.js +++ b/lib/http/client.js @@ -677,32 +677,56 @@ HTTPClient.prototype.zapWallet = function zapWallet(id, account, age) { return this._post('/wallet/' + id + '/zap', body); }; +/** + * Get wallet key. + * @param {WalletID} id + * @param {Base58Address} address + * @returns {Promise} + */ + +HTTPClient.prototype.getKey = function getKey(id, address) { + return this._get('/wallet/' + id + '/key/' + address); +}; + +/** + * Get wallet key WIF dump. + * @param {WalletID} id + * @param {Base58Address} address + * @param {String?} passphrase + * @returns {Promise} + */ + +HTTPClient.prototype.getWIF = function getWIF(id, address, passphrase) { + var options = { passphrase: passphrase }; + return this._get('/wallet/' + id + '/wif/' + address, options); +}; + /** * Add a public account/purpose key to the wallet for multisig. * @param {WalletID} id * @param {(String|Number)?} account - * @param {HDPublicKey|Base58String} key - Account (bip44) or + * @param {Base58String} key - Account (bip44) or * Purpose (bip45) key (can be in base58 form). * @returns {Promise} */ -HTTPClient.prototype.addKey = function addKey(id, account, key) { +HTTPClient.prototype.addSharedKey = function addSharedKey(id, account, key) { var options = { account: account, accountKey: key }; - return this._put('/wallet/' + id + '/key', options); + return this._put('/wallet/' + id + '/shared-key', options); }; /** * Remove a public account/purpose key to the wallet for multisig. * @param {WalletID} id * @param {(String|Number)?} account - * @param {HDPublicKey|Base58String} key - Account (bip44) or Purpose + * @param {Base58String} key - Account (bip44) or Purpose * (bip45) key (can be in base58 form). * @returns {Promise} */ -HTTPClient.prototype.removeKey = function removeKey(id, account, key) { +HTTPClient.prototype.removeSharedKey = function removeSharedKey(id, account, key) { var options = { account: account, accountKey: key }; - return this._del('/wallet/' + id + '/key', options); + return this._del('/wallet/' + id + '/shared-key', options); }; /** @@ -823,6 +847,17 @@ HTTPClient.prototype.getAccounts = function getAccounts(id) { return this._get(path); }; +/** + * Get wallet master key. + * @param {WalletID} id + * @returns {Promise} + */ + +HTTPClient.prototype.getMaster = function getMaster(id) { + var path = '/wallet/' + id + '/master'; + return this._get(path); +}; + /** * Get wallet account. * @param {WalletID} id diff --git a/lib/http/rpc.js b/lib/http/rpc.js index 9aab7848..dbf036cc 100644 --- a/lib/http/rpc.js +++ b/lib/http/rpc.js @@ -415,10 +415,10 @@ RPC.prototype.addnode = function addnode(args) { } break; case 'onetry': - if (this.pool.peers.get(addr)) - break; - peer = this.createPeer(addr); - this.peers.addPending(peer); + if (!this.pool.peers.get(addr)) { + peer = this.pool.createPeer(addr); + this.pool.peers.addPending(peer); + } break; } diff --git a/lib/http/server.js b/lib/http/server.js index 50023a5e..e0971eb2 100644 --- a/lib/http/server.js +++ b/lib/http/server.js @@ -756,6 +756,11 @@ HTTPServer.prototype._init = function _init() { send(200, req.wallet.toJSON()); }); + // Get wallet master key + this.get('/wallet/:id/master', function(req, res, send, next) { + send(200, req.wallet.master.toJSON(true)); + }); + // Create wallet this.post('/wallet/:id?', con(function* (req, res, send, next) { var wallet = yield this.walletdb.create(req.options); @@ -913,25 +918,58 @@ HTTPServer.prototype._init = function _init() { })); // Add key - this.put('/wallet/:id/key', con(function* (req, res, send, next) { + this.put('/wallet/:id/shared-key', con(function* (req, res, send, next) { var options = req.options; var acct = options.name || options.account; var key = options.accountKey; enforce(key, 'Key is required.'); - yield req.wallet.addKey(acct, key); + yield req.wallet.addSharedKey(acct, key); send(200, { success: true }); })); // Remove key - this.del('/wallet/:id/key', con(function* (req, res, send, next) { + this.del('/wallet/:id/shared-key', con(function* (req, res, send, next) { var options = req.options; var acct = options.name || options.account; var key = options.accountKey; enforce(key, 'Key is required.'); - yield req.wallet.removeKey(acct, key); + yield req.wallet.removeSharedKey(acct, key); send(200, { success: true }); })); + // Get key by address + this.get('/wallet/:id/key/:address', con(function* (req, res, send, next) { + var options = req.options; + var address = options.address; + var key; + + enforce(address instanceof Address, 'Address is required.'); + + key = yield req.wallet.getKey(address); + + if (!key) + return send(404); + + send(200, key.toJSON()); + })); + + // Get private key + this.get('/wallet/:id/wif/:address', con(function* (req, res, send, next) { + var options = req.options; + var address = options.address; + var passphrase = options.passphrase; + var key; + + enforce(address instanceof Address, 'Address is required.'); + + key = yield req.wallet.getPrivateKey(address, passphrase); + + if (!key) + return send(404); + + send(200, { privateKey: key.toSecret() }); + })); + // Create address this.post('/wallet/:id/address', con(function* (req, res, send, next) { var options = req.options; diff --git a/lib/http/wallet.js b/lib/http/wallet.js index e6493c83..f0e540a4 100644 --- a/lib/http/wallet.js +++ b/lib/http/wallet.js @@ -105,7 +105,7 @@ HTTPWallet.prototype.open = co(function* open(options) { wallet = yield this.client.getWallet(this.id); - yield this.client.join(this.id, wallet.token); + yield this.client.join(this.id, this.token); return wallet; }); @@ -118,12 +118,18 @@ HTTPWallet.prototype.open = co(function* open(options) { HTTPWallet.prototype.create = co(function* create(options) { var wallet; + yield this.client.open(); + wallet = yield this.client.createWallet(options); - return yield this.open({ - id: wallet.id, - token: wallet.token - }); + + this.id = wallet.id; + this.token = wallet.token; + this.client.token = this.token; + + yield this.client.join(this.id, this.token); + + return wallet; }); /** @@ -244,7 +250,7 @@ HTTPWallet.prototype.fillCoins = function fillCoins(tx) { * @see HTTPClient#getWallet */ -HTTPWallet.prototype.getInfo = function getInfo(callback) { +HTTPWallet.prototype.getInfo = function getInfo() { return this.client.getWallet(this.id); }; @@ -252,10 +258,18 @@ HTTPWallet.prototype.getInfo = function getInfo(callback) { * @see Wallet#getAccounts */ -HTTPWallet.prototype.getAccounts = function getAccounts(callback) { +HTTPWallet.prototype.getAccounts = function getAccounts() { return this.client.getAccounts(this.id); }; +/** + * @see Wallet#master + */ + +HTTPWallet.prototype.getMaster = function getMaster() { + return this.client.getMaster(this.id); +}; + /** * @see Wallet#getAccount */ @@ -393,6 +407,51 @@ HTTPWallet.prototype.unlock = function unlock(passphrase, timeout) { return this.client.unlock(this.id, passphrase, timeout); }; +/** + * Get wallet key. + * @param {Base58Address} address + * @returns {Promise} + */ + +HTTPWallet.prototype.getKey = function getKey(address) { + return this.client.getKey(this.id, address); +}; + +/** + * Get wallet key WIF dump. + * @param {Base58Address} address + * @param {String?} passphrase + * @returns {Promise} + */ + +HTTPWallet.prototype.getWIF = function getWIF(address, passphrase) { + return this.client.getWIF(this.id, address, passphrase); +}; + +/** + * Add a public account/purpose key to the wallet for multisig. + * @param {(String|Number)?} account + * @param {Base58String} key - Account (bip44) or + * Purpose (bip45) key (can be in base58 form). + * @returns {Promise} + */ + +HTTPWallet.prototype.addSharedKey = function addSharedKey(account, key) { + return this.client.addSharedKey(this.id, account, key); +}; + +/** + * Remove a public account/purpose key to the wallet for multisig. + * @param {(String|Number)?} account + * @param {Base58String} key - Account (bip44) or Purpose + * (bip45) key (can be in base58 form). + * @returns {Promise} + */ + +HTTPWallet.prototype.removeSharedKey = function removeSharedKey(account, key) { + return this.client.removeSharedKey(this.id, account, key); +}; + /** * Resend wallet transactions. * @returns {Promise} diff --git a/lib/wallet/account.js b/lib/wallet/account.js index 84575b26..6816151e 100644 --- a/lib/wallet/account.js +++ b/lib/wallet/account.js @@ -334,7 +334,7 @@ Account.prototype.spliceKey = function spliceKey(key) { * @returns {Promise} */ -Account.prototype.addKey = co(function* addKey(key) { +Account.prototype.addSharedKey = co(function* addSharedKey(key) { var result = false; var exists; @@ -385,7 +385,7 @@ Account.prototype._checkKeys = co(function* _checkKeys() { * @returns {Promise} */ -Account.prototype.removeKey = function removeKey(key) { +Account.prototype.removeSharedKey = function removeSharedKey(key) { var result = false; try { @@ -780,54 +780,6 @@ Account.prototype.toJSON = function toJSON(minimal) { }; }; -/** - * Inject properties from json object. - * @private - * @param {Object} json - */ - -Account.prototype.fromJSON = function fromJSON(json) { - var i, key; - - assert(utils.isNumber(json.wid)); - assert(utils.isName(json.id), 'Bad wallet ID.'); - assert(utils.isName(json.name), 'Bad account name.'); - assert(typeof json.initialized === 'boolean'); - assert(typeof json.watchOnly === 'boolean'); - assert(typeof json.type === 'string'); - assert(utils.isNumber(json.m)); - assert(utils.isNumber(json.n)); - assert(typeof json.witness === 'boolean'); - assert(utils.isNumber(json.accountIndex)); - assert(utils.isNumber(json.receiveDepth)); - assert(utils.isNumber(json.changeDepth)); - assert(utils.isNumber(json.nestedDepth)); - assert(Array.isArray(json.keys)); - - this.wid = json.wid; - this.name = json.name; - this.initialized = json.initialized; - this.witness = json.witness; - this.watchOnly = json.watchOnly; - this.type = Account.types[json.type.toUpperCase()]; - this.m = json.m; - this.n = json.n; - this.accountIndex = json.accountIndex; - this.receiveDepth = json.receiveDepth; - this.changeDepth = json.changeDepth; - this.nestedDepth = json.nestedDepth; - this.accountKey = HD.fromBase58(json.accountKey); - - assert(this.type != null); - - for (i = 0; i < json.keys.length; i++) { - key = HD.fromBase58(json.keys[i]); - this.pushKey(key); - } - - return this; -}; - /** * Serialize the account. * @returns {Buffer} @@ -907,18 +859,6 @@ Account.fromRaw = function fromRaw(db, data) { return new Account(db).fromRaw(data); }; -/** - * Instantiate a Account from a - * jsonified account object. - * @param {WalletDB} db - * @param {Object} json - The jsonified account object. - * @returns {Account} - */ - -Account.fromJSON = function fromJSON(db, json) { - return new Account(db).fromJSON(json); -}; - /** * Test an object to see if it is a Account. * @param {Object} obj diff --git a/lib/wallet/masterkey.js b/lib/wallet/masterkey.js index 3f249418..2157ae25 100644 --- a/lib/wallet/masterkey.js +++ b/lib/wallet/masterkey.js @@ -530,16 +530,18 @@ MasterKey.fromKey = function fromKey(key) { /** * Convert master key to a jsonifiable object. + * @param {Boolean?} unsafe - Whether to include + * the key data in the JSON. * @returns {Object} */ -MasterKey.prototype.toJSON = function toJSON() { +MasterKey.prototype.toJSON = function toJSON(unsafe) { if (this.encrypted) { return { encrypted: true, until: this.until, iv: this.iv.toString('hex'), - ciphertext: this.ciphertext.toString('hex'), + ciphertext: unsafe ? this.ciphertext.toString('hex') : undefined, algorithm: MasterKey.algByVal[this.alg], N: this.N, r: this.r, @@ -549,59 +551,17 @@ MasterKey.prototype.toJSON = function toJSON() { return { encrypted: false, - key: this.key.toJSON() + key: unsafe ? this.key.toJSON() : undefined }; }; -/** - * Inject properties from JSON object. - * @private - * @param {Object} json - */ - -MasterKey.prototype.fromJSON = function fromJSON(json) { - assert(typeof json.encrypted === 'boolean'); - - this.encrypted = json.encrypted; - - if (json.encrypted) { - assert(typeof json.iv === 'string'); - assert(typeof json.ciphertext === 'string'); - assert(typeof json.algorithm === 'string'); - assert(utils.isNumber(json.N)); - assert(utils.isNumber(json.r)); - assert(utils.isNumber(json.p)); - this.iv = new Buffer(json.iv, 'hex'); - this.ciphertext = new Buffer(json.ciphertext, 'hex'); - this.alg = MasterKey.alg[json.algorithm]; - assert(this.alg != null); - this.N = json.N; - this.r = json.r; - this.p = json.p; - } else { - this.key = HD.fromJSON(json.key); - } - - return this; -}; - -/** - * Instantiate master key from jsonified object. - * @param {Object} json - * @returns {MasterKey} - */ - -MasterKey.fromJSON = function fromJSON(json) { - return new MasterKey().fromJSON(json); -}; - /** * Inspect the key. * @returns {Object} */ MasterKey.prototype.inspect = function inspect() { - var json = this.toJSON(); + var json = this.toJSON(true); if (this.key) json.key = this.key.toJSON(); return json; diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 098c2e8f..a196c29a 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -254,10 +254,10 @@ Wallet.prototype.destroy = co(function* destroy() { * @returns {Promise} */ -Wallet.prototype.addKey = co(function* addKey(acct, key) { +Wallet.prototype.addSharedKey = co(function* addSharedKey(acct, key) { var unlock = yield this.writeLock.lock(); try { - return yield this._addKey(acct, key); + return yield this._addSharedKey(acct, key); } finally { unlock(); } @@ -271,7 +271,7 @@ Wallet.prototype.addKey = co(function* addKey(acct, key) { * @returns {Promise} */ -Wallet.prototype._addKey = co(function* addKey(acct, key) { +Wallet.prototype._addSharedKey = co(function* addSharedKey(acct, key) { var account, result; if (!key) { @@ -290,7 +290,7 @@ Wallet.prototype._addKey = co(function* addKey(acct, key) { this.start(); try { - result = yield account.addKey(key); + result = yield account.addSharedKey(key); } catch (e) { this.drop(); throw e; @@ -308,10 +308,10 @@ Wallet.prototype._addKey = co(function* addKey(acct, key) { * @returns {Promise} */ -Wallet.prototype.removeKey = co(function* removeKey(acct, key) { +Wallet.prototype.removeSharedKey = co(function* removeSharedKey(acct, key) { var unlock = yield this.writeLock.lock(); try { - return yield this._removeKey(acct, key); + return yield this._removeSharedKey(acct, key); } finally { unlock(); } @@ -325,7 +325,7 @@ Wallet.prototype.removeKey = co(function* removeKey(acct, key) { * @returns {Promise} */ -Wallet.prototype._removeKey = co(function* removeKey(acct, key) { +Wallet.prototype._removeSharedKey = co(function* removeSharedKey(acct, key) { var account, result; if (!key) { @@ -344,7 +344,7 @@ Wallet.prototype._removeKey = co(function* removeKey(acct, key) { this.start(); try { - result = yield account.removeKey(key); + result = yield account.removeSharedKey(key); } catch (e) { this.drop(); throw e; @@ -1649,6 +1649,36 @@ Wallet.prototype.getKey = co(function* getKey(address) { return account.derivePath(path, this.master); }); +/** + * Retrieve a single keyring by address + * (with the private key reference). + * @param {Address|Hash} hash + * @param {(Buffer|String)?} passphrase + * @returns {Promise} + */ + +Wallet.prototype.getPrivateKey = co(function* getPrivateKey(address, passphrase) { + var hash = Address.getHash(address, 'hex'); + var path, account; + + if (!hash) + return; + + path = yield this.getPath(hash); + + if (!path) + return; + + account = yield this.getAccount(path.account); + + if (!account) + return; + + yield this.unlock(passphrase); + + return account.derivePath(path, this.master); +}); + /** * Map input addresses to paths. * @param {TX} tx @@ -2457,12 +2487,13 @@ Wallet.prototype.inspect = function inspect() { /** * Convert the wallet to an object suitable for - * serialization. Will automatically encrypt the - * master key based on the `passphrase` option. + * serialization. + * @param {Boolean?} unsafe - Whether to include + * the master key in the JSON. * @returns {Object} */ -Wallet.prototype.toJSON = function toJSON() { +Wallet.prototype.toJSON = function toJSON(unsafe) { return { network: this.network.type, wid: this.wid, @@ -2473,44 +2504,11 @@ Wallet.prototype.toJSON = function toJSON() { token: this.token.toString('hex'), tokenDepth: this.tokenDepth, state: this.state.toJSON(true), - master: this.master.toJSON(), - account: this.account ? this.account.toJSON(true) : null + master: this.master.toJSON(unsafe), + account: this.account.toJSON(true) }; }; -/** - * Inject properties from json object. - * @private - * @param {Object} json - */ - -Wallet.prototype.fromJSON = function fromJSON(json) { - var network; - - assert(utils.isNumber(json.wid)); - assert(typeof json.initialized === 'boolean'); - assert(typeof json.watchOnly === 'boolean'); - assert(utils.isName(json.id), 'Bad wallet ID.'); - assert(utils.isNumber(json.accountDepth)); - assert(typeof json.token === 'string'); - assert(json.token.length === 64); - assert(utils.isNumber(json.tokenDepth)); - - network = Network.get(json.network); - - this.wid = json.wid; - this.id = json.id; - this.initialized = json.initialized; - this.watchOnly = json.watchOnly; - this.accountDepth = json.accountDepth; - this.token = new Buffer(json.token, 'hex'); - this.master.fromJSON(json.master); - - assert(network === this.db.network, 'Wallet network mismatch.'); - - return this; -}; - /** * Serialize the wallet. * @returns {Buffer} @@ -2571,17 +2569,6 @@ Wallet.fromRaw = function fromRaw(db, data) { return new Wallet(db).fromRaw(data); }; -/** - * Instantiate a Wallet from a - * jsonified wallet object. - * @param {Object} json - The jsonified wallet object. - * @returns {Wallet} - */ - -Wallet.fromJSON = function fromJSON(db, json) { - return new Wallet(db).fromJSON(json); -}; - /** * Test an object to see if it is a Wallet. * @param {Object} obj diff --git a/test/http-test.js b/test/http-test.js index 1f9ae805..d9c618fb 100644 --- a/test/http-test.js +++ b/test/http-test.js @@ -146,7 +146,7 @@ describe('HTTP', function() { })); it('should get a tx', cob(function* () { - var tx = yield wallet.getTX('default', hash); + var tx = yield wallet.getTX(hash); assert(tx); assert.equal(tx.hash, hash); })); diff --git a/test/wallet-test.js b/test/wallet-test.js index 24a508c1..5e273504 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -170,7 +170,7 @@ describe('Wallet', function() { k = bcoin.hd.fromMnemonic().deriveAccount44(0).hdPublicKey; - yield w.addKey(k); + yield w.addSharedKey(k); keys = [ w.getPublicKey(), @@ -681,12 +681,12 @@ describe('Wallet', function() { w3 = yield walletdb.create(options); receive = yield walletdb.create(); - yield w1.addKey(w2.accountKey); - yield w1.addKey(w3.accountKey); - yield w2.addKey(w1.accountKey); - yield w2.addKey(w3.accountKey); - yield w3.addKey(w1.accountKey); - yield w3.addKey(w2.accountKey); + yield w1.addSharedKey(w2.accountKey); + yield w1.addSharedKey(w3.accountKey); + yield w2.addSharedKey(w1.accountKey); + yield w2.addSharedKey(w3.accountKey); + yield w3.addSharedKey(w1.accountKey); + yield w3.addSharedKey(w2.accountKey); // Our p2sh address b58 = w1[rec].getAddress('base58');