aboutsummaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/manifest.json2
-rw-r--r--app/scripts/config.js3
-rw-r--r--app/scripts/inpage.js18
-rw-r--r--app/scripts/metamask-controller.js33
-rw-r--r--app/scripts/notice-controller.js96
5 files changed, 132 insertions, 20 deletions
diff --git a/app/manifest.json b/app/manifest.json
index b9d3735ad..f53c3b8b1 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "2.13.10",
+ "version": "2.14.0",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
diff --git a/app/scripts/config.js b/app/scripts/config.js
index 9a0f2a50b..e09206c5f 100644
--- a/app/scripts/config.js
+++ b/app/scripts/config.js
@@ -1,6 +1,5 @@
const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask'
const TESTNET_RPC_URL = 'https://ropsten.infura.io/metamask'
-const MORDEN_RPC_URL = 'https://morden.infura.io/metamask'
const DEFAULT_RPC_URL = TESTNET_RPC_URL
global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
@@ -11,6 +10,6 @@ module.exports = {
default: DEFAULT_RPC_URL,
mainnet: MAINET_RPC_URL,
testnet: TESTNET_RPC_URL,
- morden: MORDEN_RPC_URL,
+ morden: TESTNET_RPC_URL,
},
}
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index 68c6165c8..42332d92e 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -2,8 +2,8 @@
cleanContextForImports()
require('web3/dist/web3.min.js')
const LocalMessageDuplexStream = require('post-message-stream')
-const PingStream = require('ping-pong-stream/ping')
-const endOfStream = require('end-of-stream')
+// const PingStream = require('ping-pong-stream/ping')
+// const endOfStream = require('end-of-stream')
const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
@@ -40,13 +40,15 @@ reloadStream.once('data', triggerReload)
// setup ping timeout autoreload
// LocalMessageDuplexStream does not self-close, so reload if pingStream fails
-var pingChannel = inpageProvider.multiStream.createStream('pingpong')
-var pingStream = new PingStream({ objectMode: true })
+// var pingChannel = inpageProvider.multiStream.createStream('pingpong')
+// var pingStream = new PingStream({ objectMode: true })
// wait for first successful reponse
-metamaskStream.once('_data', function () {
- pingStream.pipe(pingChannel).pipe(pingStream)
-})
-endOfStream(pingStream, triggerReload)
+
+// disable pingStream until https://github.com/MetaMask/metamask-plugin/issues/746 is resolved more gracefully
+// metamaskStream.once('data', function(){
+// pingStream.pipe(pingChannel).pipe(pingStream)
+// })
+// endOfStream(pingStream, triggerReload)
// set web3 defaultAcount
inpageProvider.publicConfigStore.subscribe(function (state) {
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index ae761c753..4b8fa4323 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -2,6 +2,7 @@ const extend = require('xtend')
const EthStore = require('eth-store')
const MetaMaskProvider = require('web3-provider-engine/zero.js')
const KeyringController = require('./keyring-controller')
+const NoticeController = require('./notice-controller')
const messageManager = require('./lib/message-manager')
const HostStore = require('./lib/remote-store.js').HostStore
const Web3 = require('web3')
@@ -22,6 +23,13 @@ module.exports = class MetamaskController {
configManager: this.configManager,
getNetwork: this.getStateNetwork.bind(this),
})
+ // notices
+ this.noticeController = new NoticeController({
+ configManager: this.configManager,
+ })
+ this.noticeController.updateNoticesList()
+ // to be uncommented when retrieving notices from a remote server.
+ // this.noticeController.startPolling()
this.provider = this.initializeProvider(opts)
this.ethStore = new EthStore(this.provider)
this.keyringController.setStore(this.ethStore)
@@ -43,12 +51,14 @@ module.exports = class MetamaskController {
this.state,
this.ethStore.getState(),
this.configManager.getConfig(),
- this.keyringController.getState()
+ this.keyringController.getState(),
+ this.noticeController.getState()
)
}
getApi () {
const keyringController = this.keyringController
+ const noticeController = this.noticeController
return {
getState: (cb) => { cb(null, this.getState()) },
@@ -85,6 +95,9 @@ module.exports = class MetamaskController {
buyEth: this.buyEth.bind(this),
// shapeshift
createShapeShiftTx: this.createShapeShiftTx.bind(this),
+ // notices
+ checkNotices: noticeController.updateNoticesList.bind(noticeController),
+ markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
}
}
@@ -268,7 +281,7 @@ module.exports = class MetamaskController {
setTOSHash (hash) {
try {
this.configManager.setTOSHash(hash)
- } catch (e) {
+ } catch (err) {
console.error('Error in setting terms of service hash.')
}
}
@@ -280,17 +293,19 @@ module.exports = class MetamaskController {
this.resetDisclaimer()
this.setTOSHash(global.TOS_HASH)
}
- } catch (e) {
+ } catch (err) {
console.error('Error in checking TOS change.')
}
}
+ // disclaimer
+
agreeToDisclaimer (cb) {
try {
this.configManager.setConfirmedDisclaimer(true)
cb()
- } catch (e) {
- cb(e)
+ } catch (err) {
+ cb(err)
}
}
@@ -313,8 +328,8 @@ module.exports = class MetamaskController {
conversionDate: this.configManager.getConversionDate(),
}
cb(data)
- } catch (e) {
- cb(null, e)
+ } catch (err) {
+ cb(null, err)
}
}
@@ -387,8 +402,8 @@ module.exports = class MetamaskController {
try {
this.configManager.setGasMultiplier(gasMultiplier)
cb()
- } catch (e) {
- cb(e)
+ } catch (err) {
+ cb(err)
}
}
diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js
new file mode 100644
index 000000000..438f5c27e
--- /dev/null
+++ b/app/scripts/notice-controller.js
@@ -0,0 +1,96 @@
+const EventEmitter = require('events').EventEmitter
+const hardCodedNotices = require('../../development/notices.json')
+
+module.exports = class NoticeController extends EventEmitter {
+
+ constructor (opts) {
+ super()
+ this.configManager = opts.configManager
+ this.noticePoller = null
+ }
+
+ getState() {
+ var lastUnreadNotice = this.getLatestUnreadNotice()
+
+ return {
+ lastUnreadNotice: lastUnreadNotice,
+ noActiveNotices: !lastUnreadNotice,
+ }
+ }
+
+ getNoticesList() {
+ var data = this.configManager.getData()
+ if ('noticesList' in data) {
+ return data.noticesList
+ } else {
+ return []
+ }
+ }
+
+ setNoticesList(list) {
+ var data = this.configManager.getData()
+ data.noticesList = list
+ this.configManager.setData(data)
+ return Promise.resolve(true)
+ }
+
+ markNoticeRead(notice, cb) {
+ cb = cb || function(err){ if (err) throw err }
+ try {
+ var notices = this.getNoticesList()
+ var id = notice.id
+ notices[id].read = true
+ this.setNoticesList(notices)
+ let latestNotice = this.getLatestUnreadNotice()
+ cb(null, latestNotice)
+ } catch (err) {
+ cb(err)
+ }
+ }
+
+ updateNoticesList() {
+ return this._retrieveNoticeData().then((newNotices) => {
+ var oldNotices = this.getNoticesList()
+ var combinedNotices = this._mergeNotices(oldNotices, newNotices)
+ return Promise.resolve(this.setNoticesList(combinedNotices))
+ })
+ }
+
+ getLatestUnreadNotice() {
+ var notices = this.getNoticesList()
+ var filteredNotices = notices.filter((notice) => {
+ return notice.read === false
+ })
+ return filteredNotices[filteredNotices.length - 1]
+ }
+
+ startPolling () {
+ if (this.noticePoller) {
+ clearInterval(this.noticePoller)
+ }
+ this.noticePoller = setInterval(() => {
+ this.noticeController.updateNoticesList()
+ }, 300000)
+ }
+
+ _mergeNotices(oldNotices, newNotices) {
+ var noticeMap = this._mapNoticeIds(oldNotices)
+ newNotices.forEach((notice) => {
+ if (noticeMap.indexOf(notice.id) === -1) {
+ oldNotices.push(notice)
+ }
+ })
+ return oldNotices
+ }
+
+ _mapNoticeIds(notices) {
+ return notices.map((notice) => notice.id)
+ }
+
+ _retrieveNoticeData() {
+ // Placeholder for the API.
+ return Promise.resolve(hardCodedNotices)
+ }
+
+
+}