Fix conflict

feature/default_network_editable
Frankie 9 years ago
commit cf663f1104
  1. 151
      .eslintrc
  2. 1
      .nvmrc
  3. 4
      README.md
  4. 87
      app/scripts/background.js
  5. 1499
      app/scripts/chromereload.js
  6. 6
      app/scripts/contentscript.js
  7. 11
      app/scripts/inpage.js
  8. 4
      app/scripts/lib/auto-faucet.js
  9. 13
      app/scripts/lib/auto-reload.js
  10. 97
      app/scripts/lib/config-manager.js
  11. 10
      app/scripts/lib/ensnare.js
  12. 41
      app/scripts/lib/id-management.js
  13. 99
      app/scripts/lib/idStore.js
  14. 32
      app/scripts/lib/inpage-provider.js
  15. 19
      app/scripts/lib/local-message-stream.js
  16. 20
      app/scripts/lib/message-manager.js
  17. 39
      app/scripts/lib/notifications.js
  18. 13
      app/scripts/lib/obj-multiplex.js
  19. 15
      app/scripts/lib/port-stream.js
  20. 34
      app/scripts/lib/remote-store.js
  21. 15
      app/scripts/lib/stream-utils.js
  22. 4
      app/scripts/migrations/002.js
  23. 4
      app/scripts/migrations/003.js
  24. 8
      app/scripts/migrations/004.js
  25. 19
      app/scripts/popup.js
  26. 3
      circle.yml
  27. 22
      gulpfile.js
  28. 3
      package.json
  29. 9
      test/unit/linting_test.js
  30. 26
      ui/app/account-detail.js
  31. 14
      ui/app/accounts/account-panel.js
  32. 27
      ui/app/accounts/index.js
  33. 137
      ui/app/actions.js
  34. 59
      ui/app/app.js
  35. 21
      ui/app/components/account-export.js
  36. 20
      ui/app/components/account-panel.js
  37. 8
      ui/app/components/drop-menu-item.js
  38. 21
      ui/app/components/editable-label.js
  39. 5
      ui/app/components/eth-balance.js
  40. 6
      ui/app/components/identicon.js
  41. 15
      ui/app/components/mascot.js
  42. 29
      ui/app/components/network.js
  43. 9
      ui/app/components/panel.js
  44. 10
      ui/app/components/pending-msg.js
  45. 8
      ui/app/components/pending-tx.js
  46. 9
      ui/app/components/template.js
  47. 13
      ui/app/components/transaction-list-item-icon.js
  48. 28
      ui/app/components/transaction-list-item.js
  49. 17
      ui/app/components/transaction-list.js
  50. 23
      ui/app/conf-tx.js
  51. 47
      ui/app/config.js
  52. 11
      ui/app/first-time/create-vault-complete.js
  53. 17
      ui/app/first-time/create-vault.js
  54. 13
      ui/app/first-time/disclaimer.js
  55. 19
      ui/app/first-time/init-menu.js
  56. 16
      ui/app/first-time/restore-vault.js
  57. 60
      ui/app/info.js
  58. 9
      ui/app/loading.js
  59. 23
      ui/app/recover-seed/confirmation.js
  60. 7
      ui/app/reducers.js
  61. 18
      ui/app/reducers/app.js
  62. 5
      ui/app/reducers/identities.js
  63. 19
      ui/app/reducers/metamask.js
  64. 8
      ui/app/root.js
  65. 27
      ui/app/send.js
  66. 23
      ui/app/settings.js
  67. 3
      ui/app/store.js
  68. 11
      ui/app/template.js
  69. 21
      ui/app/unlock.js
  70. 87
      ui/app/util.js
  71. 19
      ui/css.js
  72. 30
      ui/example.js
  73. 19
      ui/index.js
  74. 2
      ui/lib/explorer-link.js
  75. 23
      ui/lib/icon-factory.js
  76. 2
      ui/lib/tx-helper.js

@ -0,0 +1,151 @@
{
"parserOptions": {
"ecmaVersion": 6,
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"impliedStrict": true,
"modules": true,
"blockBindings": true,
"arrowFunctions": true,
"objectLiteralShorthandMethods": true,
"objectLiteralShorthandProperties": true,
"templateStrings": true
},
},
"env": {
"es6": true,
"node": true,
"browser": true
},
"plugins": [
],
"globals": {
"chrome": true,
"document": false,
"navigator": false,
"web3": true,
"window": false
},
"rules": {
"accessor-pairs": 2,
"arrow-spacing": [2, { "before": true, "after": true }],
"block-spacing": [2, "always"],
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
"camelcase": [2, { "properties": "never" }],
"comma-dangle": [2, "always-multiline"],
"comma-spacing": [2, { "before": false, "after": true }],
"comma-style": [2, "last"],
"constructor-super": 2,
"curly": [2, "multi-line"],
"dot-location": [2, "property"],
"eol-last": 2,
"eqeqeq": [2, "allow-null"],
"generator-star-spacing": [2, { "before": true, "after": true }],
"handle-callback-err": [2, "^(err|error)$" ],
"indent": [2, 2, { "SwitchCase": 1 }],
"jsx-quotes": [2, "prefer-single"],
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
"keyword-spacing": [2, { "before": true, "after": true }],
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
"new-parens": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-class-assign": 2,
"no-cond-assign": 2,
"no-const-assign": 2,
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-duplicate-imports": 2,
"no-empty-character-class": 2,
"no-empty-pattern": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": [2, "functions"],
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-implied-eval": 2,
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": [2, { "allowLoop": false, "allowSwitch": false }],
"no-lone-blocks": 2,
"no-mixed-spaces-and-tabs": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [2, { "max": 1 }],
"no-native-reassign": 2,
"no-negated-in-lhs": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-symbol": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-path-concat": 2,
"no-proto": 2,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-return-assign": [2, "except-parens"],
"no-self-assign": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-sparse-arrays": 2,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": 2,
"no-undef": 2,
"no-undef-init": 2,
"no-unexpected-multiline": 2,
"no-unmodified-loop-condition": 2,
"no-unneeded-ternary": [2, { "defaultAssignment": false }],
"no-unreachable": 2,
"no-unsafe-finally": 2,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"no-useless-call": 2,
"no-useless-computed-key": 2,
"no-useless-constructor": 2,
"no-useless-escape": 2,
"no-whitespace-before-property": 2,
"no-with": 2,
"one-var": [2, { "initialized": "never" }],
"operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }],
"padded-blocks": [2, "never"],
"quotes": [2, "single", "avoid-escape"],
"semi": [2, "never"],
"semi-spacing": [2, { "before": false, "after": true }],
"space-before-blocks": [1, "always"],
"space-before-function-paren": [1, "always"],
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }],
"strict": 0,
"template-curly-spacing": [2, "never"],
"use-isnan": 2,
"valid-typeof": 2,
"wrap-iife": [2, "any"],
"yield-star-spacing": [2, "both"],
"yoda": [2, "never"],
"prefer-const": 1
}
}

@ -0,0 +1 @@
6.0

@ -1,4 +1,4 @@
# Metamask Plugin [![Build Status](https://travis-ci.com/MetaMask/metamask-plugin.svg?token=3txzDGFpqQqvRCdgwTJp&branch=master)](https://travis-ci.com/MetaMask/metamask-plugin) # Metamask Plugin [![Build Status](https://circleci.com/gh/MetaMask/metamask-plugin.svg?style=shield&circle-token=a1ddcf3cd38e29267f254c9c59d556d513e3a1fd)](https://circleci.com/gh/MetaMask/metamask-plugin)
## Architecture ## Architecture
@ -54,6 +54,8 @@ Then just run `npm test`.
You can also test with a continuously watching process, via `npm run watch`. You can also test with a continuously watching process, via `npm run watch`.
You can run the linter by itself with `gulp lint`.
### Deploying the UI ### Deploying the UI
You must be authorized already on the Metamask plugin. You must be authorized already on the Metamask plugin.

