From bd39adf8fcb1032b4dde71f6a180cec7b27ab8d3 Mon Sep 17 00:00:00 2001 From: Stepan Snigirev Date: Sat, 4 Jul 2020 22:25:31 +0200 Subject: [PATCH] zpub with fingerprint * parse core-like HD key [mfp/derivation]zpub * add unittest for zpub with fingerprint --- class/wallets/abstract-wallet.js | 12 ++++++++++++ tests/unit/watch-only-wallet.test.js | 14 ++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/class/wallets/abstract-wallet.js b/class/wallets/abstract-wallet.js index 94df2eba9..20b386cc5 100644 --- a/class/wallets/abstract-wallet.js +++ b/class/wallets/abstract-wallet.js @@ -142,6 +142,18 @@ export class AbstractWallet { if (this.secret.startsWith('BC1')) this.secret = this.secret.toLowerCase(); + // [fingerprint/derivation]zpub + let re = /\[([^\]]+)\](.*)/; + let m = this.secret.match(re); + if(m && m.length==3){ + let hexFingerprint = m[1].split("/")[0]; + if(hexFingerprint.length == 8){ + hexFingerprint = Buffer.from(hexFingerprint, 'hex').reverse().toString('hex'); + this.masterFingerprint = parseInt(hexFingerprint, 16); + } + this.secret = m[2]; + } + try { const parsedSecret = JSON.parse(this.secret); if (parsedSecret && parsedSecret.keystore && parsedSecret.keystore.xpub) { diff --git a/tests/unit/watch-only-wallet.test.js b/tests/unit/watch-only-wallet.test.js index 5b54ac833..d4db82470 100644 --- a/tests/unit/watch-only-wallet.test.js +++ b/tests/unit/watch-only-wallet.test.js @@ -119,6 +119,20 @@ describe('Watch only wallet', () => { assert.strictEqual(w.getLabel(), 'Cobo Vault 5271c071'); }); + it('can import zpub with master fingerprint', async () => { + const zpub = "[8cce63f8/84h/0h/0h]zpub6s2RJ9qAEBW8Abhojs6LyDzF7gttcDr6EsR3Umu2aptZBb45e734rGtt4KqsCMmNyR1EEzUU2ugdVYez2VywQvAbBjUSKn8ho4Zk2c5otkk"; + const w = new WatchOnlyWallet(); + w.setSecret(zpub); + w.init(); + assert.ok(w.valid()); + assert.strictEqual( + w.getSecret(), + 'zpub6s2RJ9qAEBW8Abhojs6LyDzF7gttcDr6EsR3Umu2aptZBb45e734rGtt4KqsCMmNyR1EEzUU2ugdVYez2VywQvAbBjUSKn8ho4Zk2c5otkk', + ); + assert.strictEqual(w.getMasterFingerprint(), 4167290508); + assert.strictEqual(w.getMasterFingerprintHex(), '8cce63f8'); + }); + it('can combine signed PSBT and prepare it for broadcast', async () => { const w = new WatchOnlyWallet(); w.setSecret('zpub6rjLjQVqVnj7crz9E4QWj4WgczmEseJq22u2B6k2HZr6NE2PQx3ZYg8BnbjN9kCfHymSeMd2EpwpM5iiz5Nrb3TzvddxW2RMcE3VXdVaXHk');