FIX: resubscribe addresses to push notifications after wallet import

This commit is contained in:
Overtorment 2020-07-29 21:00:00 +01:00
parent 12016f1277
commit 932ab6f182
15 changed files with 74 additions and 2 deletions

View file

@ -15,18 +15,19 @@ import {
HDSegwitElectrumSeedP2WPKHWallet,
} from '.';
import ReactNativeHapticFeedback from 'react-native-haptic-feedback';
import loc from '../loc';
const EV = require('../blue_modules/events');
const A = require('../blue_modules/analytics');
const BlueApp: AppStorage = require('../BlueApp');
import loc from '../loc';;
const bip38 = require('../blue_modules/bip38');
const wif = require('wif');
const prompt = require('../blue_modules/prompt');
const notifications = require('../blue_modules/notifications');
export default class WalletImport {
/**
*
* @param w
* @param w {AbstractWallet}
* @param additionalProperties key-values passed from outside. Used only to set up `masterFingerprint` property for watch-only wallet
* @returns {Promise<void>}
* @private
@ -52,6 +53,7 @@ export default class WalletImport {
await BlueApp.saveToDisk();
A(A.ENUM.CREATED_WALLET);
alert(loc.wallets.import_success);
notifications.majorTomToGroundControl(w.getAllExternalAddresses(), [], []);
}
EV(EV.enum.WALLETS_COUNT_CHANGED);
} catch (e) {

View file

@ -992,4 +992,17 @@ export class AbstractHDElectrumWallet extends AbstractHDWallet {
const txs = await BlueElectrum.getTransactionsByAddress(this._getExternalAddressByIndex(0));
return txs.length > 0;
}
/**
* @inheritDoc
*/
getAllExternalAddresses() {
const ret = [];
for (let c = 0; c < this.next_free_address_index + this.gap_limit; c++) {
ret.push(this._getExternalAddressByIndex(c));
}
return ret;
}
}

View file