@ -1,11 +1,9 @@
const urlUtil = require('url') const urlUtil = require('url')
const Dnode = require('dnode') const Dnode = require('dnode')
const eos = require('end-of-stream') const eos = require('end-of-stream')
const combineStreams = require('pumpify')
const extend = require('xtend') const extend = require('xtend')
const EthStore = require('eth-store') const EthStore = require('eth-store')
const MetaMaskProvider = require('web3-provider-engine/zero.js') const MetaMaskProvider = require('web3-provider-engine/zero.js')
const ObjectMultiplex = require('./lib/obj-multiplex')
const PortStream = require('./lib/port-stream.js') const PortStream = require('./lib/port-stream.js')
const IdentityStore = require('./lib/idStore') const IdentityStore = require('./lib/idStore')
const createUnlockRequestNotification = require('./lib/notifications.js').createUnlockRequestNotification const createUnlockRequestNotification = require('./lib/notifications.js').createUnlockRequestNotification
@ -22,7 +20,7 @@ const Web3 = require('web3')
// //
chrome.runtime.onConnect.addListener(connectRemote) chrome.runtime.onConnect.addListener(connectRemote)
function connectRemote(remotePort){ function connectRemote (remotePort) {
var isMetaMaskInternalProcess = (remotePort.name === 'popup') var isMetaMaskInternalProcess = (remotePort.name === 'popup')
var portStream = new PortStream(remotePort) var portStream = new PortStream(remotePort)
if (isMetaMaskInternalProcess) { if (isMetaMaskInternalProcess) {
@ -35,7 +33,7 @@ function connectRemote(remotePort){
} }
} }
function setupUntrustedCommunication(connectionStream, originDomain){ function setupUntrustedCommunication (connectionStream, originDomain) {
// setup multiplexing // setup multiplexing
var mx = setupMultiplex(connectionStream) var mx = setupMultiplex(connectionStream)
// connect features // connect features
@ -43,7 +41,7 @@ function setupUntrustedCommunication(connectionStream, originDomain){
setupPublicConfig(mx.createStream('publicConfig')) setupPublicConfig(mx.createStream('publicConfig'))
} }
function setupTrustedCommunication(connectionStream, originDomain){ function setupTrustedCommunication (connectionStream, originDomain) {
// setup multiplexing // setup multiplexing
var mx = setupMultiplex(connectionStream) var mx = setupMultiplex(connectionStream)
// connect features // connect features
@ -55,13 +53,12 @@ function setupTrustedCommunication(connectionStream, originDomain){
// state and network // state and network
// //
var providerConfig = configManager.getProvider()
var idStore = new IdentityStore() var idStore = new IdentityStore()
var providerOpts = { var providerOpts = {
rpcUrl: configManager.getCurrentRpcAddress(), rpcUrl: configManager.getCurrentRpcAddress(),
// account mgmt // account mgmt
getAccounts: function(cb){ getAccounts: function (cb) {
var selectedAddress = idStore.getSelectedAddress() var selectedAddress = idStore.getSelectedAddress()
var result = selectedAddress ? [selectedAddress] : [] var result = selectedAddress ? [selectedAddress] : []
cb(null, result) cb(null, result)
@ -79,8 +76,8 @@ idStore.web3 = web3
idStore.getNetwork() idStore.getNetwork()
// log new blocks // log new blocks
provider.on('block', function(block){ provider.on('block', function (block) {
console.log('BLOCK CHANGED:', '#'+block.number.toString('hex'), '0x'+block.hash.toString('hex')) console.log('BLOCK CHANGED:', '#' + block.number.toString('hex'), '0x' + block.hash.toString('hex'))
// Check network when restoring connectivity: // Check network when restoring connectivity:
if (idStore._currentState.network === 'loading') { if (idStore._currentState.network === 'loading') {
@ -93,7 +90,7 @@ provider.on('error', idStore.getNetwork.bind(idStore))
var ethStore = new EthStore(provider) var ethStore = new EthStore(provider)
idStore.setStore(ethStore) idStore.setStore(ethStore)
function getState(){ function getState () {
var state = extend( var state = extend(
ethStore.getState(), ethStore.getState(),
idStore.getState(), idStore.getState(),
@ -115,45 +112,46 @@ var initPublicState = extend(
var publicConfigStore = new HostStore(initPublicState) var publicConfigStore = new HostStore(initPublicState)
// subscribe to changes // subscribe to changes
configManager.subscribe(function(state){ configManager.subscribe(function (state) {
storeSetFromObj(publicConfigStore, configToPublic(state)) storeSetFromObj(publicConfigStore, configToPublic(state))
}) })
idStore.on('update', function(state){ idStore.on('update', function (state) {
storeSetFromObj(publicConfigStore, idStoreToPublic(state)) storeSetFromObj(publicConfigStore, idStoreToPublic(state))
}) })
// idStore substate // idStore substate
function idStoreToPublic(state){ function idStoreToPublic (state) {
return { return {
selectedAddress: state.selectedAddress, selectedAddress: state.selectedAddress,
} }
} }
// config substate // config substate
function configToPublic(state){ function configToPublic (state) {
return { return {
provider: state.provider, provider: state.provider,
} }
} }
// dump obj into store // dump obj into store
function storeSetFromObj(store, obj){ function storeSetFromObj (store, obj) {
Object.keys(obj).forEach(function(key){ Object.keys(obj).forEach(function (key) {
store.set(key, obj[key]) store.set(key, obj[key])
}) })
} }
// //
// remote features // remote features
// //
function setupPublicConfig(stream){ function setupPublicConfig (stream) {
var storeStream = publicConfigStore.createStream() var storeStream = publicConfigStore.createStream()
stream.pipe(storeStream).pipe(stream) stream.pipe(storeStream).pipe(stream)
} }
function setupProviderConnection(stream, originDomain){ function setupProviderConnection (stream, originDomain) {
// decorate all payloads with origin domain
stream.on('data', function onRpcRequest(payload){ stream.on('data', function onRpcRequest (request) {
var payloads = Array.isArray(request) ? request : [request]
payloads.forEach(function (payload) {
// Append origin to rpc payload // Append origin to rpc payload
payload.origin = originDomain payload.origin = originDomain
// Append origin to signature request // Append origin to signature request
@ -162,9 +160,13 @@ function setupProviderConnection(stream, originDomain){
} else if (payload.method === 'eth_sign') { } else if (payload.method === 'eth_sign') {
payload.params.push({ origin: originDomain }) payload.params.push({ origin: originDomain })
} }
})
// handle rpc request // handle rpc request
provider.sendAsync(payload, function onPayloadHandled(err, response){ provider.sendAsync(request, function onPayloadHandled (err, response) {
logger(null, payload, response) if (err) {
return logger(err)
}
logger(null, request, response)
try { try {
stream.write(response) stream.write(response)
} catch (err) { } catch (err) {
@ -173,18 +175,18 @@ function setupProviderConnection(stream, originDomain){
}) })
}) })
function logger(err, request, response){ function logger (err, request, response) {
if (err) return console.error(err.stack) if (err) return console.error(err.stack)
if (!request.isMetamaskInternal) { if (!request.isMetamaskInternal) {
console.log(`RPC (${originDomain}):`, request, '->', response) console.log(`RPC (${originDomain}):`, request, '->', response)
if (response.error) console.error('Error in RPC response:\n'+response.error.message) if (response.error) console.error('Error in RPC response:\n' + response.error.message)
} }
} }
} }
function setupControllerConnection(stream){ function setupControllerConnection (stream) {
var dnode = Dnode({ var dnode = Dnode({
getState: function(cb){ cb(null, getState()) }, getState: function (cb) { cb(null, getState()) },
setRpcTarget: setRpcTarget, setRpcTarget: setRpcTarget,
setProviderType: setProviderType, setProviderType: setProviderType,
useEtherscanProvider: useEtherscanProvider, useEtherscanProvider: useEtherscanProvider,
@ -207,20 +209,18 @@ function setupControllerConnection(stream){
recoverSeed: idStore.recoverSeed.bind(idStore), recoverSeed: idStore.recoverSeed.bind(idStore),
}) })
stream.pipe(dnode).pipe(stream) stream.pipe(dnode).pipe(stream)
dnode.on('remote', function(remote){ dnode.on('remote', function (remote) {
// push updates to popup // push updates to popup
ethStore.on('update', sendUpdate) ethStore.on('update', sendUpdate)
idStore.on('update', sendUpdate) idStore.on('update', sendUpdate)
// teardown on disconnect // teardown on disconnect
eos(stream, function unsubscribe(){ eos(stream, function unsubscribe () {
ethStore.removeListener('update', sendUpdate) ethStore.removeListener('update', sendUpdate)
}) })
function sendUpdate(){ function sendUpdate () {
var state = getState() var state = getState()
remote.sendUpdate(state) remote.sendUpdate(state)
} }
}) })
} }
@ -230,7 +230,7 @@ function setupControllerConnection(stream){
idStore.on('update', updateBadge) idStore.on('update', updateBadge)
function updateBadge(state){ function updateBadge (state) {
var label = '' var label = ''
var unconfTxs = configManager.unconfirmedTxs() var unconfTxs = configManager.unconfirmedTxs()
var unconfTxLen = Object.keys(unconfTxs).length var unconfTxLen = Object.keys(unconfTxs).length
@ -248,7 +248,7 @@ function updateBadge(state){
// Add unconfirmed Tx + Msg // Add unconfirmed Tx + Msg
// //
function newUnsignedTransaction(txParams, onTxDoneCb){ function newUnsignedTransaction (txParams, onTxDoneCb) {
var state = idStore.getState() var state = idStore.getState()
if (!state.isUnlocked) { if (!state.isUnlocked) {
createUnlockRequestNotification({ createUnlockRequestNotification({
@ -260,20 +260,19 @@ function newUnsignedTransaction(txParams, onTxDoneCb){
} }
} }
function newUnsignedMessage(msgParams, cb){ function newUnsignedMessage (msgParams, cb) {
var state = idStore.getState() var state = idStore.getState()
if (!state.isUnlocked) { if (!state.isUnlocked) {
createUnlockRequestNotification({ createUnlockRequestNotification({
title: 'Account Unlock Request', title: 'Account Unlock Request',
}) })
var msgId = idStore.addUnconfirmedMessage(msgParams, cb)
} else { } else {
addUnconfirmedMsg(msgParams, cb) addUnconfirmedMsg(msgParams, cb)
} }
} }
function addUnconfirmedTx(txParams, onTxDoneCb){ function addUnconfirmedTx (txParams, onTxDoneCb) {
idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, function(err, txData){ idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, function (err, txData) {
if (err) return onTxDoneCb(err) if (err) return onTxDoneCb(err)
createTxNotification({ createTxNotification({
title: 'New Unsigned Transaction', title: 'New Unsigned Transaction',
@ -284,7 +283,7 @@ function addUnconfirmedTx(txParams, onTxDoneCb){
}) })
} }
function addUnconfirmedMsg(msgParams, cb){ function addUnconfirmedMsg (msgParams, cb) {
var msgId = idStore.addUnconfirmedMessage(msgParams, cb) var msgId = idStore.addUnconfirmedMessage(msgParams, cb)
createMsgNotification({ createMsgNotification({
title: 'New Unsigned Message', title: 'New Unsigned Message',
@ -298,7 +297,7 @@ function addUnconfirmedMsg(msgParams, cb){
// config // config
// //
function agreeToDisclaimer(cb) { function agreeToDisclaimer (cb) {
try { try {
configManager.setConfirmed(true) configManager.setConfirmed(true)
cb() cb()
@ -308,23 +307,23 @@ function agreeToDisclaimer(cb) {
} }
// called from popup // called from popup
function setRpcTarget(rpcTarget){ function setRpcTarget (rpcTarget) {
configManager.setRpcTarget(rpcTarget) configManager.setRpcTarget(rpcTarget)
chrome.runtime.reload() chrome.runtime.reload()
idStore.getNetwork() idStore.getNetwork()
} }
function setProviderType(type) { function setProviderType (type) {
configManager.setProviderType(type) configManager.setProviderType(type)
chrome.runtime.reload() chrome.runtime.reload()
idStore.getNetwork() idStore.getNetwork()
} }
function useEtherscanProvider() { function useEtherscanProvider () {
configManager.useEtherscanProvider() configManager.useEtherscanProvider()
chrome.runtime.reload() chrome.runtime.reload()
} }
// util // util
function noop(){} function noop () {}

File diff suppressed because it is too large Load Diff

@ -2,12 +2,10 @@ const LocalMessageDuplexStream = require('./lib/local-message-stream.js')
const PortStream = require('./lib/port-stream.js') const PortStream = require('./lib/port-stream.js')
const ObjectMultiplex = require('./lib/obj-multiplex') const ObjectMultiplex = require('./lib/obj-multiplex')
// inject in-page script // inject in-page script
var scriptTag = document.createElement('script') var scriptTag = document.createElement('script')
scriptTag.src = chrome.extension.getURL('scripts/inpage.js') scriptTag.src = chrome.extension.getURL('scripts/inpage.js')
scriptTag.onload = function() { this.parentNode.removeChild(this) } scriptTag.onload = function () { this.parentNode.removeChild(this) }
var container = document.head || document.documentElement var container = document.head || document.documentElement
// append as first child // append as first child
container.insertBefore(scriptTag, container.children[0]) container.insertBefore(scriptTag, container.children[0])
@ -33,6 +31,6 @@ var reloadStream = mx.createStream('reload')
reloadStream.on('error', console.error.bind(console)) reloadStream.on('error', console.error.bind(console))
// if we lose connection with the plugin, trigger tab refresh // if we lose connection with the plugin, trigger tab refresh
pluginStream.on('close', function(){ pluginStream.on('close', function () {
reloadStream.write({ method: 'reset' }) reloadStream.write({ method: 'reset' })
}) })

@ -8,7 +8,6 @@ restoreContextAfterImports()
// remove from window // remove from window
delete window.Web3 delete window.Web3
// //
// setup plugin communication // setup plugin communication
// //
@ -27,7 +26,7 @@ var inpageProvider = new MetamaskInpageProvider(metamaskStream)
// //
var web3 = new Web3(inpageProvider) var web3 = new Web3(inpageProvider)
web3.setProvider = function(){ web3.setProvider = function () {
console.log('MetaMask - overrode web3.setProvider') console.log('MetaMask - overrode web3.setProvider')
} }
console.log('MetaMask - injected web3') console.log('MetaMask - injected web3')
@ -40,7 +39,7 @@ var reloadStream = inpageProvider.multiStream.createStream('reload')
setupDappAutoReload(web3, reloadStream) setupDappAutoReload(web3, reloadStream)
// set web3 defaultAcount // set web3 defaultAcount
inpageProvider.publicConfigStore.subscribe(function(state){ inpageProvider.publicConfigStore.subscribe(function (state) {
web3.eth.defaultAccount = state.selectedAddress web3.eth.defaultAccount = state.selectedAddress
}) })
@ -51,13 +50,13 @@ inpageProvider.publicConfigStore.subscribe(function(state){
// need to make sure we aren't affected by overlapping namespaces // need to make sure we aren't affected by overlapping namespaces
// and that we dont affect the app with our namespace // and that we dont affect the app with our namespace
// mostly a fix for web3's BigNumber if AMD's "define" is defined... // mostly a fix for web3's BigNumber if AMD's "define" is defined...
var __define = undefined var __define
function cleanContextForImports(){ function cleanContextForImports () {
__define = global.define __define = global.define
delete global.define delete global.define
} }
function restoreContextAfterImports(){ function restoreContextAfterImports () {
global.define = __define global.define = __define
} }

@ -1,11 +1,9 @@
var uri = 'https://faucet.metamask.io/' var uri = 'https://faucet.metamask.io/'
module.exports = function(address) { module.exports = function (address) {
var http = new XMLHttpRequest() var http = new XMLHttpRequest()
var data = address var data = address
http.open('POST', uri, true) http.open('POST', uri, true)
http.setRequestHeader('Content-type', 'application/rawdata') http.setRequestHeader('Content-type', 'application/rawdata')
http.send(data) http.send(data)
} }

@ -3,13 +3,11 @@ const ensnare = require('./ensnare.js')
module.exports = setupDappAutoReload module.exports = setupDappAutoReload
function setupDappAutoReload (web3, controlStream) {
function setupDappAutoReload(web3, controlStream){
// export web3 as a global, checking for usage // export web3 as a global, checking for usage
var pageIsUsingWeb3 = false var pageIsUsingWeb3 = false
var resetWasRequested = false var resetWasRequested = false
global.web3 = ensnare(web3, once(function(){ global.web3 = ensnare(web3, once(function () {
// if web3 usage happened after a reset request, trigger reset late // if web3 usage happened after a reset request, trigger reset late
if (resetWasRequested) return triggerReset() if (resetWasRequested) return triggerReset()
// mark web3 as used // mark web3 as used
@ -19,7 +17,7 @@ function setupDappAutoReload(web3, controlStream){
})) }))
// listen for reset requests from metamask // listen for reset requests from metamask
controlStream.once('data', function(){ controlStream.once('data', function () {
resetWasRequested = true resetWasRequested = true
// ignore if web3 was not used // ignore if web3 was not used
if (!pageIsUsingWeb3) return if (!pageIsUsingWeb3) return
@ -28,10 +26,9 @@ function setupDappAutoReload(web3, controlStream){
}) })
// reload the page // reload the page
function triggerReset(){ function triggerReset () {
setTimeout(function(){ setTimeout(function () {
global.location.reload() global.location.reload()
}, 500) }, 500)
} }
} }

@ -7,7 +7,6 @@ const STORAGE_KEY = 'metamask-config'
const TESTNET_RPC = MetamaskConfig.network.testnet const TESTNET_RPC = MetamaskConfig.network.testnet
const MAINNET_RPC = MetamaskConfig.network.mainnet const MAINNET_RPC = MetamaskConfig.network.mainnet
/* The config-manager is a convenience object /* The config-manager is a convenience object
* wrapping a pojo-migrator. * wrapping a pojo-migrator.
* *
@ -16,7 +15,7 @@ const MAINNET_RPC = MetamaskConfig.network.mainnet
* particular portions of the state. * particular portions of the state.
*/ */
module.exports = ConfigManager module.exports = ConfigManager
function ConfigManager() { function ConfigManager () {
// ConfigManager is observable and will emit updates // ConfigManager is observable and will emit updates
this._subs = [] this._subs = []
@ -41,20 +40,20 @@ function ConfigManager() {
loadData: loadData, loadData: loadData,
// How to persist migrated config. // How to persist migrated config.
setData: function(data) { setData: function (data) {
window.localStorage[STORAGE_KEY] = JSON.stringify(data) window.localStorage[STORAGE_KEY] = JSON.stringify(data)
}, },
}) })
} }
ConfigManager.prototype.setConfig = function(config) { ConfigManager.prototype.setConfig = function (config) {
var data = this.migrator.getData() var data = this.migrator.getData()
data.config = config data.config = config
this.setData(data) this.setData(data)
this._emitUpdates(config) this._emitUpdates(config)
} }
ConfigManager.prototype.getConfig = function() { ConfigManager.prototype.getConfig = function () {
var data = this.migrator.getData() var data = this.migrator.getData()
if ('config' in data) { if ('config' in data) {
return data.config return data.config
@ -62,12 +61,12 @@ ConfigManager.prototype.getConfig = function() {
return { return {
provider: { provider: {
type: 'testnet', type: 'testnet',
} },
} }
} }
} }
ConfigManager.prototype.setRpcTarget = function(rpcUrl) { ConfigManager.prototype.setRpcTarget = function (rpcUrl) {
var config = this.getConfig() var config = this.getConfig()
config.provider = { config.provider = {
type: 'rpc', type: 'rpc',
@ -76,7 +75,7 @@ ConfigManager.prototype.setRpcTarget = function(rpcUrl) {
this.setConfig(config) this.setConfig(config)
} }
ConfigManager.prototype.setProviderType = function(type) { ConfigManager.prototype.setProviderType = function (type) {
var config = this.getConfig() var config = this.getConfig()
config.provider = { config.provider = {
type: type, type: type,
@ -84,7 +83,7 @@ ConfigManager.prototype.setProviderType = function(type) {
this.setConfig(config) this.setConfig(config)
} }
ConfigManager.prototype.useEtherscanProvider = function() { ConfigManager.prototype.useEtherscanProvider = function () {
var config = this.getConfig() var config = this.getConfig()
config.provider = { config.provider = {
type: 'etherscan', type: 'etherscan',
@ -92,53 +91,53 @@ ConfigManager.prototype.useEtherscanProvider = function() {
this.setConfig(config) this.setConfig(config)
} }
ConfigManager.prototype.getProvider = function() { ConfigManager.prototype.getProvider = function () {
var config = this.getConfig() var config = this.getConfig()
return config.provider return config.provider
} }
ConfigManager.prototype.setData = function(data) { ConfigManager.prototype.setData = function (data) {
this.migrator.saveData(data) this.migrator.saveData(data)
} }
ConfigManager.prototype.getData = function() { ConfigManager.prototype.getData = function () {
return this.migrator.getData() return this.migrator.getData()
} }
ConfigManager.prototype.setWallet = function(wallet) { ConfigManager.prototype.setWallet = function (wallet) {
var data = this.migrator.getData() var data = this.migrator.getData()
data.wallet = wallet data.wallet = wallet
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.getSelectedAccount = function() { ConfigManager.prototype.getSelectedAccount = function () {
var config = this.getConfig() var config = this.getConfig()
return config.selectedAccount return config.selectedAccount
} }
ConfigManager.prototype.setSelectedAccount = function(address) { ConfigManager.prototype.setSelectedAccount = function (address) {
var config = this.getConfig() var config = this.getConfig()
config.selectedAccount = address config.selectedAccount = address
this.setConfig(config) this.setConfig(config)
} }
ConfigManager.prototype.getWallet = function() { ConfigManager.prototype.getWallet = function () {
return this.migrator.getData().wallet return this.migrator.getData().wallet
} }
// Takes a boolean // Takes a boolean
ConfigManager.prototype.setShowSeedWords = function(should) { ConfigManager.prototype.setShowSeedWords = function (should) {
var data = this.migrator.getData() var data = this.migrator.getData()
data.showSeedWords = should data.showSeedWords = should
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.getShouldShowSeedWords = function() { ConfigManager.prototype.getShouldShowSeedWords = function () {
var data = this.migrator.getData() var data = this.migrator.getData()
return data.showSeedWords return data.showSeedWords
} }
ConfigManager.prototype.getCurrentRpcAddress = function() { ConfigManager.prototype.getCurrentRpcAddress = function () {
var provider = this.getProvider() var provider = this.getProvider()
if (!provider) return null if (!provider) return null
switch (provider.type) { switch (provider.type) {
@ -154,13 +153,13 @@ ConfigManager.prototype.getCurrentRpcAddress = function() {
} }
} }
ConfigManager.prototype.clearWallet = function() { ConfigManager.prototype.clearWallet = function () {
var data = this.getConfig() var data = this.getConfig()
delete data.wallet delete data.wallet
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.setData = function(data) { ConfigManager.prototype.setData = function (data) {
this.migrator.saveData(data) this.migrator.saveData(data)
} }
@ -168,7 +167,7 @@ ConfigManager.prototype.setData = function(data) {
// Tx // Tx
// //
ConfigManager.prototype.getTxList = function() { ConfigManager.prototype.getTxList = function () {
var data = this.migrator.getData() var data = this.migrator.getData()
if (data.transactions !== undefined) { if (data.transactions !== undefined) {
return data.transactions return data.transactions
@ -177,45 +176,45 @@ ConfigManager.prototype.getTxList = function() {
} }
} }
ConfigManager.prototype.unconfirmedTxs = function() { ConfigManager.prototype.unconfirmedTxs = function () {
var transactions = this.getTxList() var transactions = this.getTxList()
return transactions.filter(tx => tx.status === 'unconfirmed') return transactions.filter(tx => tx.status === 'unconfirmed')
.reduce((result, tx) => { result[tx.id] = tx; return result }, {}) .reduce((result, tx) => { result[tx.id] = tx; return result }, {})
} }
ConfigManager.prototype._saveTxList = function(txList) { ConfigManager.prototype._saveTxList = function (txList) {
var data = this.migrator.getData() var data = this.migrator.getData()
data.transactions = txList data.transactions = txList
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.addTx = function(tx) { ConfigManager.prototype.addTx = function (tx) {
var transactions = this.getTxList() var transactions = this.getTxList()
transactions.push(tx) transactions.push(tx)
this._saveTxList(transactions) this._saveTxList(transactions)
} }
ConfigManager.prototype.getTx = function(txId) { ConfigManager.prototype.getTx = function (txId) {
var transactions = this.getTxList() var transactions = this.getTxList()
var matching = transactions.filter(tx => tx.id === txId) var matching = transactions.filter(tx => tx.id === txId)
return matching.length > 0 ? matching[0] : null return matching.length > 0 ? matching[0] : null
} }
ConfigManager.prototype.confirmTx = function(txId) { ConfigManager.prototype.confirmTx = function (txId) {
this._setTxStatus(txId, 'confirmed') this._setTxStatus(txId, 'confirmed')
} }
ConfigManager.prototype.rejectTx = function(txId) { ConfigManager.prototype.rejectTx = function (txId) {
this._setTxStatus(txId, 'rejected') this._setTxStatus(txId, 'rejected')
} }
ConfigManager.prototype._setTxStatus = function(txId, status) { ConfigManager.prototype._setTxStatus = function (txId, status) {
var tx = this.getTx(txId) var tx = this.getTx(txId)
tx.status = status tx.status = status
this.updateTx(tx) this.updateTx(tx)
} }
ConfigManager.prototype.updateTx = function(tx) { ConfigManager.prototype.updateTx = function (tx) {
var transactions = this.getTxList() var transactions = this.getTxList()
var found, index var found, index
transactions.forEach((otherTx, i) => { transactions.forEach((otherTx, i) => {
@ -232,19 +231,19 @@ ConfigManager.prototype.updateTx = function(tx) {
// wallet nickname methods // wallet nickname methods
ConfigManager.prototype.getWalletNicknames = function() { ConfigManager.prototype.getWalletNicknames = function () {
var data = this.getData() var data = this.getData()
let nicknames = ('walletNicknames' in data) ? data.walletNicknames : {} const nicknames = ('walletNicknames' in data) ? data.walletNicknames : {}
return nicknames return nicknames
} }
ConfigManager.prototype.nicknameForWallet = function(account) { ConfigManager.prototype.nicknameForWallet = function (account) {
let nicknames = this.getWalletNicknames() const nicknames = this.getWalletNicknames()
return nicknames[account] return nicknames[account]
} }
ConfigManager.prototype.setNicknameForWallet = function(account, nickname) { ConfigManager.prototype.setNicknameForWallet = function (account, nickname) {
let nicknames = this.getWalletNicknames() const nicknames = this.getWalletNicknames()
nicknames[account] = nickname nicknames[account] = nickname
var data = this.getData() var data = this.getData()
data.walletNicknames = nicknames data.walletNicknames = nicknames
@ -253,37 +252,35 @@ ConfigManager.prototype.setNicknameForWallet = function(account, nickname) {
// observable // observable
ConfigManager.prototype.subscribe = function(fn){ ConfigManager.prototype.subscribe = function (fn) {
this._subs.push(fn) this._subs.push(fn)
var unsubscribe = this.unsubscribe.bind(this, fn) var unsubscribe = this.unsubscribe.bind(this, fn)
return unsubscribe return unsubscribe
} }
ConfigManager.prototype.unsubscribe = function(fn){ ConfigManager.prototype.unsubscribe = function (fn) {
var index = this._subs.indexOf(fn) var index = this._subs.indexOf(fn)
if (index !== -1) this._subs.splice(index, 1) if (index !== -1) this._subs.splice(index, 1)
} }
ConfigManager.prototype._emitUpdates = function(state){ ConfigManager.prototype._emitUpdates = function (state) {
this._subs.forEach(function(handler){ this._subs.forEach(function (handler) {
handler(state) handler(state)
}) })
} }
ConfigManager.prototype.setConfirmed = function(confirmed) { ConfigManager.prototype.setConfirmed = function (confirmed) {
var data = this.getData() var data = this.getData()
data.isConfirmed = confirmed data.isConfirmed = confirmed
this.setData(data) this.setData(data)
} }
ConfigManager.prototype.getConfirmed = function() { ConfigManager.prototype.getConfirmed = function () {
var data = this.getData() var data = this.getData()
return ('isConfirmed' in data) && data.isConfirmed return ('isConfirmed' in data) && data.isConfirmed
} }
function loadData () {
function loadData() {
var oldData = getOldStyleData() var oldData = getOldStyleData()
var newData var newData
try { try {
@ -298,14 +295,14 @@ function loadData() {
config: { config: {
provider: { provider: {
type: 'testnet', type: 'testnet',
} },
} },
} },
}, oldData ? oldData : null, newData ? newData : null) }, oldData || null, newData || null)
return data return data
} }
function getOldStyleData() { function getOldStyleData () {
var config, wallet, seedWords var config, wallet, seedWords
var result = { var result = {

@ -1,21 +1,21 @@
module.exports = ensnare module.exports = ensnare
// creates a proxy object that calls cb everytime the obj's properties/fns are accessed // creates a proxy object that calls cb everytime the obj's properties/fns are accessed
function ensnare(obj, cb){ function ensnare (obj, cb) {
var proxy = {} var proxy = {}
Object.keys(obj).forEach(function(key){ Object.keys(obj).forEach(function (key) {
var val = obj[key] var val = obj[key]
switch (typeof val) { switch (typeof val) {
case 'function': case 'function':
proxy[key] = function(){ proxy[key] = function () {
cb() cb()
val.apply(obj, arguments) val.apply(obj, arguments)
} }
return return
default: default:
Object.defineProperty(proxy, key, { Object.defineProperty(proxy, key, {
get: function(){ cb(); return obj[key] }, get: function () { cb(); return obj[key] },
set: function(val){ cb(); return obj[key] = val }, set: function (val) { cb(); obj[key] = val; return val },
}) })
return return
} }

@ -4,19 +4,18 @@ const configManager = require('./config-manager-singleton')
module.exports = IdManagement module.exports = IdManagement
function IdManagement (opts) {
function IdManagement(opts) {
if (!opts) opts = {} if (!opts) opts = {}
this.keyStore = opts.keyStore this.keyStore = opts.keyStore
this.derivedKey = opts.derivedKey this.derivedKey = opts.derivedKey
this.hdPathString = "m/44'/60'/0'/0" this.hdPathString = "m/44'/60'/0'/0"
this.getAddresses = function(){ this.getAddresses = function () {
return keyStore.getAddresses(this.hdPathString).map(function(address){ return '0x'+address }) return this.keyStore.getAddresses(this.hdPathString).map(function (address) { return '0x' + address })
} }
this.signTx = function(txParams){ this.signTx = function (txParams) {
// normalize values // normalize values
txParams.to = ethUtil.addHexPrefix(txParams.to) txParams.to = ethUtil.addHexPrefix(txParams.to)
txParams.from = ethUtil.addHexPrefix(txParams.from) txParams.from = ethUtil.addHexPrefix(txParams.from)
@ -44,34 +43,34 @@ function IdManagement(opts) {
this.signMsg = function (address, message) { this.signMsg = function (address, message) {
// sign message // sign message
var privKeyHex = this.exportPrivateKey(address); var privKeyHex = this.exportPrivateKey(address)
var privKey = ethUtil.toBuffer(privKeyHex); var privKey = ethUtil.toBuffer(privKeyHex)
var msgSig = ethUtil.ecsign(new Buffer(message.replace('0x',''), 'hex'), privKey); var msgSig = ethUtil.ecsign(new Buffer(message.replace('0x', ''), 'hex'), privKey)
var rawMsgSig = ethUtil.bufferToHex(concatSig(msgSig.v, msgSig.r, msgSig.s)); var rawMsgSig = ethUtil.bufferToHex(concatSig(msgSig.v, msgSig.r, msgSig.s))
return rawMsgSig; return rawMsgSig
}; }
this.getSeed = function(){ this.getSeed = function () {
return this.keyStore.getSeed(this.derivedKey) return this.keyStore.getSeed(this.derivedKey)
} }
this.exportPrivateKey = function(address) { this.exportPrivateKey = function (address) {
var privKeyHex = ethUtil.addHexPrefix(this.keyStore.exportPrivateKey(address, this.derivedKey, this.hdPathString)) var privKeyHex = ethUtil.addHexPrefix(this.keyStore.exportPrivateKey(address, this.derivedKey, this.hdPathString))
return privKeyHex return privKeyHex
} }
} }
function pad_with_zeroes(number, length){ function padWithZeroes (number, length) {
var my_string = '' + number; var myString = '' + number
while (my_string.length < length) { while (myString.length < length) {
my_string = '0' + my_string; myString = '0' + myString
} }
return my_string; return myString
} }
function concatSig(v, r, s) { function concatSig (v, r, s) {
r = pad_with_zeroes(ethUtil.fromSigned(r), 64) r = padWithZeroes(ethUtil.fromSigned(r), 64)
s = pad_with_zeroes(ethUtil.fromSigned(s), 64) s = padWithZeroes(ethUtil.fromSigned(s), 64)
r = ethUtil.stripHexPrefix(r.toString('hex')) r = ethUtil.stripHexPrefix(r.toString('hex'))
s = ethUtil.stripHexPrefix(s.toString('hex')) s = ethUtil.stripHexPrefix(s.toString('hex'))
v = ethUtil.stripHexPrefix(ethUtil.intToHex(v)) v = ethUtil.stripHexPrefix(ethUtil.intToHex(v))

@ -1,10 +1,7 @@
const EventEmitter = require('events').EventEmitter const EventEmitter = require('events').EventEmitter
const inherits = require('util').inherits const inherits = require('util').inherits
const Transaction = require('ethereumjs-tx')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
const LightwalletKeyStore = require('eth-lightwallet').keystore const LightwalletKeyStore = require('eth-lightwallet').keystore
const LightwalletSigner = require('eth-lightwallet').signing
const async = require('async')
const clone = require('clone') const clone = require('clone')
const extend = require('xtend') const extend = require('xtend')
const createId = require('web3-provider-engine/util/random-id') const createId = require('web3-provider-engine/util/random-id')
@ -15,12 +12,10 @@ const messageManager = require('./message-manager')
const DEFAULT_RPC = 'https://testrpc.metamask.io/' const DEFAULT_RPC = 'https://testrpc.metamask.io/'
const IdManagement = require('./id-management') const IdManagement = require('./id-management')
module.exports = IdentityStore module.exports = IdentityStore
inherits(IdentityStore, EventEmitter) inherits(IdentityStore, EventEmitter)
function IdentityStore(opts = {}) { function IdentityStore (opts = {}) {
EventEmitter.call(this) EventEmitter.call(this)
// we just use the ethStore to auto-add accounts // we just use the ethStore to auto-add accounts
@ -46,7 +41,7 @@ function IdentityStore(opts = {}) {
// public // public
// //
IdentityStore.prototype.createNewVault = function(password, entropy, cb){ IdentityStore.prototype.createNewVault = function (password, entropy, cb) {
delete this._keyStore delete this._keyStore
configManager.clearWallet() configManager.clearWallet()
this._createIdmgmt(password, null, entropy, (err) => { this._createIdmgmt(password, null, entropy, (err) => {
@ -62,14 +57,14 @@ IdentityStore.prototype.createNewVault = function(password, entropy, cb){
}) })
} }
IdentityStore.prototype.recoverSeed = function(cb){ IdentityStore.prototype.recoverSeed = function (cb) {
configManager.setShowSeedWords(true) configManager.setShowSeedWords(true)
if (!this._idmgmt) return cb(new Error('Unauthenticated. Please sign in.')) if (!this._idmgmt) return cb(new Error('Unauthenticated. Please sign in.'))
var seedWords = this._idmgmt.getSeed() var seedWords = this._idmgmt.getSeed()
cb(null, seedWords) cb(null, seedWords)
} }
IdentityStore.prototype.recoverFromSeed = function(password, seed, cb){ IdentityStore.prototype.recoverFromSeed = function (password, seed, cb) {
this._createIdmgmt(password, seed, null, (err) => { this._createIdmgmt(password, seed, null, (err) => {
if (err) return cb(err) if (err) return cb(err)
@ -79,18 +74,17 @@ IdentityStore.prototype.recoverFromSeed = function(password, seed, cb){
}) })
} }
IdentityStore.prototype.setStore = function(store){ IdentityStore.prototype.setStore = function (store) {
this._ethStore = store this._ethStore = store
} }
IdentityStore.prototype.clearSeedWordCache = function(cb) { IdentityStore.prototype.clearSeedWordCache = function (cb) {
configManager.setShowSeedWords(false) configManager.setShowSeedWords(false)
cb(null, configManager.getSelectedAccount()) cb(null, configManager.getSelectedAccount())
} }
IdentityStore.prototype.getState = function(){ IdentityStore.prototype.getState = function () {
var seedWords = this.getSeedIfUnlocked() var seedWords = this.getSeedIfUnlocked()
var wallet = configManager.getWallet()
return clone(extend(this._currentState, { return clone(extend(this._currentState, {
isInitialized: !!configManager.getWallet() && !seedWords, isInitialized: !!configManager.getWallet() && !seedWords,
isUnlocked: this._isUnlocked(), isUnlocked: this._isUnlocked(),
@ -104,7 +98,7 @@ IdentityStore.prototype.getState = function(){
})) }))
} }
IdentityStore.prototype.getSeedIfUnlocked = function() { IdentityStore.prototype.getSeedIfUnlocked = function () {
var showSeed = configManager.getShouldShowSeedWords() var showSeed = configManager.getShouldShowSeedWords()
var idmgmt = this._idmgmt var idmgmt = this._idmgmt
var shouldShow = showSeed && !!idmgmt var shouldShow = showSeed && !!idmgmt
@ -112,11 +106,11 @@ IdentityStore.prototype.getSeedIfUnlocked = function() {
return seedWords return seedWords
} }
IdentityStore.prototype.getSelectedAddress = function(){ IdentityStore.prototype.getSelectedAddress = function () {
return configManager.getSelectedAccount() return configManager.getSelectedAccount()
} }
IdentityStore.prototype.setSelectedAddress = function(address, cb){ IdentityStore.prototype.setSelectedAddress = function (address, cb) {
if (!address) { if (!address) {
var addresses = this._getAddresses() var addresses = this._getAddresses()
address = addresses[0] address = addresses[0]
@ -126,8 +120,7 @@ IdentityStore.prototype.setSelectedAddress = function(address, cb){
if (cb) return cb(null, address) if (cb) return cb(null, address)
} }
IdentityStore.prototype.revealAccount = function(cb) { IdentityStore.prototype.revealAccount = function (cb) {
let addresses = this._getAddresses()
const derivedKey = this._idmgmt.derivedKey const derivedKey = this._idmgmt.derivedKey
const keyStore = this._keyStore const keyStore = this._keyStore
@ -135,14 +128,12 @@ IdentityStore.prototype.revealAccount = function(cb) {
keyStore.generateNewAddress(derivedKey, 1) keyStore.generateNewAddress(derivedKey, 1)
configManager.setWallet(keyStore.serialize()) configManager.setWallet(keyStore.serialize())
addresses = this._getAddresses()
this._loadIdentities() this._loadIdentities()
this._didUpdate() this._didUpdate()
cb(null) cb(null)
} }
IdentityStore.prototype.getNetwork = function(err) { IdentityStore.prototype.getNetwork = function (err) {
if (err) { if (err) {
this._currentState.network = 'loading' this._currentState.network = 'loading'
this._didUpdate() this._didUpdate()
@ -160,13 +151,13 @@ IdentityStore.prototype.getNetwork = function(err) {
}) })
} }
IdentityStore.prototype.setLocked = function(cb){ IdentityStore.prototype.setLocked = function (cb) {
delete this._keyStore delete this._keyStore
delete this._idmgmt delete this._idmgmt
cb() cb()
} }
IdentityStore.prototype.submitPassword = function(password, cb){ IdentityStore.prototype.submitPassword = function (password, cb) {
this.tryPassword(password, (err) => { this.tryPassword(password, (err) => {
if (err) return cb(err) if (err) return cb(err)
// load identities before returning... // load identities before returning...
@ -175,7 +166,7 @@ IdentityStore.prototype.submitPassword = function(password, cb){
}) })
} }
IdentityStore.prototype.exportAccount = function(address, cb) { IdentityStore.prototype.exportAccount = function (address, cb) {
var privateKey = this._idmgmt.exportPrivateKey(address) var privateKey = this._idmgmt.exportPrivateKey(address)
cb(null, privateKey) cb(null, privateKey)
} }
@ -185,7 +176,7 @@ IdentityStore.prototype.exportAccount = function(address, cb) {
// //
// comes from dapp via zero-client hooked-wallet provider // comes from dapp via zero-client hooked-wallet provider
IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, onTxDoneCb, cb){ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDoneCb, cb) {
var self = this var self = this
// create txData obj with parameters and meta data // create txData obj with parameters and meta data
var time = (new Date()).getTime() var time = (new Date()).getTime()
@ -208,13 +199,13 @@ IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, onTxDoneC
// perform static analyis on the target contract code // perform static analyis on the target contract code
var provider = self._ethStore._query.currentProvider var provider = self._ethStore._query.currentProvider
if (txParams.to) { if (txParams.to) {
provider.sendAsync({ id: 1, method: 'eth_getCode', params: [txParams.to, 'latest'] }, function(err, res){ provider.sendAsync({ id: 1, method: 'eth_getCode', params: [txParams.to, 'latest'] }, function (err, res) {
if (err) return didComplete(err) if (err) return didComplete(err)
if (res.error) return didComplete(res.error) if (res.error) return didComplete(res.error)
var code = ethUtil.toBuffer(res.result) var code = ethUtil.toBuffer(res.result)
if (code !== '0x') { if (code !== '0x') {
var ops = ethBinToOps(code) var ops = ethBinToOps(code)
var containsDelegateCall = ops.some((op)=>op.name === 'DELEGATECALL') var containsDelegateCall = ops.some((op) => op.name === 'DELEGATECALL')
txData.containsDelegateCall = containsDelegateCall txData.containsDelegateCall = containsDelegateCall
didComplete() didComplete()
} else { } else {
@ -225,19 +216,17 @@ IdentityStore.prototype.addUnconfirmedTransaction = function(txParams, onTxDoneC
didComplete() didComplete()
} }
function didComplete(err){ function didComplete (err) {
if (err) return cb(err) if (err) return cb(err)
// signal update // signal update
self._didUpdate() self._didUpdate()
// signal completion of add tx // signal completion of add tx
cb(null, txData) cb(null, txData)
} }
} }
// comes from metamask ui // comes from metamask ui
IdentityStore.prototype.approveTransaction = function(txId, cb){ IdentityStore.prototype.approveTransaction = function (txId, cb) {
var txData = configManager.getTx(txId)
var approvalCb = this._unconfTxCbs[txId] || noop var approvalCb = this._unconfTxCbs[txId] || noop
// accept tx // accept tx
@ -250,8 +239,7 @@ IdentityStore.prototype.approveTransaction = function(txId, cb){
} }
// comes from metamask ui // comes from metamask ui
IdentityStore.prototype.cancelTransaction = function(txId){ IdentityStore.prototype.cancelTransaction = function (txId) {
var txData = configManager.getTx(txId)
var approvalCb = this._unconfTxCbs[txId] || noop var approvalCb = this._unconfTxCbs[txId] || noop
// reject tx // reject tx
@ -263,7 +251,7 @@ IdentityStore.prototype.cancelTransaction = function(txId){
} }
// performs the actual signing, no autofill of params // performs the actual signing, no autofill of params
IdentityStore.prototype.signTransaction = function(txParams, cb){ IdentityStore.prototype.signTransaction = function (txParams, cb) {
try { try {
console.log('signing tx...', txParams) console.log('signing tx...', txParams)
var rawTx = this._idmgmt.signTx(txParams) var rawTx = this._idmgmt.signTx(txParams)
@ -278,8 +266,7 @@ IdentityStore.prototype.signTransaction = function(txParams, cb){
// //
// comes from dapp via zero-client hooked-wallet provider // comes from dapp via zero-client hooked-wallet provider
IdentityStore.prototype.addUnconfirmedMessage = function(msgParams, cb){ IdentityStore.prototype.addUnconfirmedMessage = function (msgParams, cb) {
// create txData obj with parameters and meta data // create txData obj with parameters and meta data
var time = (new Date()).getTime() var time = (new Date()).getTime()
var msgId = createId() var msgId = createId()
@ -303,8 +290,7 @@ IdentityStore.prototype.addUnconfirmedMessage = function(msgParams, cb){
} }
// comes from metamask ui // comes from metamask ui
IdentityStore.prototype.approveMessage = function(msgId, cb){ IdentityStore.prototype.approveMessage = function (msgId, cb) {
var msgData = messageManager.getMsg(msgId)
var approvalCb = this._unconfMsgCbs[msgId] || noop var approvalCb = this._unconfMsgCbs[msgId] || noop
// accept msg // accept msg
@ -317,8 +303,7 @@ IdentityStore.prototype.approveMessage = function(msgId, cb){
} }
// comes from metamask ui // comes from metamask ui
IdentityStore.prototype.cancelMessage = function(msgId){ IdentityStore.prototype.cancelMessage = function (msgId) {
var txData = messageManager.getMsg(msgId)
var approvalCb = this._unconfMsgCbs[msgId] || noop var approvalCb = this._unconfMsgCbs[msgId] || noop
// reject tx // reject tx
@ -330,7 +315,7 @@ IdentityStore.prototype.cancelMessage = function(msgId){
} }
// performs the actual signing, no autofill of params // performs the actual signing, no autofill of params
IdentityStore.prototype.signMessage = function(msgParams, cb){ IdentityStore.prototype.signMessage = function (msgParams, cb) {
try { try {
console.log('signing msg...', msgParams.data) console.log('signing msg...', msgParams.data)
var rawMsg = this._idmgmt.signMsg(msgParams.from, msgParams.data) var rawMsg = this._idmgmt.signMsg(msgParams.from, msgParams.data)
@ -351,17 +336,17 @@ IdentityStore.prototype.signMessage = function(msgParams, cb){
// private // private
// //
IdentityStore.prototype._didUpdate = function(){ IdentityStore.prototype._didUpdate = function () {
this.emit('update', this.getState()) this.emit('update', this.getState())
} }
IdentityStore.prototype._isUnlocked = function(){ IdentityStore.prototype._isUnlocked = function () {
var result = Boolean(this._keyStore) && Boolean(this._idmgmt) var result = Boolean(this._keyStore) && Boolean(this._idmgmt)
return result return result
} }
// load identities from keyStoreet // load identities from keyStoreet
IdentityStore.prototype._loadIdentities = function(){ IdentityStore.prototype._loadIdentities = function () {
if (!this._isUnlocked()) throw new Error('not unlocked') if (!this._isUnlocked()) throw new Error('not unlocked')
var addresses = this._getAddresses() var addresses = this._getAddresses()
@ -369,7 +354,7 @@ IdentityStore.prototype._loadIdentities = function(){
// // add to ethStore // // add to ethStore
this._ethStore.addAccount(address) this._ethStore.addAccount(address)
// add to identities // add to identities
const defaultLabel = 'Wallet ' + (i+1) const defaultLabel = 'Wallet ' + (i + 1)
const nickname = configManager.nicknameForWallet(address) const nickname = configManager.nicknameForWallet(address)
var identity = { var identity = {
name: nickname || defaultLabel, name: nickname || defaultLabel,
@ -381,7 +366,7 @@ IdentityStore.prototype._loadIdentities = function(){
this._didUpdate() this._didUpdate()
} }
IdentityStore.prototype.saveAccountLabel = function(account, label, cb) { IdentityStore.prototype.saveAccountLabel = function (account, label, cb) {
configManager.setNicknameForWallet(account, label) configManager.setNicknameForWallet(account, label)
this._loadIdentities() this._loadIdentities()
cb(null, label) cb(null, label)
@ -393,7 +378,7 @@ IdentityStore.prototype.saveAccountLabel = function(account, label, cb) {
// The UI will have to check the balance to know. // The UI will have to check the balance to know.
// If there is no balance and it mayBeFauceting, // If there is no balance and it mayBeFauceting,
// then it is in fact fauceting. // then it is in fact fauceting.
IdentityStore.prototype._mayBeFauceting = function(i) { IdentityStore.prototype._mayBeFauceting = function (i) {
var config = configManager.getProvider() var config = configManager.getProvider()
if (i === 0 && if (i === 0 &&
config.type === 'rpc' && config.type === 'rpc' &&
@ -407,11 +392,11 @@ IdentityStore.prototype._mayBeFauceting = function(i) {
// keyStore managment - unlocking + deserialization // keyStore managment - unlocking + deserialization
// //
IdentityStore.prototype.tryPassword = function(password, cb){ IdentityStore.prototype.tryPassword = function (password, cb) {
this._createIdmgmt(password, null, null, cb) this._createIdmgmt(password, null, null, cb)
} }
IdentityStore.prototype._createIdmgmt = function(password, seed, entropy, cb){ IdentityStore.prototype._createIdmgmt = function (password, seed, entropy, cb) {
var keyStore = null var keyStore = null
LightwalletKeyStore.deriveKeyFromPassword(password, (err, derivedKey) => { LightwalletKeyStore.deriveKeyFromPassword(password, (err, derivedKey) => {
if (err) return cb(err) if (err) return cb(err)
@ -446,9 +431,9 @@ IdentityStore.prototype._createIdmgmt = function(password, seed, entropy, cb){
}) })
} }
IdentityStore.prototype._restoreFromSeed = function(password, seed, derivedKey) { IdentityStore.prototype._restoreFromSeed = function (password, seed, derivedKey) {
var keyStore = new LightwalletKeyStore(seed, derivedKey, this.hdPathString) var keyStore = new LightwalletKeyStore(seed, derivedKey, this.hdPathString)
keyStore.addHdDerivationPath(this.hdPathString, derivedKey, {curve: 'secp256k1', purpose: 'sign'}); keyStore.addHdDerivationPath(this.hdPathString, derivedKey, {curve: 'secp256k1', purpose: 'sign'})
keyStore.setDefaultHdDerivationPath(this.hdPathString) keyStore.setDefaultHdDerivationPath(this.hdPathString)
keyStore.generateNewAddress(derivedKey, 3) keyStore.generateNewAddress(derivedKey, 3)
@ -457,10 +442,10 @@ IdentityStore.prototype._restoreFromSeed = function(password, seed, derivedKey)
return keyStore return keyStore
} }
IdentityStore.prototype._createFirstWallet = function(entropy, derivedKey) { IdentityStore.prototype._createFirstWallet = function (entropy, derivedKey) {
var secretSeed = LightwalletKeyStore.generateRandomSeed(entropy) var secretSeed = LightwalletKeyStore.generateRandomSeed(entropy)
var keyStore = new LightwalletKeyStore(secretSeed, derivedKey, this.hdPathString) var keyStore = new LightwalletKeyStore(secretSeed, derivedKey, this.hdPathString)
keyStore.addHdDerivationPath(this.hdPathString, derivedKey, {curve: 'secp256k1', purpose: 'sign'}); keyStore.addHdDerivationPath(this.hdPathString, derivedKey, {curve: 'secp256k1', purpose: 'sign'})
keyStore.setDefaultHdDerivationPath(this.hdPathString) keyStore.setDefaultHdDerivationPath(this.hdPathString)
keyStore.generateNewAddress(derivedKey, 3) keyStore.generateNewAddress(derivedKey, 3)
@ -470,15 +455,15 @@ IdentityStore.prototype._createFirstWallet = function(entropy, derivedKey) {
} }
// get addresses and normalize address hexString // get addresses and normalize address hexString
IdentityStore.prototype._getAddresses = function() { IdentityStore.prototype._getAddresses = function () {
return this._keyStore.getAddresses(this.hdPathString).map((address) => { return '0x'+address }) return this._keyStore.getAddresses(this.hdPathString).map((address) => { return '0x' + address })
} }
IdentityStore.prototype._autoFaucet = function() { IdentityStore.prototype._autoFaucet = function () {
var addresses = this._getAddresses() var addresses = this._getAddresses()
autoFaucet(addresses[0]) autoFaucet(addresses[0])
} }
// util // util
function noop(){} function noop () {}

@ -7,13 +7,12 @@ const MetamaskConfig = require('../config.js')
module.exports = MetamaskInpageProvider module.exports = MetamaskInpageProvider
function MetamaskInpageProvider (connectionStream) {
function MetamaskInpageProvider(connectionStream){
const self = this const self = this
// setup connectionStream multiplexing // setup connectionStream multiplexing
var multiStream = ObjectMultiplex() var multiStream = ObjectMultiplex()
Streams.pipe(connectionStream, multiStream, connectionStream, function(err){ Streams.pipe(connectionStream, multiStream, connectionStream, function (err) {
console.warn('MetamaskInpageProvider - lost connection to MetaMask') console.warn('MetamaskInpageProvider - lost connection to MetaMask')
if (err) throw err if (err) throw err
}) })
@ -22,7 +21,7 @@ function MetamaskInpageProvider(connectionStream){
// subscribe to metamask public config // subscribe to metamask public config
var publicConfigStore = remoteStoreWithLocalStorageCache('MetaMask-Config') var publicConfigStore = remoteStoreWithLocalStorageCache('MetaMask-Config')
var storeStream = publicConfigStore.createStream() var storeStream = publicConfigStore.createStream()
Streams.pipe(storeStream, multiStream.createStream('publicConfig'), storeStream, function(err){ Streams.pipe(storeStream, multiStream.createStream('publicConfig'), storeStream, function (err) {
console.warn('MetamaskInpageProvider - lost connection to MetaMask publicConfig') console.warn('MetamaskInpageProvider - lost connection to MetaMask publicConfig')
if (err) throw err if (err) throw err
}) })
@ -31,13 +30,13 @@ function MetamaskInpageProvider(connectionStream){
// connect to sync provider // connect to sync provider
self.syncProvider = createSyncProvider(publicConfigStore.get('provider')) self.syncProvider = createSyncProvider(publicConfigStore.get('provider'))
// subscribe to publicConfig to update the syncProvider on change // subscribe to publicConfig to update the syncProvider on change
publicConfigStore.subscribe(function(state){ publicConfigStore.subscribe(function (state) {
self.syncProvider = createSyncProvider(state.provider) self.syncProvider = createSyncProvider(state.provider)
}) })
// connect to async provider // connect to async provider
var asyncProvider = new StreamProvider() var asyncProvider = new StreamProvider()
Streams.pipe(asyncProvider, multiStream.createStream('provider'), asyncProvider, function(err){ Streams.pipe(asyncProvider, multiStream.createStream('provider'), asyncProvider, function (err) {
console.warn('MetamaskInpageProvider - lost connection to MetaMask provider') console.warn('MetamaskInpageProvider - lost connection to MetaMask provider')
if (err) throw err if (err) throw err
}) })
@ -47,21 +46,22 @@ function MetamaskInpageProvider(connectionStream){
self.sendAsync = asyncProvider.sendAsync.bind(asyncProvider) self.sendAsync = asyncProvider.sendAsync.bind(asyncProvider)
} }
MetamaskInpageProvider.prototype.send = function(payload){ MetamaskInpageProvider.prototype.send = function (payload) {
const self = this const self = this
let selectedAddress
var result = null var result = null
switch (payload.method) { switch (payload.method) {
case 'eth_accounts': case 'eth_accounts':
// read from localStorage // read from localStorage
var selectedAddress = self.publicConfigStore.get('selectedAddress') selectedAddress = self.publicConfigStore.get('selectedAddress')
result = selectedAddress ? [selectedAddress] : [] result = selectedAddress ? [selectedAddress] : []
break break
case 'eth_coinbase': case 'eth_coinbase':
// read from localStorage // read from localStorage
var selectedAddress = self.publicConfigStore.get('selectedAddress') selectedAddress = self.publicConfigStore.get('selectedAddress')
result = selectedAddress || '0x0000000000000000000000000000000000000000' result = selectedAddress || '0x0000000000000000000000000000000000000000'
break break
@ -79,24 +79,24 @@ MetamaskInpageProvider.prototype.send = function(payload){
} }
} }
MetamaskInpageProvider.prototype.sendAsync = function(){ MetamaskInpageProvider.prototype.sendAsync = function () {
throw new Error('MetamaskInpageProvider - sendAsync not overwritten') throw new Error('MetamaskInpageProvider - sendAsync not overwritten')
} }
MetamaskInpageProvider.prototype.isConnected = function(){ MetamaskInpageProvider.prototype.isConnected = function () {
return true return true
} }
// util // util
function createSyncProvider(providerConfig){ function createSyncProvider (providerConfig) {
providerConfig = providerConfig || {} providerConfig = providerConfig || {}
var syncProviderUrl = undefined let syncProviderUrl
if (providerConfig.rpcTarget) { if (providerConfig.rpcTarget) {
syncProviderUrl = providerConfig.rpcTarget syncProviderUrl = providerConfig.rpcTarget
} else { } else {
switch(providerConfig.type) { switch (providerConfig.type) {
case 'testnet': case 'testnet':
syncProviderUrl = MetamaskConfig.network.testnet syncProviderUrl = MetamaskConfig.network.testnet
break break
@ -110,12 +110,12 @@ function createSyncProvider(providerConfig){
return new HttpProvider(syncProviderUrl) return new HttpProvider(syncProviderUrl)
} }
function remoteStoreWithLocalStorageCache(storageKey){ function remoteStoreWithLocalStorageCache (storageKey) {
// read local cache // read local cache
var initState = JSON.parse(localStorage[storageKey] || '{}') var initState = JSON.parse(localStorage[storageKey] || '{}')
var store = new RemoteStore(initState) var store = new RemoteStore(initState)
// cache the latest state locally // cache the latest state locally
store.subscribe(function(state){ store.subscribe(function (state) {
localStorage[storageKey] = JSON.stringify(state) localStorage[storageKey] = JSON.stringify(state)
}) })

@ -3,10 +3,9 @@ const inherits = require('util').inherits
module.exports = LocalMessageDuplexStream module.exports = LocalMessageDuplexStream
inherits(LocalMessageDuplexStream, Duplex) inherits(LocalMessageDuplexStream, Duplex)
function LocalMessageDuplexStream(opts){ function LocalMessageDuplexStream (opts) {
Duplex.call(this, { Duplex.call(this, {
objectMode: true, objectMode: true,
}) })
@ -21,19 +20,19 @@ function LocalMessageDuplexStream(opts){
// private // private
LocalMessageDuplexStream.prototype._onMessage = function(event){ LocalMessageDuplexStream.prototype._onMessage = function (event) {
var msg = event.data var msg = event.data
// console.log('LocalMessageDuplexStream ('+this._name+') - heard message...', event) // console.log('LocalMessageDuplexStream ('+this._name+') - heard message...', event)
// validate message // validate message
if (event.origin !== location.origin) return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (event.origin !== location.origin) ') if (event.origin !== location.origin) return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (event.origin !== location.origin) ')
if (typeof msg !== 'object') return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (typeof msg !== "object") ') if (typeof msg !== 'object') return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (typeof msg !== "object") ')
if (msg.target !== this._name) return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (msg.target !== this._name) ', msg.target, this._name) if (msg.target !== this._name) return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (msg.target !== this._name) ', msg.target, this._name)
if (!msg.data) return //console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (!msg.data) ') if (!msg.data) return // console.log('LocalMessageDuplexStream ('+this._name+') - rejected - (!msg.data) ')
// console.log('LocalMessageDuplexStream ('+this._name+') - accepted', msg.data) // console.log('LocalMessageDuplexStream ('+this._name+') - accepted', msg.data)
// forward message // forward message
try { try {
this.push(msg.data) this.push(msg.data)
} catch(err) { } catch (err) {
this.emit('error', err) this.emit('error', err)
} }
} }
@ -42,7 +41,7 @@ LocalMessageDuplexStream.prototype._onMessage = function(event){
LocalMessageDuplexStream.prototype._read = noop LocalMessageDuplexStream.prototype._read = noop
LocalMessageDuplexStream.prototype._write = function(data, encoding, cb){ LocalMessageDuplexStream.prototype._write = function (data, encoding, cb) {
// console.log('LocalMessageDuplexStream ('+this._name+') - sending message...') // console.log('LocalMessageDuplexStream ('+this._name+') - sending message...')
var message = { var message = {
target: this._target, target: this._target,
@ -54,4 +53,4 @@ LocalMessageDuplexStream.prototype._write = function(data, encoding, cb){
// util // util
function noop(){} function noop () {}

@ -1,50 +1,50 @@
module.exports = new MessageManager() module.exports = new MessageManager()
function MessageManager(opts) { function MessageManager (opts) {
this.messages = [] this.messages = []
} }
MessageManager.prototype.getMsgList = function() { MessageManager.prototype.getMsgList = function () {
return this.messages return this.messages
} }
MessageManager.prototype.unconfirmedMsgs = function() { MessageManager.prototype.unconfirmedMsgs = function () {
var messages = this.getMsgList() var messages = this.getMsgList()
return messages.filter(msg => msg.status === 'unconfirmed') return messages.filter(msg => msg.status === 'unconfirmed')
.reduce((result, msg) => { result[msg.id] = msg; return result }, {}) .reduce((result, msg) => { result[msg.id] = msg; return result }, {})
} }
MessageManager.prototype._saveMsgList = function(msgList) { MessageManager.prototype._saveMsgList = function (msgList) {
this.messages = msgList this.messages = msgList
} }
MessageManager.prototype.addMsg = function(msg) { MessageManager.prototype.addMsg = function (msg) {
var messages = this.getMsgList() var messages = this.getMsgList()
messages.push(msg) messages.push(msg)
this._saveMsgList(messages) this._saveMsgList(messages)
} }
MessageManager.prototype.getMsg = function(msgId) { MessageManager.prototype.getMsg = function (msgId) {
var messages = this.getMsgList() var messages = this.getMsgList()
var matching = messages.filter(msg => msg.id === msgId) var matching = messages.filter(msg => msg.id === msgId)
return matching.length > 0 ? matching[0] : null return matching.length > 0 ? matching[0] : null
} }
MessageManager.prototype.confirmMsg = function(msgId) { MessageManager.prototype.confirmMsg = function (msgId) {
this._setMsgStatus(msgId, 'confirmed') this._setMsgStatus(msgId, 'confirmed')
} }
MessageManager.prototype.rejectMsg = function(msgId) { MessageManager.prototype.rejectMsg = function (msgId) {
this._setMsgStatus(msgId, 'rejected') this._setMsgStatus(msgId, 'rejected')
} }
MessageManager.prototype._setMsgStatus = function(msgId, status) { MessageManager.prototype._setMsgStatus = function (msgId, status) {
var msg = this.getMsg(msgId) var msg = this.getMsg(msgId)
if (msg) msg.status = status if (msg) msg.status = status
this.updateMsg(msg) this.updateMsg(msg)
} }
MessageManager.prototype.updateMsg = function(msg) { MessageManager.prototype.updateMsg = function (msg) {
var messages = this.getMsgList() var messages = this.getMsgList()
var found, index var found, index
messages.forEach((otherMsg, i) => { messages.forEach((otherMsg, i) => {

@ -10,13 +10,12 @@ module.exports = {
setupListeners() setupListeners()
function setupListeners(){ function setupListeners () {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236 // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...') if (!chrome.notifications) return console.error('Chrome notifications API missing...')
// notification button press // notification button press
chrome.notifications.onButtonClicked.addListener(function(notificationId, buttonIndex){ chrome.notifications.onButtonClicked.addListener(function (notificationId, buttonIndex) {
var handlers = notificationHandlers[notificationId] var handlers = notificationHandlers[notificationId]
if (buttonIndex === 0) { if (buttonIndex === 0) {
handlers.confirm() handlers.confirm()
@ -27,14 +26,13 @@ function setupListeners(){
}) })
// notification teardown // notification teardown
chrome.notifications.onClosed.addListener(function(notificationId){ chrome.notifications.onClosed.addListener(function (notificationId) {
delete notificationHandlers[notificationId] delete notificationHandlers[notificationId]
}) })
} }
// creation helper // creation helper
function createUnlockRequestNotification(opts){ function createUnlockRequestNotification (opts) {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236 // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...') if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = 'An Ethereum app has requested a signature. Please unlock your account.' var message = 'An Ethereum app has requested a signature. Please unlock your account.'
@ -46,18 +44,17 @@ function createUnlockRequestNotification(opts){
title: opts.title, title: opts.title,
message: message, message: message,
}) })
} }
function createTxNotification(opts){ function createTxNotification (opts) {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236 // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...') if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = [ var message = [
'Submitted by '+opts.txParams.origin, 'Submitted by ' + opts.txParams.origin,
'to: '+uiUtils.addressSummary(opts.txParams.to), 'to: ' + uiUtils.addressSummary(opts.txParams.to),
'from: '+uiUtils.addressSummary(opts.txParams.from), 'from: ' + uiUtils.addressSummary(opts.txParams.from),
'value: '+uiUtils.formatBalance(opts.txParams.value), 'value: ' + uiUtils.formatBalance(opts.txParams.value),
'data: '+uiUtils.dataSize(opts.txParams.data), 'data: ' + uiUtils.dataSize(opts.txParams.data),
].join('\n') ].join('\n')
var id = createId() var id = createId()
@ -69,9 +66,9 @@ function createTxNotification(opts){
message: message, message: message,
buttons: [{ buttons: [{
title: 'confirm', title: 'confirm',
},{ }, {
title: 'cancel', title: 'cancel',
}] }],
}) })
notificationHandlers[id] = { notificationHandlers[id] = {
confirm: opts.confirm, confirm: opts.confirm,
@ -79,13 +76,13 @@ function createTxNotification(opts){
} }
} }
function createMsgNotification(opts){ function createMsgNotification (opts) {
// guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236 // guard for chrome bug https://github.com/MetaMask/metamask-plugin/issues/236
if (!chrome.notifications) return console.error('Chrome notifications API missing...') if (!chrome.notifications) return console.error('Chrome notifications API missing...')
var message = [ var message = [
'Submitted by '+opts.msgParams.origin, 'Submitted by ' + opts.msgParams.origin,
'to be signed by: '+uiUtils.addressSummary(opts.msgParams.from), 'to be signed by: ' + uiUtils.addressSummary(opts.msgParams.from),
'message:\n'+opts.msgParams.data, 'message:\n' + opts.msgParams.data,
].join('\n') ].join('\n')
var id = createId() var id = createId()
@ -97,9 +94,9 @@ function createMsgNotification(opts){
message: message, message: message,
buttons: [{ buttons: [{
title: 'confirm', title: 'confirm',
},{ }, {
title: 'cancel', title: 'cancel',
}] }],
}) })
notificationHandlers[id] = { notificationHandlers[id] = {
confirm: opts.confirm, confirm: opts.confirm,

@ -2,11 +2,10 @@ const through = require('through2')
module.exports = ObjectMultiplex module.exports = ObjectMultiplex
function ObjectMultiplex (opts) {
function ObjectMultiplex(opts){
opts = opts || {} opts = opts || {}
// create multiplexer // create multiplexer
var mx = through.obj(function(chunk, enc, cb) { var mx = through.obj(function (chunk, enc, cb) {
var name = chunk.name var name = chunk.name
var data = chunk.data var data = chunk.data
var substream = mx.streams[name] var substream = mx.streams[name]
@ -19,19 +18,19 @@ function ObjectMultiplex(opts){
}) })
mx.streams = {} mx.streams = {}
// create substreams // create substreams
mx.createStream = function(name) { mx.createStream = function (name) {
var substream = mx.streams[name] = through.obj(function(chunk, enc, cb) { var substream = mx.streams[name] = through.obj(function (chunk, enc, cb) {
mx.push({ mx.push({
name: name, name: name,
data: chunk, data: chunk,
}) })
return cb() return cb()
}) })
mx.on('end', function() { mx.on('end', function () {
return substream.emit('end') return substream.emit('end')
}) })
if (opts.error) { if (opts.error) {
mx.on('error', function() { mx.on('error', function () {
return substream.emit('error') return substream.emit('error')
}) })
} }

@ -3,10 +3,9 @@ const inherits = require('util').inherits
module.exports = PortDuplexStream module.exports = PortDuplexStream
inherits(PortDuplexStream, Duplex) inherits(PortDuplexStream, Duplex)
function PortDuplexStream(port){ function PortDuplexStream (port) {
Duplex.call(this, { Duplex.call(this, {
objectMode: true, objectMode: true,
}) })
@ -17,7 +16,7 @@ function PortDuplexStream(port){
// private // private
PortDuplexStream.prototype._onMessage = function(msg){ PortDuplexStream.prototype._onMessage = function (msg) {
if (Buffer.isBuffer(msg)) { if (Buffer.isBuffer(msg)) {
delete msg._isBuffer delete msg._isBuffer
var data = new Buffer(msg) var data = new Buffer(msg)
@ -29,11 +28,11 @@ PortDuplexStream.prototype._onMessage = function(msg){
} }
} }
PortDuplexStream.prototype._onDisconnect = function(){ PortDuplexStream.prototype._onDisconnect = function () {
try { try {
// this.end() // this.end()
this.emit('close') this.emit('close')
} catch(err){ } catch (err) {
this.emit('error', err) this.emit('error', err)
} }
} }
@ -42,7 +41,7 @@ PortDuplexStream.prototype._onDisconnect = function(){
PortDuplexStream.prototype._read = noop PortDuplexStream.prototype._read = noop
PortDuplexStream.prototype._write = function(msg, encoding, cb){ PortDuplexStream.prototype._write = function (msg, encoding, cb) {
try { try {
if (Buffer.isBuffer(msg)) { if (Buffer.isBuffer(msg)) {
var data = msg.toJSON() var data = msg.toJSON()
@ -54,7 +53,7 @@ PortDuplexStream.prototype._write = function(msg, encoding, cb){
this._port.postMessage(msg) this._port.postMessage(msg)
} }
cb() cb()
} catch(err){ } catch (err) {
console.error(err) console.error(err)
// this.emit('error', err) // this.emit('error', err)
cb(new Error('PortDuplexStream - disconnected')) cb(new Error('PortDuplexStream - disconnected'))
@ -63,4 +62,4 @@ PortDuplexStream.prototype._write = function(msg, encoding, cb){
// util // util
function noop(){} function noop () {}

@ -6,32 +6,32 @@ module.exports = {
RemoteStore: RemoteStore, RemoteStore: RemoteStore,
} }
function BaseStore(initState){ function BaseStore (initState) {
this._state = initState || {} this._state = initState || {}
this._subs = [] this._subs = []
} }
BaseStore.prototype.set = function(key, value){ BaseStore.prototype.set = function (key, value) {
throw Error('Not implemented.') throw Error('Not implemented.')
} }
BaseStore.prototype.get = function(key){ BaseStore.prototype.get = function (key) {
return this._state[key] return this._state[key]
} }
BaseStore.prototype.subscribe = function(fn){ BaseStore.prototype.subscribe = function (fn) {
this._subs.push(fn) this._subs.push(fn)
var unsubscribe = this.unsubscribe.bind(this, fn) var unsubscribe = this.unsubscribe.bind(this, fn)
return unsubscribe return unsubscribe
} }
BaseStore.prototype.unsubscribe = function(fn){ BaseStore.prototype.unsubscribe = function (fn) {
var index = this._subs.indexOf(fn) var index = this._subs.indexOf(fn)
if (index !== -1) this._subs.splice(index, 1) if (index !== -1) this._subs.splice(index, 1)
} }
BaseStore.prototype._emitUpdates = function(state){ BaseStore.prototype._emitUpdates = function (state) {
this._subs.forEach(function(handler){ this._subs.forEach(function (handler) {
handler(state) handler(state)
}) })
} }
@ -41,16 +41,16 @@ BaseStore.prototype._emitUpdates = function(state){
// //
inherits(HostStore, BaseStore) inherits(HostStore, BaseStore)
function HostStore(initState, opts){ function HostStore (initState, opts) {
BaseStore.call(this, initState) BaseStore.call(this, initState)
} }
HostStore.prototype.set = function(key, value){ HostStore.prototype.set = function (key, value) {
this._state[key] = value this._state[key] = value
process.nextTick(this._emitUpdates.bind(this, this._state)) process.nextTick(this._emitUpdates.bind(this, this._state))
} }
HostStore.prototype.createStream = function(){ HostStore.prototype.createStream = function () {
var dnode = Dnode({ var dnode = Dnode({
// update: this._didUpdate.bind(this), // update: this._didUpdate.bind(this),
}) })
@ -58,8 +58,8 @@ HostStore.prototype.createStream = function(){
return dnode return dnode
} }
HostStore.prototype._didConnect = function(remote){ HostStore.prototype._didConnect = function (remote) {
this.subscribe(function(state){ this.subscribe(function (state) {
remote.update(state) remote.update(state)
}) })
remote.update(this._state) remote.update(this._state)
@ -70,16 +70,16 @@ HostStore.prototype._didConnect = function(remote){
// //
inherits(RemoteStore, BaseStore) inherits(RemoteStore, BaseStore)
function RemoteStore(initState, opts){ function RemoteStore (initState, opts) {
BaseStore.call(this, initState) BaseStore.call(this, initState)
this._remote = null this._remote = null
} }
RemoteStore.prototype.set = function(key, value){ RemoteStore.prototype.set = function (key, value) {
this._remote.set(key, value) this._remote.set(key, value)
} }
RemoteStore.prototype.createStream = function(){ RemoteStore.prototype.createStream = function () {
var dnode = Dnode({ var dnode = Dnode({
update: this._didUpdate.bind(this), update: this._didUpdate.bind(this),
}) })
@ -87,11 +87,11 @@ RemoteStore.prototype.createStream = function(){
return dnode return dnode
} }
RemoteStore.prototype._didConnect = function(remote){ RemoteStore.prototype._didConnect = function (remote) {
this._remote = remote this._remote = remote
} }
RemoteStore.prototype._didUpdate = function(state){ RemoteStore.prototype._didUpdate = function (state) {
this._state = state this._state = state
this._emitUpdates(state) this._emitUpdates(state)
} }

@ -1,34 +1,33 @@
const Through = require('through2') const Through = require('through2')
const ObjectMultiplex = require('./obj-multiplex') const ObjectMultiplex = require('./obj-multiplex')
module.exports = { module.exports = {
jsonParseStream: jsonParseStream, jsonParseStream: jsonParseStream,
jsonStringifyStream: jsonStringifyStream, jsonStringifyStream: jsonStringifyStream,
setupMultiplex: setupMultiplex, setupMultiplex: setupMultiplex,
} }
function jsonParseStream(){ function jsonParseStream () {
return Through.obj(function(serialized, encoding, cb){ return Through.obj(function (serialized, encoding, cb) {
this.push(JSON.parse(serialized)) this.push(JSON.parse(serialized))
cb() cb()
}) })
} }
function jsonStringifyStream(){ function jsonStringifyStream () {
return Through.obj(function(obj, encoding, cb){ return Through.obj(function (obj, encoding, cb) {
this.push(JSON.stringify(obj)) this.push(JSON.stringify(obj))
cb() cb()
}) })
} }
function setupMultiplex(connectionStream){ function setupMultiplex (connectionStream) {
var mx = ObjectMultiplex() var mx = ObjectMultiplex()
connectionStream.pipe(mx).pipe(connectionStream) connectionStream.pipe(mx).pipe(connectionStream)
mx.on('error', function(err) { mx.on('error', function (err) {
console.error(err) console.error(err)
}) })
connectionStream.on('error', function(err) { connectionStream.on('error', function (err) {
console.error(err) console.error(err)
mx.destroy() mx.destroy()
}) })

@ -1,7 +1,7 @@
module.exports = { module.exports = {
version: 2, version: 2,
migrate: function(data) { migrate: function (data) {
try { try {
if (data.config.provider.type === 'etherscan') { if (data.config.provider.type === 'etherscan') {
data.config.provider.type = 'rpc' data.config.provider.type = 'rpc'
@ -9,5 +9,5 @@ module.exports = {
} }
} catch (e) {} } catch (e) {}
return data return data
} },
} }

@ -4,12 +4,12 @@ var newTestRpc = 'https://testrpc.metamask.io/'
module.exports = { module.exports = {
version: 3, version: 3,
migrate: function(data) { migrate: function (data) {
try { try {
if (data.config.provider.rpcTarget === oldTestRpc) { if (data.config.provider.rpcTarget === oldTestRpc) {
data.config.provider.rpcTarget = newTestRpc data.config.provider.rpcTarget = newTestRpc
} }
} catch (e) {} } catch (e) {}
return data return data
} },
} }

@ -1,22 +1,22 @@
module.exports = { module.exports = {
version: 4, version: 4,
migrate: function(data) { migrate: function (data) {
try { try {
if (data.config.provider.type !== 'rpc') return data if (data.config.provider.type !== 'rpc') return data
switch (data.config.provider.rpcTarget) { switch (data.config.provider.rpcTarget) {
case 'https://testrpc.metamask.io/': case 'https://testrpc.metamask.io/':
data.config.provider = { data.config.provider = {
type: 'testnet' type: 'testnet',
} }
break break
case 'https://rpc.metamask.io/': case 'https://rpc.metamask.io/':
data.config.provider = { data.config.provider = {
type: 'mainnet' type: 'mainnet',
} }
break break
} }
} catch (_) {} } catch (_) {}
return data return data
} },
} }

@ -19,7 +19,7 @@ async.parallel({
accountManager: connectToAccountManager, accountManager: connectToAccountManager,
}, setupApp) }, setupApp)
function connectToAccountManager(cb){ function connectToAccountManager (cb) {
// setup communication with background // setup communication with background
var pluginPort = chrome.runtime.connect({name: 'popup'}) var pluginPort = chrome.runtime.connect({name: 'popup'})
var portStream = new PortStream(pluginPort) var portStream = new PortStream(pluginPort)
@ -30,7 +30,7 @@ function connectToAccountManager(cb){
setupWeb3Connection(mx.createStream('provider')) setupWeb3Connection(mx.createStream('provider'))
} }
function setupWeb3Connection(stream){ function setupWeb3Connection (stream) {
var remoteProvider = new StreamProvider() var remoteProvider = new StreamProvider()
remoteProvider.pipe(stream).pipe(remoteProvider) remoteProvider.pipe(stream).pipe(remoteProvider)
stream.on('error', console.error.bind(console)) stream.on('error', console.error.bind(console))
@ -38,23 +38,23 @@ function setupWeb3Connection(stream){
global.web3 = new Web3(remoteProvider) global.web3 = new Web3(remoteProvider)
} }
function setupControllerConnection(stream, cb){ function setupControllerConnection (stream, cb) {
var eventEmitter = new EventEmitter() var eventEmitter = new EventEmitter()
var background = Dnode({ var background = Dnode({
sendUpdate: function(state){ sendUpdate: function (state) {
eventEmitter.emit('update', state) eventEmitter.emit('update', state)
}, },
}) })
stream.pipe(background).pipe(stream) stream.pipe(background).pipe(stream)
background.once('remote', function(accountManager){ background.once('remote', function (accountManager) {
// setup push events // setup push events
accountManager.on = eventEmitter.on.bind(eventEmitter) accountManager.on = eventEmitter.on.bind(eventEmitter)
cb(null, accountManager) cb(null, accountManager)
}) })
} }
function getCurrentDomain(cb){ function getCurrentDomain (cb) {
chrome.tabs.query({active: true, currentWindow: true}, function(results){ chrome.tabs.query({active: true, currentWindow: true}, function (results) {
var activeTab = results[0] var activeTab = results[0]
var currentUrl = activeTab && activeTab.url var currentUrl = activeTab && activeTab.url
var currentDomain = url.parse(currentUrl).host var currentDomain = url.parse(currentUrl).host
@ -65,16 +65,15 @@ function getCurrentDomain(cb){
}) })
} }
function setupApp(err, opts){ function setupApp (err, opts) {
if (err) { if (err) {
alert(err.stack) alert(err.stack)
throw err throw err
return
} }
var container = document.getElementById('app-content') var container = document.getElementById('app-content')
var app = MetaMaskUi({ MetaMaskUi({
container: container, container: container,
accountManager: opts.accountManager, accountManager: opts.accountManager,
currentDomain: opts.currentDomain, currentDomain: opts.currentDomain,

@ -0,0 +1,3 @@
machine:
node:
version: 6.0.0

@ -9,6 +9,9 @@ var sourcemaps = require('gulp-sourcemaps')
var assign = require('lodash.assign') var assign = require('lodash.assign')
var livereload = require('gulp-livereload') var livereload = require('gulp-livereload')
var del = require('del') var del = require('del')
var eslint = require('gulp-eslint')
var fs = require('fs')
var path = require('path')
// browser reload // browser reload
@ -49,6 +52,25 @@ gulp.task('copy:watch', function(){
gulp.watch(['./app/{_locales,images}/*', './app/scripts/chromereload.js', './app/*.{html,json}'], gulp.series('copy')) gulp.watch(['./app/{_locales,images}/*', './app/scripts/chromereload.js', './app/*.{html,json}'], gulp.series('copy'))
}) })
// lint js
gulp.task('lint', function () {
// Ignoring node_modules, dist, and docs folders:
return gulp.src(['app/**/*.js', 'ui/**/*.js', '!node_modules/**', '!dist/**', '!docs/**', '!app/scripts/chromereload.js'])
.pipe(eslint(fs.readFileSync(path.join(__dirname, '.eslintrc'))))
// eslint.format() outputs the lint results to the console.
// Alternatively use eslint.formatEach() (see Docs).
.pipe(eslint.format())
// To have the process exit with an error code (1) on
// lint error, return the stream and pipe to failAfterError last.
.pipe(eslint.failAfterError())
});
/*
gulp.task('default', ['lint'], function () {
// This will only run if the lint task is successful...
});
*/
// build js // build js

@ -36,6 +36,7 @@
"eth-store": "^1.1.0", "eth-store": "^1.1.0",
"ethereumjs-tx": "^1.0.0", "ethereumjs-tx": "^1.0.0",
"ethereumjs-util": "^4.4.0", "ethereumjs-util": "^4.4.0",
"gulp-eslint": "^2.0.0",
"hat": "0.0.3", "hat": "0.0.3",
"identicon.js": "^1.2.1", "identicon.js": "^1.2.1",
"inject-css": "^0.1.1", "inject-css": "^0.1.1",
@ -68,6 +69,7 @@
"xtend": "^4.0.1" "xtend": "^4.0.1"
}, },
"devDependencies": { "devDependencies": {
"babel-eslint": "^6.0.5",
"babel-preset-es2015": "^6.6.0", "babel-preset-es2015": "^6.6.0",
"babel-register": "^6.7.2", "babel-register": "^6.7.2",
"babelify": "^7.2.0", "babelify": "^7.2.0",
@ -87,6 +89,7 @@
"jshint-stylish": "~0.1.5", "jshint-stylish": "~0.1.5",
"lodash.assign": "^4.0.6", "lodash.assign": "^4.0.6",
"mocha": "^2.4.5", "mocha": "^2.4.5",
"mocha-eslint": "^2.1.1",
"mocha-jsdom": "^1.1.0", "mocha-jsdom": "^1.1.0",
"mocha-sinon": "^1.1.5", "mocha-sinon": "^1.1.5",
"sinon": "^1.17.3", "sinon": "^1.17.3",

@ -0,0 +1,9 @@
// LINTING:
const lint = require('mocha-eslint');
const lintPaths = ['app/**/*.js', 'ui/**/*.js', '!node_modules/**', '!dist/**', '!docs/**', '!app/scripts/chromereload.js']
const lintOptions = {
strict: true,
}
lint(lintPaths, lintOptions)

@ -17,7 +17,7 @@ const EditableLabel = require('./components/editable-label')
module.exports = connect(mapStateToProps)(AccountDetailScreen) module.exports = connect(mapStateToProps)(AccountDetailScreen)
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
identities: state.metamask.identities, identities: state.metamask.identities,
accounts: state.metamask.accounts, accounts: state.metamask.accounts,
@ -31,17 +31,15 @@ function mapStateToProps(state) {
} }
inherits(AccountDetailScreen, Component) inherits(AccountDetailScreen, Component)
function AccountDetailScreen() { function AccountDetailScreen () {
Component.call(this) Component.call(this)
} }
AccountDetailScreen.prototype.render = function() { AccountDetailScreen.prototype.render = function () {
var props = this.props var props = this.props
var selected = props.address || Object.keys(props.accounts)[0] var selected = props.address || Object.keys(props.accounts)[0]
var identity = props.identities[selected] var identity = props.identities[selected]
var account = props.accounts[selected] var account = props.accounts[selected]
var accountDetail = props.accountDetail
var transactions = props.transactions
return ( return (
@ -88,7 +86,7 @@ AccountDetailScreen.prototype.render = function() {
style: { style: {
height: '62px', height: '62px',
paddingTop: '8px', paddingTop: '8px',
} },
}, [ }, [
h(EditableLabel, { h(EditableLabel, {
textValue: identity ? identity.name : '', textValue: identity ? identity.name : '',
@ -101,7 +99,7 @@ AccountDetailScreen.prototype.render = function() {
}, [ }, [
// What is shown when not editing + edit text: // What is shown when not editing + edit text:
h('label.editing-label',[h('.edit-text','edit')]), h('label.editing-label', [h('.edit-text', 'edit')]),
h('h2.font-medium.color-forest', {name: 'edit'}, identity && identity.name), h('h2.font-medium.color-forest', {name: 'edit'}, identity && identity.name),
]), ]),
]), ]),
@ -124,7 +122,7 @@ AccountDetailScreen.prototype.render = function() {
h('img.cursor-pointer.color-orange', { h('img.cursor-pointer.color-orange', {
src: 'images/copy.svg', src: 'images/copy.svg',
onClick: () => copyToClipboard(ethUtil.toChecksumAddress(selected)), onClick: () => copyToClipboard(ethUtil.toChecksumAddress(selected)),
style:{ style: {
margin: '0px 5px', margin: '0px 5px',
}, },
}), }),
@ -179,7 +177,7 @@ AccountDetailScreen.prototype.render = function() {
) )
} }
AccountDetailScreen.prototype.subview = function() { AccountDetailScreen.prototype.subview = function () {
var subview var subview
try { try {
subview = this.props.accountDetail.subview subview = this.props.accountDetail.subview
@ -198,7 +196,7 @@ AccountDetailScreen.prototype.subview = function() {
} }
} }
AccountDetailScreen.prototype.transactionList = function() { AccountDetailScreen.prototype.transactionList = function () {
const { transactions, unconfTxs, unconfMsgs, address, network } = this.props const { transactions, unconfTxs, unconfMsgs, address, network } = this.props
var txsToRender = transactions var txsToRender = transactions
@ -214,18 +212,18 @@ AccountDetailScreen.prototype.transactionList = function() {
network, network,
unconfTxs, unconfTxs,
unconfMsgs, unconfMsgs,
viewPendingTx:(txId) => { viewPendingTx: (txId) => {
this.props.dispatch(actions.viewPendingTx(txId)) this.props.dispatch(actions.viewPendingTx(txId))
} },
}) })
} }
AccountDetailScreen.prototype.navigateToAccounts = function(event){ AccountDetailScreen.prototype.navigateToAccounts = function (event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showAccountsPage()) this.props.dispatch(actions.showAccountsPage())
} }
AccountDetailScreen.prototype.requestAccountExport = function() { AccountDetailScreen.prototype.requestAccountExport = function () {
this.props.dispatch(actions.requestExportAccount()) this.props.dispatch(actions.requestExportAccount())
} }

@ -9,18 +9,15 @@ const Identicon = require('../components/identicon')
module.exports = NewComponent module.exports = NewComponent
inherits(NewComponent, Component) inherits(NewComponent, Component)
function NewComponent() { function NewComponent () {
Component.call(this) Component.call(this)
} }
NewComponent.prototype.render = function() { NewComponent.prototype.render = function () {
const identity = this.props.identity const identity = this.props.identity
var mayBeFauceting = identity.mayBeFauceting
var isSelected = this.props.selectedAddress === identity.address var isSelected = this.props.selectedAddress === identity.address
var account = this.props.accounts[identity.address] var account = this.props.accounts[identity.address]
var isFauceting = mayBeFauceting && account.balance === '0x0'
const selectedClass = isSelected ? '.selected' : '' const selectedClass = isSelected ? '.selected' : ''
return ( return (
@ -35,7 +32,7 @@ NewComponent.prototype.render = function() {
h('.identicon-wrapper.flex-column.flex-center.select-none', [ h('.identicon-wrapper.flex-column.flex-center.select-none', [
this.pendingOrNot(), this.pendingOrNot(),
h(Identicon, { h(Identicon, {
address: identity.address address: identity.address,
}), }),
]), ]),
@ -70,16 +67,19 @@ NewComponent.prototype.render = function() {
event.preventDefault() event.preventDefault()
copyToClipboard(ethUtil.toChecksumAddress(identity.address)) copyToClipboard(ethUtil.toChecksumAddress(identity.address))
}, },
<<<<<<< HEAD
style:{ style:{
margin: '0px 5px', margin: '0px 5px',
}, },
=======
>>>>>>> master
}), }),
]), ]),
]) ])
) )
} }
NewComponent.prototype.pendingOrNot = function() { NewComponent.prototype.pendingOrNot = function () {
const pending = this.props.pending const pending = this.props.pending
if (pending.length === 0) return null if (pending.length === 0) return null
return h('.pending-dot', pending.length) return h('.pending-dot', pending.length)

@ -2,7 +2,6 @@ const inherits = require('util').inherits
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const extend = require('xtend')
const actions = require('../actions') const actions = require('../actions')
const valuesFor = require('../util').valuesFor const valuesFor = require('../util').valuesFor
const findDOMNode = require('react-dom').findDOMNode const findDOMNode = require('react-dom').findDOMNode
@ -10,8 +9,7 @@ const AccountPanel = require('./account-panel')
module.exports = connect(mapStateToProps)(AccountsScreen) module.exports = connect(mapStateToProps)(AccountsScreen)
function mapStateToProps (state) {
function mapStateToProps(state) {
const pendingTxs = valuesFor(state.metamask.unconfTxs) const pendingTxs = valuesFor(state.metamask.unconfTxs)
const pendingMsgs = valuesFor(state.metamask.unconfMsgs) const pendingMsgs = valuesFor(state.metamask.unconfMsgs)
const pending = pendingTxs.concat(pendingMsgs) const pending = pendingTxs.concat(pendingMsgs)
@ -28,12 +26,11 @@ function mapStateToProps(state) {
} }
inherits(AccountsScreen, Component) inherits(AccountsScreen, Component)
function AccountsScreen() { function AccountsScreen () {
Component.call(this) Component.call(this)
} }
AccountsScreen.prototype.render = function () {
AccountsScreen.prototype.render = function() {
var state = this.props var state = this.props
var identityList = valuesFor(state.identities) var identityList = valuesFor(state.identities)
var unconfTxList = valuesFor(state.unconfTxs) var unconfTxList = valuesFor(state.unconfTxs)
@ -63,7 +60,7 @@ AccountsScreen.prototype.render = function() {
height: '418px', height: '418px',
overflowY: 'auto', overflowY: 'auto',
overflowX: 'hidden', overflowX: 'hidden',
} },
}, },
[ [
identityList.map((identity) => { identityList.map((identity) => {
@ -90,7 +87,7 @@ AccountsScreen.prototype.render = function() {
h('hr.horizontal-line', {key: 'horizontal-line1'}), h('hr.horizontal-line', {key: 'horizontal-line1'}),
h('div.footer.hover-white.pointer', { h('div.footer.hover-white.pointer', {
key: 'reveal-account-bar', key: 'reveal-account-bar',
onClick:() => { onClick: () => {
actions.revealAccount() actions.revealAccount()
}, },
style: { style: {
@ -100,7 +97,7 @@ AccountsScreen.prototype.render = function() {
paddint: '10px', paddint: '10px',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
} },
}, [ }, [
h('i.fa.fa-plus.fa-lg', {key: ''}), h('i.fa.fa-plus.fa-lg', {key: ''}),
]), ]),
@ -123,7 +120,7 @@ AccountsScreen.prototype.render = function() {
} }
// If a new account was revealed, scroll to the bottom // If a new account was revealed, scroll to the bottom
AccountsScreen.prototype.componentDidUpdate = function(){ AccountsScreen.prototype.componentDidUpdate = function () {
const scrollToBottom = this.props.scrollToBottom const scrollToBottom = this.props.scrollToBottom
if (scrollToBottom) { if (scrollToBottom) {
@ -133,27 +130,27 @@ AccountsScreen.prototype.componentDidUpdate = function(){
} }
} }
AccountsScreen.prototype.navigateToConfTx = function(){ AccountsScreen.prototype.navigateToConfTx = function () {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showConfTxPage()) this.props.dispatch(actions.showConfTxPage())
} }
AccountsScreen.prototype.onSelect = function(address, event){ AccountsScreen.prototype.onSelect = function (address, event) {
event.stopPropagation() event.stopPropagation()
// if already selected, deselect // if already selected, deselect
if (this.props.selectedAddress === address) address = null if (this.props.selectedAddress === address) address = null
this.props.dispatch(actions.setSelectedAddress(address)) this.props.dispatch(actions.setSelectedAddress(address))
} }
AccountsScreen.prototype.onShowDetail = function(address, event){ AccountsScreen.prototype.onShowDetail = function (address, event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showAccountDetail(address)) this.props.dispatch(actions.showAccountDetail(address))
} }
AccountsScreen.prototype.onRevealAccount = function() { AccountsScreen.prototype.onRevealAccount = function () {
this.props.dispatch(actions.revealAccount()) this.props.dispatch(actions.revealAccount())
} }
AccountsScreen.prototype.goHome = function() { AccountsScreen.prototype.goHome = function () {
this.props.dispatch(actions.goHome()) this.props.dispatch(actions.goHome())
} }

@ -114,11 +114,11 @@ var actions = {
module.exports = actions module.exports = actions
var _accountManager = null var _accountManager = null
function _setAccountManager(accountManager){ function _setAccountManager (accountManager) {
_accountManager = accountManager _accountManager = accountManager
} }
function goHome() { function goHome () {
return { return {
type: actions.GO_HOME, type: actions.GO_HOME,
} }
@ -126,28 +126,22 @@ function goHome() {
// menu state // menu state
function toggleMenu() { function toggleMenu () {
return { return {
type: actions.TOGGLE_MENU, type: actions.TOGGLE_MENU,
} }
} }
function closeMenu() { function closeMenu () {
return { return {
type: actions.SET_MENU_STATE, type: actions.SET_MENU_STATE,
value: false, value: false,
} }
} }
function getNetworkStatus(){
return {
type: actions.getNetworkStatus,
}
}
// async actions // async actions
function tryUnlockMetamask(password) { function tryUnlockMetamask (password) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.unlockInProgress()) dispatch(actions.unlockInProgress())
_accountManager.submitPassword(password, (err, selectedAccount) => { _accountManager.submitPassword(password, (err, selectedAccount) => {
@ -160,22 +154,25 @@ function tryUnlockMetamask(password) {
} }
} }
function createNewVault(password, entropy) { function createNewVault (password, entropy) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.createNewVaultInProgress()) dispatch(actions.createNewVaultInProgress())
_accountManager.createNewVault(password, entropy, (err, result) => { _accountManager.createNewVault(password, entropy, (err, result) => {
if (err) {
return dispatch(actions.showWarning(err.message))
}
dispatch(actions.showNewVaultSeed(result)) dispatch(actions.showNewVaultSeed(result))
}) })
} }
} }
function revealSeedConfirmation() { function revealSeedConfirmation () {
return { return {
type: this.REVEAL_SEED_CONFIRMATION, type: this.REVEAL_SEED_CONFIRMATION,
} }
} }
function requestRevealSeed(password) { function requestRevealSeed (password) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
_accountManager.tryPassword(password, (err, seed) => { _accountManager.tryPassword(password, (err, seed) => {
@ -189,7 +186,7 @@ function requestRevealSeed(password) {
} }
} }
function recoverFromSeed(password, seed) { function recoverFromSeed (password, seed) {
return (dispatch) => { return (dispatch) => {
// dispatch(actions.createNewVaultInProgress()) // dispatch(actions.createNewVaultInProgress())
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
@ -203,19 +200,19 @@ function recoverFromSeed(password, seed) {
} }
} }
function showInfoPage() { function showInfoPage () {
return { return {
type: actions.SHOW_INFO_PAGE, type: actions.SHOW_INFO_PAGE,
} }
} }
function setSelectedAddress(address) { function setSelectedAddress (address) {
return (dispatch) => { return (dispatch) => {
_accountManager.setSelectedAddress(address) _accountManager.setSelectedAddress(address)
} }
} }
function revealAccount() { function revealAccount () {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
_accountManager.revealAccount((err) => { _accountManager.revealAccount((err) => {
@ -228,7 +225,7 @@ function revealAccount() {
} }
} }
function signMsg(msgData) { function signMsg (msgData) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
@ -241,7 +238,7 @@ function signMsg(msgData) {
} }
} }
function signTx(txData) { function signTx (txData) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
@ -255,7 +252,7 @@ function signTx(txData) {
} }
} }
function sendTx(txData) { function sendTx (txData) {
return (dispatch) => { return (dispatch) => {
_accountManager.approveTransaction(txData.id, (err) => { _accountManager.approveTransaction(txData.id, (err) => {
if (err) { if (err) {
@ -268,26 +265,26 @@ function sendTx(txData) {
} }
} }
function completedTx(id) { function completedTx (id) {
return { return {
type: actions.COMPLETED_TX, type: actions.COMPLETED_TX,
id, id,
} }
} }
function txError(err) { function txError (err) {
return { return {
type: actions.TRANSACTION_ERROR, type: actions.TRANSACTION_ERROR,
message: err.message, message: err.message,
} }
} }
function cancelMsg(msgData){ function cancelMsg (msgData) {
_accountManager.cancelMessage(msgData.id) _accountManager.cancelMessage(msgData.id)
return actions.completedTx(msgData.id) return actions.completedTx(msgData.id)
} }
function cancelTx(txData){ function cancelTx (txData) {
_accountManager.cancelTransaction(txData.id) _accountManager.cancelTransaction(txData.id)
return actions.completedTx(txData.id) return actions.completedTx(txData.id)
} }
@ -296,29 +293,32 @@ function cancelTx(txData){
// initialize screen // initialize screen
// //
function showCreateVault () {
function showCreateVault() {
return { return {
type: actions.SHOW_CREATE_VAULT, type: actions.SHOW_CREATE_VAULT,
} }
} }
function showRestoreVault() { function showRestoreVault () {
return { return {
type: actions.SHOW_RESTORE_VAULT, type: actions.SHOW_RESTORE_VAULT,
} }
} }
function showInitializeMenu() { function showInitializeMenu () {
return { return {
type: actions.SHOW_INIT_MENU, type: actions.SHOW_INIT_MENU,
} }
} }
function agreeToDisclaimer() { function agreeToDisclaimer () {
return (dispatch) => { return (dispatch) => {
dispatch(this.showLoadingIndication()) dispatch(this.showLoadingIndication())
_accountManager.agreeToDisclaimer((err) => { _accountManager.agreeToDisclaimer((err) => {
if (err) {
return dispatch(actions.showWarning(err.message))
}
dispatch(this.hideLoadingIndication()) dispatch(this.hideLoadingIndication())
dispatch({ dispatch({
type: this.AGREE_TO_DISCLAIMER, type: this.AGREE_TO_DISCLAIMER,
@ -327,13 +327,13 @@ function agreeToDisclaimer() {
} }
} }
function createNewVaultInProgress() { function createNewVaultInProgress () {
return { return {
type: actions.CREATE_NEW_VAULT_IN_PROGRESS, type: actions.CREATE_NEW_VAULT_IN_PROGRESS,
} }
} }
function showNewVaultSeed(seed) { function showNewVaultSeed (seed) {
return { return {
type: actions.SHOW_NEW_VAULT_SEED, type: actions.SHOW_NEW_VAULT_SEED,
value: seed, value: seed,
@ -344,48 +344,56 @@ function showNewVaultSeed(seed) {
// unlock screen // unlock screen
// //
function unlockInProgress() { function unlockInProgress () {
return { return {
type: actions.UNLOCK_IN_PROGRESS, type: actions.UNLOCK_IN_PROGRESS,
} }
} }
function unlockFailed() { function unlockFailed () {
return { return {
type: actions.UNLOCK_FAILED, type: actions.UNLOCK_FAILED,
} }
} }
function unlockMetamask(account) { function unlockMetamask (account) {
return { return {
type: actions.UNLOCK_METAMASK, type: actions.UNLOCK_METAMASK,
value: account, value: account,
} }
} }
function updateMetamaskState(newState) { function updateMetamaskState (newState) {
return { return {
type: actions.UPDATE_METAMASK_STATE, type: actions.UPDATE_METAMASK_STATE,
value: newState, value: newState,
} }
} }
function lockMetamask() { function lockMetamask () {
return (dispatch) => { return (dispatch) => {
_accountManager.setLocked((err) => { _accountManager.setLocked((err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.showWarning(err.message))
}
dispatch({ dispatch({
type: actions.LOCK_METAMASK, type: actions.LOCK_METAMASK,
}) })
dispatch(actions.hideLoadingIndication())
}) })
} }
} }
function showAccountDetail(address) { function showAccountDetail (address) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
_accountManager.setSelectedAddress(address, (err, address) => { _accountManager.setSelectedAddress(address, (err, address) => {
dispatch(actions.hideLoadingIndication()) dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.showWarning(err.message))
}
dispatch({ dispatch({
type: actions.SHOW_ACCOUNT_DETAIL, type: actions.SHOW_ACCOUNT_DETAIL,
value: address, value: address,
@ -394,61 +402,66 @@ function showAccountDetail(address) {
} }
} }
function backToAccountDetail(address) { function backToAccountDetail (address) {
return { return {
type: actions.BACK_TO_ACCOUNT_DETAIL, type: actions.BACK_TO_ACCOUNT_DETAIL,
value: address, value: address,
} }
} }
function clearSeedWordCache(account) { function clearSeedWordCache (account) {
return { return {
type: actions.CLEAR_SEED_WORD_CACHE, type: actions.CLEAR_SEED_WORD_CACHE,
value: account, value: account,
} }
} }
function confirmSeedWords() { function confirmSeedWords () {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
_accountManager.clearSeedWordCache((err, account) => { _accountManager.clearSeedWordCache((err, account) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.showWarning(err.message))
}
console.log('Seed word cache cleared. ' + account) console.log('Seed word cache cleared. ' + account)
dispatch(actions.showAccountDetail(account)) dispatch(actions.showAccountDetail(account))
}) })
} }
} }
function showAccountsPage() { function showAccountsPage () {
return { return {
type: actions.SHOW_ACCOUNTS_PAGE, type: actions.SHOW_ACCOUNTS_PAGE,
} }
} }
function showConfTxPage() { function showConfTxPage () {
return { return {
type: actions.SHOW_CONF_TX_PAGE, type: actions.SHOW_CONF_TX_PAGE,
} }
} }
function nextTx() { function nextTx () {
return { return {
type: actions.NEXT_TX, type: actions.NEXT_TX,
} }
} }
function viewPendingTx(txId) { function viewPendingTx (txId) {
return { return {
type: actions.VIEW_PENDING_TX, type: actions.VIEW_PENDING_TX,
value: txId, value: txId,
} }
} }
function previousTx() { function previousTx () {
return { return {
type: actions.PREVIOUS_TX, type: actions.PREVIOUS_TX,
} }
} }
function showConfigPage(transitionForward = true) { function showConfigPage (transitionForward = true) {
return { return {
type: actions.SHOW_CONFIG_PAGE, type: actions.SHOW_CONFIG_PAGE,
value: transitionForward, value: transitionForward,
@ -459,7 +472,7 @@ function showConfigPage(transitionForward = true) {
// config // config
// //
function setRpcTarget(newRpc) { function setRpcTarget (newRpc) {
_accountManager.setRpcTarget(newRpc) _accountManager.setRpcTarget(newRpc)
return { return {
type: actions.SET_RPC_TARGET, type: actions.SET_RPC_TARGET,
@ -467,7 +480,7 @@ function setRpcTarget(newRpc) {
} }
} }
function setProviderType(type) { function setProviderType (type) {
_accountManager.setProviderType(type) _accountManager.setProviderType(type)
return { return {
type: actions.SET_PROVIDER_TYPE, type: actions.SET_PROVIDER_TYPE,
@ -475,51 +488,51 @@ function setProviderType(type) {
} }
} }
function useEtherscanProvider() { function useEtherscanProvider () {
_accountManager.useEtherscanProvider() _accountManager.useEtherscanProvider()
return { return {
type: actions.USE_ETHERSCAN_PROVIDER, type: actions.USE_ETHERSCAN_PROVIDER,
} }
} }
function showLoadingIndication() { function showLoadingIndication () {
return { return {
type: actions.SHOW_LOADING, type: actions.SHOW_LOADING,
} }
} }
function hideLoadingIndication() { function hideLoadingIndication () {
return { return {
type: actions.HIDE_LOADING, type: actions.HIDE_LOADING,
} }
} }
function displayWarning(text) { function displayWarning (text) {
return { return {
type: actions.DISPLAY_WARNING, type: actions.DISPLAY_WARNING,
value: text, value: text,
} }
} }
function hideWarning() { function hideWarning () {
return { return {
type: actions.HIDE_WARNING, type: actions.HIDE_WARNING,
} }
} }
function requestExportAccount() { function requestExportAccount () {
return { return {
type: actions.REQUEST_ACCOUNT_EXPORT, type: actions.REQUEST_ACCOUNT_EXPORT,
} }
} }
function exportAccount(address) { function exportAccount (address) {
var self = this var self = this
return function(dispatch) { return function (dispatch) {
dispatch(self.showLoadingIndication()) dispatch(self.showLoadingIndication())
_accountManager.exportAccount(address, function(err, result) { _accountManager.exportAccount(address, function (err, result) {
dispatch(self.hideLoadingIndication()) dispatch(self.hideLoadingIndication())
if (err) { if (err) {
@ -532,14 +545,14 @@ function exportAccount(address) {
} }
} }
function showPrivateKey(key) { function showPrivateKey (key) {
return { return {
type: actions.SHOW_PRIVATE_KEY, type: actions.SHOW_PRIVATE_KEY,
value: key, value: key,
} }
} }
function saveAccountLabel(account, label) { function saveAccountLabel (account, label) {
return (dispatch) => { return (dispatch) => {
dispatch(actions.showLoadingIndication()) dispatch(actions.showLoadingIndication())
_accountManager.saveAccountLabel(account, label, (err) => { _accountManager.saveAccountLabel(account, label, (err) => {
@ -555,7 +568,7 @@ function saveAccountLabel(account, label) {
} }
} }
function showSendPage() { function showSendPage () {
return { return {
type: actions.SHOW_SEND_PAGE, type: actions.SHOW_SEND_PAGE,
} }

@ -1,10 +1,7 @@
const inherits = require('util').inherits const inherits = require('util').inherits
const React = require('react')
const Component = require('react').Component const Component = require('react').Component
const PropTypes = require('react').PropTypes
const connect = require('react-redux').connect const connect = require('react-redux').connect
const h = require('react-hyperscript') const h = require('react-hyperscript')
const extend = require('xtend')
const actions = require('./actions') const actions = require('./actions')
const ReactCSSTransitionGroup = require('react-addons-css-transition-group') const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
// init // init
@ -25,7 +22,6 @@ const ConfigScreen = require('./config')
const RevealSeedConfirmation = require('./recover-seed/confirmation') const RevealSeedConfirmation = require('./recover-seed/confirmation')
const InfoScreen = require('./info') const InfoScreen = require('./info')
const LoadingIndicator = require('./loading') const LoadingIndicator = require('./loading')
const txHelper = require('../lib/tx-helper')
const SandwichExpando = require('sandwich-expando') const SandwichExpando = require('sandwich-expando')
const MenuDroppo = require('menu-droppo') const MenuDroppo = require('menu-droppo')
const DropMenuItem = require('./components/drop-menu-item') const DropMenuItem = require('./components/drop-menu-item')
@ -33,11 +29,10 @@ const NetworkIndicator = require('./components/network')
module.exports = connect(mapStateToProps)(App) module.exports = connect(mapStateToProps)(App)
inherits(App, Component) inherits(App, Component)
function App() { Component.call(this) } function App () { Component.call(this) }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
// state from plugin // state from plugin
isConfirmed: state.metamask.isConfirmed, isConfirmed: state.metamask.isConfirmed,
@ -54,9 +49,8 @@ function mapStateToProps(state) {
} }
} }
App.prototype.render = function() { App.prototype.render = function () {
var props = this.props var props = this.props
var view = props.currentView.name
var transForward = props.transForward var transForward = props.transForward
return ( return (
@ -65,7 +59,7 @@ App.prototype.render = function() {
style: { style: {
// Windows was showing a vertical scroll bar: // Windows was showing a vertical scroll bar:
overflow: 'hidden', overflow: 'hidden',
} },
}, [ }, [
h(LoadingIndicator), h(LoadingIndicator),
@ -80,7 +74,7 @@ App.prototype.render = function() {
style: { style: {
height: '380px', height: '380px',
width: '360px', width: '360px',
} },
}, [ }, [
h(ReactCSSTransitionGroup, { h(ReactCSSTransitionGroup, {
className: 'css-transition-group', className: 'css-transition-group',
@ -95,7 +89,7 @@ App.prototype.render = function() {
) )
} }
App.prototype.renderAppBar = function(){ App.prototype.renderAppBar = function () {
const props = this.props const props = this.props
const state = this.state || {} const state = this.state || {}
const isNetworkMenuOpen = state.isNetworkMenuOpen || false const isNetworkMenuOpen = state.isNetworkMenuOpen || false
@ -117,11 +111,11 @@ App.prototype.renderAppBar = function(){
h(NetworkIndicator, { h(NetworkIndicator, {
network: this.props.network, network: this.props.network,
onClick:(event) => { onClick: (event) => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen }) this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
} },
}), }),
// metamask name // metamask name
@ -144,16 +138,14 @@ App.prototype.renderAppBar = function(){
) )
} }
App.prototype.renderNetworkDropdown = function() { App.prototype.renderNetworkDropdown = function () {
const props = this.props const props = this.props
const state = this.state || {} const state = this.state || {}
const isOpen = state.isNetworkMenuOpen const isOpen = state.isNetworkMenuOpen
const checked = h('i.fa.fa-check.fa-lg', { ariaHidden: true })
return h(MenuDroppo, { return h(MenuDroppo, {
isOpen, isOpen,
onClickOutside:(event) => { onClickOutside: (event) => {
this.setState({ isNetworkMenuOpen: !isOpen }) this.setState({ isNetworkMenuOpen: !isOpen })
}, },
style: { style: {
@ -173,28 +165,28 @@ App.prototype.renderNetworkDropdown = function() {
h(DropMenuItem, { h(DropMenuItem, {
label: 'Main Ethereum Network', label: 'Main Ethereum Network',
closeMenu:() => this.setState({ isNetworkMenuOpen: false }), closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action:() => props.dispatch(actions.setProviderType('mainnet')), action: () => props.dispatch(actions.setProviderType('mainnet')),
icon: h('.menu-icon.ether-icon'), icon: h('.menu-icon.ether-icon'),
}), }),
h(DropMenuItem, { h(DropMenuItem, {
label: 'Morden Test Network', label: 'Morden Test Network',
closeMenu:() => this.setState({ isNetworkMenuOpen: false }), closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action:() => props.dispatch(actions.setProviderType('testnet')), action: () => props.dispatch(actions.setProviderType('testnet')),
icon: h('.menu-icon.morden-icon'), icon: h('.menu-icon.morden-icon'),
}), }),
h(DropMenuItem, { h(DropMenuItem, {
label: 'Localhost 8545', label: 'Localhost 8545',
closeMenu:() => this.setState({ isNetworkMenuOpen: false }), closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action:() => props.dispatch(actions.setRpcTarget('http://localhost:8545')), action: () => props.dispatch(actions.setRpcTarget('http://localhost:8545')),
icon: h('i.fa.fa-question-circle.fa-lg', { ariaHidden: true }), icon: h('i.fa.fa-question-circle.fa-lg', { ariaHidden: true }),
}), }),
]) ])
} }
App.prototype.renderDropdown = function() { App.prototype.renderDropdown = function () {
const props = this.props const props = this.props
return h(MenuDroppo, { return h(MenuDroppo, {
isOpen: props.menuOpen, isOpen: props.menuOpen,
@ -218,28 +210,28 @@ App.prototype.renderDropdown = function() {
h(DropMenuItem, { h(DropMenuItem, {
label: 'Settings', label: 'Settings',
closeMenu:() => this.props.dispatch(actions.closeMenu()), closeMenu: () => this.props.dispatch(actions.closeMenu()),
action:() => this.props.dispatch(actions.showConfigPage()), action: () => this.props.dispatch(actions.showConfigPage()),
icon: h('i.fa.fa-gear.fa-lg', { ariaHidden: true }), icon: h('i.fa.fa-gear.fa-lg', { ariaHidden: true }),
}), }),
h(DropMenuItem, { h(DropMenuItem, {
label: 'Lock', label: 'Lock',
closeMenu:() => this.props.dispatch(actions.closeMenu()), closeMenu: () => this.props.dispatch(actions.closeMenu()),
action:() => this.props.dispatch(actions.lockMetamask()), action: () => this.props.dispatch(actions.lockMetamask()),
icon: h('i.fa.fa-lock.fa-lg', { ariaHidden: true }), icon: h('i.fa.fa-lock.fa-lg', { ariaHidden: true }),
}), }),
h(DropMenuItem, { h(DropMenuItem, {
label: 'Help', label: 'Help',
closeMenu:() => this.props.dispatch(actions.closeMenu()), closeMenu: () => this.props.dispatch(actions.closeMenu()),
action:() => this.props.dispatch(actions.showInfoPage()), action: () => this.props.dispatch(actions.showInfoPage()),
icon: h('i.fa.fa-question.fa-lg', { ariaHidden: true }), icon: h('i.fa.fa-question.fa-lg', { ariaHidden: true }),
}), }),
]) ])
} }
App.prototype.renderPrimary = function(){ App.prototype.renderPrimary = function () {
var props = this.props var props = this.props
if (!props.isConfirmed) { if (!props.isConfirmed) {
@ -252,7 +244,6 @@ App.prototype.renderPrimary = function(){
// show initialize screen // show initialize screen
if (!props.isInitialized) { if (!props.isInitialized) {
// show current view // show current view
switch (props.currentView.name) { switch (props.currentView.name) {
@ -308,7 +299,7 @@ App.prototype.renderPrimary = function(){
} }
} }
App.prototype.toggleMetamaskActive = function(){ App.prototype.toggleMetamaskActive = function () {
if (!this.props.isUnlocked) { if (!this.props.isUnlocked) {
// currently inactive: redirect to password box // currently inactive: redirect to password box
var passwordBox = document.querySelector('input[type=password]') var passwordBox = document.querySelector('input[type=password]')

@ -6,14 +6,13 @@ const actions = require('../actions')
module.exports = ExportAccountView module.exports = ExportAccountView
inherits(ExportAccountView, Component) inherits(ExportAccountView, Component)
function ExportAccountView() { function ExportAccountView () {
Component.call(this) Component.call(this)
} }
ExportAccountView.prototype.render = function() { ExportAccountView.prototype.render = function () {
console.log("EXPORT VIEW") console.log('EXPORT VIEW')
console.dir(this.props) console.dir(this.props)
var state = this.props var state = this.props
var accountDetail = state.accountDetail var accountDetail = state.accountDetail
@ -47,13 +46,13 @@ ExportAccountView.prototype.render = function() {
style: { style: {
position: 'relative', position: 'relative',
top: '1.5px', top: '1.5px',
} },
}), }),
h('button', { h('button', {
onClick: () => this.onExportKeyPress({ key: 'Enter', preventDefault: () => {} }), onClick: () => this.onExportKeyPress({ key: 'Enter', preventDefault: () => {} }),
}, 'Submit'), }, 'Submit'),
h('button', { h('button', {
onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)) onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
}, 'Cancel'), }, 'Cancel'),
]) ])
@ -72,18 +71,18 @@ ExportAccountView.prototype.render = function() {
webkitUserSelect: 'text', webkitUserSelect: 'text',
width: '100%', width: '100%',
}, },
onClick: function(event) { onClick: function (event) {
copyToClipboard(accountDetail.privateKey) copyToClipboard(accountDetail.privateKey)
} },
}, accountDetail.privateKey), }, accountDetail.privateKey),
h('button', { h('button', {
onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)) onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
}, 'Done'), }, 'Done'),
]) ])
} }
} }
ExportAccountView.prototype.onExportKeyPress = function(event) { ExportAccountView.prototype.onExportKeyPress = function (event) {
if (event.key !== 'Enter') return if (event.key !== 'Enter') return
event.preventDefault() event.preventDefault()
@ -96,6 +95,6 @@ ExportAccountView.prototype.onExportKeyPress = function(event) {
} }
} }
ExportAccountView.prototype.exportAccount = function(address) { ExportAccountView.prototype.exportAccount = function (address) {
this.props.dispatch(actions.exportAccount(address)) this.props.dispatch(actions.exportAccount(address))
} }

@ -1,30 +1,24 @@
const inherits = require('util').inherits const inherits = require('util').inherits
const ethUtil = require('ethereumjs-util')
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const formatBalance = require('../util').formatBalance const formatBalance = require('../util').formatBalance
const Identicon = require('./identicon')
const addressSummary = require('../util').addressSummary const addressSummary = require('../util').addressSummary
const Panel = require('./panel') const Panel = require('./panel')
module.exports = AccountPanel module.exports = AccountPanel
inherits(AccountPanel, Component) inherits(AccountPanel, Component)
function AccountPanel() { function AccountPanel () {
Component.call(this) Component.call(this)
} }
AccountPanel.prototype.render = function() { AccountPanel.prototype.render = function () {
var state = this.props var state = this.props
var identity = state.identity || {} var identity = state.identity || {}
var account = state.account || {} var account = state.account || {}
var isFauceting = state.isFauceting var isFauceting = state.isFauceting
var identicon = new Identicon(identity.address, 46).toString()
var identiconSrc = `data:image/png;base64,${identicon}`
var panelOpts = { var panelOpts = {
key: `accountPanel${identity.address}`, key: `accountPanel${identity.address}`,
onClick: (event) => { onClick: (event) => {
@ -40,21 +34,19 @@ AccountPanel.prototype.render = function() {
value: addressSummary(identity.address), value: addressSummary(identity.address),
}, },
balanceOrFaucetingIndication(account, isFauceting), balanceOrFaucetingIndication(account, isFauceting),
] ],
} }
return h(Panel, panelOpts, return h(Panel, panelOpts,
!state.onShowDetail ? null : h('.arrow-right.cursor-pointer', [ !state.onShowDetail ? null : h('.arrow-right.cursor-pointer', [
h('i.fa.fa-chevron-right.fa-lg'), h('i.fa.fa-chevron-right.fa-lg'),
])) ]))
} }
function balanceOrFaucetingIndication(account, isFauceting) { function balanceOrFaucetingIndication (account, isFauceting) {
// Temporarily deactivating isFauceting indication // Temporarily deactivating isFauceting indication
// because it shows fauceting for empty restored accounts. // because it shows fauceting for empty restored accounts.
if (/*isFauceting*/ false) { if (/* isFauceting*/ false) {
return { return {
key: 'Account is auto-funding.', key: 'Account is auto-funding.',
value: 'Please wait.', value: 'Please wait.',
@ -62,7 +54,7 @@ function balanceOrFaucetingIndication(account, isFauceting) {
} else { } else {
return { return {
key: 'BALANCE', key: 'BALANCE',
value: formatBalance(account.balance) value: formatBalance(account.balance),
} }
} }
} }

@ -4,16 +4,14 @@ const inherits = require('util').inherits
module.exports = DropMenuItem module.exports = DropMenuItem
inherits(DropMenuItem, Component) inherits(DropMenuItem, Component)
function DropMenuItem() { function DropMenuItem () {
Component.call(this) Component.call(this)
} }
DropMenuItem.prototype.render = function() { DropMenuItem.prototype.render = function () {
return h('li.drop-menu-item', { return h('li.drop-menu-item', {
onClick:() => { onClick: () => {
this.props.closeMenu() this.props.closeMenu()
this.props.action() this.props.action()
}, },

@ -5,46 +5,43 @@ const findDOMNode = require('react-dom').findDOMNode
module.exports = EditableLabel module.exports = EditableLabel
inherits(EditableLabel, Component) inherits(EditableLabel, Component)
function EditableLabel() { function EditableLabel () {
Component.call(this) Component.call(this)
} }
EditableLabel.prototype.render = function() { EditableLabel.prototype.render = function () {
const props = this.props const props = this.props
let state = this.state const state = this.state
if (state && state.isEditingLabel) { if (state && state.isEditingLabel) {
return h('div.editable-label', [ return h('div.editable-label', [
h('input.sizing-input', { h('input.sizing-input', {
defaultValue: props.textValue, defaultValue: props.textValue,
onKeyPress:(event) => { onKeyPress: (event) => {
this.saveIfEnter(event) this.saveIfEnter(event)
}, },
}), }),
h('button.editable-button', { h('button.editable-button', {
onClick:() => this.saveText(), onClick: () => this.saveText(),
}, 'Save') }, 'Save'),
]) ])
} else { } else {
return h('div.name-label', { return h('div.name-label', {
onClick:(event) => { onClick: (event) => {
this.setState({ isEditingLabel: true }) this.setState({ isEditingLabel: true })
}, },
}, this.props.children) }, this.props.children)
} }
} }
EditableLabel.prototype.saveIfEnter = function(event) { EditableLabel.prototype.saveIfEnter = function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
this.saveText() this.saveText()
} }
} }
EditableLabel.prototype.saveText = function() { EditableLabel.prototype.saveText = function () {
var container = findDOMNode(this) var container = findDOMNode(this)
var text = container.querySelector('.editable-label input').value var text = container.querySelector('.editable-label input').value
this.props.saveText(text) this.props.saveText(text)

@ -1,17 +1,16 @@
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const inherits = require('util').inherits const inherits = require('util').inherits
const parseBalance = require('../util').parseBalance
const formatBalance = require('../util').formatBalance const formatBalance = require('../util').formatBalance
module.exports = EthBalanceComponent module.exports = EthBalanceComponent
inherits(EthBalanceComponent, Component) inherits(EthBalanceComponent, Component)
function EthBalanceComponent() { function EthBalanceComponent () {
Component.call(this) Component.call(this)
} }
EthBalanceComponent.prototype.render = function() { EthBalanceComponent.prototype.render = function () {
var state = this.props var state = this.props
var style = state.style var style = state.style
var value = formatBalance(state.value) var value = formatBalance(state.value)

@ -9,13 +9,13 @@ const iconFactory = iconFactoryGen(jazzicon)
module.exports = IdenticonComponent module.exports = IdenticonComponent
inherits(IdenticonComponent, Component) inherits(IdenticonComponent, Component)
function IdenticonComponent() { function IdenticonComponent () {
Component.call(this) Component.call(this)
this.defaultDiameter = 46 this.defaultDiameter = 46
} }
IdenticonComponent.prototype.render = function() { IdenticonComponent.prototype.render = function () {
var state = this.props var state = this.props
var diameter = state.diameter || this.defaultDiameter var diameter = state.diameter || this.defaultDiameter
return ( return (
@ -32,7 +32,7 @@ IdenticonComponent.prototype.render = function() {
) )
} }
IdenticonComponent.prototype.componentDidMount = function(){ IdenticonComponent.prototype.componentDidMount = function () {
var state = this.props var state = this.props
var address = state.address var address = state.address

@ -2,14 +2,12 @@ const inherits = require('util').inherits
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const metamaskLogo = require('metamask-logo') const metamaskLogo = require('metamask-logo')
const getCaretCoordinates = require('textarea-caret')
const debounce = require('debounce') const debounce = require('debounce')
module.exports = Mascot module.exports = Mascot
inherits(Mascot, Component) inherits(Mascot, Component)
function Mascot() { function Mascot () {
Component.call(this) Component.call(this)
this.logo = metamaskLogo({ this.logo = metamaskLogo({
followMouse: true, followMouse: true,
@ -22,8 +20,7 @@ function Mascot() {
this.unfollowMouse = this.logo.setFollowMouse.bind(this.logo, false) this.unfollowMouse = this.logo.setFollowMouse.bind(this.logo, false)
} }
Mascot.prototype.render = function () {
Mascot.prototype.render = function() {
// this is a bit hacky // this is a bit hacky
// the event emitter is on `this.props` // the event emitter is on `this.props`
// and we dont get that until render // and we dont get that until render
@ -36,19 +33,19 @@ Mascot.prototype.render = function() {
) )
} }
Mascot.prototype.componentDidMount = function() { Mascot.prototype.componentDidMount = function () {
if (!this.logo) return if (!this.logo) return
var targetDivId = 'metamask-mascot-container' var targetDivId = 'metamask-mascot-container'
var container = document.getElementById(targetDivId) var container = document.getElementById(targetDivId)
container.appendChild(this.logo.canvas) container.appendChild(this.logo.canvas)
} }
Mascot.prototype.componentWillUnmount = function() { Mascot.prototype.componentWillUnmount = function () {
if (!this.logo) return if (!this.logo) return
this.logo.canvas.remove() this.logo.canvas.remove()
} }
Mascot.prototype.handleAnimationEvents = function(){ Mascot.prototype.handleAnimationEvents = function () {
if (!this.logo) return if (!this.logo) return
// only setup listeners once // only setup listeners once
if (this.animations) return if (this.animations) return
@ -57,7 +54,7 @@ Mascot.prototype.handleAnimationEvents = function(){
this.animations.on('setFollowMouse', this.logo.setFollowMouse.bind(this.logo)) this.animations.on('setFollowMouse', this.logo.setFollowMouse.bind(this.logo))
} }
Mascot.prototype.lookAt = function(target){ Mascot.prototype.lookAt = function (target) {
if (!this.logo) return if (!this.logo) return
this.unfollowMouse() this.unfollowMouse()
this.logo.lookAt(target) this.logo.lookAt(target)

@ -6,34 +6,33 @@ module.exports = Network
inherits(Network, Component) inherits(Network, Component)
function Network() { function Network () {
Component.call(this) Component.call(this)
} }
Network.prototype.render = function() { Network.prototype.render = function () {
const state = this.props const state = this.props
const networkNumber = state.network const networkNumber = state.network
let iconName, hoverText let iconName, hoverText
const imagePath = "/images/"
if (networkNumber == 'loading') { if (networkNumber === 'loading') {
return h('img', { return h('img', {
title: 'Attempting to connect to blockchain.', title: 'Attempting to connect to blockchain.',
onClick:(event) => this.props.onClick(event), onClick: (event) => this.props.onClick(event),
style: { style: {
width: '27px', width: '27px',
marginRight: '-27px' marginRight: '-27px',
}, },
src: 'images/loading.svg', src: 'images/loading.svg',
}) })
} else if (parseInt(networkNumber) == 1) { } else if (parseInt(networkNumber) === 1) {
hoverText = 'Main Ethereum Network' hoverText = 'Main Ethereum Network'
iconName = 'ethereum-network' iconName = 'ethereum-network'
}else if (parseInt(networkNumber) == 2) { } else if (parseInt(networkNumber) === 2) {
hoverText = "Morden Test Network" hoverText = 'Morden Test Network'
iconName = 'morden-test-network' iconName = 'morden-test-network'
}else { } else {
hoverText = "Unknown Private Network" hoverText = 'Unknown Private Network'
iconName = 'unknown-private-network' iconName = 'unknown-private-network'
} }
return ( return (
@ -43,9 +42,9 @@ Network.prototype.render = function() {
marginLeft: '-3px', marginLeft: '-3px',
}, },
title: hoverText, title: hoverText,
onClick:(event) => this.props.onClick(event), onClick: (event) => this.props.onClick(event),
},[ }, [
function() { (function () {
switch (iconName) { switch (iconName) {
case 'ethereum-network': case 'ethereum-network':
return h('.menu-icon.ether-icon') return h('.menu-icon.ether-icon')
@ -60,7 +59,7 @@ Network.prototype.render = function() {
}, },
}) })
} }
}() })(),
]) ])
) )
} }

@ -1,23 +1,18 @@
const inherits = require('util').inherits const inherits = require('util').inherits
const ethUtil = require('ethereumjs-util')
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const Identicon = require('./identicon') const Identicon = require('./identicon')
module.exports = Panel module.exports = Panel
inherits(Panel, Component) inherits(Panel, Component)
function Panel() { function Panel () {
Component.call(this) Component.call(this)
} }
Panel.prototype.render = function() { Panel.prototype.render = function () {
var state = this.props var state = this.props
var identity = state.identity || {}
var account = state.account || {}
var isFauceting = state.isFauceting
var style = { var style = {
flex: '1 0 auto', flex: '1 0 auto',
} }

@ -3,20 +3,16 @@ const h = require('react-hyperscript')
const inherits = require('util').inherits const inherits = require('util').inherits
const AccountPanel = require('./account-panel') const AccountPanel = require('./account-panel')
const addressSummary = require('../util').addressSummary
const readableDate = require('../util').readableDate const readableDate = require('../util').readableDate
const formatBalance = require('../util').formatBalance
const dataSize = require('../util').dataSize
module.exports = PendingMsg module.exports = PendingMsg
inherits(PendingMsg, Component) inherits(PendingMsg, Component)
function PendingMsg() { function PendingMsg () {
Component.call(this) Component.call(this)
} }
PendingMsg.prototype.render = function() { PendingMsg.prototype.render = function () {
var state = this.props var state = this.props
var msgData = state.txData var msgData = state.txData
@ -34,7 +30,7 @@ PendingMsg.prototype.render = function() {
style: { style: {
fontWeight: 'bold', fontWeight: 'bold',
textAlign: 'center', textAlign: 'center',
} },
}, 'Sign Message'), }, 'Sign Message'),
// account that will sign // account that will sign

@ -6,17 +6,15 @@ const AccountPanel = require('./account-panel')
const addressSummary = require('../util').addressSummary const addressSummary = require('../util').addressSummary
const readableDate = require('../util').readableDate const readableDate = require('../util').readableDate
const formatBalance = require('../util').formatBalance const formatBalance = require('../util').formatBalance
const dataSize = require('../util').dataSize
module.exports = PendingTx module.exports = PendingTx
inherits(PendingTx, Component) inherits(PendingTx, Component)
function PendingTx() { function PendingTx () {
Component.call(this) Component.call(this)
} }
PendingTx.prototype.render = function() { PendingTx.prototype.render = function () {
var state = this.props var state = this.props
var txData = state.txData var txData = state.txData
@ -34,7 +32,7 @@ PendingTx.prototype.render = function() {
style: { style: {
fontWeight: 'bold', fontWeight: 'bold',
textAlign: 'center', textAlign: 'center',
} },
}, 'Submit Transaction'), }, 'Submit Transaction'),
// account that will sign // account that will sign

@ -4,16 +4,15 @@ const inherits = require('util').inherits
module.exports = NewComponent module.exports = NewComponent
inherits(NewComponent, Component) inherits(NewComponent, Component)
function NewComponent() { function NewComponent () {
Component.call(this) Component.call(this)
} }
NewComponent.prototype.render = function() { NewComponent.prototype.render = function () {
var state = this.props const props = this.props
return ( return (
h('span', 'Placeholder component') h('span', props.message)
) )
} }

@ -6,20 +6,19 @@ const Identicon = require('./identicon')
module.exports = TransactionIcon module.exports = TransactionIcon
inherits(TransactionIcon, Component) inherits(TransactionIcon, Component)
function TransactionIcon() { function TransactionIcon () {
Component.call(this) Component.call(this)
} }
TransactionIcon.prototype.render = function() { TransactionIcon.prototype.render = function () {
const { transaction, txParams, isTx, isMsg } = this.props const { transaction, txParams, isMsg } = this.props
if (transaction.status === 'rejected') { if (transaction.status === 'rejected') {
return h('i.fa.fa-exclamation-triangle.fa-lg.error', { return h('i.fa.fa-exclamation-triangle.fa-lg.error', {
style: { style: {
width: '24px', width: '24px',
} },
}) })
} }
@ -27,7 +26,7 @@ TransactionIcon.prototype.render = function() {
return h('i.fa.fa-certificate.fa-lg', { return h('i.fa.fa-certificate.fa-lg', {
style: { style: {
width: '24px', width: '24px',
} },
}) })
} }
@ -40,7 +39,7 @@ TransactionIcon.prototype.render = function() {
return h('i.fa.fa-file-text-o.fa-lg', { return h('i.fa.fa-file-text-o.fa-lg', {
style: { style: {
width: '24px', width: '24px',
} },
}) })
} }
} }

@ -5,20 +5,18 @@ const inherits = require('util').inherits
const EtherBalance = require('./eth-balance') const EtherBalance = require('./eth-balance')
const addressSummary = require('../util').addressSummary const addressSummary = require('../util').addressSummary
const explorerLink = require('../../lib/explorer-link') const explorerLink = require('../../lib/explorer-link')
const formatBalance = require('../util').formatBalance
const vreme = new (require('vreme')) const vreme = new (require('vreme'))
const TransactionIcon = require('./transaction-list-item-icon') const TransactionIcon = require('./transaction-list-item-icon')
module.exports = TransactionListItem module.exports = TransactionListItem
inherits(TransactionListItem, Component) inherits(TransactionListItem, Component)
function TransactionListItem() { function TransactionListItem () {
Component.call(this) Component.call(this)
} }
TransactionListItem.prototype.render = function() { TransactionListItem.prototype.render = function () {
const { transaction, i, network } = this.props const { transaction, i, network } = this.props
var date = formatDate(transaction.time) var date = formatDate(transaction.time)
@ -59,8 +57,8 @@ TransactionListItem.prototype.render = function() {
// large identicon // large identicon
h('.identicon-wrapper.flex-column.flex-center.select-none', [ h('.identicon-wrapper.flex-column.flex-center.select-none', [
transaction.status === 'unconfirmed' ? h('.red-dot', ' ') : transaction.status === 'unconfirmed' ? h('.red-dot', ' ')
h(TransactionIcon, { txParams, transaction, isTx, isMsg }), : h(TransactionIcon, { txParams, transaction, isTx, isMsg }),
]), ]),
h('.flex-column', [ h('.flex-column', [
@ -76,18 +74,18 @@ TransactionListItem.prototype.render = function() {
) )
} }
function domainField(txParams) { function domainField (txParams) {
return h('div', { return h('div', {
style: { style: {
fontSize: 'small', fontSize: 'small',
color: '#ABA9AA', color: '#ABA9AA',
}, },
},[ }, [
txParams.origin, txParams.origin,
]) ])
} }
function recipientField(txParams, transaction, isTx, isMsg) { function recipientField (txParams, transaction, isTx, isMsg) {
let message let message
if (isMsg) { if (isMsg) {
@ -103,23 +101,17 @@ function recipientField(txParams, transaction, isTx, isMsg) {
fontSize: 'small', fontSize: 'small',
color: '#ABA9AA', color: '#ABA9AA',
}, },
},[ }, [
message, message,
failIfFailed(transaction), failIfFailed(transaction),
]) ])
}
TransactionListItem.prototype.renderMessage = function() {
const { transaction, i, network } = this.props
return h('div', 'wowie, thats a message')
} }
function formatDate(date){ function formatDate (date) {
return vreme.format(new Date(date), 'March 16 2014 14:30') return vreme.format(new Date(date), 'March 16 2014 14:30')
} }
function failIfFailed(transaction) { function failIfFailed (transaction) {
if (transaction.status === 'rejected') { if (transaction.status === 'rejected') {
return h('span.error', ' (Rejected)') return h('span.error', ' (Rejected)')
} }

@ -8,12 +8,12 @@ module.exports = TransactionList
inherits(TransactionList, Component) inherits(TransactionList, Component)
function TransactionList() { function TransactionList () {
Component.call(this) Component.call(this)
} }
TransactionList.prototype.render = function() { TransactionList.prototype.render = function () {
const { txsToRender, network, unconfTxs, unconfMsgs } = this.props const { txsToRender, network, unconfMsgs } = this.props
const transactions = txsToRender.concat(unconfMsgs) const transactions = txsToRender.concat(unconfMsgs)
.sort((a, b) => b.time - a.time) .sort((a, b) => b.time - a.time)
@ -49,22 +49,21 @@ TransactionList.prototype.render = function() {
}, },
}, ( }, (
transactions.length ? transactions.length
transactions.map((transaction, i) => { ? transactions.map((transaction, i) => {
return h(TransactionListItem, { return h(TransactionListItem, {
transaction, i, network, transaction, i, network,
showTx:(txId) => { showTx: (txId) => {
this.props.viewPendingTx(txId) this.props.viewPendingTx(txId)
}, },
}) })
}) })
: : [h('.flex-center', {
[h('.flex-center', {
style: { style: {
height: '100%', height: '100%',
}, },
}, 'No transaction history...')] }, 'No transaction history...')]
)) )),
]) ])
) )
} }

@ -3,10 +3,7 @@ const Component = require('react').Component
const ReactCSSTransitionGroup = require('react-addons-css-transition-group') const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const h = require('react-hyperscript') const h = require('react-hyperscript')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const copyToClipboard = require('copy-to-clipboard')
const actions = require('./actions') const actions = require('./actions')
const AccountPanel = require('./components/account-panel')
const valuesFor = require('./util').valuesFor
const txHelper = require('../lib/tx-helper') const txHelper = require('../lib/tx-helper')
const ConfirmTx = require('./components/pending-tx') const ConfirmTx = require('./components/pending-tx')
@ -14,7 +11,7 @@ const PendingMsg = require('./components/pending-msg')
module.exports = connect(mapStateToProps)(ConfirmTxScreen) module.exports = connect(mapStateToProps)(ConfirmTxScreen)
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
identities: state.metamask.identities, identities: state.metamask.identities,
accounts: state.metamask.accounts, accounts: state.metamask.accounts,
@ -27,12 +24,11 @@ function mapStateToProps(state) {
} }
inherits(ConfirmTxScreen, Component) inherits(ConfirmTxScreen, Component)
function ConfirmTxScreen() { function ConfirmTxScreen () {
Component.call(this) Component.call(this)
} }
ConfirmTxScreen.prototype.render = function () {
ConfirmTxScreen.prototype.render = function() {
var state = this.props var state = this.props
var unconfTxs = state.unconfTxs var unconfTxs = state.unconfTxs
@ -103,7 +99,6 @@ ConfirmTxScreen.prototype.render = function() {
} }
function currentTxView (opts) { function currentTxView (opts) {
if ('txParams' in opts.txData) { if ('txParams' in opts.txData) {
// This is a pending transaction // This is a pending transaction
return h(ConfirmTx, opts) return h(ConfirmTx, opts)
@ -113,34 +108,34 @@ function currentTxView (opts) {
} }
} }
ConfirmTxScreen.prototype.sendTransaction = function(txData, event){ ConfirmTxScreen.prototype.sendTransaction = function (txData, event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.sendTx(txData)) this.props.dispatch(actions.sendTx(txData))
} }
ConfirmTxScreen.prototype.cancelTransaction = function(txData, event){ ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.cancelTx(txData)) this.props.dispatch(actions.cancelTx(txData))
} }
ConfirmTxScreen.prototype.signMessage = function(msgData, event){ ConfirmTxScreen.prototype.signMessage = function (msgData, event) {
var params = msgData.msgParams var params = msgData.msgParams
params.metamaskId = msgData.id params.metamaskId = msgData.id
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.signMsg(params)) this.props.dispatch(actions.signMsg(params))
} }
ConfirmTxScreen.prototype.cancelMessage = function(msgData, event){ ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.cancelMsg(msgData)) this.props.dispatch(actions.cancelMsg(msgData))
} }
ConfirmTxScreen.prototype.goHome = function(event){ ConfirmTxScreen.prototype.goHome = function (event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.goHome()) this.props.dispatch(actions.goHome())
} }
function warningIfExists(warning) { function warningIfExists (warning) {
if (warning) { if (warning) {
return h('span.error', { style: { margin: 'auto' } }, warning) return h('span.error', { style: { margin: 'auto' } }, warning)
} }

@ -6,22 +6,19 @@ const actions = require('./actions')
module.exports = connect(mapStateToProps)(ConfigScreen) module.exports = connect(mapStateToProps)(ConfigScreen)
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
rpc: state.metamask.rpcTarget,
metamask: state.metamask, metamask: state.metamask,
} }
} }
inherits(ConfigScreen, Component) inherits(ConfigScreen, Component)
function ConfigScreen() { function ConfigScreen () {
Component.call(this) Component.call(this)
} }
ConfigScreen.prototype.render = function () {
ConfigScreen.prototype.render = function() {
var state = this.props var state = this.props
var rpc = state.rpc
var metamaskState = state.metamask var metamaskState = state.metamask
return ( return (
@ -32,7 +29,7 @@ ConfigScreen.prototype.render = function() {
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
onClick: (event) => { onClick: (event) => {
state.dispatch(actions.goHome()) state.dispatch(actions.goHome())
} },
}), }),
h('h2.page-subtitle', 'Configuration'), h('h2.page-subtitle', 'Configuration'),
]), ]),
@ -42,7 +39,7 @@ ConfigScreen.prototype.render = function() {
h('.flex-space-around', { h('.flex-space-around', {
style: { style: {
padding: '20px', padding: '20px',
} },
}, [ }, [
currentProviderDisplay(metamaskState), currentProviderDisplay(metamaskState),
@ -56,25 +53,25 @@ ConfigScreen.prototype.render = function() {
height: '30px', height: '30px',
margin: '8px', margin: '8px',
}, },
onKeyPress(event) { onKeyPress (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
var element = event.target var element = event.target
var newRpc = element.value var newRpc = element.value
state.dispatch(actions.setRpcTarget(newRpc)) state.dispatch(actions.setRpcTarget(newRpc))
} }
} },
}), }),
h('button', { h('button', {
style: { style: {
alignSelf: 'center', alignSelf: 'center',
}, },
onClick(event) { onClick (event) {
event.preventDefault() event.preventDefault()
var element = document.querySelector('input#new_rpc') var element = document.querySelector('input#new_rpc')
var newRpc = element.value var newRpc = element.value
state.dispatch(actions.setRpcTarget(newRpc)) state.dispatch(actions.setRpcTarget(newRpc))
} },
}, 'Save') }, 'Save'),
]), ]),
h('div', [ h('div', [
@ -82,10 +79,10 @@ ConfigScreen.prototype.render = function() {
style: { style: {
alignSelf: 'center', alignSelf: 'center',
}, },
onClick(event) { onClick (event) {
event.preventDefault() event.preventDefault()
state.dispatch(actions.setProviderType('mainnet')) state.dispatch(actions.setProviderType('mainnet'))
} },
}, 'Use Main Network'), }, 'Use Main Network'),
]), ]),
@ -94,10 +91,10 @@ ConfigScreen.prototype.render = function() {
style: { style: {
alignSelf: 'center', alignSelf: 'center',
}, },
onClick(event) { onClick (event) {
event.preventDefault() event.preventDefault()
state.dispatch(actions.setProviderType('testnet')) state.dispatch(actions.setProviderType('testnet'))
} },
}, 'Use Morden Test Network'), }, 'Use Morden Test Network'),
]), ]),
@ -106,10 +103,10 @@ ConfigScreen.prototype.render = function() {
style: { style: {
alignSelf: 'center', alignSelf: 'center',
}, },
onClick(event) { onClick (event) {
event.preventDefault() event.preventDefault()
state.dispatch(actions.setRpcTarget('http://localhost:8545/')) state.dispatch(actions.setRpcTarget('http://localhost:8545/'))
} },
}, 'Use http://localhost:8545'), }, 'Use http://localhost:8545'),
]), ]),
@ -118,17 +115,17 @@ ConfigScreen.prototype.render = function() {
h('div', { h('div', {
style: { style: {
marginTop: '20px', marginTop: '20px',
} },
}, [ }, [
h('button', { h('button', {
style: { style: {
alignSelf: 'center', alignSelf: 'center',
}, },
onClick(event) { onClick (event) {
event.preventDefault() event.preventDefault()
state.dispatch(actions.revealSeedConfirmation()) state.dispatch(actions.revealSeedConfirmation())
} },
}, 'Reveal Seed Words') }, 'Reveal Seed Words'),
]), ]),
]), ]),
@ -137,7 +134,7 @@ ConfigScreen.prototype.render = function() {
) )
} }
function currentProviderDisplay(metamaskState) { function currentProviderDisplay (metamaskState) {
var provider = metamaskState.provider var provider = metamaskState.provider
var title, value var title, value
@ -160,6 +157,6 @@ function currentProviderDisplay(metamaskState) {
return h('div', [ return h('div', [
h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, title), h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, title),
h('span', value) h('span', value),
]) ])
} }

@ -6,20 +6,19 @@ const actions = require('../actions')
module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen) module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen)
inherits(CreateVaultCompleteScreen, Component) inherits(CreateVaultCompleteScreen, Component)
function CreateVaultCompleteScreen() { function CreateVaultCompleteScreen () {
Component.call(this) Component.call(this)
} }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
seed: state.appState.currentView.seedWords, seed: state.appState.currentView.seedWords,
cachedSeed: state.metamask.seedWords, cachedSeed: state.metamask.seedWords,
} }
} }
CreateVaultCompleteScreen.prototype.render = function() { CreateVaultCompleteScreen.prototype.render = function () {
var state = this.props var state = this.props
var seed = state.seed || state.cachedSeed var seed = state.seed || state.cachedSeed
@ -50,7 +49,7 @@ CreateVaultCompleteScreen.prototype.render = function() {
style: { style: {
padding: '12px 20px 0px 20px', padding: '12px 20px 0px 20px',
textAlign: 'center', textAlign: 'center',
} },
}, 'These 12 words can restore all of your MetaMask accounts for this vault.\nSave them somewhere safe and secret.'), }, 'These 12 words can restore all of your MetaMask accounts for this vault.\nSave them somewhere safe and secret.'),
h('textarea.twelve-word-phrase', { h('textarea.twelve-word-phrase', {
@ -68,7 +67,7 @@ CreateVaultCompleteScreen.prototype.render = function() {
) )
} }
CreateVaultCompleteScreen.prototype.confirmSeedWords = function() { CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
this.props.dispatch(actions.confirmSeedWords()) this.props.dispatch(actions.confirmSeedWords())
} }

@ -7,19 +7,18 @@ const actions = require('../actions')
module.exports = connect(mapStateToProps)(CreateVaultScreen) module.exports = connect(mapStateToProps)(CreateVaultScreen)
inherits(CreateVaultScreen, Component) inherits(CreateVaultScreen, Component)
function CreateVaultScreen() { function CreateVaultScreen () {
Component.call(this) Component.call(this)
} }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
warning: state.appState.warning, warning: state.appState.warning,
} }
} }
CreateVaultScreen.prototype.render = function() { CreateVaultScreen.prototype.render = function () {
var state = this.props var state = this.props
return ( return (
@ -91,24 +90,24 @@ CreateVaultScreen.prototype.render = function() {
) )
} }
CreateVaultScreen.prototype.componentDidMount = function(){ CreateVaultScreen.prototype.componentDidMount = function () {
document.getElementById('password-box').focus() document.getElementById('password-box').focus()
} }
CreateVaultScreen.prototype.showInitializeMenu = function() { CreateVaultScreen.prototype.showInitializeMenu = function () {
this.props.dispatch(actions.showInitializeMenu()) this.props.dispatch(actions.showInitializeMenu())
} }
// create vault // create vault
CreateVaultScreen.prototype.createVaultOnEnter = function(event) { CreateVaultScreen.prototype.createVaultOnEnter = function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
event.preventDefault() event.preventDefault()
this.createNewVault() this.createNewVault()
} }
} }
CreateVaultScreen.prototype.createNewVault = function(){ CreateVaultScreen.prototype.createNewVault = function () {
var passwordBox = document.getElementById('password-box') var passwordBox = document.getElementById('password-box')
var password = passwordBox.value var password = passwordBox.value
var passwordConfirmBox = document.getElementById('password-box-confirm') var passwordConfirmBox = document.getElementById('password-box-confirm')
@ -126,5 +125,5 @@ CreateVaultScreen.prototype.createNewVault = function(){
return return
} }
this.props.dispatch(actions.createNewVault(password, ''/*entropy*/)) this.props.dispatch(actions.createNewVault(password, ''/* entropy*/))
} }

@ -8,17 +8,16 @@ const path = require('path')
const disclaimer = fs.readFileSync(path.join(__dirname, 'disclaimer.txt')).toString() const disclaimer = fs.readFileSync(path.join(__dirname, 'disclaimer.txt')).toString()
module.exports = connect(mapStateToProps)(DisclaimerScreen) module.exports = connect(mapStateToProps)(DisclaimerScreen)
function mapStateToProps(state) { function mapStateToProps (state) {
return {} return {}
} }
inherits(DisclaimerScreen, Component) inherits(DisclaimerScreen, Component)
function DisclaimerScreen() { function DisclaimerScreen () {
Component.call(this) Component.call(this)
} }
DisclaimerScreen.prototype.render = function() { DisclaimerScreen.prototype.render = function () {
return ( return (
h('.flex-column.flex-center.flex-grow', [ h('.flex-column.flex-center.flex-grow', [
@ -43,13 +42,13 @@ DisclaimerScreen.prototype.render = function() {
padding: '6px', padding: '6px',
width: '80%', width: '80%',
overflowY: 'scroll', overflowY: 'scroll',
} },
}, disclaimer), }, disclaimer),
h('button', { h('button', {
style: { marginTop: '18px' }, style: { marginTop: '18px' },
onClick: () => this.props.dispatch(actions.agreeToDisclaimer()) onClick: () => this.props.dispatch(actions.agreeToDisclaimer()),
}, 'I Agree') }, 'I Agree'),
]) ])
) )
} }

@ -3,28 +3,25 @@ const EventEmitter = require('events').EventEmitter
const Component = require('react').Component const Component = require('react').Component
const connect = require('react-redux').connect const connect = require('react-redux').connect
const h = require('react-hyperscript') const h = require('react-hyperscript')
const getCaretCoordinates = require('textarea-caret')
const Mascot = require('../components/mascot') const Mascot = require('../components/mascot')
const actions = require('../actions') const actions = require('../actions')
const CreateVaultScreen = require('./create-vault')
const CreateVaultCompleteScreen = require('./create-vault-complete')
module.exports = connect(mapStateToProps)(InitializeMenuScreen) module.exports = connect(mapStateToProps)(InitializeMenuScreen)
inherits(InitializeMenuScreen, Component) inherits(InitializeMenuScreen, Component)
function InitializeMenuScreen() { function InitializeMenuScreen () {
Component.call(this) Component.call(this)
this.animationEventEmitter = new EventEmitter() this.animationEventEmitter = new EventEmitter()
} }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
// state from plugin // state from plugin
currentView: state.appState.currentView, currentView: state.appState.currentView,
} }
} }
InitializeMenuScreen.prototype.render = function() { InitializeMenuScreen.prototype.render = function () {
var state = this.props var state = this.props
switch (state.currentView.name) { switch (state.currentView.name) {
@ -33,15 +30,13 @@ InitializeMenuScreen.prototype.render = function() {
return this.renderMenu() return this.renderMenu()
} }
} }
// InitializeMenuScreen.prototype.componentDidMount = function(){ // InitializeMenuScreen.prototype.componentDidMount = function(){
// document.getElementById('password-box').focus() // document.getElementById('password-box').focus()
// } // }
InitializeMenuScreen.prototype.renderMenu = function() { InitializeMenuScreen.prototype.renderMenu = function () {
var state = this.props
return ( return (
h('.initialize-screen.flex-column.flex-center.flex-grow', [ h('.initialize-screen.flex-column.flex-center.flex-grow', [
@ -88,15 +83,15 @@ InitializeMenuScreen.prototype.renderMenu = function() {
// this.props.dispatch(actions.showInitializeMenu()) // this.props.dispatch(actions.showInitializeMenu())
// } // }
InitializeMenuScreen.prototype.showInitializeMenu = function() { InitializeMenuScreen.prototype.showInitializeMenu = function () {
this.props.dispatch(actions.showInitializeMenu()) this.props.dispatch(actions.showInitializeMenu())
} }
InitializeMenuScreen.prototype.showCreateVault = function() { InitializeMenuScreen.prototype.showCreateVault = function () {
this.props.dispatch(actions.showCreateVault()) this.props.dispatch(actions.showCreateVault())
} }
InitializeMenuScreen.prototype.showRestoreVault = function() { InitializeMenuScreen.prototype.showRestoreVault = function () {
this.props.dispatch(actions.showRestoreVault()) this.props.dispatch(actions.showRestoreVault())
} }

@ -6,20 +6,18 @@ const actions = require('../actions')
module.exports = connect(mapStateToProps)(RestoreVaultScreen) module.exports = connect(mapStateToProps)(RestoreVaultScreen)
inherits(RestoreVaultScreen, Component) inherits(RestoreVaultScreen, Component)
function RestoreVaultScreen() { function RestoreVaultScreen () {
Component.call(this) Component.call(this)
} }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
warning: state.appState.warning, warning: state.appState.warning,
} }
} }
RestoreVaultScreen.prototype.render = function () {
RestoreVaultScreen.prototype.render = function() {
var state = this.props var state = this.props
return ( return (
@ -41,7 +39,7 @@ RestoreVaultScreen.prototype.render = function() {
// wallet seed entry // wallet seed entry
h('h3', 'Wallet Seed'), h('h3', 'Wallet Seed'),
h('textarea.twelve-word-phrase.letter-spacey', { h('textarea.twelve-word-phrase.letter-spacey', {
placeholder: 'Enter your secret twelve word phrase here to restore your vault.' placeholder: 'Enter your secret twelve word phrase here to restore your vault.',
}), }),
// password // password
@ -97,17 +95,17 @@ RestoreVaultScreen.prototype.render = function() {
) )
} }
RestoreVaultScreen.prototype.showInitializeMenu = function() { RestoreVaultScreen.prototype.showInitializeMenu = function () {
this.props.dispatch(actions.showInitializeMenu()) this.props.dispatch(actions.showInitializeMenu())
} }
RestoreVaultScreen.prototype.onMaybeCreate = function(event) { RestoreVaultScreen.prototype.onMaybeCreate = function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
this.restoreVault() this.restoreVault()
} }
} }
RestoreVaultScreen.prototype.restoreVault = function(){ RestoreVaultScreen.prototype.restoreVault = function () {
// check password // check password
var passwordBox = document.getElementById('password-box') var passwordBox = document.getElementById('password-box')
var password = passwordBox.value var password = passwordBox.value

@ -6,19 +6,18 @@ const actions = require('./actions')
module.exports = connect(mapStateToProps)(InfoScreen) module.exports = connect(mapStateToProps)(InfoScreen)
function mapStateToProps(state) { function mapStateToProps (state) {
return {} return {}
} }
inherits(InfoScreen, Component) inherits(InfoScreen, Component)
function InfoScreen() { function InfoScreen () {
Component.call(this) Component.call(this)
} }
InfoScreen.prototype.render = function() { InfoScreen.prototype.render = function () {
var state = this.props var state = this.props
var rpc = state.rpc var manifest = chrome.runtime.getManifest()
var manifest = chrome.runtime.getManifest();
return ( return (
h('.flex-column.flex-grow', [ h('.flex-column.flex-grow', [
@ -27,7 +26,7 @@ InfoScreen.prototype.render = function() {
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', { h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
onClick: (event) => { onClick: (event) => {
state.dispatch(actions.goHome()) state.dispatch(actions.goHome())
} },
}), }),
h('h2.page-subtitle', 'Info'), h('h2.page-subtitle', 'Info'),
]), ]),
@ -37,28 +36,27 @@ InfoScreen.prototype.render = function() {
h('.flex-space-around', { h('.flex-space-around', {
style: { style: {
padding: '20px', padding: '20px',
} },
}, [ }, [
//current version number // current version number
h('.info.info-gray',[ h('.info.info-gray', [
h('div','Metamask'), h('div', 'Metamask'),
h('div', { h('div', {
style: { style: {
marginBottom: '10px', marginBottom: '10px',
} },
},`Version: ${manifest.version}`), }, `Version: ${manifest.version}`),
]), ]),
h('hr',{ h('hr', {
style: { style: {
margin:'20px 0 ', margin: '20px 0 ',
width: '7em', width: '7em',
} },
}), }),
h('.info', {
h('.info',{
style: { style: {
marginBottom: '20px', marginBottom: '20px',
}}, }},
@ -67,7 +65,7 @@ InfoScreen.prototype.render = function() {
contact us with questions or just contact us with questions or just
say 'Hi', you can find us on theise platforms:`), say 'Hi', you can find us on theise platforms:`),
h('div',{ h('div', {
style: { style: {
paddingLeft: '30px', paddingLeft: '30px',
}}, }},
@ -76,32 +74,31 @@ InfoScreen.prototype.render = function() {
h('a', { h('a', {
href: 'https://metamask.io/', href: 'https://metamask.io/',
target: '_blank', target: '_blank',
onClick(event) { this.navigateTo(event.target.href) }, onClick (event) { this.navigateTo(event.target.href) },
},[ }, [
h('img.icon-size', { h('img.icon-size', {
src: manifest.icons[128] src: manifest.icons[128],
}), }),
h('div.info',{ h('div.info', {
style: { style: {
fontWeight: 800, fontWeight: 800,
} },
},'Visit our web site') }, 'Visit our web site'),
]) ]),
]), ]),
h('div.fa.fa-slack', [ h('div.fa.fa-slack', [
h('a.info', { h('a.info', {
href: 'http://slack.metamask.io', href: 'http://slack.metamask.io',
target: '_blank', target: '_blank',
onClick(event) { this.navigateTo(event.target.href) }, onClick (event) { this.navigateTo(event.target.href) },
}, 'Join the conversation on Slack'), }, 'Join the conversation on Slack'),
]), ]),
h('div.fa.fa-twitter', [ h('div.fa.fa-twitter', [
h('a.info', { h('a.info', {
href: 'https://twitter.com/metamask_io', href: 'https://twitter.com/metamask_io',
target: '_blank', target: '_blank',
onClick(event) { this.navigateTo(event.target.href) }, onClick (event) { this.navigateTo(event.target.href) },
}, 'Follow us on Twitter'), }, 'Follow us on Twitter'),
]), ]),
@ -116,7 +113,7 @@ InfoScreen.prototype.render = function() {
h('a.info', { h('a.info', {
href: 'https://github.com/metamask/talk/issues', href: 'https://github.com/metamask/talk/issues',
target: '_blank', target: '_blank',
onClick(event) { this.navigateTo(event.target.href) }, onClick (event) { this.navigateTo(event.target.href) },
}, 'Start a thread on Github'), }, 'Start a thread on Github'),
]), ]),
]), ]),
@ -124,9 +121,8 @@ InfoScreen.prototype.render = function() {
]), ]),
]) ])
) )
} }
InfoScreen.prototype.navigateTo = function(url) { InfoScreen.prototype.navigateTo = function (url) {
chrome.tabs.create({ url }); chrome.tabs.create({ url })
} }

@ -2,23 +2,22 @@ const inherits = require('util').inherits
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const actions = require('./actions')
const ReactCSSTransitionGroup = require('react-addons-css-transition-group') const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
module.exports = connect(mapStateToProps)(LoadingIndicator) module.exports = connect(mapStateToProps)(LoadingIndicator)
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
isLoading: state.appState.isLoading, isLoading: state.appState.isLoading,
} }
} }
inherits(LoadingIndicator, Component) inherits(LoadingIndicator, Component)
function LoadingIndicator() { function LoadingIndicator () {
Component.call(this) Component.call(this)
} }
LoadingIndicator.prototype.render = function() { LoadingIndicator.prototype.render = function () {
var isLoading = this.props.isLoading var isLoading = this.props.isLoading
return ( return (
@ -38,7 +37,7 @@ LoadingIndicator.prototype.render = function() {
height: '100%', height: '100%',
width: '100%', width: '100%',
background: 'rgba(255, 255, 255, 0.5)', background: 'rgba(255, 255, 255, 0.5)',
} },
}, [ }, [
h('img', { h('img', {
src: 'images/loading.svg', src: 'images/loading.svg',

@ -7,13 +7,12 @@ const actions = require('../actions')
module.exports = connect(mapStateToProps)(RevealSeedConfirmatoin) module.exports = connect(mapStateToProps)(RevealSeedConfirmatoin)
inherits(RevealSeedConfirmatoin, Component) inherits(RevealSeedConfirmatoin, Component)
function RevealSeedConfirmatoin() { function RevealSeedConfirmatoin () {
Component.call(this) Component.call(this)
} }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
warning: state.appState.warning, warning: state.appState.warning,
} }
@ -21,7 +20,7 @@ function mapStateToProps(state) {
RevealSeedConfirmatoin.prototype.confirmationPhrase = 'I understand' RevealSeedConfirmatoin.prototype.confirmationPhrase = 'I understand'
RevealSeedConfirmatoin.prototype.render = function() { RevealSeedConfirmatoin.prototype.render = function () {
const props = this.props const props = this.props
const state = this.state const state = this.state
@ -48,7 +47,7 @@ RevealSeedConfirmatoin.prototype.render = function() {
flexDirection: 'column', flexDirection: 'column',
padding: '20px', padding: '20px',
justifyContent: 'center', justifyContent: 'center',
} },
}, [ }, [
h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'), h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'),
@ -68,8 +67,8 @@ RevealSeedConfirmatoin.prototype.render = function() {
h(`h4${state && state.confirmationWrong ? '.error' : ''}`, { h(`h4${state && state.confirmationWrong ? '.error' : ''}`, {
style: { style: {
marginTop: '12px', marginTop: '12px',
} },
}, `Enter the phrase "I understand" to proceed.`), }, 'Enter the phrase "I understand" to proceed.'),
// confirm confirmation // confirm confirmation
h('input.large-input.letter-spacey', { h('input.large-input.letter-spacey', {
@ -105,7 +104,7 @@ RevealSeedConfirmatoin.prototype.render = function() {
h('span.error', { h('span.error', {
style: { style: {
margin: '20px', margin: '20px',
} },
}, props.warning.split('-')) }, props.warning.split('-'))
), ),
@ -117,24 +116,24 @@ RevealSeedConfirmatoin.prototype.render = function() {
) )
} }
RevealSeedConfirmatoin.prototype.componentDidMount = function(){ RevealSeedConfirmatoin.prototype.componentDidMount = function () {
document.getElementById('password-box').focus() document.getElementById('password-box').focus()
} }
RevealSeedConfirmatoin.prototype.goHome = function() { RevealSeedConfirmatoin.prototype.goHome = function () {
this.props.dispatch(actions.showConfigPage(false)) this.props.dispatch(actions.showConfigPage(false))
} }
// create vault // create vault
RevealSeedConfirmatoin.prototype.checkConfirmation = function(event) { RevealSeedConfirmatoin.prototype.checkConfirmation = function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
event.preventDefault() event.preventDefault()
this.revealSeedWords() this.revealSeedWords()
} }
} }
RevealSeedConfirmatoin.prototype.revealSeedWords = function(){ RevealSeedConfirmatoin.prototype.revealSeedWords = function () {
this.setState({ confirmationWrong: false }) this.setState({ confirmationWrong: false })
const confirmBox = document.getElementById('confirm-box') const confirmBox = document.getElementById('confirm-box')

@ -1,5 +1,3 @@
const combineReducers = require('redux').combineReducers
const actions = require('./actions')
const extend = require('xtend') const extend = require('xtend')
// //
@ -11,8 +9,7 @@ const reduceApp = require('./reducers/app')
module.exports = rootReducer module.exports = rootReducer
function rootReducer(state, action) { function rootReducer (state, action) {
// clone // clone
state = extend(state) state = extend(state)
@ -34,8 +31,6 @@ function rootReducer(state, action) {
state.appState = reduceApp(state, action) state.appState = reduceApp(state, action)
return state return state
} }

@ -1,12 +1,10 @@
const extend = require('xtend') const extend = require('xtend')
const actions = require('../actions') const actions = require('../actions')
const valuesFor = require('../util').valuesFor
const txHelper = require('../../lib/tx-helper') const txHelper = require('../../lib/tx-helper')
module.exports = reduceApp module.exports = reduceApp
function reduceApp(state, action) { function reduceApp (state, action) {
// clone and defaults // clone and defaults
const selectedAccount = state.metamask.selectedAccount const selectedAccount = state.metamask.selectedAccount
const pendingTxs = hasPendingTxs(state) const pendingTxs = hasPendingTxs(state)
@ -156,7 +154,6 @@ function reduceApp(state, action) {
warning: null, warning: null,
}) })
// accounts // accounts
case actions.SET_SELECTED_ACCOUNT: case actions.SET_SELECTED_ACCOUNT:
@ -182,7 +179,7 @@ function reduceApp(state, action) {
return extend(appState, { return extend(appState, {
currentView: { currentView: {
name: 'accountDetail', name: 'accountDetail',
context: action.value || account, context: action.value,
}, },
accountDetail: { accountDetail: {
subview: 'transactions', subview: 'transactions',
@ -207,7 +204,6 @@ function reduceApp(state, action) {
}) })
case actions.SHOW_ACCOUNTS_PAGE: case actions.SHOW_ACCOUNTS_PAGE:
var seedWords = state.metamask.seedWords
return extend(appState, { return extend(appState, {
currentView: { currentView: {
name: seedWords ? 'createVaultComplete' : 'accounts', name: seedWords ? 'createVaultComplete' : 'accounts',
@ -281,7 +277,7 @@ function reduceApp(state, action) {
name: 'confTx', name: 'confTx',
context: ++appState.currentView.context, context: ++appState.currentView.context,
warning: null, warning: null,
} },
}) })
case actions.VIEW_PENDING_TX: case actions.VIEW_PENDING_TX:
@ -292,7 +288,7 @@ function reduceApp(state, action) {
name: 'confTx', name: 'confTx',
context, context,
warning: null, warning: null,
} },
}) })
case actions.PREVIOUS_TX: case actions.PREVIOUS_TX:
@ -302,7 +298,7 @@ function reduceApp(state, action) {
name: 'confTx', name: 'confTx',
context: --appState.currentView.context, context: --appState.currentView.context,
warning: null, warning: null,
} },
}) })
case actions.TRANSACTION_ERROR: case actions.TRANSACTION_ERROR:
@ -315,7 +311,7 @@ function reduceApp(state, action) {
case actions.UNLOCK_FAILED: case actions.UNLOCK_FAILED:
return extend(appState, { return extend(appState, {
warning: 'Incorrect password. Try again.' warning: 'Incorrect password. Try again.',
}) })
case actions.SHOW_LOADING: case actions.SHOW_LOADING:
@ -392,7 +388,7 @@ function hasPendingTxs (state) {
return unconfTxList.length > 0 return unconfTxList.length > 0
} }
function indexForPending(state, txId) { function indexForPending (state, txId) {
var unconfTxs = state.metamask.unconfTxs var unconfTxs = state.metamask.unconfTxs
var unconfMsgs = state.metamask.unconfMsgs var unconfMsgs = state.metamask.unconfMsgs
var unconfTxList = txHelper(unconfTxs, unconfMsgs) var unconfTxList = txHelper(unconfTxs, unconfMsgs)

@ -1,10 +1,8 @@
const extend = require('xtend') const extend = require('xtend')
const actions = require('../actions')
module.exports = reduceIdentities module.exports = reduceIdentities
function reduceIdentities(state, action) { function reduceIdentities (state, action) {
// clone + defaults // clone + defaults
var idState = extend({ var idState = extend({
@ -14,5 +12,4 @@ function reduceIdentities(state, action) {
default: default:
return idState return idState
} }
} }

@ -3,7 +3,8 @@ const actions = require('../actions')
module.exports = reduceMetamask module.exports = reduceMetamask
function reduceMetamask(state, action) { function reduceMetamask (state, action) {
let newState
// clone + defaults // clone + defaults
var metamaskState = extend({ var metamaskState = extend({
@ -18,9 +19,9 @@ function reduceMetamask(state, action) {
switch (action.type) { switch (action.type) {
case actions.SHOW_ACCOUNTS_PAGE: case actions.SHOW_ACCOUNTS_PAGE:
var state = extend(metamaskState) newState = extend(metamaskState)
delete state.seedWords delete newState.seedWords
return state return newState
case actions.UPDATE_METAMASK_STATE: case actions.UPDATE_METAMASK_STATE:
return extend(metamaskState, action.value) return extend(metamaskState, action.value)
@ -59,16 +60,16 @@ function reduceMetamask(state, action) {
case actions.COMPLETED_TX: case actions.COMPLETED_TX:
var stringId = String(action.id) var stringId = String(action.id)
var newState = extend(metamaskState, { newState = extend(metamaskState, {
unconfTxs: {}, unconfTxs: {},
unconfMsgs: {}, unconfMsgs: {},
}) })
for (var id in metamaskState.unconfTxs) { for (const id in metamaskState.unconfTxs) {
if (id !== stringId) { if (id !== stringId) {
newState.unconfTxs[id] = metamaskState.unconfTxs[id] newState.unconfTxs[id] = metamaskState.unconfTxs[id]
} }
} }
for (var id in metamaskState.unconfMsgs) { for (const id in metamaskState.unconfMsgs) {
if (id !== stringId) { if (id !== stringId) {
newState.unconfMsgs[id] = metamaskState.unconfMsgs[id] newState.unconfMsgs[id] = metamaskState.unconfMsgs[id]
} }
@ -82,7 +83,7 @@ function reduceMetamask(state, action) {
}) })
case actions.CLEAR_SEED_WORD_CACHE: case actions.CLEAR_SEED_WORD_CACHE:
var newState = extend(metamaskState, { newState = extend(metamaskState, {
isUnlocked: true, isUnlocked: true,
isInitialized: true, isInitialized: true,
selectedAccount: action.value, selectedAccount: action.value,
@ -91,7 +92,7 @@ function reduceMetamask(state, action) {
return newState return newState
case actions.SHOW_ACCOUNT_DETAIL: case actions.SHOW_ACCOUNT_DETAIL:
const newState = extend(metamaskState, { newState = extend(metamaskState, {
isUnlocked: true, isUnlocked: true,
isInitialized: true, isInitialized: true,
selectedAccount: action.value, selectedAccount: action.value,

@ -1,5 +1,4 @@
const inherits = require('util').inherits const inherits = require('util').inherits
const React = require('react')
const Component = require('react').Component const Component = require('react').Component
const Provider = require('react-redux').Provider const Provider = require('react-redux').Provider
const h = require('react-hyperscript') const h = require('react-hyperscript')
@ -7,17 +6,16 @@ const App = require('./app')
module.exports = Root module.exports = Root
inherits(Root, Component) inherits(Root, Component)
function Root() { Component.call(this) } function Root () { Component.call(this) }
Root.prototype.render = function() { Root.prototype.render = function () {
return ( return (
h(Provider, { h(Provider, {
store: this.props.store, store: this.props.store,
}, [ }, [
h(App) h(App),
]) ])
) )

@ -6,14 +6,13 @@ const Identicon = require('./components/identicon')
const actions = require('./actions') const actions = require('./actions')
const util = require('./util') const util = require('./util')
const numericBalance = require('./util').numericBalance const numericBalance = require('./util').numericBalance
const formatBalance = require('./util').formatBalance
const addressSummary = require('./util').addressSummary const addressSummary = require('./util').addressSummary
const EtherBalance = require('./components/eth-balance') const EtherBalance = require('./components/eth-balance')
const ethUtil = require('ethereumjs-util') const ethUtil = require('ethereumjs-util')
module.exports = connect(mapStateToProps)(SendTransactionScreen) module.exports = connect(mapStateToProps)(SendTransactionScreen)
function mapStateToProps(state) { function mapStateToProps (state) {
var result = { var result = {
address: state.metamask.selectedAccount, address: state.metamask.selectedAccount,
accounts: state.metamask.accounts, accounts: state.metamask.accounts,
@ -31,11 +30,11 @@ function mapStateToProps(state) {
} }
inherits(SendTransactionScreen, Component) inherits(SendTransactionScreen, Component)
function SendTransactionScreen() { function SendTransactionScreen () {
Component.call(this) Component.call(this)
} }
SendTransactionScreen.prototype.render = function() { SendTransactionScreen.prototype.render = function () {
var state = this.props var state = this.props
var address = state.address var address = state.address
var account = state.account var account = state.account
@ -111,7 +110,7 @@ SendTransactionScreen.prototype.render = function() {
// h('div', formatBalance(account && account.balance)), // h('div', formatBalance(account && account.balance)),
h(EtherBalance, { h(EtherBalance, {
value: account && account.balance, value: account && account.balance,
}) }),
]), ]),
@ -140,7 +139,7 @@ SendTransactionScreen.prototype.render = function() {
h('input.large-input', { h('input.large-input', {
name: 'address', name: 'address',
placeholder: 'Recipient Address', placeholder: 'Recipient Address',
}) }),
]), ]),
// 'amount' and send button // 'amount' and send button
@ -160,7 +159,7 @@ SendTransactionScreen.prototype.render = function() {
style: { style: {
textTransform: 'uppercase', textTransform: 'uppercase',
}, },
}, 'Send') }, 'Send'),
]), ]),
@ -187,7 +186,7 @@ SendTransactionScreen.prototype.render = function() {
style: { style: {
width: '100%', width: '100%',
resize: 'none', resize: 'none',
} },
}), }),
]), ]),
@ -196,31 +195,31 @@ SendTransactionScreen.prototype.render = function() {
) )
} }
SendTransactionScreen.prototype.navigateToAccounts = function(event){ SendTransactionScreen.prototype.navigateToAccounts = function (event) {
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showAccountsPage()) this.props.dispatch(actions.showAccountsPage())
} }
SendTransactionScreen.prototype.back = function() { SendTransactionScreen.prototype.back = function () {
var address = this.props.address var address = this.props.address
this.props.dispatch(actions.backToAccountDetail(address)) this.props.dispatch(actions.backToAccountDetail(address))
} }
SendTransactionScreen.prototype.onSubmit = function() { SendTransactionScreen.prototype.onSubmit = function () {
const recipient = document.querySelector('input[name="address"]').value const recipient = document.querySelector('input[name="address"]').value
const input = document.querySelector('input[name="amount"]').value const input = document.querySelector('input[name="amount"]').value
const value = util.normalizeEthStringToWei(input) const value = util.normalizeEthStringToWei(input)
const txData = document.querySelector('input[name="txData"]').value const txData = document.querySelector('input[name="txData"]').value
const balance = this.props.balance const balance = this.props.balance
let message
if (value.gt(balance)) { if (value.gt(balance)) {
var message = 'Insufficient funds.' message = 'Insufficient funds.'
return this.props.dispatch(actions.displayWarning(message)) return this.props.dispatch(actions.displayWarning(message))
} }
if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) { if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) {
var message = 'Recipient address is invalid.' message = 'Recipient address is invalid.'
return this.props.dispatch(actions.displayWarning(message)) return this.props.dispatch(actions.displayWarning(message))
} }

@ -2,28 +2,20 @@ const inherits = require('util').inherits
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const copyToClipboard = require('copy-to-clipboard')
const actions = require('./actions') const actions = require('./actions')
const AccountPanel = require('./components/account-panel')
module.exports = connect(mapStateToProps)(AppSettingsPage) module.exports = connect(mapStateToProps)(AppSettingsPage)
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {}
identities: state.metamask.identities,
address: state.appState.currentView.context,
}
} }
inherits(AppSettingsPage, Component) inherits(AppSettingsPage, Component)
function AppSettingsPage() { function AppSettingsPage () {
Component.call(this) Component.call(this)
} }
AppSettingsPage.prototype.render = function () {
AppSettingsPage.prototype.render = function() {
var state = this.props
var identity = state.identities[state.address]
return ( return (
h('.account-detail-section.flex-column.flex-grow', [ h('.account-detail-section.flex-column.flex-grow', [
@ -51,19 +43,18 @@ AppSettingsPage.prototype.render = function() {
) )
} }
AppSettingsPage.prototype.componentDidMount = function(){ AppSettingsPage.prototype.componentDidMount = function () {
document.querySelector('input').focus() document.querySelector('input').focus()
} }
AppSettingsPage.prototype.onKeyPress = function(event) { AppSettingsPage.prototype.onKeyPress = function (event) {
// get submit event // get submit event
if (event.key === 'Enter') { if (event.key === 'Enter') {
// this.submitPassword(event) // this.submitPassword(event)
} }
} }
AppSettingsPage.prototype.navigateToAccounts = function (event) {
AppSettingsPage.prototype.navigateToAccounts = function(event){
event.stopPropagation() event.stopPropagation()
this.props.dispatch(actions.showAccountsPage()) this.props.dispatch(actions.showAccountsPage())
} }

@ -6,7 +6,6 @@ const rootReducer = require('./reducers')
module.exports = configureStore module.exports = configureStore
const loggerMiddleware = createLogger() const loggerMiddleware = createLogger()
const createStoreWithMiddleware = applyMiddleware( const createStoreWithMiddleware = applyMiddleware(
@ -14,6 +13,6 @@ const createStoreWithMiddleware = applyMiddleware(
loggerMiddleware loggerMiddleware
)(createStore) )(createStore)
function configureStore(initialState) { function configureStore (initialState) {
return createStoreWithMiddleware(rootReducer, initialState) return createStoreWithMiddleware(rootReducer, initialState)
} }

@ -2,29 +2,28 @@ const inherits = require('util').inherits
const Component = require('react').Component const Component = require('react').Component
const h = require('react-hyperscript') const h = require('react-hyperscript')
const connect = require('react-redux').connect const connect = require('react-redux').connect
const actions = require('./actions')
module.exports = connect(mapStateToProps)(COMPONENTNAME) module.exports = connect(mapStateToProps)(COMPONENTNAME)
function mapStateToProps(state) { function mapStateToProps (state) {
return {} return {}
} }
inherits(COMPONENTNAME, Component) inherits(COMPONENTNAME, Component)
function COMPONENTNAME() { function COMPONENTNAME () {
Component.call(this) Component.call(this)
} }
COMPONENTNAME.prototype.render = function() { COMPONENTNAME.prototype.render = function () {
const props = this.props const props = this.props
return ( return (
h('div', { h('div', {
style: { style: {
background: 'blue', background: 'blue',
} },
}, [ }, [
'Hello, world!' `Hello, ${props.sender}`,
]) ])
) )
} }

@ -9,20 +9,19 @@ const EventEmitter = require('events').EventEmitter
module.exports = connect(mapStateToProps)(UnlockScreen) module.exports = connect(mapStateToProps)(UnlockScreen)
inherits(UnlockScreen, Component) inherits(UnlockScreen, Component)
function UnlockScreen() { function UnlockScreen () {
Component.call(this) Component.call(this)
this.animationEventEmitter = new EventEmitter() this.animationEventEmitter = new EventEmitter()
} }
function mapStateToProps(state) { function mapStateToProps (state) {
return { return {
warning: state.appState.warning, warning: state.appState.warning,
} }
} }
UnlockScreen.prototype.render = function() { UnlockScreen.prototype.render = function () {
const state = this.props const state = this.props
const warning = state.warning const warning = state.warning
return ( return (
@ -55,7 +54,7 @@ UnlockScreen.prototype.render = function() {
h('.error', { h('.error', {
style: { style: {
display: warning ? 'block' : 'none', display: warning ? 'block' : 'none',
} },
}, warning), }, warning),
h('button.primary.cursor-pointer', { h('button.primary.cursor-pointer', {
@ -70,23 +69,23 @@ UnlockScreen.prototype.render = function() {
) )
} }
UnlockScreen.prototype.componentDidMount = function(){ UnlockScreen.prototype.componentDidMount = function () {
document.getElementById('password-box').focus() document.getElementById('password-box').focus()
} }
UnlockScreen.prototype.onSubmit = function(event) { UnlockScreen.prototype.onSubmit = function (event) {
const input = document.getElementById('password-box') const input = document.getElementById('password-box')
const password = input.value const password = input.value
this.props.dispatch(actions.tryUnlockMetamask(password)) this.props.dispatch(actions.tryUnlockMetamask(password))
} }
UnlockScreen.prototype.onKeyPress = function(event) { UnlockScreen.prototype.onKeyPress = function (event) {
if (event.key === 'Enter') { if (event.key === 'Enter') {
this.submitPassword(event) this.submitPassword(event)
} }
} }
UnlockScreen.prototype.submitPassword = function(event){ UnlockScreen.prototype.submitPassword = function (event) {
var element = event.target var element = event.target
var password = element.value var password = element.value
// reset input // reset input
@ -94,7 +93,7 @@ UnlockScreen.prototype.submitPassword = function(event){
this.props.dispatch(actions.tryUnlockMetamask(password)) this.props.dispatch(actions.tryUnlockMetamask(password))
} }
UnlockScreen.prototype.inputChanged = function(event){ UnlockScreen.prototype.inputChanged = function (event) {
// tell mascot to look at page action // tell mascot to look at page action
var element = event.target var element = event.target
var boundingRect = element.getBoundingClientRect() var boundingRect = element.getBoundingClientRect()
@ -105,6 +104,6 @@ UnlockScreen.prototype.inputChanged = function(event){
}) })
} }
UnlockScreen.prototype.emitAnim = function(name, a, b, c){ UnlockScreen.prototype.emitAnim = function (name, a, b, c) {
this.animationEventEmitter.emit(name, a, b, c) this.animationEventEmitter.emit(name, a, b, c)
} }

@ -6,12 +6,12 @@ var valueTable = {
mwei: '1000000000000', mwei: '1000000000000',
gwei: '1000000000', gwei: '1000000000',
szabo: '1000000', szabo: '1000000',
finney:'1000', finney: '1000',
ether: '1', ether: '1',
kether:'0.001', kether: '0.001',
mether:'0.000001', mether: '0.000001',
gether:'0.000000001', gether: '0.000000001',
tether:'0.000000000001', tether: '0.000000000001',
} }
var bnTable = {} var bnTable = {}
for (var currency in valueTable) { for (var currency in valueTable) {
@ -37,25 +37,24 @@ module.exports = {
bnTable: bnTable, bnTable: bnTable,
} }
function valuesFor (obj) {
function valuesFor(obj) {
if (!obj) return [] if (!obj) return []
return Object.keys(obj) return Object.keys(obj)
.map(function(key){ return obj[key] }) .map(function (key) { return obj[key] })
} }
function addressSummary(address) { function addressSummary (address) {
if (!address) return '' if (!address) return ''
var checked = ethUtil.toChecksumAddress(address) var checked = ethUtil.toChecksumAddress(address)
return checked ? checked.slice(0,2+8)+'...'+checked.slice(-4) : '...' return checked ? checked.slice(0, 2 + 8) + '...' + checked.slice(-4) : '...'
} }
function isValidAddress(address) { function isValidAddress (address) {
var prefixed = ethUtil.addHexPrefix(address) var prefixed = ethUtil.addHexPrefix(address)
return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed) return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
} }
function isAllOneCase(address) { function isAllOneCase (address) {
if (!address) return true if (!address) return true
var lower = address.toLowerCase() var lower = address.toLowerCase()
var upper = address.toUpperCase() var upper = address.toUpperCase()
@ -63,81 +62,81 @@ function isAllOneCase(address) {
} }
// Takes wei Hex, returns wei BN, even if input is null // Takes wei Hex, returns wei BN, even if input is null
function numericBalance(balance) { function numericBalance (balance) {
if (!balance) return new ethUtil.BN(0, 16) if (!balance) return new ethUtil.BN(0, 16)
var stripped = ethUtil.stripHexPrefix(balance) var stripped = ethUtil.stripHexPrefix(balance)
return new ethUtil.BN(stripped, 16) return new ethUtil.BN(stripped, 16)
} }
// Takes eth BN, returns BN wei // Takes eth BN, returns BN wei
function ethToWei(bn) { function ethToWei (bn) {
var eth = new ethUtil.BN('1000000000000000000') var eth = new ethUtil.BN('1000000000000000000')
var wei = bn.mul(eth) var wei = bn.mul(eth)
return wei return wei
} }
// Takes BN in Wei, returns BN in eth // Takes BN in Wei, returns BN in eth
function weiToEth(bn) { function weiToEth (bn) {
var diff = new ethUtil.BN('1000000000000000000') var diff = new ethUtil.BN('1000000000000000000')
var eth = bn.div(diff) var eth = bn.div(diff)
return eth return eth
} }
// Takes hex, returns [beforeDecimal, afterDecimal] // Takes hex, returns [beforeDecimal, afterDecimal]
function parseBalance(balance) { function parseBalance (balance) {
let beforeDecimal, afterDecimal var beforeDecimal, afterDecimal
let wei = numericBalance(balance).toString() const wei = numericBalance(balance).toString()
let trailingZeros = /0+$/ const trailingZeros = /0+$/
beforeDecimal = wei.length > 18 ? wei.slice(0, wei.length - 18) : '0' beforeDecimal = wei.length > 18 ? wei.slice(0, wei.length - 18) : '0'
afterDecimal = ("000000000000000000" + wei).slice(-18).replace(trailingZeros, "") afterDecimal = ('000000000000000000' + wei).slice(-18).replace(trailingZeros, '')
if(afterDecimal == ""){afterDecimal = "0" } if (afterDecimal === '') { afterDecimal = '0' }
return [beforeDecimal, afterDecimal] return [beforeDecimal, afterDecimal]
} }
// Takes wei hex, returns "None" or "${formattedAmount} ETH" // Takes wei hex, returns "None" or "${formattedAmount} ETH"
function formatBalance(balance, decimalsToKeep) { function formatBalance (balance, decimalsToKeep) {
var parsed = parseBalance(balance) var parsed = parseBalance(balance)
var beforeDecimal = parsed[0] var beforeDecimal = parsed[0]
var afterDecimal = parsed[1] var afterDecimal = parsed[1]
var formatted = "None" var formatted = 'None'
if(decimalsToKeep === undefined){ if (decimalsToKeep === undefined) {
if(beforeDecimal === '0'){ if (beforeDecimal === '0') {
if(afterDecimal !== '0'){ if (afterDecimal !== '0') {
var sigFigs = afterDecimal.match(/^0*(.{2})/) //default: grabs 2 most significant digits var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
if(sigFigs){afterDecimal = sigFigs[0]} if (sigFigs) { afterDecimal = sigFigs[0] }
formatted = '0.' + afterDecimal + ' ETH' formatted = '0.' + afterDecimal + ' ETH'
} }
}else{ } else {
formatted = beforeDecimal + "." + afterDecimal.slice(0,3) + ' ETH' formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH'
} }
}else{ } else {
afterDecimal += Array(decimalsToKeep).join("0") afterDecimal += Array(decimalsToKeep).join('0')
formatted = beforeDecimal + "." + afterDecimal.slice(0,decimalsToKeep) + ' ETH' formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH'
} }
return formatted return formatted
} }
function dataSize(data) { function dataSize (data) {
var size = data ? ethUtil.stripHexPrefix(data).length : 0 var size = data ? ethUtil.stripHexPrefix(data).length : 0
return size+' bytes' return size + ' bytes'
} }
// Takes a BN and an ethereum currency name, // Takes a BN and an ethereum currency name,
// returns a BN in wei // returns a BN in wei
function normalizeToWei(amount, currency) { function normalizeToWei (amount, currency) {
try { try {
return amount.mul(bnTable.wei).div(bnTable[currency]) return amount.mul(bnTable.wei).div(bnTable[currency])
} catch (e) {} } catch (e) {}
return amount return amount
} }
function normalizeEthStringToWei(str) { function normalizeEthStringToWei (str) {
const parts = str.split('.') const parts = str.split('.')
let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei) let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei)
if (parts[1]) { if (parts[1]) {
var decimal = parts[1] var decimal = parts[1]
while(decimal.length < 18) { while (decimal.length < 18) {
decimal += '0' decimal += '0'
} }
const decimalBN = new ethUtil.BN(decimal, 10) const decimalBN = new ethUtil.BN(decimal, 10)
@ -147,22 +146,22 @@ function normalizeEthStringToWei(str) {
} }
var multiple = new ethUtil.BN('10000', 10) var multiple = new ethUtil.BN('10000', 10)
function normalizeNumberToWei(n, currency) { function normalizeNumberToWei (n, currency) {
var enlarged = n * 10000 var enlarged = n * 10000
var amount = new ethUtil.BN(String(enlarged), 10) var amount = new ethUtil.BN(String(enlarged), 10)
return normalizeToWei(amount, currency).div(multiple) return normalizeToWei(amount, currency).div(multiple)
} }
function readableDate(ms) { function readableDate (ms) {
var date = new Date(ms) var date = new Date(ms)
var month = date.getMonth() var month = date.getMonth()
var day = date.getDate() var day = date.getDate()
var year = date.getFullYear() var year = date.getFullYear()
var hours = date.getHours() var hours = date.getHours()
var minutes = "0" + date.getMinutes() var minutes = '0' + date.getMinutes()
var seconds = "0" + date.getSeconds() var seconds = '0' + date.getSeconds()
var date = `${month}/${day}/${year}` var dateStr = `${month}/${day}/${year}`
var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}` var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}`
return `${date} ${time}` return `${dateStr} ${time}`
} }

@ -1,25 +1,26 @@
const fs = require('fs') const fs = require('fs')
const path = require('path')
module.exports = bundleCss module.exports = bundleCss
var cssFiles = { var cssFiles = {
'fonts.css': fs.readFileSync(__dirname+'/app/css/fonts.css', 'utf8'), 'fonts.css': fs.readFileSync(path.join(__dirname, '/app/css/fonts.css'), 'utf8'),
'reset.css': fs.readFileSync(__dirname+'/app/css/reset.css', 'utf8'), 'reset.css': fs.readFileSync(path.join(__dirname, '/app/css/reset.css'), 'utf8'),
'lib.css': fs.readFileSync(__dirname+'/app/css/lib.css', 'utf8'), 'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'),
'index.css': fs.readFileSync(__dirname+'/app/css/index.css', 'utf8'), 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'),
'transitions.css': fs.readFileSync(__dirname+'/app/css/transitions.css', 'utf8'), 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'),
} }
function bundleCss() { function bundleCss () {
var cssBundle = Object.keys(cssFiles).reduce(function(bundle, fileName){ var cssBundle = Object.keys(cssFiles).reduce(function (bundle, fileName) {
var fileContent = cssFiles[fileName] var fileContent = cssFiles[fileName]
var output = String() var output = String()
output += '/*========== '+fileName+' ==========*/\n\n' output += '/*========== ' + fileName + ' ==========*/\n\n'
output += fileContent output += fileContent
output += '\n\n' output += '\n\n'
return bundle+output return bundle + output
}, String()) }, String())
return cssBundle return cssBundle

@ -26,7 +26,7 @@ var identities = {
address: '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333', address: '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333',
balance: 0.000001, balance: 0.000001,
txCount: 1, txCount: 1,
} },
} }
var unconfTxs = {} var unconfTxs = {}
@ -42,7 +42,7 @@ addUnconfTx({
data: '0x000462427bcc9133bb46e88bcbe39cd7ef0e7000', data: '0x000462427bcc9133bb46e88bcbe39cd7ef0e7000',
}) })
function addUnconfTx(txParams){ function addUnconfTx (txParams) {
var time = (new Date()).getTime() var time = (new Date()).getTime()
var id = createRandomId() var id = createRandomId()
unconfTxs[id] = { unconfTxs[id] = {
@ -55,7 +55,7 @@ function addUnconfTx(txParams){
var isUnlocked = false var isUnlocked = false
var selectedAddress = null var selectedAddress = null
function getState(){ function getState () {
return { return {
isUnlocked: isUnlocked, isUnlocked: isUnlocked,
identities: isUnlocked ? identities : {}, identities: isUnlocked ? identities : {},
@ -66,16 +66,16 @@ function getState(){
var accountManager = new EventEmitter() var accountManager = new EventEmitter()
accountManager.getState = function(cb){ accountManager.getState = function (cb) {
cb(null, getState()) cb(null, getState())
} }
accountManager.setLocked = function(){ accountManager.setLocked = function () {
isUnlocked = false isUnlocked = false
this._didUpdate() this._didUpdate()
} }
accountManager.submitPassword = function(password, cb){ accountManager.submitPassword = function (password, cb) {
if (password === 'test') { if (password === 'test') {
isUnlocked = true isUnlocked = true
cb(null, getState()) cb(null, getState())
@ -85,17 +85,17 @@ accountManager.submitPassword = function(password, cb){
} }
} }
accountManager.setSelectedAddress = function(address, cb){ accountManager.setSelectedAddress = function (address, cb) {
selectedAddress = address selectedAddress = address
cb(null, getState()) cb(null, getState())
this._didUpdate() this._didUpdate()
} }
accountManager.signTransaction = function(txParams, cb){ accountManager.signTransaction = function (txParams, cb) {
alert('signing tx....') alert('signing tx....')
} }
accountManager._didUpdate = function(){ accountManager._didUpdate = function () {
this.emit('update', getState()) this.emit('update', getState())
} }
@ -106,18 +106,18 @@ var container = document.getElementById('app-content')
var css = MetaMaskUiCss() var css = MetaMaskUiCss()
injectCss(css) injectCss(css)
var app = MetaMaskUi({ MetaMaskUi({
container: container, container: container,
accountManager: accountManager accountManager: accountManager,
}) })
// util // util
function createRandomId(){ function createRandomId () {
// 13 time digits // 13 time digits
var datePart = new Date().getTime()*Math.pow(10, 3) var datePart = new Date().getTime() * Math.pow(10, 3)
// 3 random digits // 3 random digits
var extraPart = Math.floor(Math.random()*Math.pow(10, 3)) var extraPart = Math.floor(Math.random() * Math.pow(10, 3))
// 16 digits // 16 digits
return datePart+extraPart return datePart + extraPart
} }

@ -1,28 +1,23 @@
const React = require('react')
const render = require('react-dom').render const render = require('react-dom').render
const h = require('react-hyperscript') const h = require('react-hyperscript')
const extend = require('xtend')
const Root = require('./app/root') const Root = require('./app/root')
const actions = require('./app/actions') const actions = require('./app/actions')
const configureStore = require('./app/store') const configureStore = require('./app/store')
module.exports = launchApp module.exports = launchApp
function launchApp(opts) { function launchApp (opts) {
var accountManager = opts.accountManager var accountManager = opts.accountManager
actions._setAccountManager(accountManager) actions._setAccountManager(accountManager)
// check if we are unlocked first // check if we are unlocked first
accountManager.getState(function(err, metamaskState){ accountManager.getState(function (err, metamaskState) {
if (err) throw err if (err) throw err
startApp(metamaskState, accountManager, opts) startApp(metamaskState, accountManager, opts)
}) })
} }
function startApp(metamaskState, accountManager, opts){ function startApp (metamaskState, accountManager, opts) {
// parse opts // parse opts
var store = configureStore({ var store = configureStore({
@ -43,12 +38,7 @@ function startApp(metamaskState, accountManager, opts){
store.dispatch(actions.showConfTxPage()) store.dispatch(actions.showConfTxPage())
} }
// if unconfirmed messages, start on msgConf page accountManager.on('update', function (metamaskState) {
if (Object.keys(metamaskState.unconfMsgs || {}).length) {
store.dispatch(actions.showConfTxPage())
}
accountManager.on('update', function(metamaskState){
store.dispatch(actions.updateMetamaskState(metamaskState)) store.dispatch(actions.updateMetamaskState(metamaskState))
}) })
@ -59,5 +49,4 @@ function startApp(metamaskState, accountManager, opts){
store: store, store: store,
} }
), opts.container) ), opts.container)
} }

@ -1,4 +1,4 @@
module.exports = function(hash, network) { module.exports = function (hash, network) {
const net = parseInt(network) const net = parseInt(network)
let prefix let prefix
switch (net) { switch (net) {

@ -1,18 +1,18 @@
var iconFactory var iconFactory
module.exports = function(jazzicon) { module.exports = function (jazzicon) {
if (!iconFactory) { if (!iconFactory) {
iconFactory = new IconFactory(jazzicon) iconFactory = new IconFactory(jazzicon)
} }
return iconFactory return iconFactory
} }
function IconFactory(jazzicon) { function IconFactory (jazzicon) {
this.jazzicon = jazzicon this.jazzicon = jazzicon
this.cache = {} this.cache = {}
} }
IconFactory.prototype.iconForAddress = function(address, diameter) { IconFactory.prototype.iconForAddress = function (address, diameter) {
if (this.isCached(address, diameter)) { if (this.isCached(address, diameter)) {
return this.cache[address][diameter] return this.cache[address][diameter]
} }
@ -22,30 +22,31 @@ IconFactory.prototype.iconForAddress = function(address, diameter) {
return dataUri return dataUri
} }
IconFactory.prototype.generateNewUri = function(address, diameter) { IconFactory.prototype.generateNewUri = function (address, diameter) {
var numericRepresentation = jsNumberForAddress(address) var numericRepresentation = jsNumberForAddress(address)
var identicon = this.jazzicon(diameter, numericRepresentation) var identicon = this.jazzicon(diameter, numericRepresentation)
var identiconSrc = identicon.innerHTML var identiconSrc = identicon.innerHTML
var dataUri = 'data:image/svg+xml;charset=utf-8,'+encodeURIComponent(identiconSrc) var dataUri = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(identiconSrc)
return dataUri return dataUri
} }
IconFactory.prototype.cacheIcon = function(address, diameter, icon) { IconFactory.prototype.cacheIcon = function (address, diameter, icon) {
if (!(address in this.cache)) { if (!(address in this.cache)) {
var sizeCache = {} var sizeCache = {}
sizeCache[diameter] = icon sizeCache[diameter] = icon
return this.cache[address] = sizeCache this.cache[address] = sizeCache
return sizeCache
} else { } else {
return this.cache[address][diameter] = icon this.cache[address][diameter] = icon
return icon
} }
} }
IconFactory.prototype.isCached = function(address, diameter) { IconFactory.prototype.isCached = function (address, diameter) {
return address in this.cache && diameter in this.cache[address] return address in this.cache && diameter in this.cache[address]
} }
function jsNumberForAddress(address) { function jsNumberForAddress (address) {
var addr = address.slice(2, 10) var addr = address.slice(2, 10)
var seed = parseInt(addr, 16) var seed = parseInt(addr, 16)
return seed return seed

@ -1,6 +1,6 @@
const valuesFor = require('../app/util').valuesFor const valuesFor = require('../app/util').valuesFor
module.exports = function(unconfTxs, unconfMsgs) { module.exports = function (unconfTxs, unconfMsgs) {
var txValues = valuesFor(unconfTxs) var txValues = valuesFor(unconfTxs)
var msgValues = valuesFor(unconfMsgs) var msgValues = valuesFor(unconfMsgs)
var allValues = txValues.concat(msgValues) var allValues = txValues.concat(msgValues)

Loading…
Cancel
Save