diff --git a/.gitignore b/.gitignore
index 476b197db..2ad6b035f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,4 @@ package
.DS_Store
builds/
+notes.txt
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2bf056b31..64200fe6d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,16 @@
## Current Master
+- Show network status in title bar
+- Added seed word recovery to config screen.
+- Clicking network status indicator now reveals a provider menu.
+
+## 2.2.0 2016-06-02
+
- Redesigned init, vault create, vault restore and seed confirmation screens.
- Added pending transactions to transaction list on account screen.
- Clicking a pending transaction takes you back to the transaction approval screen.
+- Update provider-engine to fix intermittent out of gas errors.
## 2.1.0 2016-05-26
diff --git a/app/images/ethereum-network.jpg b/app/images/ethereum-network.jpg
new file mode 100644
index 000000000..61cb000ed
Binary files /dev/null and b/app/images/ethereum-network.jpg differ
diff --git a/app/images/morden-test-network.jpg b/app/images/morden-test-network.jpg
new file mode 100644
index 000000000..458708c78
Binary files /dev/null and b/app/images/morden-test-network.jpg differ
diff --git a/app/images/no-connection.jpg b/app/images/no-connection.jpg
new file mode 100644
index 000000000..a5d21242b
Binary files /dev/null and b/app/images/no-connection.jpg differ
diff --git a/app/images/unknown-private-network.jpg b/app/images/unknown-private-network.jpg
new file mode 100644
index 000000000..b8a5a9bbf
Binary files /dev/null and b/app/images/unknown-private-network.jpg differ
diff --git a/app/manifest.json b/app/manifest.json
index 5b1be504d..ce157bdf3 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "__MSG_appName__",
"short_name": "Metamask",
- "version": "2.1.0",
+ "version": "2.2.0",
"manifest_version": 2,
"description": "__MSG_appDescription__",
"icons": {
diff --git a/app/scripts/background.js b/app/scripts/background.js
index bfd1fc92b..f64209ecc 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -76,13 +76,20 @@ var providerOpts = {
var provider = MetaMaskProvider(providerOpts)
var web3 = new Web3(provider)
idStore.web3 = web3
-idStore.getNetwork(3)
+idStore.getNetwork()
// log new blocks
provider.on('block', function(block){
console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex'))
+
+ // Check network when restoring connectivity:
+ if (idStore._currentState.network === 'loading') {
+ idStore.getNetwork()
+ }
})
+provider.on('error', idStore.getNetwork.bind(idStore))
+
var ethStore = new EthStore(provider)
idStore.setStore(ethStore)
@@ -145,7 +152,7 @@ function setupPublicConfig(stream){
}
function setupProviderConnection(stream, originDomain){
-
+
stream.on('data', function onRpcRequest(payload){
// Append origin to rpc payload
payload.origin = originDomain
@@ -195,6 +202,8 @@ function setupControllerConnection(stream){
exportAccount: idStore.exportAccount.bind(idStore),
revealAccount: idStore.revealAccount.bind(idStore),
saveAccountLabel: idStore.saveAccountLabel.bind(idStore),
+ tryPassword: idStore.tryPassword.bind(idStore),
+ recoverSeed: idStore.recoverSeed.bind(idStore),
})
stream.pipe(dnode).pipe(stream)
dnode.on('remote', function(remote){
@@ -246,7 +255,7 @@ function newUnsignedTransaction(txParams, cb){
})
var txId = idStore.addUnconfirmedTransaction(txParams, cb)
} else {
- addUnconfirmedTx(txParams, cb)
+ addUnconfirmedTx(txParams, cb)
}
}
@@ -258,7 +267,7 @@ function newUnsignedMessage(msgParams, cb){
})
var msgId = idStore.addUnconfirmedMessage(msgParams, cb)
} else {
- addUnconfirmedMsg(msgParams, cb)
+ addUnconfirmedMsg(msgParams, cb)
}
}
@@ -290,13 +299,13 @@ function addUnconfirmedMsg(msgParams, cb){
function setRpcTarget(rpcTarget){
configManager.setRpcTarget(rpcTarget)
chrome.runtime.reload()
- idStore.getNetwork(3) // 3 retry attempts
+ idStore.getNetwork()
}
function setProviderType(type) {
configManager.setProviderType(type)
chrome.runtime.reload()
- idStore.getNetwork(3)
+ idStore.getNetwork()
}
function useEtherscanProvider() {
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index 4ce4fd6f2..33d842d54 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -59,6 +59,13 @@ IdentityStore.prototype.createNewVault = function(password, entropy, cb){
})
}
+IdentityStore.prototype.recoverSeed = function(cb){
+ configManager.setShowSeedWords(true)
+ if (!this._idmgmt) return cb(new Error('Unauthenticated. Please sign in.'))
+ var seedWords = this._idmgmt.getSeed()
+ cb(null, seedWords)
+}
+
IdentityStore.prototype.recoverFromSeed = function(password, seed, cb){
this._createIdmgmt(password, seed, null, (err) => {
if (err) return cb(err)
@@ -130,16 +137,22 @@ IdentityStore.prototype.revealAccount = function(cb) {
cb(null)
}
-IdentityStore.prototype.getNetwork = function(tries) {
- if (tries === 0) {
- this._currentState.network = 'error'
- return
+IdentityStore.prototype.getNetwork = function(err) {
+
+ if (err) {
+ this._currentState.network = 'loading'
+ this._didUpdate()
}
+
this.web3.version.getNetwork((err, network) => {
if (err) {
- return this.getNetwork(tries - 1, cb)
+ this._currentState.network = 'loading'
+ return this._didUpdate()
}
+
+ console.log('web3.getNetwork returned ' + network)
this._currentState.network = network
+ this._didUpdate()
})
}
@@ -150,7 +163,7 @@ IdentityStore.prototype.setLocked = function(cb){
}
IdentityStore.prototype.submitPassword = function(password, cb){
- this._tryPassword(password, (err) => {
+ this.tryPassword(password, (err) => {
if (err) return cb(err)
// load identities before returning...
this._loadIdentities()
@@ -366,7 +379,7 @@ IdentityStore.prototype._mayBeFauceting = function(i) {
// keyStore managment - unlocking + deserialization
//
-IdentityStore.prototype._tryPassword = function(password, cb){
+IdentityStore.prototype.tryPassword = function(password, cb){
this._createIdmgmt(password, null, null, cb)
}
diff --git a/app/scripts/lib/notifications.js b/app/scripts/lib/notifications.js
index d011d778b..90edaea12 100644
--- a/app/scripts/lib/notifications.js
+++ b/app/scripts/lib/notifications.js
@@ -8,24 +8,35 @@ module.exports = {
createMsgNotification: createMsgNotification,
}
-// notification button press
-chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex){
- var handlers = notificationHandlers[notificationId]
- if (buttonIndex === 0) {
- handlers.confirm()
- } else {
- handlers.cancel()
- }
- chrome.notifications.clear(notificationId)
-})
+setupListeners()
-// notification teardown
-chrome.notifications.onClosed.addListener(function(notificationId){
- delete notificationHandlers[notificationId]
-})
+function setupListeners(){
+
+ // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
+ if (!chrome.notifications) return console.error('Chrome notifications API missing...')
+
+ // notification button press
+ chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex){
+ var handlers = notificationHandlers[notificationId]
+ if (buttonIndex === 0) {
+ handlers.confirm()
+ } else {
+ handlers.cancel()
+ }
+ chrome.notifications.clear(notificationId)
+ })
+
+ // notification teardown
+ chrome.notifications.onClosed.addListener(function(notificationId){
+ delete notificationHandlers[notificationId]
+ })
+
+}
// creation helper
function createUnlockRequestNotification(opts){
+ // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
+ if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = 'An Ethereum app has requested a signature. Please unlock your account.'
var id = createId()
@@ -39,6 +50,8 @@ function createUnlockRequestNotification(opts){
}
function createTxNotification(opts){
+ // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
+ if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = [
'Submitted by '+opts.txParams.origin,
'to: '+uiUtils.addressSummary(opts.txParams.to),
@@ -67,6 +80,8 @@ function createTxNotification(opts){
}
function createMsgNotification(opts){
+ // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
+ if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = [
'Submitted by '+opts.msgParams.origin,
'to be signed by: '+uiUtils.addressSummary(opts.msgParams.from),
diff --git a/package.json b/package.json
index e9faea36c..af032a79a 100644
--- a/package.json
+++ b/package.json
@@ -62,7 +62,7 @@
"through2": "^2.0.1",
"vreme": "^3.0.2",
"web3": "ethereum/web3.js#0.16.0",
- "web3-provider-engine": "^7.7.0",
+ "web3-provider-engine": "^7.8.1",
"web3-stream-provider": "^2.0.1",
"xtend": "^4.0.1"
},
diff --git a/svg-notifications.md b/svg-notifications.md
index fd3b63f7a..577e7d07c 100644
--- a/svg-notifications.md
+++ b/svg-notifications.md
@@ -2,19 +2,9 @@ Chrome notifications allow you to show an SVG image via a data-uri
Taking advantage of this might allow us to show nicely formatted notifications
-Heres some utilities for preparing the data uri:
- http://dopiaza.org/tools/datauri/index.php
- provide text
- no base64
- specify mime type: image/svg+xml
- result should look like:
- data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%0D%0A%20%20width%3D%271000px%27%20height%3D%27500px%27%20viewBox%3D%270%200%20200%20100%27%3E%0D%0A%20%20%3Crect%20x%3D%270%27%20y%3D%270%27%20width%3D%27100%25%27%20height%3D%27100%25%27%20fill%3D%27white%27%20%2F%3E%0D%0A%20%20%3Ctext%20x%3D%270%27%20y%3D%2720%27%20font-family%3D%27monospace%27%20font-size%3D%276%27%20fill%3D%27black%27%3E%0D%0A%20%20%20%20%3Ctspan%20x%3D%270%27%20dy%3D%271.2em%27%3EDomain%3A%20https%3A%2F%2Fboardroom.to%3C%2Ftspan%3E%0D%0A%20%20%20%20%3Ctspan%20x%3D%270%27%20dy%3D%271.2em%27%3EFrom%3A%20%200xabcdef%3C%2Ftspan%3E%0D%0A%20%20%20%20%3Ctspan%20x%3D%270%27%20dy%3D%271.2em%27%3ETo%3A%20%20%20%200xfedcba%3C%2Ftspan%3E%0D%0A%20%20%20%20%3Ctspan%20x%3D%270%27%20dy%3D%271.2em%27%3EValue%3A%201.025%20Ether%3C%2Ftspan%3E%0D%0A%20%20%20%20%3Ctspan%20x%3D%270%27%20dy%3D%271.2em%27%3EGas%3A%200.025%20Ether%3C%2Ftspan%3E%0D%0A%20%20%3C%2Ftext%3E%0D%0A%3C%2Fsvg%3E
-
build a template using pure svg:
-generate uri
-'data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svgSrc)
-
+```svg
+```
+
+generate uri
+`'data:image/svg+xml;charset=utf-8,'+encodeURIComponent(svgSrc)`
or svg-embedded html:
+```svg