From 80084bc8b5b326224066ac7afef193a6f129e51d Mon Sep 17 00:00:00 2001 From: JDonadio Date: Fri, 3 Nov 2017 18:14:32 -0300 Subject: [PATCH] save and update history --- src/pages/wallet-details/wallet-details.ts | 20 +- src/providers/profile/profile.ts | 6 + src/providers/wallet/wallet.ts | 443 +++++++++++++-------- 3 files changed, 295 insertions(+), 174 deletions(-) diff --git a/src/pages/wallet-details/wallet-details.ts b/src/pages/wallet-details/wallet-details.ts index c2fd6c34c..61ed87f6d 100644 --- a/src/pages/wallet-details/wallet-details.ts +++ b/src/pages/wallet-details/wallet-details.ts @@ -1,5 +1,6 @@ import { Component } from '@angular/core'; import { NavParams } from 'ionic-angular'; +import { WalletProvider } from '../../providers/wallet/wallet'; @Component({ selector: 'page-wallet-details', @@ -10,9 +11,26 @@ export class WalletDetailsPage { constructor( private navParams: NavParams, + private walletProvider: WalletProvider, ) { this.wallet = this.navParams.data.wallet; } - ionViewDidEnter() {} + ionViewDidEnter() { + if (!this.wallet.isComplete()) { + console.log('Wallet incomplete'); + return; + }; + + console.log('Wallet:', this.wallet); + this.getTxHistory(); + } + + getTxHistory(force?: boolean) { + this.walletProvider.getTxHistory_(this.wallet, {force: force}).then((txh) => { + this.wallet.completeHistory = txh; + }).catch((err) => { + console.log(err); + }); + } } \ No newline at end of file diff --git a/src/providers/profile/profile.ts b/src/providers/profile/profile.ts index 4e735ac27..201ab7316 100644 --- a/src/providers/profile/profile.ts +++ b/src/providers/profile/profile.ts @@ -133,6 +133,12 @@ export class ProfileProvider { wallet.on('notification', (n: any) => { this.logger.debug('BWC Notification:', n); + if (n.type == "NewIncomingTx") { + this.walletProvider.getTxHistory_(wallet, { force: true }).catch((err) => { + this.logger.warn('Could not get the tx history for: ' + wallet.credentials.walletId); + }) + } + if (n.type == "NewBlock" && n.data.network == "testnet") { this.throttledBwsEvent(n, wallet); } else this.newBwsEvent(n, wallet); diff --git a/src/providers/wallet/wallet.ts b/src/providers/wallet/wallet.ts index 5e1abb19a..b18414cff 100644 --- a/src/providers/wallet/wallet.ts +++ b/src/providers/wallet/wallet.ts @@ -366,22 +366,66 @@ export class WalletProvider { }); } - private getSavedTxs(walletId: string): Promise { + public getTxHistory_(wallet: any, opts: any) { + return new Promise((resolve, reject) => { + opts = opts ? opts : {}; + + // TODO isHistoryCached should get the properties from status or profile service + + this.logger.debug('Updating Transaction History'); + + this.getTxsFromLocal(wallet.credentials.walletId).then((txsFromLocal) => { + console.log('TX FROM LOCAL:', txsFromLocal); + if (!lodash.isEmpty(txsFromLocal) && !opts.force) return resolve(txsFromLocal); + + this.getTxsFromServer(wallet, 0, null, 10).then((txsFromServer) => { + console.log('TX FROM SERVER:', txsFromServer); + + this.updateTxHistory(wallet, txsFromLocal, txsFromServer); + }).catch((err) => { + this.logger.debug('Error getting txs from server'); + return reject(err); + }); + }).catch((err) => { + this.logger.debug('Error getting txs from local'); + return reject(err); + }); + }); + } + + private updateTxHistory(wallet: any, txsFromLocal: any, txsFromServer?: any) { + let array = lodash.compact(txsFromLocal.concat(txsFromServer)); + let newHistory = lodash.uniqBy(array, (x: any) => { + return x.txid; + }); + wallet.completeHistory = newHistory; + wallet.completeHistory.isValid = true; + + let historyToSave = lodash.compact(lodash.flatten(lodash.map(newHistory, 'res'))); + + this.persistenceProvider.setTxHistory(wallet.credentials.walletId, JSON.stringify(historyToSave)).then(() => { + this.logger.debug('Tx History saved for: ' + wallet.credentials.walletId); + }).catch((err) => { + this.logger.warn('Error saving history for: ' + wallet.credentials.walletId); + }); + } + + private getTxsFromLocal(walletId: string): Promise { return new Promise((resolve, reject) => { this.persistenceProvider.getTxHistory(walletId).then((txs: any) => { let localTxs = []; - if (!txs) { + if (lodash.isEmpty(txs)) { return resolve(localTxs); }; - + try { localTxs = JSON.parse(txs); } catch (ex) { - this.logger.warn(ex); + localTxs = lodash.compact(txs); }; - return resolve(lodash.compact(localTxs)); + return resolve(localTxs); }).catch((err: Error) => { return reject(err); }); @@ -415,7 +459,7 @@ export class WalletProvider { }); } - private updateLocalTxHistory(wallet: any, opts: any) { + private updateLocalTxHistory_(wallet: any, opts: any) { return new Promise((resolve, reject) => { opts = opts ? opts : {}; let FIRST_LIMIT = 5; @@ -425,164 +469,217 @@ export class WalletProvider { let progressFn = opts.progressFn || function () { }; let foundLimitTx = []; + // if (opts.feeLevels) { + // opts.lowAmount = this.getLowAmount(wallet, opts.feeLevels); + // }; - if (opts.feeLevels) { - opts.lowAmount = this.getLowAmount(wallet, opts.feeLevels); - }; + // let fixTxsUnit = (txs: any): void => { + // if (!txs || !txs[0] || !txs[0].amountStr) return; - let fixTxsUnit = (txs: any): void => { - if (!txs || !txs[0] || !txs[0].amountStr) return; + // let cacheCoin: string = txs[0].amountStr.split(' ')[1]; - let cacheCoin: string = txs[0].amountStr.split(' ')[1]; + // if (cacheCoin == 'bits') { - if (cacheCoin == 'bits') { - - this.logger.debug('Fixing Tx Cache Unit to: ' + wallet.coin) - lodash.each(txs, (tx: any) => { - tx.amountStr = this.txFormatProvider.formatAmountStr(wallet.coin, tx.amount); - tx.feeStr = this.txFormatProvider.formatAmountStr(wallet.coin, tx.fees); - }); - }; - }; - - this.getSavedTxs(walletId).then((txsFromLocal: any) => { - - fixTxsUnit(txsFromLocal); - - var confirmedTxs = this.removeAndMarkSoftConfirmedTx(txsFromLocal); - var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null; - var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null; + // this.logger.debug('Fixing Tx Cache Unit to: ' + wallet.coin) + // lodash.each(txs, (tx: any) => { + // tx.amountStr = this.txFormatProvider.formatAmountStr(wallet.coin, tx.amount); + // tx.feeStr = this.txFormatProvider.formatAmountStr(wallet.coin, tx.fees); + // }); + // }; + // }; + this.getTxsFromLocal(walletId).then((txsFromLocal: any) => { + if (lodash.isEmpty(txsFromLocal)) { + console.log('No local transactions available'); + return resolve(null); + } + // fixTxsUnit(txsFromLocal); // First update - progressFn(txsFromLocal, 0); + // progressFn(txsFromLocal, 0); wallet.completeHistory = txsFromLocal; - let getNewTxs = (newTxs: Array, skip: number): Promise => { - return new Promise((resolve, reject) => { - this.getTxsFromServer(wallet, skip, endingTxid, requestLimit).then((result: any) => { + // Second update - var res = result.res; - var shouldContinue = result.shouldContinue ? result.shouldContinue : false; - - newTxs = newTxs.concat(this.processNewTxs(wallet, lodash.compact(res))); - progressFn(newTxs.concat(txsFromLocal), newTxs.length); - skip = skip + requestLimit; - this.logger.debug('Syncing TXs. Got:' + newTxs.length + ' Skip:' + skip, ' EndingTxid:', endingTxid, ' Continue:', shouldContinue); - - // TODO Dirty - // do not sync all history, just looking for a single TX. - if (opts.limitTx) { - foundLimitTx = lodash.find(newTxs, { - txid: opts.limitTx, - }); - if (foundLimitTx) { - this.logger.debug('Found limitTX: ' + opts.limitTx); - return resolve(foundLimitTx); - } - } - // - if (!shouldContinue) { - this.logger.debug('Finished Sync: New / soft confirmed Txs: ' + newTxs.length); - return resolve(newTxs); - }; - - requestLimit = LIMIT; - getNewTxs(newTxs, skip); - }).catch((err) => { - this.logger.warn(this.bwcErrorProvider.msg(err, 'Server Error')); //TODO - if (err instanceof this.errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) { - this.logger.info('Retrying history download in 5 secs...'); - return reject(setTimeout(() => { - return getNewTxs(newTxs, skip); - }, 5000)); - }; - return reject(err); - }); - }); - }; - - getNewTxs([], 0).then((txs: any) => { - - let array: Array = lodash.compact(txs.concat(confirmedTxs)); - let newHistory = lodash.uniqBy(array, (x: any) => { - return x.txid; - }); - - - let updateNotes = (): Promise => { - return new Promise((resolve, reject) => { - if (!endingTs) return resolve(); - - this.logger.debug('Syncing notes from: ' + endingTs); - wallet.getTxNotes({ - minTs: endingTs - }, (err: any, notes: any) => { - if (err) { - this.logger.warn(err); - return reject(err); - }; - lodash.each(notes, (note: any) => { - this.logger.debug('Note for ' + note.txid); - lodash.each(newHistory, (tx: any) => { - if (tx.txid == note.txid) { - this.logger.debug('...updating note for ' + note.txid); - tx.note = note; - }; - }); - }); - return resolve(); - }); - }); - }; - - let updateLowAmount = (txs: any) => { - if (!opts.lowAmount) return; - - lodash.each(txs, (tx: any) => { - tx.lowAmount = tx.amount < opts.lowAmount; - }); - }; - - updateLowAmount(txs); - - updateNotes().then(() => { - - // - if (foundLimitTx) { - this.logger.debug('Tx history read until limitTx: ' + opts.limitTx); - return resolve(newHistory); - } - // - - var historyToSave = JSON.stringify(newHistory); - lodash.each(txs, (tx: any) => { - tx.recent = true; - }); - this.logger.debug('Tx History synced. Total Txs: ' + newHistory.length); - - // Final update - if (walletId == wallet.credentials.walletId) { - wallet.completeHistory = newHistory; - } - - return this.persistenceProvider.setTxHistory(historyToSave, walletId).then(() => { - this.logger.debug('Tx History saved.'); - return resolve(); - }).catch((err) => { - return reject(err); - }); - }).catch((err) => { - return reject(err); - }); - }).catch((err) => { - return reject(err); - }); }).catch((err) => { return reject(err); }); }); } + private updateHistoryFromServer() { + return new Promise((resolve, reject) => { + + }); + } + + // private updateLocalTxHistory(wallet: any, opts: any) { + // return new Promise((resolve, reject) => { + // opts = opts ? opts : {}; + // let FIRST_LIMIT = 5; + // let LIMIT = 50; + // let requestLimit = FIRST_LIMIT; + // let walletId = wallet.credentials.walletId; + // let progressFn = opts.progressFn || function () { }; + // let foundLimitTx = []; + + + // if (opts.feeLevels) { + // opts.lowAmount = this.getLowAmount(wallet, opts.feeLevels); + // }; + + // let fixTxsUnit = (txs: any): void => { + // if (!txs || !txs[0] || !txs[0].amountStr) return; + + // let cacheCoin: string = txs[0].amountStr.split(' ')[1]; + + // if (cacheCoin == 'bits') { + + // this.logger.debug('Fixing Tx Cache Unit to: ' + wallet.coin) + // lodash.each(txs, (tx: any) => { + // tx.amountStr = this.txFormatProvider.formatAmountStr(wallet.coin, tx.amount); + // tx.feeStr = this.txFormatProvider.formatAmountStr(wallet.coin, tx.fees); + // }); + // }; + // }; + + // this.getTxsFromLocal(walletId).then((txsFromLocal: any) => { + + // fixTxsUnit(txsFromLocal); + + // var confirmedTxs = this.removeAndMarkSoftConfirmedTx(txsFromLocal); + // var endingTxid = confirmedTxs[0] ? confirmedTxs[0].txid : null; + // var endingTs = confirmedTxs[0] ? confirmedTxs[0].time : null; + + // // First update + // progressFn(txsFromLocal, 0); + // wallet.completeHistory = txsFromLocal; + + // let getNewTxs = (newTxs: Array, skip: number): Promise => { + // return new Promise((resolve, reject) => { + // this.getTxsFromServer(wallet, skip, endingTxid, requestLimit).then((result: any) => { + + // var res = result.res; + // var shouldContinue = result.shouldContinue ? result.shouldContinue : false; + + // newTxs = newTxs.concat(this.processNewTxs(wallet, lodash.compact(res))); + // progressFn(newTxs.concat(txsFromLocal), newTxs.length); + // skip = skip + requestLimit; + // this.logger.debug('Syncing TXs. Got:' + newTxs.length + ' Skip:' + skip, ' EndingTxid:', endingTxid, ' Continue:', shouldContinue); + + // // TODO Dirty + // // do not sync all history, just looking for a single TX. + // if (opts.limitTx) { + // foundLimitTx = lodash.find(newTxs, { + // txid: opts.limitTx, + // }); + // if (foundLimitTx) { + // this.logger.debug('Found limitTX: ' + opts.limitTx); + // return resolve(foundLimitTx); + // } + // } + // // + // if (!shouldContinue) { + // this.logger.debug('Finished Sync: New / soft confirmed Txs: ' + newTxs.length); + // return resolve(newTxs); + // }; + + // requestLimit = LIMIT; + // getNewTxs(newTxs, skip); + // }).catch((err) => { + // this.logger.warn(this.bwcErrorProvider.msg(err, 'Server Error')); //TODO + // if (err instanceof this.errors.CONNECTION_ERROR || (err.message && err.message.match(/5../))) { + // this.logger.info('Retrying history download in 5 secs...'); + // return reject(setTimeout(() => { + // return getNewTxs(newTxs, skip); + // }, 5000)); + // }; + // return reject(err); + // }); + // }); + // }; + + // getNewTxs([], 0).then((txs: any) => { + + // let array: Array = lodash.compact(txs.concat(confirmedTxs)); + // let newHistory = lodash.uniqBy(array, (x: any) => { + // return x.txid; + // }); + + + // let updateNotes = (): Promise => { + // return new Promise((resolve, reject) => { + // if (!endingTs) return resolve(); + + // this.logger.debug('Syncing notes from: ' + endingTs); + // wallet.getTxNotes({ + // minTs: endingTs + // }, (err: any, notes: any) => { + // if (err) { + // this.logger.warn(err); + // return reject(err); + // }; + // lodash.each(notes, (note: any) => { + // this.logger.debug('Note for ' + note.txid); + // lodash.each(newHistory, (tx: any) => { + // if (tx.txid == note.txid) { + // this.logger.debug('...updating note for ' + note.txid); + // tx.note = note; + // }; + // }); + // }); + // return resolve(); + // }); + // }); + // }; + + // let updateLowAmount = (txs: any) => { + // if (!opts.lowAmount) return; + + // lodash.each(txs, (tx: any) => { + // tx.lowAmount = tx.amount < opts.lowAmount; + // }); + // }; + + // updateLowAmount(txs); + + // updateNotes().then(() => { + + // // + // if (foundLimitTx) { + // this.logger.debug('Tx history read until limitTx: ' + opts.limitTx); + // return resolve(newHistory); + // } + // // + + // var historyToSave = JSON.stringify(newHistory); + // lodash.each(txs, (tx: any) => { + // tx.recent = true; + // }); + // this.logger.debug('Tx History synced. Total Txs: ' + newHistory.length); + + // // Final update + // if (walletId == wallet.credentials.walletId) { + // wallet.completeHistory = newHistory; + // } + + // return this.persistenceProvider.setTxHistory(historyToSave, walletId).then(() => { + // this.logger.debug('Tx History saved.'); + // return resolve(); + // }).catch((err) => { + // return reject(err); + // }); + // }).catch((err) => { + // return reject(err); + // }); + // }).catch((err) => { + // return reject(err); + // }); + // }).catch((err) => { + // return reject(err); + // }); + // }); + // } + private processNewTxs(wallet: any, txs: any): Array { let configGet: any = this.configProvider.get(); let config: any = configGet.wallet.settings; @@ -717,7 +814,7 @@ export class WalletProvider { let opts = { limitTx: txid }; - this.getTxHistory(wallet, opts).then((txHistory: any) => { + this.getTxHistory_(wallet, opts).then((txHistory: any) => { finish(txHistory); }).catch((err) => { return reject(err); @@ -726,32 +823,32 @@ export class WalletProvider { }); } - public getTxHistory(wallet: any, opts: any): Promise { - return new Promise((resolve, reject) => { - opts = opts ? opts : {}; - let walletId = wallet.credentials.walletId; + // public getTxHistory(wallet: any, opts: any): Promise { + // return new Promise((resolve, reject) => { + // opts = opts ? opts : {}; + // let walletId = wallet.credentials.walletId; - if (!wallet.isComplete()) return resolve(); + // if (!wallet.isComplete()) return resolve(); - let isHistoryCached = () => { - return wallet.completeHistory && wallet.completeHistory.isValid; - }; + // let isHistoryCached = () => { + // return wallet.completeHistory && wallet.completeHistory.isValid; + // }; - if (isHistoryCached() && !opts.force) return resolve(wallet.completeHistory); + // if (isHistoryCached() && !opts.force) return resolve(wallet.completeHistory); - this.logger.debug('Updating Transaction History'); - this.updateLocalTxHistory(wallet, opts).then((txs: any) => { - if (opts.limitTx) { - return resolve(txs); - }; + // this.logger.debug('Updating Transaction History'); + // this.updateLocalTxHistory(wallet, opts).then((txs: any) => { + // if (opts.limitTx) { + // return resolve(txs); + // }; - wallet.completeHistory.isValid = true; - return resolve(wallet.completeHistory); - }).catch((err) => { - return reject(err); - }); - }); - } + // wallet.completeHistory.isValid = true; + // return resolve(wallet.completeHistory); + // }).catch((err) => { + // return reject(err); + // }); + // }); + // } public isEncrypted(wallet: any): boolean { if (lodash.isEmpty(wallet)) return; @@ -852,7 +949,7 @@ export class WalletProvider { this.logger.debug('Transaction removed'); this.invalidateCache(wallet); - // $rootScope.$emit('Local/TxAction', wallet.id); + // $rootScope.$emit('Local/TxAction', wallet.id); return resolve(err); }); }); @@ -1053,7 +1150,7 @@ export class WalletProvider { public handleEncryptedWallet(wallet: any): Promise { return new Promise((resolve, reject) => { - if (!this.isEncrypted(wallet)) return resolve(); + if (!this.isEncrypted(wallet)) return reject(); this.askPassword(wallet.name, 'Enter Spending Password').then((password: string) => { //TODO gettextcatalog if (!password) return reject('No password'); if (!wallet.checkPassword(password)) return reject('Wrong password');