Merge pull request #2108 from BlueWallet/fix-removed-tx

FIX: missing transactions after restart for single-address wallets (c…
This commit is contained in:
GLaDOS 2020-11-10 19:14:27 +00:00 committed by GitHub
commit 58cc3df6a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 6 additions and 101 deletions

View file

@ -16,7 +16,6 @@ import {
HDSegwitElectrumSeedP2WPKHWallet,
MultisigHDWallet,
} from './';
import { AbstractHDElectrumWallet } from './wallets/abstract-hd-electrum-wallet';
import { Platform } from 'react-native';
const encryption = require('../blue_modules/encryption');
const Realm = require('realm');
@ -59,7 +58,7 @@ export class AppStorage {
} else {
return AsyncStorage.setItem(key, value);
}
}
};
/**
* Wrapper for storage call. Secure store works only in RN environment. AsyncStorage is
@ -68,13 +67,13 @@ export class AppStorage {
* @param key
* @returns {Promise<any>|*}
*/
getItem = (key) => {
getItem = key => {
if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {
return RNSecureKeyStore.get(key);
} else {
return AsyncStorage.getItem(key);
}
}
};
setResetOnAppUninstallTo = async value => {
if (Platform.OS === 'ios') {
@ -396,7 +395,7 @@ export class AppStorage {
const id = wallet.getID();
const walletToSave = wallet._hdWalletInstance ?? wallet;
if (walletToSave instanceof AbstractHDElectrumWallet) {
if (walletToSave._txs_by_external_index) {
realm.write(() => {
const j1 = JSON.stringify(walletToSave._txs_by_external_index);
const j2 = JSON.stringify(walletToSave._txs_by_internal_index);

View file

@ -1,5 +1,4 @@
import { LegacyWallet } from './legacy-wallet';
import Frisbee from 'frisbee';
const bip39 = require('bip39');
const BlueElectrum = require('../../blue_modules/BlueElectrum');
@ -180,99 +179,7 @@ export class AbstractHDWallet extends LegacyWallet {
* @returns {Promise<void>}
*/
async fetchTransactions() {
try {
const api = new Frisbee({ baseURI: 'https://blockchain.info' });
this.transactions = [];
let offset = 0;
while (1) {
const response = await api.get('/multiaddr?active=' + this.getXpub() + '&n=100&offset=' + offset);
if (response && response.body) {
if (response.body.txs && response.body.txs.length === 0) {
break;
}
let latestBlock = false;
if (response.body.info && response.body.info.latest_block) {
latestBlock = response.body.info.latest_block.height;
}
this._lastTxFetch = +new Date();
// processing TXs and adding to internal memory
if (response.body.txs) {
for (const tx of response.body.txs) {
let value = 0;
for (const input of tx.inputs) {
// ----- INPUTS
if (input.prev_out.xpub) {
// sent FROM US
value -= input.prev_out.value;
// setting internal caches to help ourselves in future...
const path = input.prev_out.xpub.path.split('/');
if (path[path.length - 2] === '1') {
// change address
this.next_free_change_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_change_address_index);
// setting to point to last maximum known change address + 1
}
if (path[path.length - 2] === '0') {
// main (aka external) address
this.next_free_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_address_index);
// setting to point to last maximum known main address + 1
}
// done with cache
}
}
for (const output of tx.out) {
// ----- OUTPUTS
if (output.xpub) {
// sent TO US (change)
value += output.value;
// setting internal caches to help ourselves in future...
const path = output.xpub.path.split('/');
if (path[path.length - 2] === '1') {
// change address
this.next_free_change_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_change_address_index);
// setting to point to last maximum known change address + 1
}
if (path[path.length - 2] === '0') {
// main (aka external) address
this.next_free_address_index = Math.max(path[path.length - 1] * 1 + 1, this.next_free_address_index);
// setting to point to last maximum known main address + 1
}
// done with cache
}
}
tx.value = value; // new BigNumber(value).div(100000000).toString() * 1;
if (!tx.confirmations && latestBlock) {
tx.confirmations = latestBlock - tx.block_height + 1;
}
this.transactions.push(tx);
}
if (response.body.txs.length < 100) {
// this fetch yilded less than page size, thus requesting next batch makes no sense
break;
}
} else {
break; // error ?
}
} else {
throw new Error('Could not fetch transactions from API: ' + response.err); // breaks here
}
offset += 100;
}
} catch (err) {
console.warn(err);
}
throw new Error('not implemented');
}
/**

View file

@ -23,7 +23,6 @@ export class AbstractWallet {
this.secret = ''; // private key or recovery phrase
this.balance = 0;
this.unconfirmed_balance = 0;
this.transactions = [];
this._address = false; // cache
this.utxo = [];
this._lastTxFetch = 0;
@ -40,7 +39,7 @@ export class AbstractWallet {
}
getTransactions() {
return this.transactions;
throw new Error('not implemented');
}
getUserHasSavedExport() {