aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorDan J Miller <danjm.com@gmail.com>2018-12-01 06:51:24 +0800
committerDan Finlay <542863+danfinlay@users.noreply.github.com>2018-12-01 06:51:24 +0800
commit4c2455554540b9d0dd979bad329892279fddd8b9 (patch)
treee3b101ec86a65500023d8b7e99dd5973a9473626 /app
parent45a9f40aa614753e274275eaeb4dd6c0251dcf45 (diff)
downloadtangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.tar
tangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.tar.gz
tangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.tar.bz2
tangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.tar.lz
tangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.tar.xz
tangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.tar.zst
tangerine-wallet-browser-4c2455554540b9d0dd979bad329892279fddd8b9.zip
Save recent network balances in local storage (#5843)
* Use selector for state.metamask.accounts in all cases. * Default to cached balance when selecting metamask accounts * Adds the cached-balances controller * Documentation and small codes fixes for #5843 Co-Authored-By: danjm <danjm.com@gmail.com>
Diffstat (limited to 'app')
-rw-r--r--app/scripts/controllers/cached-balances.js83
-rw-r--r--app/scripts/metamask-controller.js9
2 files changed, 92 insertions, 0 deletions
diff --git a/app/scripts/controllers/cached-balances.js b/app/scripts/controllers/cached-balances.js
new file mode 100644
index 000000000..925c45334
--- /dev/null
+++ b/app/scripts/controllers/cached-balances.js
@@ -0,0 +1,83 @@
+const ObservableStore = require('obs-store')
+const extend = require('xtend')
+
+/**
+ * @typedef {Object} CachedBalancesOptions
+ * @property {Object} accountTracker An {@code AccountTracker} reference
+ * @property {Function} getNetwork A function to get the current network
+ * @property {Object} initState The initial controller state
+ */
+
+/**
+ * Background controller responsible for maintaining
+ * a cache of account balances in local storage
+ */
+class CachedBalancesController {
+ /**
+ * Creates a new controller instance
+ *
+ * @param {CachedBalancesOptions} [opts] Controller configuration parameters
+ */
+ constructor (opts = {}) {
+ const { accountTracker, getNetwork } = opts
+
+ this.accountTracker = accountTracker
+ this.getNetwork = getNetwork
+
+ const initState = extend({
+ cachedBalances: {},
+ }, opts.initState)
+ this.store = new ObservableStore(initState)
+
+ this._registerUpdates()
+ }
+
+ /**
+ * Updates the cachedBalances property for the current network. Cached balances will be updated to those in the passed accounts
+ * if balances in the passed accounts are truthy.
+ *
+ * @param {Object} obj The the recently updated accounts object for the current network
+ * @returns {Promise<void>}
+ */
+ async updateCachedBalances ({ accounts }) {
+ const network = await this.getNetwork()
+ const balancesToCache = await this._generateBalancesToCache(accounts, network)
+ this.store.updateState({
+ cachedBalances: balancesToCache,
+ })
+ }
+
+ _generateBalancesToCache (newAccounts, currentNetwork) {
+ const { cachedBalances } = this.store.getState()
+ const currentNetworkBalancesToCache = { ...cachedBalances[currentNetwork] }
+
+ Object.keys(newAccounts).forEach(accountID => {
+ const account = newAccounts[accountID]
+
+ if (account.balance) {
+ currentNetworkBalancesToCache[accountID] = account.balance
+ }
+ })
+ const balancesToCache = {
+ ...cachedBalances,
+ [currentNetwork]: currentNetworkBalancesToCache,
+ }
+
+ return balancesToCache
+ }
+
+ /**
+ * Sets up listeners and subscriptions which should trigger an update of cached balances. These updates will
+ * happen when the current account changes. Which happens on block updates, as well as on network and account
+ * selections.
+ *
+ * @private
+ *
+ */
+ _registerUpdates () {
+ const update = this.updateCachedBalances.bind(this)
+ this.accountTracker.store.subscribe(update)
+ }
+}
+
+module.exports = CachedBalancesController
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 7d6f06f92..fe806e47e 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -29,6 +29,7 @@ const ShapeShiftController = require('./controllers/shapeshift')
const AddressBookController = require('./controllers/address-book')
const InfuraController = require('./controllers/infura')
const BlacklistController = require('./controllers/blacklist')
+const CachedBalancesController = require('./controllers/cached-balances')
const RecentBlocksController = require('./controllers/recent-blocks')
const MessageManager = require('./lib/message-manager')
const PersonalMessageManager = require('./lib/personal-message-manager')
@@ -142,6 +143,12 @@ module.exports = class MetamaskController extends EventEmitter {
}
})
+ this.cachedBalancesController = new CachedBalancesController({
+ accountTracker: this.accountTracker,
+ getNetwork: this.networkController.getNetworkState.bind(this.networkController),
+ initState: initState.CachedBalancesController,
+ })
+
// ensure accountTracker updates balances after network change
this.networkController.on('networkDidChange', () => {
this.accountTracker._updateAccounts()
@@ -241,6 +248,7 @@ module.exports = class MetamaskController extends EventEmitter {
ShapeShiftController: this.shapeshiftController.store,
NetworkController: this.networkController.store,
InfuraController: this.infuraController.store,
+ CachedBalancesController: this.cachedBalancesController.store,
})
this.memStore = new ComposableObservableStore(null, {
@@ -248,6 +256,7 @@ module.exports = class MetamaskController extends EventEmitter {
AccountTracker: this.accountTracker.store,
TxController: this.txController.memStore,
BalancesController: this.balancesController.store,
+ CachedBalancesController: this.cachedBalancesController.store,
TokenRatesController: this.tokenRatesController.store,
MessageManager: this.messageManager.memStore,
PersonalMessageManager: this.personalMessageManager.memStore,