@ -220,6 +220,16 @@ export class AbstractWallet {
}
/**
* Returns _all_ external addresses in hierarchy (for HD wallets) or just address for single-address wallets
* _Not_ internal ones, as this method is supposed to be used for subscription of external notifications.
*
* @returns string[] Addresses
*/
getAllExternalAddresses() {
return [];
}
/*
* Converts zpub to xpub
*
* @param {String} zpub

View file

@ -82,6 +82,13 @@ export class LegacyWallet extends AbstractWallet {
return this._address;
}
/**
* @inheritDoc
*/
getAllExternalAddresses() {
return [this.getAddress()];
}
/**
* Fetches balance of the Wallet via API.
* Returns VOID. Get the actual balance via getter.

View file

@ -215,6 +215,14 @@ export class WatchOnlyWallet extends LegacyWallet {
this.use_with_hardware_wallet = !!enabled;
}
/**
* @inheritDoc
*/
getAllExternalAddresses() {
if (this._hdWalletInstance) return this._hdWalletInstance.getAllExternalAddresses();
return super.getAllExternalAddresses();
}
isXpubValid() {
let xpub;

View file

@ -12,6 +12,7 @@ it('Legacy HD Breadwallet works', async () => {
assert.strictEqual(hdBread.validateMnemonic(), true);
assert.strictEqual(hdBread._getExternalAddressByIndex(0), '1ARGkNMdsBE36fJhddSwf8PqBXG3s4d2KU');
assert.ok(hdBread.getAllExternalAddresses().includes('1ARGkNMdsBE36fJhddSwf8PqBXG3s4d2KU'));
assert.strictEqual(hdBread._getInternalAddressByIndex(0), '1JLvA5D7RpWgChb4A5sFcLNrfxYbyZdw3V');
assert.strictEqual(hdBread._getExternalWIFByIndex(0), 'L25CoHfqWKR5byQhgp4M8sW1roifBteD3Lj3zCGNcV4JXhbxZ93F');
assert.strictEqual(hdBread._getInternalWIFByIndex(0), 'KyEQuB73eueeS7D6iBJrNSvkD1kkdkJoUsavuxGXv5fxWkPJxt96');

View file

@ -14,6 +14,7 @@ describe('HDLegacyElectrumSeedP2PKHWallet', () => {
let address = hd._getExternalAddressByIndex(0);
assert.strictEqual(address, '1Ca9ZVshGdKiiMEMNTG1bYqbifYMZMwV8');
assert.ok(hd.getAllExternalAddresses().includes('1Ca9ZVshGdKiiMEMNTG1bYqbifYMZMwV8'));
address = hd._getInternalAddressByIndex(0);
assert.strictEqual(address, '1JygAvTQS9haAYgRfPSdHgmXd3syjB8Fnp');

View file

@ -23,6 +23,9 @@ it('Legacy HD (BIP44) works', async () => {
assert.strictEqual(hd._getInternalWIFByIndex(0), 'L4ojevRtK81A8Kof3qyLS2M7HvsVDbUDENNhJqU4vf79w9yGnQLb');
assert.strictEqual(hd._getExternalWIFByIndex(0), 'Kz6kLhdyDfSbKuVH25XVqBRztjmFe8X22Xe1hnFzEv79gJNMkTAH');
assert.ok(hd.getAllExternalAddresses().includes('186FBQmCV5W1xY7ywaWtTZPAQNciVN8Por'));
assert.ok(!hd.getAllExternalAddresses().includes('1J9zoJz5LsAJ361SQHYnLTWg46Tc2AXUCj')); // not internal
assert.strictEqual(
hd._getPubkeyByAddress(hd._getExternalAddressByIndex(0)).toString('hex'),
'0316e84a2556f30a199541633f5dda6787710ccab26771b7084f4c9e1104f47667',

View file

@ -24,6 +24,10 @@ describe('Bech32 Segwit HD (BIP84)', () => {
assert.strictEqual(hd._getInternalAddressByIndex(0), 'bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el');
assert.ok(hd._getInternalAddressByIndex(0) !== hd._getInternalAddressByIndex(1));
assert.ok(hd.getAllExternalAddresses().includes('bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu'));
assert.ok(hd.getAllExternalAddresses().includes('bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g'));
assert.ok(!hd.getAllExternalAddresses().includes('bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el')); // not internal
assert.strictEqual(
hd._getPubkeyByAddress(hd._getExternalAddressByIndex(0)).toString('hex'),
'0330d54fd0dd420a6e5f8d3624f5f3482cae350f79d5f0753bf5beef9c2d91af3c',
@ -47,6 +51,10 @@ describe('Bech32 Segwit HD (BIP84)', () => {
assert.strictEqual(hd._getExternalAddressByIndex(1), 'bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g');
assert.strictEqual(hd._getInternalAddressByIndex(0), 'bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el');
assert.ok(hd._getInternalAddressByIndex(0) !== hd._getInternalAddressByIndex(1));
assert.ok(hd.getAllExternalAddresses().includes('bc1qcr8te4kr609gcawutmrza0j4xv80jy8z306fyu'));
assert.ok(hd.getAllExternalAddresses().includes('bc1qnjg0jd8228aq7egyzacy8cys3knf9xvrerkf9g'));
assert.ok(!hd.getAllExternalAddresses().includes('bc1q8c6fshw2dlwun7ekn9qwf37cu2rn755upcp6el')); // not internal
});
it('can generate', async () => {

View file

@ -14,6 +14,7 @@ describe('HDSegwitElectrumSeedP2WPKHWallet', () => {
let address = hd._getExternalAddressByIndex(0);
assert.strictEqual(address, 'bc1q2yv6rhtw9ycqeq2rkch65sucf66ytwsd3csawr');
assert.ok(hd.getAllExternalAddresses().includes('bc1q2yv6rhtw9ycqeq2rkch65sucf66ytwsd3csawr'));
address = hd._getInternalAddressByIndex(0);
assert.strictEqual(address, 'bc1qvdu80q26ghe66zq8tf5y09qr29vay4cg65mvuk');

View file

@ -10,6 +10,9 @@ it('can create a Segwit HD (BIP49)', async function () {
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', hd._getExternalAddressByIndex(0));
assert.strictEqual('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3', hd._getExternalAddressByIndex(1));
assert.strictEqual('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei', hd._getInternalAddressByIndex(0));
assert.ok(hd.getAllExternalAddresses().includes('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'));
assert.ok(hd.getAllExternalAddresses().includes('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3'));
assert.ok(!hd.getAllExternalAddresses().includes('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei')); // not internal
assert.strictEqual(true, hd.validateMnemonic());
assert.strictEqual(
@ -55,6 +58,9 @@ it('Segwit HD (BIP49) can generate addressess only via ypub', function () {
assert.strictEqual('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK', hd._getExternalAddressByIndex(0));
assert.strictEqual('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3', hd._getExternalAddressByIndex(1));
assert.strictEqual('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei', hd._getInternalAddressByIndex(0));
assert.ok(hd.getAllExternalAddresses().includes('3GcKN7q7gZuZ8eHygAhHrvPa5zZbG5Q1rK'));
assert.ok(hd.getAllExternalAddresses().includes('35p5LwCAE7mH2css7onyQ1VuS1jgWtQ4U3'));
assert.ok(!hd.getAllExternalAddresses().includes('32yn5CdevZQLk3ckuZuA8fEKBco8mEkLei')); // not internal
});
it('can generate Segwit HD (BIP49)', async () => {
@ -107,6 +113,9 @@ it('Legacy HD (BIP44) can generate addressess based on xpub', async function ()
assert.strictEqual(hd._getInternalAddressByIndex(0), '1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX');
assert.strictEqual(hd._getExternalAddressByIndex(1), '1QDCFcpnrZ4yrAQxmbvSgeUC9iZZ8ehcR5');
assert.strictEqual(hd._getInternalAddressByIndex(1), '13CW9WWBsWpDUvLtbFqYziWBWTYUoQb4nU');
assert.ok(hd.getAllExternalAddresses().includes('12eQ9m4sgAwTSQoNXkRABKhCXCsjm2jdVG'));
assert.ok(hd.getAllExternalAddresses().includes('1QDCFcpnrZ4yrAQxmbvSgeUC9iZZ8ehcR5'));
assert.ok(!hd.getAllExternalAddresses().includes('1KZjqYHm7a1DjhjcdcjfQvYfF2h6PqatjX')); // not internal
});
it('can consume user generated entropy', async () => {

View file

@ -8,6 +8,7 @@ describe('Legacy wallet', () => {
const l = new LegacyWallet();
l.setSecret('L4ccWrPMmFDZw4kzAKFqJNxgHANjdy6b7YKNXMwB4xac4FLF3Tov');
assert.strictEqual(l.getAddress(), '14YZ6iymQtBVQJk6gKnLCk49UScJK7SH4M');
assert.deepStrictEqual(l.getAllExternalAddresses(), ['14YZ6iymQtBVQJk6gKnLCk49UScJK7SH4M']);
assert.strictEqual(await l.getChangeAddressAsync(), l.getAddress());
const utxos = [

View file

@ -8,6 +8,7 @@ describe('Segwit P2SH wallet', () => {
const wallet = new SegwitBech32Wallet();
wallet.setSecret('L4vn2KxgMLrEVpxjfLwxfjnPPQMnx42DCjZJ2H7nN4mdHDyEUWXd');
assert.strictEqual(wallet.getAddress(), 'bc1q3rl0mkyk0zrtxfmqn9wpcd3gnaz00yv9yp0hxe');
assert.deepStrictEqual(wallet.getAllExternalAddresses(), ['bc1q3rl0mkyk0zrtxfmqn9wpcd3gnaz00yv9yp0hxe']);
assert.strictEqual(await wallet.getChangeAddressAsync(), wallet.getAddress());
const utxos = [

View file

@ -8,6 +8,7 @@ describe('Segwit P2SH wallet', () => {
const wallet = new SegwitP2SHWallet();
wallet.setSecret('Ky1vhqYGCiCbPd8nmbUeGfwLdXB1h5aGwxHwpXrzYRfY5cTZPDo4');
assert.strictEqual(wallet.getAddress(), '3CKN8HTCews4rYJYsyub5hjAVm5g5VFdQJ');
assert.deepStrictEqual(wallet.getAllExternalAddresses(), ['3CKN8HTCews4rYJYsyub5hjAVm5g5VFdQJ']);
assert.strictEqual(await wallet.getChangeAddressAsync(), wallet.getAddress());
const utxos = [

View file

@ -13,6 +13,10 @@ describe('Watch only wallet', () => {
]) {
w.setSecret(secret);
assert.ok(w.valid());
assert.deepStrictEqual(
w.getAllExternalAddresses().map(elem => elem.toUpperCase()),
[secret.toUpperCase()],
);
assert.strictEqual(w.isHd(), false);
}
@ -173,6 +177,7 @@ describe('Watch only wallet', () => {
w.setSecret('ypub6Y9u3QCRC1HkZv3stNxcQVwmw7vC7KX5Ldz38En5P88RQbesP2oy16hNyQocVCfYRQPxdHcd3pmu9AFhLv7NdChWmw5iNLryZ2U6EEHdnfo');
w.init();
assert.ok((await w._getExternalAddressByIndex(0)).startsWith('3'));
assert.ok(w.getAllExternalAddresses().includes(await w._getExternalAddressByIndex(0)));
});
it('xpub watch-only can generate addresses', async () => {
@ -180,5 +185,6 @@ describe('Watch only wallet', () => {
w.setSecret('xpub6CQdfC3v9gU86eaSn7AhUFcBVxiGhdtYxdC5Cw2vLmFkfth2KXCMmYcPpvZviA89X6DXDs4PJDk5QVL2G2xaVjv7SM4roWHr1gR4xB3Z7Ps');
w.init();
assert.ok((await w._getExternalAddressByIndex(0)).startsWith('1'));
assert.ok(w.getAllExternalAddresses().includes(await w._getExternalAddressByIndex(0)));
});
});