aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts
diff options
context:
space:
mode:
authorkumavis <kumavis@users.noreply.github.com>2018-06-15 01:11:35 +0800
committerGitHub <noreply@github.com>2018-06-15 01:11:35 +0800
commitd9ef72cb7ef78a1c2bf7ce119352425d72a10dc0 (patch)
tree6c14bb94e21996bdf688cc08011c8955322697ad /app/scripts
parent11bfdf444dca3917479cff82f807cc0d4c217191 (diff)
parentd814bee578bfe931766804612ed57a545e4b21a8 (diff)
downloadtangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.tar
tangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.tar.gz
tangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.tar.bz2
tangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.tar.lz
tangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.tar.xz
tangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.tar.zst
tangerine-wallet-browser-d9ef72cb7ef78a1c2bf7ce119352425d72a10dc0.zip
Merge branch 'develop' into save-brave
Diffstat (limited to 'app/scripts')
-rw-r--r--app/scripts/account-import-strategies/index.js13
-rw-r--r--app/scripts/background.js14
-rw-r--r--app/scripts/controllers/transactions/index.js9
-rw-r--r--app/scripts/controllers/transactions/nonce-tracker.js54
-rw-r--r--app/scripts/controllers/transactions/pending-tx-tracker.js4
-rw-r--r--app/scripts/inpage.js21
-rw-r--r--app/scripts/lib/auto-reload.js61
-rw-r--r--app/scripts/lib/createStreamSink.js24
-rw-r--r--app/scripts/metamask-controller.js31
-rw-r--r--app/scripts/notice-controller.js32
10 files changed, 119 insertions, 144 deletions
diff --git a/app/scripts/account-import-strategies/index.js b/app/scripts/account-import-strategies/index.js
index 96e2b5912..16ae224ea 100644
--- a/app/scripts/account-import-strategies/index.js
+++ b/app/scripts/account-import-strategies/index.js
@@ -16,7 +16,18 @@ const accountImporter = {
strategies: {
'Private Key': (privateKey) => {
- const stripped = ethUtil.stripHexPrefix(privateKey)
+ if (!privateKey) {
+ throw new Error('Cannot import an empty key.')
+ }
+
+ const prefixed = ethUtil.addHexPrefix(privateKey)
+ const buffer = ethUtil.toBuffer(prefixed)
+
+ if (!ethUtil.isValidPrivate(buffer)) {
+ throw new Error('Cannot import invalid private key.')
+ }
+
+ const stripped = ethUtil.stripHexPrefix(prefixed)
return stripped
},
'JSON File': (input, password) => {
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 56e190f97..2451cddb6 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -16,6 +16,7 @@ const ExtensionPlatform = require('./platforms/extension')
const Migrator = require('./lib/migrator/')
const migrations = require('./migrations/')
const PortStream = require('./lib/port-stream.js')
+const createStreamSink = require('./lib/createStreamSink')
const NotificationManager = require('./lib/notification-manager.js')
const MetamaskController = require('./metamask-controller')
const firstTimeState = require('./first-time-state')
@@ -273,7 +274,7 @@ function setupController (initState, initLangCode) {
asStream(controller.store),
debounce(1000),
storeTransform(versionifyData),
- storeTransform(persistData),
+ createStreamSink(persistData),
(error) => {
log.error('MetaMask - Persistence pipeline failed', error)
}
@@ -289,7 +290,7 @@ function setupController (initState, initLangCode) {
return versionedData
}
- function persistData (state) {
+ async function persistData (state) {
if (!state) {
throw new Error('MetaMask - updated state is missing', state)
}
@@ -297,12 +298,13 @@ function setupController (initState, initLangCode) {
throw new Error('MetaMask - updated state does not have data', state)
}
if (localStore.isSupported) {
- localStore.set(state)
- .catch((err) => {
+ try {
+ await localStore.set(state)
+ } catch (err) {
+ // log error so we dont break the pipeline
log.error('error setting state in local store:', err)
- })
+ }
}
- return state
}
//
diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js
index b53947e27..8e2288aed 100644
--- a/app/scripts/controllers/transactions/index.js
+++ b/app/scripts/controllers/transactions/index.js
@@ -165,7 +165,7 @@ class TransactionController extends EventEmitter {
// add default tx params
txMeta = await this.addTxGasDefaults(txMeta)
} catch (error) {
- console.log(error)
+ log.warn(error)
this.txStateManager.setTxStatusFailed(txMeta.id, error)
throw error
}
@@ -264,7 +264,12 @@ class TransactionController extends EventEmitter {
// must set transaction to submitted/failed before releasing lock
nonceLock.releaseLock()
} catch (err) {
- this.txStateManager.setTxStatusFailed(txId, err)
+ // this is try-catch wrapped so that we can guarantee that the nonceLock is released
+ try {
+ this.txStateManager.setTxStatusFailed(txId, err)
+ } catch (err) {
+ log.error(err)
+ }
// must set transaction to submitted/failed before releasing lock
if (nonceLock) nonceLock.releaseLock()
// continue with error chain
diff --git a/app/scripts/controllers/transactions/nonce-tracker.js b/app/scripts/controllers/transactions/nonce-tracker.js
index f8cdc5523..35ca08d6c 100644
--- a/app/scripts/controllers/transactions/nonce-tracker.js
+++ b/app/scripts/controllers/transactions/nonce-tracker.js
@@ -49,29 +49,35 @@ class NonceTracker {
await this._globalMutexFree()
// await lock free, then take lock
const releaseLock = await this._takeMutex(address)
- // evaluate multiple nextNonce strategies
- const nonceDetails = {}
- const networkNonceResult = await this._getNetworkNextNonce(address)
- const highestLocallyConfirmed = this._getHighestLocallyConfirmed(address)
- const nextNetworkNonce = networkNonceResult.nonce
- const highestSuggested = Math.max(nextNetworkNonce, highestLocallyConfirmed)
-
- const pendingTxs = this.getPendingTransactions(address)
- const localNonceResult = this._getHighestContinuousFrom(pendingTxs, highestSuggested) || 0
-
- nonceDetails.params = {
- highestLocallyConfirmed,
- highestSuggested,
- nextNetworkNonce,
+ try {
+ // evaluate multiple nextNonce strategies
+ const nonceDetails = {}
+ const networkNonceResult = await this._getNetworkNextNonce(address)
+ const highestLocallyConfirmed = this._getHighestLocallyConfirmed(address)
+ const nextNetworkNonce = networkNonceResult.nonce
+ const highestSuggested = Math.max(nextNetworkNonce, highestLocallyConfirmed)
+
+ const pendingTxs = this.getPendingTransactions(address)
+ const localNonceResult = this._getHighestContinuousFrom(pendingTxs, highestSuggested) || 0
+
+ nonceDetails.params = {
+ highestLocallyConfirmed,
+ highestSuggested,
+ nextNetworkNonce,
+ }
+ nonceDetails.local = localNonceResult
+ nonceDetails.network = networkNonceResult
+
+ const nextNonce = Math.max(networkNonceResult.nonce, localNonceResult.nonce)
+ assert(Number.isInteger(nextNonce), `nonce-tracker - nextNonce is not an integer - got: (${typeof nextNonce}) "${nextNonce}"`)
+
+ // return nonce and release cb
+ return { nextNonce, nonceDetails, releaseLock }
+ } catch (err) {
+ // release lock if we encounter an error
+ releaseLock()
+ throw err
}
- nonceDetails.local = localNonceResult
- nonceDetails.network = networkNonceResult
-
- const nextNonce = Math.max(networkNonceResult.nonce, localNonceResult.nonce)
- assert(Number.isInteger(nextNonce), `nonce-tracker - nextNonce is not an integer - got: (${typeof nextNonce}) "${nextNonce}"`)
-
- // return nonce and release cb
- return { nextNonce, nonceDetails, releaseLock }
}
async _getCurrentBlock () {
@@ -85,8 +91,8 @@ class NonceTracker {
async _globalMutexFree () {
const globalMutex = this._lookupMutex('global')
- const release = await globalMutex.acquire()
- release()
+ const releaseLock = await globalMutex.acquire()
+ releaseLock()
}
async _takeMutex (lockId) {
diff --git a/app/scripts/controllers/transactions/pending-tx-tracker.js b/app/scripts/controllers/transactions/pending-tx-tracker.js
index 6e2fcb40b..4e41cdaf8 100644
--- a/app/scripts/controllers/transactions/pending-tx-tracker.js
+++ b/app/scripts/controllers/transactions/pending-tx-tracker.js
@@ -196,14 +196,14 @@ class PendingTransactionTracker extends EventEmitter {
async _checkPendingTxs () {
const signedTxList = this.getPendingTransactions()
// in order to keep the nonceTracker accurate we block it while updating pending transactions
- const nonceGlobalLock = await this.nonceTracker.getGlobalLock()
+ const { releaseLock } = await this.nonceTracker.getGlobalLock()
try {
await Promise.all(signedTxList.map((txMeta) => this._checkPendingTx(txMeta)))
} catch (err) {
log.error('PendingTransactionWatcher - Error updating pending transactions')
log.error(err)
}
- nonceGlobalLock.releaseLock()
+ releaseLock()
}
/**
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index 6d16eebd4..070f5d247 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -3,7 +3,6 @@ cleanContextForImports()
require('web3/dist/web3.min.js')
const log = require('loglevel')
const LocalMessageDuplexStream = require('post-message-stream')
-const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
@@ -38,8 +37,24 @@ web3.setProvider = function () {
log.debug('MetaMask - overrode web3.setProvider')
}
log.debug('MetaMask - injected web3')
-// export global web3, with usage-detection
-setupDappAutoReload(web3, inpageProvider.publicConfigStore)
+
+// export global web3, with usage-detection and deprecation warning
+let hasBeenWarned = false
+global.web3 = new Proxy(web3, {
+ get: (_web3, key) => {
+ // show warning once on web3 access
+ if (!hasBeenWarned && key !== 'currentProvider') {
+ console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation')
+ hasBeenWarned = true
+ }
+ // return value normally
+ return _web3[key]
+ },
+ set: (_web3, key, value) => {
+ // set value normally
+ _web3[key] = value
+ },
+})
// set web3 defaultAccount
inpageProvider.publicConfigStore.subscribe(function (state) {
diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js
deleted file mode 100644
index cce31c3d2..000000000
--- a/app/scripts/lib/auto-reload.js
+++ /dev/null
@@ -1,61 +0,0 @@
-module.exports = setupDappAutoReload
-
-function setupDappAutoReload (web3, observable) {
- // export web3 as a global, checking for usage
- let hasBeenWarned = false
- let reloadInProgress = false
- let lastTimeUsed
- let lastSeenNetwork
-
- global.web3 = new Proxy(web3, {
- get: (_web3, key) => {
- // show warning once on web3 access
- if (!hasBeenWarned && key !== 'currentProvider') {
- console.warn('MetaMask: web3 will be deprecated in the near future in favor of the ethereumProvider \nhttps://github.com/MetaMask/faq/blob/master/detecting_metamask.md#web3-deprecation')
- hasBeenWarned = true
- }
- // get the time of use
- lastTimeUsed = Date.now()
- // return value normally
- return _web3[key]
- },
- set: (_web3, key, value) => {
- // set value normally
- _web3[key] = value
- },
- })
-
- observable.subscribe(function (state) {
- // if reload in progress, no need to check reload logic
- if (reloadInProgress) return
-
- const currentNetwork = state.networkVersion
-
- // set the initial network
- if (!lastSeenNetwork) {
- lastSeenNetwork = currentNetwork
- return
- }
-
- // skip reload logic if web3 not used
- if (!lastTimeUsed) return
-
- // if network did not change, exit
- if (currentNetwork === lastSeenNetwork) return
-
- // initiate page reload
- reloadInProgress = true
- const timeSinceUse = Date.now() - lastTimeUsed
- // if web3 was recently used then delay the reloading of the page
- if (timeSinceUse > 500) {
- triggerReset()
- } else {
- setTimeout(triggerReset, 500)
- }
- })
-}
-
-// reload the page
-function triggerReset () {
- global.location.reload()
-}
diff --git a/app/scripts/lib/createStreamSink.js b/app/scripts/lib/createStreamSink.js
new file mode 100644
index 000000000..cf9416fea
--- /dev/null
+++ b/app/scripts/lib/createStreamSink.js
@@ -0,0 +1,24 @@
+const WritableStream = require('readable-stream').Writable
+const promiseToCallback = require('promise-to-callback')
+
+module.exports = createStreamSink
+
+
+function createStreamSink(asyncWriteFn, _opts) {
+ return new AsyncWritableStream(asyncWriteFn, _opts)
+}
+
+class AsyncWritableStream extends WritableStream {
+
+ constructor (asyncWriteFn, _opts) {
+ const opts = Object.assign({ objectMode: true }, _opts)
+ super(opts)
+ this._asyncWriteFn = asyncWriteFn
+ }
+
+ // write from incomming stream to state
+ _write (chunk, encoding, callback) {
+ promiseToCallback(this._asyncWriteFn(chunk, encoding))(callback)
+ }
+
+}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index a362e3826..d40a351a5 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -46,7 +46,6 @@ const GWEI_BN = new BN('1000000000')
const percentile = require('percentile')
const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
const cleanErrorStack = require('./lib/cleanErrorStack')
-const DiagnosticsReporter = require('./lib/diagnostics-reporter')
const log = require('loglevel')
module.exports = class MetamaskController extends EventEmitter {
@@ -65,12 +64,6 @@ module.exports = class MetamaskController extends EventEmitter {
const initState = opts.initState || {}
this.recordFirstTimeInfo(initState)
- // metamask diagnostics reporter
- this.diagnostics = opts.diagnostics || new DiagnosticsReporter({
- firstTimeInfo: initState.firstTimeInfo,
- version,
- })
-
// platform-specific api
this.platform = opts.platform
@@ -92,7 +85,6 @@ module.exports = class MetamaskController extends EventEmitter {
this.preferencesController = new PreferencesController({
initState: initState.PreferencesController,
initLangCode: opts.initLangCode,
- diagnostics: this.diagnostics,
})
// currency controller
@@ -189,9 +181,6 @@ module.exports = class MetamaskController extends EventEmitter {
version,
firstVersion: initState.firstTimeInfo.version,
})
- this.noticeController.updateNoticesList()
- // to be uncommented when retrieving notices from a remote server.
- // this.noticeController.startPolling()
this.shapeshiftController = new ShapeShiftController({
initState: initState.ShapeShiftController,
@@ -436,28 +425,24 @@ module.exports = class MetamaskController extends EventEmitter {
* @returns {Object} vault
*/
async createNewVaultAndKeychain (password) {
- const release = await this.createVaultMutex.acquire()
- let vault
-
+ const releaseLock = await this.createVaultMutex.acquire()
try {
+ let vault
const accounts = await this.keyringController.getAccounts()
-
if (accounts.length > 0) {
vault = await this.keyringController.fullUpdate()
-
} else {
vault = await this.keyringController.createNewVaultAndKeychain(password)
const accounts = await this.keyringController.getAccounts()
this.preferencesController.setAddresses(accounts)
this.selectFirstIdentity()
}
- release()
+ releaseLock()
+ return vault
} catch (err) {
- release()
+ releaseLock()
throw err
}
-
- return vault
}
/**
@@ -466,7 +451,7 @@ module.exports = class MetamaskController extends EventEmitter {
* @param {} seed
*/
async createNewVaultAndRestore (password, seed) {
- const release = await this.createVaultMutex.acquire()
+ const releaseLock = await this.createVaultMutex.acquire()
try {
// clear known identities
this.preferencesController.setAddresses([])
@@ -476,10 +461,10 @@ module.exports = class MetamaskController extends EventEmitter {
const accounts = await this.keyringController.getAccounts()
this.preferencesController.setAddresses(accounts)
this.selectFirstIdentity()
- release()
+ releaseLock()
return vault
} catch (err) {
- release()
+ releaseLock()
throw err
}
}
diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js
index 14a63eae7..e202043cf 100644
--- a/app/scripts/notice-controller.js
+++ b/app/scripts/notice-controller.js
@@ -2,7 +2,7 @@ const EventEmitter = require('events').EventEmitter
const semver = require('semver')
const extend = require('xtend')
const ObservableStore = require('obs-store')
-const hardCodedNotices = require('../../notices/notices.json')
+const hardCodedNotices = require('../../notices/notices.js')
const uniqBy = require('lodash.uniqby')
module.exports = class NoticeController extends EventEmitter {
@@ -13,11 +13,12 @@ module.exports = class NoticeController extends EventEmitter {
this.firstVersion = opts.firstVersion
this.version = opts.version
const initState = extend({
- noticesList: [],
+ noticesList: this._filterNotices(hardCodedNotices),
}, opts.initState)
this.store = new ObservableStore(initState)
this.memStore = new ObservableStore({})
this.store.subscribe(() => this._updateMemstore())
+ this._updateMemstore()
}
getNoticesList () {
@@ -29,9 +30,9 @@ module.exports = class NoticeController extends EventEmitter {
return notices.filter((notice) => notice.read === false)
}
- getLatestUnreadNotice () {
+ getNextUnreadNotice () {
const unreadNotices = this.getUnreadNotices()
- return unreadNotices[unreadNotices.length - 1]
+ return unreadNotices[0]
}
async setNoticesList (noticesList) {
@@ -47,7 +48,7 @@ module.exports = class NoticeController extends EventEmitter {
notices[index].read = true
notices[index].body = ''
this.setNoticesList(notices)
- const latestNotice = this.getLatestUnreadNotice()
+ const latestNotice = this.getNextUnreadNotice()
cb(null, latestNotice)
} catch (err) {
cb(err)
@@ -64,15 +65,6 @@ module.exports = class NoticeController extends EventEmitter {
return result
}
- startPolling () {
- if (this.noticePoller) {
- clearInterval(this.noticePoller)
- }
- this.noticePoller = setInterval(() => {
- this.noticeController.updateNoticesList()
- }, 300000)
- }
-
_mergeNotices (oldNotices, newNotices) {
return uniqBy(oldNotices.concat(newNotices), 'id')
}
@@ -91,19 +83,15 @@ module.exports = class NoticeController extends EventEmitter {
})
}
- _mapNoticeIds (notices) {
- return notices.map((notice) => notice.id)
- }
-
async _retrieveNoticeData () {
// Placeholder for the API.
- return hardCodedNotices
+ return []
}
_updateMemstore () {
- const lastUnreadNotice = this.getLatestUnreadNotice()
- const noActiveNotices = !lastUnreadNotice
- this.memStore.updateState({ lastUnreadNotice, noActiveNotices })
+ const nextUnreadNotice = this.getNextUnreadNotice()
+ const noActiveNotices = !nextUnreadNotice
+ this.memStore.updateState({ nextUnreadNotice, noActiveNotices })
}
}