diff --git a/CHANGELOG.md b/CHANGELOG.md index 53e27d377..38a861f3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # HSD Release Notes & Changelog +## vX.Y.Z + +### Wallet API changes + +Creating a watch-only wallet now requires an `account-key` (or `accountKey`) +argument. This is to prevent hsd from generating keys and addresses the user +can not spend from. + ## v0.0.0 ### Notable Changes diff --git a/lib/wallet/wallet.js b/lib/wallet/wallet.js index 03f3f5341..bc34a9d4e 100644 --- a/lib/wallet/wallet.js +++ b/lib/wallet/wallet.js @@ -584,7 +584,7 @@ class Wallet extends EventEmitter { await this.unlock(passphrase); let key; - if (this.watchOnly && options.accountKey) { + if (this.watchOnly) { key = options.accountKey; if (typeof key === 'string') diff --git a/test/wallet-test.js b/test/wallet-test.js index 6e42a732a..8f3bad5e4 100644 --- a/test/wallet-test.js +++ b/test/wallet-test.js @@ -18,6 +18,8 @@ const KeyRing = require('../lib/primitives/keyring'); const Input = require('../lib/primitives/input'); const Outpoint = require('../lib/primitives/outpoint'); const Script = require('../lib/script/script'); +const HD = require('../lib/hd'); +const PrivateKey = require('../lib/hd/private.js'); const KEY1 = 'xprv9s21ZrQH143K3Aj6xQBymM31Zb4BVc7wxqfUhMZrzewdDVCt' + 'qUP9iWfcHgJofs25xbaUpCps9GDXj83NiWvQCAkWQhVj5J4CorfnpKX94AZ'; @@ -35,6 +37,7 @@ let importedWallet = null; let importedKey = null; let doubleSpendWallet = null; let doubleSpendCoin = null; +let watchWallet = null; function fromU32(num) { const data = Buffer.allocUnsafe(4); @@ -1175,37 +1178,49 @@ describe('Wallet', function() { importedKey = key; }); + it('should require account key to create watch only wallet', async () => { + try { + watchWallet = await wdb.create({ + watchOnly: true + }); + } catch (e) { + assert.strictEqual( + e.message, + 'Must add HD public keys to watch only wallet.' + ); + } + + const privateKey = PrivateKey.generate(); + const xpub = privateKey.xpubkey('main'); + watchWallet = await wdb.create({ + watchOnly: true, + accountKey: xpub + }); + }); + it('should import pubkey', async () => { const key = KeyRing.generate(); const pub = new KeyRing(key.publicKey); - const wallet = await wdb.create({ - watchOnly: true - }); + await watchWallet.importKey('default', pub); - await wallet.importKey('default', pub); - - const path = await wallet.getPath(pub.getHash()); + const path = await watchWallet.getPath(pub.getHash()); assert.bufferEqual(path.hash, pub.getHash()); - const wkey = await wallet.getKey(pub.getHash()); + const wkey = await watchWallet.getKey(pub.getHash()); assert(wkey); }); it('should import address', async () => { const key = KeyRing.generate(); - const wallet = await wdb.create({ - watchOnly: true - }); - - await wallet.importAddress('default', key.getAddress()); + await watchWallet.importAddress('default', key.getAddress()); - const path = await wallet.getPath(key.getHash()); + const path = await watchWallet.getPath(key.getHash()); assert(path); assert.bufferEqual(path.hash, key.getHash()); - const wkey = await wallet.getKey(key.getHash()); + const wkey = await watchWallet.getKey(key.getHash()); assert(!wkey); });