aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintignore1
-rw-r--r--.eslintrc6
-rw-r--r--.gitignore4
-rw-r--r--CHANGELOG.md65
-rw-r--r--README.md51
-rw-r--r--app/manifest.json4
-rw-r--r--app/scripts/background.js22
-rw-r--r--app/scripts/config.js3
-rw-r--r--app/scripts/contentscript.js14
-rw-r--r--app/scripts/inpage.js20
-rw-r--r--app/scripts/keyring-controller.js946
-rw-r--r--app/scripts/keyrings/hd.js104
-rw-r--r--app/scripts/keyrings/simple.js61
-rw-r--r--app/scripts/lib/auto-reload.js5
-rw-r--r--app/scripts/lib/config-manager.js96
-rw-r--r--app/scripts/lib/encryptor.js149
-rw-r--r--app/scripts/lib/eth-store.js146
-rw-r--r--app/scripts/lib/idStore-migrator.js58
-rw-r--r--app/scripts/lib/idStore.js225
-rw-r--r--app/scripts/lib/inpage-provider.js36
-rw-r--r--app/scripts/lib/is-popup-or-notification.js2
-rw-r--r--app/scripts/lib/nodeify.js24
-rw-r--r--app/scripts/lib/notifications.js12
-rw-r--r--app/scripts/lib/port-stream.js4
-rw-r--r--app/scripts/lib/random-id.js9
-rw-r--r--app/scripts/lib/sig-util.js5
-rw-r--r--app/scripts/lib/tx-utils.js132
-rw-r--r--app/scripts/metamask-controller.js289
-rw-r--r--app/scripts/notice-controller.js96
-rw-r--r--app/scripts/popup-core.js4
-rw-r--r--app/scripts/popup.js2
-rw-r--r--app/scripts/transaction-manager.js362
-rw-r--r--development/notice-generator.js36
-rw-r--r--development/notices.json1
-rw-r--r--development/states.js1
-rw-r--r--development/states.json2
-rw-r--r--development/states/account-detail-with-shapeshift-tx.json4
-rw-r--r--development/states/account-detail-with-transaction-history.json4
-rw-r--r--development/states/account-detail.json4
-rw-r--r--development/states/accounts-loose.json126
-rw-r--r--development/states/accounts.json4
-rw-r--r--development/states/compilation-bug.json124
-rw-r--r--development/states/config.json4
-rw-r--r--development/states/create-vault-password.json2
-rw-r--r--development/states/custom-rpc.json4
-rw-r--r--development/states/empty-account-detail.json4
-rw-r--r--development/states/first-time.json2
-rw-r--r--development/states/help.json4
-rw-r--r--development/states/locked.json4
-rw-r--r--development/states/lost-accounts.json91
-rw-r--r--development/states/new-vault.json2
-rw-r--r--development/states/notice.json62
-rw-r--r--development/states/pending-crash.json2
-rw-r--r--development/states/pending-signature.json4
-rw-r--r--development/states/pending-tx-contract.json2
-rw-r--r--development/states/pending-tx-send-coin.json2
-rw-r--r--development/states/pending-tx-value.json2
-rw-r--r--development/states/private-network.json86
-rw-r--r--development/states/restore-vault.json2
-rw-r--r--development/states/send.json2
-rw-r--r--development/states/shapeshift.json4
-rw-r--r--development/states/show-seed-words.json2
-rw-r--r--development/states/terms-and-conditions.json40
-rw-r--r--development/test.html31
-rw-r--r--gulpfile.js141
-rw-r--r--library/controller.js8
-rw-r--r--mock-dev.js4
-rw-r--r--package.json27
-rw-r--r--test/integration/helpers.js4
-rw-r--r--test/integration/index.html2
-rw-r--r--test/integration/lib/encryptor-test.js67
-rw-r--r--test/integration/lib/first-time.js87
-rw-r--r--test/integration/lib/idStore-migrator-test.js91
-rw-r--r--test/integration/mocks/badVault.json1
-rw-r--r--test/integration/mocks/badVault2.json1
-rw-r--r--test/integration/mocks/oldVault.json21
-rw-r--r--test/lib/mock-config-manager.js1
-rw-r--r--test/unit/account-link-test.js10
-rw-r--r--test/unit/actions/set_selected_account_test.js1
-rw-r--r--test/unit/config-manager-test.js119
-rw-r--r--test/unit/explorer-link-test.js2
-rw-r--r--test/unit/idStore-migration-test.js42
-rw-r--r--test/unit/idStore-test.js32
-rw-r--r--test/unit/keyring-controller-test.js110
-rw-r--r--test/unit/keyrings/hd-test.js79
-rw-r--r--test/unit/keyrings/simple-test.js68
-rw-r--r--test/unit/metamask-controller-test.js20
-rw-r--r--test/unit/nodeify-test.js22
-rw-r--r--test/unit/notice-controller-test.js116
-rw-r--r--test/unit/tx-manager-test.js215
-rw-r--r--ui-dev.js2
-rw-r--r--ui/app/account-detail.js17
-rw-r--r--ui/app/accounts/account-list-item.js20
-rw-r--r--ui/app/accounts/index.js29
-rw-r--r--ui/app/actions.js211
-rw-r--r--ui/app/app.js118
-rw-r--r--ui/app/components/buy-button-subview.js6
-rw-r--r--ui/app/components/coinbase-form.js20
-rw-r--r--ui/app/components/copyButton.js4
-rw-r--r--ui/app/components/drop-menu-item.js8
-rw-r--r--ui/app/components/eth-balance.js4
-rw-r--r--ui/app/components/network.js19
-rw-r--r--ui/app/components/notice.js110
-rw-r--r--ui/app/components/pending-msg-details.js2
-rw-r--r--ui/app/components/pending-tx-details.js39
-rw-r--r--ui/app/components/pending-tx.js9
-rw-r--r--ui/app/components/shapeshift-form.js6
-rw-r--r--ui/app/components/shift-list-item.js1
-rw-r--r--ui/app/components/tooltip.js2
-rw-r--r--ui/app/components/transaction-list-item-icon.js39
-rw-r--r--ui/app/components/transaction-list-item.js23
-rw-r--r--ui/app/components/transaction-list.js9
-rw-r--r--ui/app/conf-tx.js50
-rw-r--r--ui/app/config.js32
-rw-r--r--ui/app/conversion-util.js5
-rw-r--r--ui/app/conversion.json5730
-rw-r--r--ui/app/css/index.css3
-rw-r--r--ui/app/css/lib.css19
-rw-r--r--ui/app/first-time/disclaimer.js12
-rw-r--r--ui/app/first-time/init-menu.js4
-rw-r--r--ui/app/info.js2
-rw-r--r--ui/app/keychains/hd/recover-seed/confirmation.js18
-rw-r--r--ui/app/keychains/hd/restore-vault.js8
-rw-r--r--ui/app/reducers.js2
-rw-r--r--ui/app/reducers/app.js46
-rw-r--r--ui/app/reducers/metamask.js16
-rw-r--r--ui/app/unlock.js3
-rw-r--r--ui/example.js8
-rw-r--r--ui/lib/account-link.js5
-rw-r--r--ui/lib/contract-namer.js9
-rw-r--r--ui/lib/explorer-link.js2
-rw-r--r--ui/lib/icon-factory.js4
-rw-r--r--ui/lib/lost-accounts-notice.js23
133 files changed, 9735 insertions, 1876 deletions
diff --git a/.eslintignore b/.eslintignore
index bfb2163d2..df49525be 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,2 +1 @@
app/scripts/lib/extension-instance.js
-ui/app/conversion-util.js
diff --git a/.eslintrc b/.eslintrc
index cadd38110..84f65bea4 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -45,7 +45,7 @@
"eol-last": 1,
"eqeqeq": [2, "allow-null"],
"generator-star-spacing": [2, { "before": true, "after": true }],
- "handle-callback-err": [2, "^(err|error)$" ],
+ "handle-callback-err": [1, "^(err|error)$" ],
"indent": [2, 2, { "SwitchCase": 1 }],
"jsx-quotes": [2, "prefer-single"],
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
@@ -128,7 +128,7 @@
"no-whitespace-before-property": 2,
"no-with": 2,
"one-var": [2, { "initialized": "never" }],
- "operator-linebreak": [1, "after", { "overrides": { "?": "before", ":": "before" } }],
+ "operator-linebreak": [1, "after", { "overrides": { "?": "ignore", ":": "ignore" } }],
"padded-blocks": [1, "never"],
"quotes": [2, "single", {"avoidEscape": true, "allowTemplateLiterals": true}],
"semi": [2, "never"],
@@ -146,6 +146,6 @@
"wrap-iife": [2, "any"],
"yield-star-spacing": [2, "both"],
"yoda": [2, "never"],
- "prefer-const": 1
+ "prefer-const": 1,
}
}
diff --git a/.gitignore b/.gitignore
index 5d901bac3..c61847aab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
dist
+npm-debug.log
node_modules
temp
.tmp
@@ -8,9 +9,10 @@ test/bower_components
package
.DS_Store
builds/
+disc/
notes.txt
app/.DS_Store
development/bundle.js
builds.zip
test/integration/bundle.js
-npm-debug.log
+development/states.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c6a06788..f7306146c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,71 @@
## Current Master
+## 3.0.1 2017-1-17
+
+- Fixed bug that prevented eth.sign from working.
+
+## 3.0.0 2017-1-16
+
+- Fix seed word account generation (https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd#.t4i1qmmsz).
+- Fix Bug where you see a empty transaction flash by on the confirm transaction view.
+- Create visible difference in transaction history between a approved but not yet included in a block transaction and a transaction who has been confirmed.
+- Fix memory leak in RPC Cache
+- Override RPC commands eth_syncing and web3_clientVersion
+- Remove certain non-essential permissions from certain builds.
+- Add a check for when a tx is included in a block.
+- Fix bug where browser-solidity would sometimes warn of a contract creation error when there was none.
+- Minor modifications to network display.
+- Network now displays properly for pending transactions.
+- Implement replay attack protections allowed by EIP 155.
+- Fix bug where sometimes loading account data would fail by querying a future block.
+
+## 2.14.1 2016-12-20
+
+- Update Coinbase info. and increase the buy amount to $15
+- Fixed ropsten transaction links
+- Temporarily disable extension reload detection causing infinite reload bug.
+- Implemented basic checking for valid RPC URIs.
+
+## 2.14.0 2016-12-16
+
+- Removed Morden testnet provider from provider menu.
+- Add support for notices.
+- Fix broken reload detection.
+- Fix transaction forever cached-as-pending bug.
+
+## 2.13.11 2016-11-23
+
+- Add support for synchronous RPC method "eth_uninstallFilter".
+- Forgotten password prompts now send users directly to seed word restoration.
+
+## 2.13.10 2016-11-22
+
+- Improve gas calculation logic.
+- Default to Dapp-specified gas limits for transactions.
+- Ropsten networks now properly point to the faucet when attempting to buy ether.
+- Ropsten transactions now link to etherscan correctly.
+
+## 2.13.9 2016-11-21
+
+- Add support for the new, default Ropsten Test Network.
+- Fix bug that would cause MetaMask to occasionally lose its StreamProvider connection and drop requests.
+- Fix bug that would cause the Custom RPC menu item to not appear when Localhost 8545 was selected.
+- Point ropsten faucet button to actual faucet.
+- Phase out ethereumjs-util from our encryptor module.
+
+## 2.13.8 2016-11-16
+
+- Show a warning when a transaction fails during simulation.
+- Fix bug where 20% of gas estimate was not being added properly.
+- Render error messages in confirmation screen more gracefully.
+
+## 2.13.7 2016-11-8
+
+- Fix bug where gas estimate would sometimes be very high.
+- Increased our gas estimate from 100k gas to 20% of estimate.
+- Fix github link on info page to point at current repository.
+
## 2.13.6 2016-10-26
- Add a check for improper Transaction data.
diff --git a/README.md b/README.md
index 09fb0079c..3a7277f3f 100644
--- a/README.md
+++ b/README.md
@@ -18,6 +18,12 @@ If you're a web dapp developer, we've got two types of guides for you:
Uncompressed builds can be found in `/dist`, compressed builds can be found in `/builds` once they're built.
+## Installing Local Builds on Chrome
+
+To install your locally built extension on Chrome, [follow this guide](http://stackoverflow.com/a/24577660/272576).
+
+The built extension is stored in `./dist/chrome/`.
+
## Architecture
[![Architecture Diagram](./docs/architecture.png)][1]
@@ -26,6 +32,13 @@ If you're a web dapp developer, we've got two types of guides for you:
```bash
npm install
+npm start
+```
+
+## Build for Publishing
+
+```bash
+npm run dist
```
#### In Chrome
@@ -78,7 +91,7 @@ To enjoy the live-reloading that `gulp dev` offers while working on the `web3-pr
2. `npm install` in its folder.
3. Run `npm link` in its folder.
4. Run `npm link $DEP_NAME` in this project folder.
- 5. Next time you `gulp dev` it will watch the dependency for changes as well!
+ 5. Next time you `npm start` it will watch the dependency for changes as well!
### Running Tests
@@ -104,3 +117,39 @@ To write tests that will be run in the browser using QUnit, add your test files
3. Upload the latest zip file from `builds/metamask-$PLATFORM-$VERSION.zip` as the updated package.
[1]: http://www.nomnoml.com/#view/%5B%3Cactor%3Euser%5D%0A%0A%5Bmetamask-ui%7C%0A%20%20%20%5Btools%7C%0A%20%20%20%20%20react%0A%20%20%20%20%20redux%0A%20%20%20%20%20thunk%0A%20%20%20%20%20ethUtils%0A%20%20%20%20%20jazzicon%0A%20%20%20%5D%0A%20%20%20%5Bcomponents%7C%0A%20%20%20%20%20app%0A%20%20%20%20%20account-detail%0A%20%20%20%20%20accounts%0A%20%20%20%20%20locked-screen%0A%20%20%20%20%20restore-vault%0A%20%20%20%20%20identicon%0A%20%20%20%20%20config%0A%20%20%20%20%20info%0A%20%20%20%5D%0A%20%20%20%5Breducers%7C%0A%20%20%20%20%20app%0A%20%20%20%20%20metamask%0A%20%20%20%20%20identities%0A%20%20%20%5D%0A%20%20%20%5Bactions%7C%0A%20%20%20%20%20%5BaccountManager%5D%0A%20%20%20%5D%0A%20%20%20%5Bcomponents%5D%3A-%3E%5Bactions%5D%0A%20%20%20%5Bactions%5D%3A-%3E%5Breducers%5D%0A%20%20%20%5Breducers%5D%3A-%3E%5Bcomponents%5D%0A%5D%0A%0A%5Bweb%20dapp%7C%0A%20%20%5Bui%20code%5D%0A%20%20%5Bweb3%5D%0A%20%20%5Bmetamask-inpage%5D%0A%20%20%0A%20%20%5B%3Cactor%3Eui%20developer%5D%0A%20%20%5Bui%20developer%5D-%3E%5Bui%20code%5D%0A%20%20%5Bui%20code%5D%3C-%3E%5Bweb3%5D%0A%20%20%5Bweb3%5D%3C-%3E%5Bmetamask-inpage%5D%0A%5D%0A%0A%5Bmetamask-background%7C%0A%20%20%5Bprovider-engine%5D%0A%20%20%5Bhooked%20wallet%20subprovider%5D%0A%20%20%5Bid%20store%5D%0A%20%20%0A%20%20%5Bprovider-engine%5D%3C-%3E%5Bhooked%20wallet%20subprovider%5D%0A%20%20%5Bhooked%20wallet%20subprovider%5D%3C-%3E%5Bid%20store%5D%0A%20%20%5Bconfig%20manager%7C%0A%20%20%20%20%5Brpc%20configuration%5D%0A%20%20%20%20%5Bencrypted%20keys%5D%0A%20%20%20%20%5Bwallet%20nicknames%5D%0A%20%20%5D%0A%20%20%0A%20%20%5Bprovider-engine%5D%3C-%5Bconfig%20manager%5D%0A%20%20%5Bid%20store%5D%3C-%3E%5Bconfig%20manager%5D%0A%5D%0A%0A%5Buser%5D%3C-%3E%5Bmetamask-ui%5D%0A%0A%5Buser%5D%3C%3A--%3A%3E%5Bweb%20dapp%5D%0A%0A%5Bmetamask-contentscript%7C%0A%20%20%5Bplugin%20restart%20detector%5D%0A%20%20%5Brpc%20passthrough%5D%0A%5D%0A%0A%5Brpc%20%7C%0A%20%20%5Bethereum%20blockchain%20%7C%0A%20%20%20%20%5Bcontracts%5D%0A%20%20%20%20%5Baccounts%5D%0A%20%20%5D%0A%5D%0A%0A%5Bweb%20dapp%5D%3C%3A--%3A%3E%5Bmetamask-contentscript%5D%0A%5Bmetamask-contentscript%5D%3C-%3E%5Bmetamask-background%5D%0A%5Bmetamask-background%5D%3C-%3E%5Bmetamask-ui%5D%0A%5Bmetamask-background%5D%3C-%3E%5Brpc%5D%0A
+
+
+### Generate Development Visualization
+
+This will generate a video of the repo commit history.
+
+Install preqs:
+```
+brew install gource
+brew install ffmpeg
+```
+
+From the repo dir, pipe `gource` into `ffmpeg`:
+```
+gource \
+ --seconds-per-day .1 \
+ --user-scale 1.5 \
+ --default-user-image "./images/icon-512.png" \
+ --viewport 1280x720 \
+ --auto-skip-seconds .1 \
+ --multi-sampling \
+ --stop-at-end \
+ --highlight-users \
+ --hide mouse,progress \
+ --file-idle-time 0 \
+ --max-files 0 \
+ --background-colour 000000 \
+ --font-size 18 \
+ --date-format "%b %d, %Y" \
+ --highlight-dirs \
+ --user-friction 0.1 \
+ --title "MetaMask Development History" \
+ --output-ppm-stream - \
+ --output-framerate 30 \
+ | ffmpeg -y -r 30 -f image2pipe -vcodec ppm -i - -b 65536K metamask-dev-history.mp4
+```
diff --git a/app/manifest.json b/app/manifest.json
index e35f2918d..a13b43ca7 100644
--- a/app/manifest.json
+++ b/app/manifest.json
@@ -1,7 +1,7 @@
{
"name": "MetaMask",
"short_name": "Metamask",
- "version": "2.13.6",
+ "version": "3.0.1",
"manifest_version": 2,
"author": "https://metamask.io",
"description": "Ethereum Browser Extension",
@@ -56,9 +56,7 @@
],
"permissions": [
"storage",
- "tabs",
"clipboardWrite",
- "clipboardRead",
"http://localhost:8545/"
],
"web_accessible_resources": [
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 7cb25d8bf..f3837a028 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -17,18 +17,16 @@ const controller = new MetamaskController({
// User confirmation callbacks:
showUnconfirmedMessage: triggerUi,
unlockAccountMessage: triggerUi,
- showUnconfirmedTx: triggerUi,
+ showUnapprovedTx: triggerUi,
// Persistence Methods:
setData,
loadData,
})
-const keyringController = controller.keyringController
function triggerUi () {
if (!popupIsOpen) notification.show()
}
// On first install, open a window to MetaMask website to how-it-works.
-
extension.runtime.onInstalled.addListener(function (details) {
if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
@@ -81,13 +79,11 @@ function setupControllerConnection (stream) {
stream.pipe(dnode).pipe(stream)
dnode.on('remote', (remote) => {
// push updates to popup
- controller.ethStore.on('update', controller.sendUpdate.bind(controller))
- controller.listeners.push(remote)
- keyringController.on('update', controller.sendUpdate.bind(controller))
-
+ var sendUpdate = remote.sendUpdate.bind(remote)
+ controller.on('update', sendUpdate)
// teardown on disconnect
eos(stream, () => {
- controller.ethStore.removeListener('update', controller.sendUpdate.bind(controller))
+ controller.removeListener('update', sendUpdate)
popupIsOpen = false
})
})
@@ -97,15 +93,15 @@ function setupControllerConnection (stream) {
// plugin badge text
//
-keyringController.on('update', updateBadge)
+controller.txManager.on('updateBadge', updateBadge)
+updateBadge()
function updateBadge () {
var label = ''
- var unconfTxs = controller.configManager.unconfirmedTxs()
- var unconfTxLen = Object.keys(unconfTxs).length
+ var unapprovedTxCount = controller.txManager.unapprovedTxCount
var unconfMsgs = messageManager.unconfirmedMsgs()
var unconfMsgLen = Object.keys(unconfMsgs).length
- var count = unconfTxLen + unconfMsgLen
+ var count = unapprovedTxCount + unconfMsgLen
if (count) {
label = String(count)
}
@@ -113,6 +109,8 @@ function updateBadge () {
extension.browserAction.setBadgeBackgroundColor({ color: '#506F8B' })
}
+// data :: setters/getters
+
function loadData () {
var oldData = getOldStyleData()
var newData
diff --git a/app/scripts/config.js b/app/scripts/config.js
index e40b5e104..e09206c5f 100644
--- a/app/scripts/config.js
+++ b/app/scripts/config.js
@@ -1,5 +1,5 @@
const MAINET_RPC_URL = 'https://mainnet.infura.io/metamask'
-const TESTNET_RPC_URL = 'https://morden.infura.io/metamask'
+const TESTNET_RPC_URL = 'https://ropsten.infura.io/metamask'
const DEFAULT_RPC_URL = TESTNET_RPC_URL
global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
@@ -10,5 +10,6 @@ module.exports = {
default: DEFAULT_RPC_URL,
mainnet: MAINET_RPC_URL,
testnet: TESTNET_RPC_URL,
+ morden: TESTNET_RPC_URL,
},
}
diff --git a/app/scripts/contentscript.js b/app/scripts/contentscript.js
index e2a968ac9..ab64dc9fa 100644
--- a/app/scripts/contentscript.js
+++ b/app/scripts/contentscript.js
@@ -6,7 +6,7 @@ const extension = require('./lib/extension')
const fs = require('fs')
const path = require('path')
-const inpageText = fs.readFileSync(path.join(__dirname + '/inpage.js')).toString()
+const inpageText = fs.readFileSync(path.join(__dirname, 'inpage.js')).toString()
// Eventually this streaming injection could be replaced with:
// https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.exportFunction
@@ -20,9 +20,8 @@ if (shouldInjectWeb3()) {
setupStreams()
}
-function setupInjection(){
+function setupInjection () {
try {
-
// inject in-page script
var scriptTag = document.createElement('script')
scriptTag.src = extension.extension.getURL('scripts/inpage.js')
@@ -31,14 +30,12 @@ function setupInjection(){
var container = document.head || document.documentElement
// append as first child
container.insertBefore(scriptTag, container.children[0])
-
} catch (e) {
console.error('Metamask injection failed.', e)
}
}
-function setupStreams(){
-
+function setupStreams () {
// setup communication to page and plugin
var pageStream = new LocalMessageDuplexStream({
name: 'contentscript',
@@ -65,14 +62,13 @@ function setupStreams(){
mx.ignoreStream('provider')
mx.ignoreStream('publicConfig')
mx.ignoreStream('reload')
-
}
-function shouldInjectWeb3(){
+function shouldInjectWeb3 () {
return isAllowedSuffix(window.location.href)
}
-function isAllowedSuffix(testCase) {
+function isAllowedSuffix (testCase) {
var prohibitedTypes = ['xml', 'pdf']
var currentUrl = window.location.href
var currentRegex
diff --git a/app/scripts/inpage.js b/app/scripts/inpage.js
index 85dd70b4d..42332d92e 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -2,8 +2,8 @@
cleanContextForImports()
require('web3/dist/web3.min.js')
const LocalMessageDuplexStream = require('post-message-stream')
-const PingStream = require('ping-pong-stream/ping')
-const endOfStream = require('end-of-stream')
+// const PingStream = require('ping-pong-stream/ping')
+// const endOfStream = require('end-of-stream')
const setupDappAutoReload = require('./lib/auto-reload.js')
const MetamaskInpageProvider = require('./lib/inpage-provider.js')
restoreContextAfterImports()
@@ -40,17 +40,19 @@ reloadStream.once('data', triggerReload)
// setup ping timeout autoreload
// LocalMessageDuplexStream does not self-close, so reload if pingStream fails
-var pingChannel = inpageProvider.multiStream.createStream('pingpong')
-var pingStream = new PingStream({ objectMode: true })
+// var pingChannel = inpageProvider.multiStream.createStream('pingpong')
+// var pingStream = new PingStream({ objectMode: true })
// wait for first successful reponse
-metamaskStream.once('_data', function(){
- pingStream.pipe(pingChannel).pipe(pingStream)
-})
-endOfStream(pingStream, triggerReload)
+
+// disable pingStream until https://github.com/MetaMask/metamask-plugin/issues/746 is resolved more gracefully
+// metamaskStream.once('data', function(){
+// pingStream.pipe(pingChannel).pipe(pingStream)
+// })
+// endOfStream(pingStream, triggerReload)
// set web3 defaultAcount
inpageProvider.publicConfigStore.subscribe(function (state) {
- web3.eth.defaultAccount = state.selectedAddress
+ web3.eth.defaultAccount = state.selectedAccount
})
//
diff --git a/app/scripts/keyring-controller.js b/app/scripts/keyring-controller.js
index fb3091143..4be00a5a5 100644
--- a/app/scripts/keyring-controller.js
+++ b/app/scripts/keyring-controller.js
@@ -1,18 +1,12 @@
-const async = require('async')
-const EventEmitter = require('events').EventEmitter
-const encryptor = require('./lib/encryptor')
-const messageManager = require('./lib/message-manager')
const ethUtil = require('ethereumjs-util')
-const ethBinToOps = require('eth-bin-to-ops')
-const EthQuery = require('eth-query')
-const BN = ethUtil.BN
-const Transaction = require('ethereumjs-tx')
-const createId = require('web3-provider-engine/util/random-id')
-const autoFaucet = require('./lib/auto-faucet')
const bip39 = require('bip39')
+const EventEmitter = require('events').EventEmitter
+const filter = require('promise-filter')
+const encryptor = require('browser-passworder')
-// TEMPORARY UNTIL FULL DEPRECATION:
-const IdStoreMigrator = require('./lib/idStore-migrator')
+const normalize = require('./lib/sig-util').normalize
+const messageManager = require('./lib/message-manager')
+const BN = ethUtil.BN
// Keyrings:
const SimpleKeyring = require('./keyrings/simple')
@@ -22,390 +16,322 @@ const keyringTypes = [
HdKeyring,
]
+const createId = require('./lib/random-id')
+
module.exports = class KeyringController extends EventEmitter {
+ // PUBLIC METHODS
+ //
+ // THE FIRST SECTION OF METHODS ARE PUBLIC-FACING,
+ // MEANING THEY ARE USED BY CONSUMERS OF THIS CLASS.
+ //
+ // THEIR SURFACE AREA SHOULD BE CHANGED WITH GREAT CARE.
+
constructor (opts) {
super()
- this.web3 = opts.web3
this.configManager = opts.configManager
this.ethStore = opts.ethStore
this.encryptor = encryptor
this.keyringTypes = keyringTypes
-
this.keyrings = []
this.identities = {} // Essentially a name hash
- this._unconfTxCbs = {}
this._unconfMsgCbs = {}
- this.network = opts.network
+ this.getNetwork = opts.getNetwork
+ }
- // TEMPORARY UNTIL FULL DEPRECATION:
- this.idStoreMigrator = new IdStoreMigrator({
- configManager: this.configManager,
- })
+ // Set Store
+ //
+ // Allows setting the ethStore after the constructor.
+ // This is currently required because of the initialization order
+ // of the ethStore and this class.
+ //
+ // Eventually would be nice to be able to add this in the constructor.
+ setStore (ethStore) {
+ this.ethStore = ethStore
}
- getState() {
+ // Full Update
+ // returns Promise( @object state )
+ //
+ // Emits the `update` event and
+ // returns a Promise that resolves to the current state.
+ //
+ // Frequently used to end asynchronous chains in this class,
+ // indicating consumers can often either listen for updates,
+ // or accept a state-resolving promise to consume their results.
+ //
+ // Not all methods end with this, that might be a nice refactor.
+ fullUpdate () {
+ this.emit('update')
+ return Promise.resolve(this.getState())
+ }
+
+ // Get State
+ // returns @object state
+ //
+ // This method returns a hash representing the current state
+ // that the keyringController manages.
+ //
+ // It is extended in the MetamaskController along with the EthStore
+ // state, and its own state, to create the metamask state branch
+ // that is passed to the UI.
+ //
+ // This is currently a rare example of a synchronously resolving method
+ // in this class, but will need to be Promisified when we move our
+ // persistence to an async model.
+ getState () {
const configManager = this.configManager
const address = configManager.getSelectedAccount()
const wallet = configManager.getWallet() // old style vault
const vault = configManager.getVault() // new style vault
+ const keyrings = this.keyrings
- return {
- seedWords: this.configManager.getSeedWords(),
- isInitialized: (!!wallet || !!vault),
- isUnlocked: !!this.key,
- isConfirmed: true, // AUDIT this.configManager.getConfirmed(),
- unconfTxs: this.configManager.unconfirmedTxs(),
- transactions: this.configManager.getTxList(),
- unconfMsgs: messageManager.unconfirmedMsgs(),
- messages: messageManager.getMsgList(),
- selectedAddress: address,
- selectedAccount: address,
- shapeShiftTxList: this.configManager.getShapeShiftTxList(),
- currentFiat: this.configManager.getCurrentFiat(),
- conversionRate: this.configManager.getConversionRate(),
- conversionDate: this.configManager.getConversionDate(),
- keyringTypes: this.keyringTypes.map((krt) => krt.type()),
- identities: this.identities,
- }
- }
-
- setStore(ethStore) {
- this.ethStore = ethStore
- }
-
- createNewVaultAndKeychain(password, entropy, cb) {
- this.createNewVault(password, entropy, (err) => {
- if (err) return cb(err)
- this.createFirstKeyTree(password, cb)
+ return Promise.all(keyrings.map(this.displayForKeyring))
+ .then((displayKeyrings) => {
+ return {
+ seedWords: this.configManager.getSeedWords(),
+ isInitialized: (!!wallet || !!vault),
+ isUnlocked: Boolean(this.password),
+ isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(),
+ unconfMsgs: messageManager.unconfirmedMsgs(),
+ messages: messageManager.getMsgList(),
+ selectedAccount: address,
+ shapeShiftTxList: this.configManager.getShapeShiftTxList(),
+ currentFiat: this.configManager.getCurrentFiat(),
+ conversionRate: this.configManager.getConversionRate(),
+ conversionDate: this.configManager.getConversionDate(),
+ keyringTypes: this.keyringTypes.map(krt => krt.type),
+ identities: this.identities,
+ keyrings: displayKeyrings,
+ }
})
}
- createNewVaultAndRestore(password, seed, cb) {
+ // Create New Vault And Keychain
+ // @string password - The password to encrypt the vault with
+ //
+ // returns Promise( @object state )
+ //
+ // Destroys any old encrypted storage,
+ // creates a new encrypted store with the given password,
+ // randomly creates a new HD wallet with 1 account,
+ // faucets that account on the testnet.
+ createNewVaultAndKeychain (password) {
+ return this.persistAllKeyrings(password)
+ .then(this.createFirstKeyTree.bind(this))
+ .then(this.fullUpdate.bind(this))
+ }
+
+ // CreateNewVaultAndRestore
+ // @string password - The password to encrypt the vault with
+ // @string seed - The BIP44-compliant seed phrase.
+ //
+ // returns Promise( @object state )
+ //
+ // Destroys any old encrypted storage,
+ // creates a new encrypted store with the given password,
+ // creates a new HD wallet from the given seed with 1 account.
+ createNewVaultAndRestore (password, seed) {
if (typeof password !== 'string') {
- return cb('Password must be text.')
+ return Promise.reject('Password must be text.')
}
if (!bip39.validateMnemonic(seed)) {
- return cb('Seed phrase is invalid.')
+ return Promise.reject('Seed phrase is invalid.')
}
this.clearKeyrings()
- this.createNewVault(password, '', (err) => {
- if (err) return cb(err)
- this.addNewKeyring('HD Key Tree', {
+ return this.persistAllKeyrings(password)
+ .then(() => {
+ return this.addNewKeyring('HD Key Tree', {
mnemonic: seed,
- n: 1,
- }, (err) => {
- if (err) return cb(err)
- const firstKeyring = this.keyrings[0]
- const accounts = firstKeyring.getAccounts()
- const firstAccount = accounts[0]
- const hexAccount = normalize(firstAccount)
- this.configManager.setSelectedAccount(hexAccount)
- this.setupAccounts(accounts)
-
- this.emit('update')
- cb(null, this.getState())
+ numberOfAccounts: 1,
})
- })
- }
-
- migrateAndGetKey(password) {
- let key
- const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault()
-
- return this.loadKey(password)
- .then((derivedKey) => {
- key = derivedKey
- this.key = key
- return this.idStoreMigrator.oldSeedForPassword(password)
- })
- .then((serialized) => {
- if (serialized && shouldMigrate) {
- const keyring = this.restoreKeyring(serialized)
- this.keyrings.push(keyring)
- this.configManager.setSelectedAccount(keyring.getAccounts()[0])
- }
- return key
- })
- }
-
- createNewVault(password, entropy, cb) {
- const configManager = this.configManager
- const salt = this.encryptor.generateSalt()
- configManager.setSalt(salt)
-
- return this.migrateAndGetKey(password)
- .then(() => {
- return this.persistAllKeyrings()
- })
- .then(() => {
- cb(null)
- })
- .catch((err) => {
- cb(err)
- })
- }
-
- createFirstKeyTree(password, cb) {
- this.clearKeyrings()
- this.addNewKeyring('HD Key Tree', {n: 1}, (err) => {
+ }).then(() => {
const firstKeyring = this.keyrings[0]
- const accounts = firstKeyring.getAccounts()
+ return firstKeyring.getAccounts()
+ })
+ .then((accounts) => {
const firstAccount = accounts[0]
const hexAccount = normalize(firstAccount)
- const seedWords = firstKeyring.serialize().mnemonic
- this.configManager.setSelectedAccount(firstAccount)
+ this.configManager.setSelectedAccount(hexAccount)
+ return this.setupAccounts(accounts)
+ })
+ .then(this.persistAllKeyrings.bind(this, password))
+ .then(this.fullUpdate.bind(this))
+ }
+
+ // PlaceSeedWords
+ // returns Promise( @object state )
+ //
+ // Adds the current vault's seed words to the UI's state tree.
+ //
+ // Used when creating a first vault, to allow confirmation.
+ // Also used when revealing the seed words in the confirmation view.
+ placeSeedWords () {
+ const firstKeyring = this.keyrings[0]
+ return firstKeyring.serialize()
+ .then((serialized) => {
+ const seedWords = serialized.mnemonic
this.configManager.setSeedWords(seedWords)
- autoFaucet(hexAccount)
- this.setupAccounts(accounts)
- this.persistAllKeyrings()
- .then(() => {
- cb(err, this.getState())
- })
- .catch((reason) => {
- cb(reason)
- })
+ return this.fullUpdate()
})
}
- placeSeedWords (cb) {
- const firstKeyring = this.keyrings[0]
- const seedWords = firstKeyring.serialize().mnemonic
- this.configManager.setSeedWords(seedWords)
+ // ClearSeedWordCache
+ //
+ // returns Promise( @string currentSelectedAccount )
+ //
+ // Removes the current vault's seed words from the UI's state tree,
+ // ensuring they are only ever available in the background process.
+ clearSeedWordCache () {
+ this.configManager.setSeedWords(null)
+ return Promise.resolve(this.configManager.getSelectedAccount())
}
- submitPassword(password, cb) {
- this.migrateAndGetKey(password)
- .then((key) => {
- return this.unlockKeyrings(key)
- })
+ // Set Locked
+ // returns Promise( @object state )
+ //
+ // This method deallocates all secrets, and effectively locks metamask.
+ setLocked () {
+ this.password = null
+ this.keyrings = []
+ return this.fullUpdate()
+ }
+
+ // Submit Password
+ // @string password
+ //
+ // returns Promise( @object state )
+ //
+ // Attempts to decrypt the current vault and load its keyrings
+ // into memory.
+ //
+ // Temporarily also migrates any old-style vaults first, as well.
+ // (Pre MetaMask 3.0.0)
+ submitPassword (password) {
+ return this.unlockKeyrings(password)
.then((keyrings) => {
this.keyrings = keyrings
- this.setupAccounts()
- this.emit('update')
- cb(null, this.getState())
- })
- .catch((err) => {
- console.error(err)
- cb(err)
+ return this.fullUpdate()
})
}
- loadKey(password) {
- const salt = this.configManager.getSalt() || this.encryptor.generateSalt()
- return this.encryptor.keyFromPassword(password + salt)
- .then((key) => {
- this.key = key
- this.configManager.setSalt(salt)
- return key
- })
- }
-
- addNewKeyring(type, opts, cb) {
+ // Add New Keyring
+ // @string type
+ // @object opts
+ //
+ // returns Promise( @Keyring keyring )
+ //
+ // Adds a new Keyring of the given `type` to the vault
+ // and the current decrypted Keyrings array.
+ //
+ // All Keyring classes implement a unique `type` string,
+ // and this is used to retrieve them from the keyringTypes array.
+ addNewKeyring (type, opts) {
const Keyring = this.getKeyringClassForType(type)
const keyring = new Keyring(opts)
- const accounts = keyring.getAccounts()
-
- this.keyrings.push(keyring)
- this.setupAccounts(accounts)
- this.persistAllKeyrings()
- .then(() => {
- cb(null, this.getState())
- })
- .catch((reason) => {
- cb(reason)
+ return keyring.getAccounts()
+ .then((accounts) => {
+ this.keyrings.push(keyring)
+ return this.setupAccounts(accounts)
})
- }
-
- addNewAccount(keyRingNum = 0, cb) {
- const ring = this.keyrings[keyRingNum]
- const accounts = ring.addAccounts(1)
- this.setupAccounts(accounts)
- this.persistAllKeyrings()
+ .then(() => { return this.password })
+ .then(this.persistAllKeyrings.bind(this))
.then(() => {
- cb(null, this.getState())
- })
- .catch((reason) => {
- cb(reason)
- })
- }
-
- setupAccounts(accounts) {
- var arr = accounts || this.getAccounts()
- arr.forEach((account) => {
- this.loadBalanceAndNickname(account)
+ return keyring
})
}
- // Takes an account address and an iterator representing
- // the current number of named accounts.
- loadBalanceAndNickname(account) {
- const address = normalize(account)
- this.ethStore.addAccount(address)
- this.createNickname(address)
- }
-
- createNickname(address) {
- const hexAddress = normalize(address)
- var i = Object.keys(this.identities).length
- const oldNickname = this.configManager.nicknameForWallet(address)
- const name = oldNickname || `Account ${++i}`
- this.identities[hexAddress] = {
- address: hexAddress,
- name,
- }
- return this.saveAccountLabel(hexAddress, name)
+ // Add New Account
+ // @number keyRingNum
+ //
+ // returns Promise( @object state )
+ //
+ // Calls the `addAccounts` method on the Keyring
+ // in the kryings array at index `keyringNum`,
+ // and then saves those changes.
+ addNewAccount (keyRingNum = 0) {
+ const ring = this.keyrings[keyRingNum]
+ return ring.addAccounts(1)
+ .then(this.setupAccounts.bind(this))
+ .then(this.persistAllKeyrings.bind(this))
+ .then(this.fullUpdate.bind(this))
+ }
+
+ // Set Selected Account
+ // @string address
+ //
+ // returns Promise( @string address )
+ //
+ // Sets the state's `selectedAccount` value
+ // to the specified address.
+ setSelectedAccount (address) {
+ var addr = normalize(address)
+ this.configManager.setSelectedAccount(addr)
+ return this.fullUpdate()
}
- saveAccountLabel (account, label, cb) {
+ // Save Account Label
+ // @string account
+ // @string label
+ //
+ // returns Promise( @string label )
+ //
+ // Persists a nickname equal to `label` for the specified account.
+ saveAccountLabel (account, label) {
const address = normalize(account)
const configManager = this.configManager
configManager.setNicknameForWallet(address, label)
this.identities[address].name = label
- if (cb) {
- cb(null, label)
- } else {
- return label
+ return Promise.resolve(label)
+ }
+
+ // Export Account
+ // @string address
+ //
+ // returns Promise( @string privateKey )
+ //
+ // Requests the private key from the keyring controlling
+ // the specified address.
+ //
+ // Returns a Promise that may resolve with the private key string.
+ exportAccount (address) {
+ try {
+ return this.getKeyringForAccount(address)
+ .then((keyring) => {
+ return keyring.exportAccount(normalize(address))
+ })
+ } catch (e) {
+ return Promise.reject(e)
}
}
- persistAllKeyrings() {
- const serialized = this.keyrings.map((k) => {
- return {
- type: k.type,
- data: k.serialize(),
- }
- })
- return this.encryptor.encryptWithKey(this.key, serialized)
- .then((encryptedString) => {
- this.configManager.setVault(encryptedString)
- return true
- })
- }
+ // SIGNING METHODS
+ //
+ // This method signs tx and returns a promise for
+ // TX Manager to update the state after signing
- unlockKeyrings(key) {
- const encryptedVault = this.configManager.getVault()
- return this.encryptor.decryptWithKey(key, encryptedVault)
- .then((vault) => {
- vault.forEach(this.restoreKeyring.bind(this))
- return this.keyrings
+ signTransaction (ethTx, _fromAddress) {
+ const fromAddress = normalize(_fromAddress)
+ return this.getKeyringForAccount(fromAddress)
+ .then((keyring) => {
+ return keyring.signTransaction(fromAddress, ethTx)
})
}
-
- restoreKeyring(serialized) {
- const { type, data } = serialized
- const Keyring = this.getKeyringClassForType(type)
- const keyring = new Keyring()
- keyring.deserialize(data)
-
- const accounts = keyring.getAccounts()
- this.setupAccounts(accounts)
-
- this.keyrings.push(keyring)
- return keyring
- }
-
- getKeyringClassForType(type) {
- const Keyring = this.keyringTypes.reduce((res, kr) => {
- if (kr.type() === type) {
- return kr
- } else {
- return res
- }
- })
- return Keyring
- }
-
- getAccounts() {
- const keyrings = this.keyrings || []
- return keyrings.map(kr => kr.getAccounts())
- .reduce((res, arr) => {
- return res.concat(arr)
- }, [])
- }
-
- setSelectedAddress(address, cb) {
- var addr = normalize(address)
- this.configManager.setSelectedAccount(addr)
- cb(null, addr)
- }
-
- addUnconfirmedTransaction(txParams, onTxDoneCb, cb) {
- var self = this
- const configManager = this.configManager
-
- // create txData obj with parameters and meta data
- var time = (new Date()).getTime()
- var txId = createId()
- txParams.metamaskId = txId
- txParams.metamaskNetworkId = this.network
- var txData = {
- id: txId,
- txParams: txParams,
- time: time,
- status: 'unconfirmed',
- gasMultiplier: configManager.getGasMultiplier() || 1,
- }
-
-
- // keep the onTxDoneCb around for after approval/denial (requires user interaction)
- // This onTxDoneCb fires completion to the Dapp's write operation.
- this._unconfTxCbs[txId] = onTxDoneCb
-
- var provider = this.ethStore._query.currentProvider
- var query = new EthQuery(provider)
-
- // calculate metadata for tx
- async.parallel([
- analyzeForDelegateCall,
- estimateGas,
- ], didComplete)
-
- // perform static analyis on the target contract code
- function analyzeForDelegateCall(cb){
- if (txParams.to) {
- query.getCode(txParams.to, function (err, result) {
- if (err) return cb(err)
- var code = ethUtil.toBuffer(result)
- if (code !== '0x') {
- var ops = ethBinToOps(code)
- var containsDelegateCall = ops.some((op) => op.name === 'DELEGATECALL')
- txData.containsDelegateCall = containsDelegateCall
- cb()
- } else {
- cb()
- }
- })
- } else {
- cb()
- }
- }
-
- function estimateGas(cb){
- query.estimateGas(txParams, function(err, result){
- if (err) return cb(err)
- txData.estimatedGas = self.addGasBuffer(result)
- cb()
- })
- }
-
- function didComplete (err) {
- if (err) return cb(err)
- configManager.addTx(txData)
- // signal update
- self.emit('update')
- // signal completion of add tx
- cb(null, txData)
- }
- }
-
- addUnconfirmedMessage(msgParams, cb) {
+ // Add Unconfirmed Message
+ // @object msgParams
+ // @function cb
+ //
+ // Does not call back, only emits an `update` event.
+ //
+ // Adds the given `msgParams` and `cb` to a local cache,
+ // for displaying to a user for approval before signing or canceling.
+ addUnconfirmedMessage (msgParams, cb) {
// create txData obj with parameters and meta data
var time = (new Date()).getTime()
var msgId = createId()
@@ -427,125 +353,313 @@ module.exports = class KeyringController extends EventEmitter {
return msgId
}
- approveTransaction(txId, cb) {
- const configManager = this.configManager
- var approvalCb = this._unconfTxCbs[txId] || noop
-
- // accept tx
- cb()
- approvalCb(null, true)
- // clean up
- configManager.confirmTx(txId)
- delete this._unconfTxCbs[txId]
- this.emit('update')
- }
-
- cancelTransaction(txId, cb) {
- const configManager = this.configManager
- var approvalCb = this._unconfTxCbs[txId] || noop
+ // Cancel Message
+ // @string msgId
+ // @function cb (optional)
+ //
+ // Calls back to cached `unconfMsgCb`.
+ // Calls back to `cb` if provided.
+ //
+ // Forgets any messages matching `msgId`.
+ cancelMessage (msgId, cb) {
+ var approvalCb = this._unconfMsgCbs[msgId] || noop
// reject tx
approvalCb(null, false)
// clean up
- configManager.rejectTx(txId)
- delete this._unconfTxCbs[txId]
+ messageManager.rejectMsg(msgId)
+ delete this._unconfTxCbs[msgId]
if (cb && typeof cb === 'function') {
cb()
}
}
- signTransaction(txParams, cb) {
+ // Sign Message
+ // @object msgParams
+ // @function cb
+ //
+ // returns Promise(@buffer rawSig)
+ // calls back @function cb with @buffer rawSig
+ // calls back cached Dapp's @function unconfMsgCb.
+ //
+ // Attempts to sign the provided @object msgParams.
+ signMessage (msgParams, cb) {
try {
- const address = normalize(txParams.from)
- const keyring = this.getKeyringForAccount(address)
-
- // Handle gas pricing
- var gasMultiplier = this.configManager.getGasMultiplier() || 1
- var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16)
- gasPrice = gasPrice.mul(new BN(gasMultiplier * 100, 10)).div(new BN(100, 10))
- txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber())
-
- // normalize values
- txParams.to = normalize(txParams.to)
- txParams.from = normalize(txParams.from)
- txParams.value = normalize(txParams.value)
- txParams.data = normalize(txParams.data)
- txParams.gasLimit = normalize(txParams.gasLimit || txParams.gas)
- txParams.nonce = normalize(txParams.nonce)
-
- let tx = new Transaction(txParams)
- tx = keyring.signTransaction(address, tx)
-
- // Add the tx hash to the persisted meta-tx object
- var txHash = ethUtil.bufferToHex(tx.hash())
- var metaTx = this.configManager.getTx(txParams.metamaskId)
- metaTx.hash = txHash
- this.configManager.updateTx(metaTx)
-
- // return raw serialized tx
- var rawTx = ethUtil.bufferToHex(tx.serialize())
- cb(null, rawTx)
- } catch (e) {
- cb(e)
- }
- }
+ const msgId = msgParams.metamaskId
+ delete msgParams.metamaskId
+ const approvalCb = this._unconfMsgCbs[msgId] || noop
- signMessage(msgParams, cb) {
- try {
- const keyring = this.getKeyringForAccount(msgParams.from)
const address = normalize(msgParams.from)
- const rawSig = keyring.signMessage(address, msgParams.data)
- cb(null, rawSig)
+ return this.getKeyringForAccount(address)
+ .then((keyring) => {
+ return keyring.signMessage(address, msgParams.data)
+ }).then((rawSig) => {
+ cb(null, rawSig)
+ approvalCb(null, true)
+ messageManager.confirmMsg(msgId)
+ return rawSig
+ })
} catch (e) {
cb(e)
}
}
- getKeyringForAccount(address) {
- const hexed = normalize(address)
- return this.keyrings.find((ring) => {
- return ring.getAccounts()
- .map(normalize)
- .includes(hexed)
+ // PRIVATE METHODS
+ //
+ // THESE METHODS ARE ONLY USED INTERNALLY TO THE KEYRING-CONTROLLER
+ // AND SO MAY BE CHANGED MORE LIBERALLY THAN THE ABOVE METHODS.
+
+ // Create First Key Tree
+ // returns @Promise
+ //
+ // Clears the vault,
+ // creates a new one,
+ // creates a random new HD Keyring with 1 account,
+ // makes that account the selected account,
+ // faucets that account on testnet,
+ // puts the current seed words into the state tree.
+ createFirstKeyTree () {
+ this.clearKeyrings()
+ return this.addNewKeyring('HD Key Tree', {numberOfAccounts: 1})
+ .then(() => {
+ return this.keyrings[0].getAccounts()
+ })
+ .then((accounts) => {
+ const firstAccount = accounts[0]
+ const hexAccount = normalize(firstAccount)
+ this.configManager.setSelectedAccount(hexAccount)
+ this.emit('newAccount', hexAccount)
+ return this.setupAccounts(accounts)
+ }).then(() => {
+ return this.placeSeedWords()
+ })
+ .then(this.persistAllKeyrings.bind(this))
+ }
+
+ // Setup Accounts
+ // @array accounts
+ //
+ // returns @Promise(@object account)
+ //
+ // Initializes the provided account array
+ // Gives them numerically incremented nicknames,
+ // and adds them to the ethStore for regular balance checking.
+ setupAccounts (accounts) {
+ return this.getAccounts()
+ .then((loadedAccounts) => {
+ const arr = accounts || loadedAccounts
+ return Promise.all(arr.map((account) => {
+ return this.getBalanceAndNickname(account)
+ }))
})
}
- cancelMessage(msgId, cb) {
- if (cb && typeof cb === 'function') {
- cb()
+ // Get Balance And Nickname
+ // @string account
+ //
+ // returns Promise( @string label )
+ //
+ // Takes an account address and an iterator representing
+ // the current number of named accounts.
+ getBalanceAndNickname (account) {
+ if (!account) {
+ throw new Error('Problem loading account.')
+ }
+ const address = normalize(account)
+ this.ethStore.addAccount(address)
+ return this.createNickname(address)
+ }
+
+ // Create Nickname
+ // @string address
+ //
+ // returns Promise( @string label )
+ //
+ // Takes an address, and assigns it an incremented nickname, persisting it.
+ createNickname (address) {
+ const hexAddress = normalize(address)
+ var i = Object.keys(this.identities).length
+ const oldNickname = this.configManager.nicknameForWallet(address)
+ const name = oldNickname || `Account ${++i}`
+ this.identities[hexAddress] = {
+ address: hexAddress,
+ name,
}
+ return this.saveAccountLabel(hexAddress, name)
}
- setLocked(cb) {
- this.key = null
- this.keyrings = []
- cb()
+ // Persist All Keyrings
+ // @password string
+ //
+ // returns Promise
+ //
+ // Iterates the current `keyrings` array,
+ // serializes each one into a serialized array,
+ // encrypts that array with the provided `password`,
+ // and persists that encrypted string to storage.
+ persistAllKeyrings (password = this.password) {
+ if (typeof password === 'string') {
+ this.password = password
+ }
+ return Promise.all(this.keyrings.map((keyring) => {
+ return Promise.all([keyring.type, keyring.serialize()])
+ .then((serializedKeyringArray) => {
+ // Label the output values on each serialized Keyring:
+ return {
+ type: serializedKeyringArray[0],
+ data: serializedKeyringArray[1],
+ }
+ })
+ }))
+ .then((serializedKeyrings) => {
+ return this.encryptor.encrypt(this.password, serializedKeyrings)
+ })
+ .then((encryptedString) => {
+ this.configManager.setVault(encryptedString)
+ return true
+ })
}
- exportAccount(address, cb) {
- try {
- const keyring = this.getKeyringForAccount(address)
- const privateKey = keyring.exportAccount(normalize(address))
- cb(null, privateKey)
- } catch (e) {
- cb(e)
+ // Unlock Keyrings
+ // @string password
+ //
+ // returns Promise( @array keyrings )
+ //
+ // Attempts to unlock the persisted encrypted storage,
+ // initializing the persisted keyrings to RAM.
+ unlockKeyrings (password) {
+ const encryptedVault = this.configManager.getVault()
+ if (!encryptedVault) {
+ throw new Error('Cannot unlock without a previous vault.')
}
+
+ return this.encryptor.decrypt(password, encryptedVault)
+ .then((vault) => {
+ this.password = password
+ vault.forEach(this.restoreKeyring.bind(this))
+ return this.keyrings
+ })
}
- addGasBuffer(gasHex) {
- var gas = new BN(gasHex, 16)
- var buffer = new BN('100000', 10)
- var result = gas.add(buffer)
- return normalize(result.toString(16))
+ // Restore Keyring
+ // @object serialized
+ //
+ // returns Promise( @Keyring deserialized )
+ //
+ // Attempts to initialize a new keyring from the provided
+ // serialized payload.
+ //
+ // On success, returns the resulting @Keyring instance.
+ restoreKeyring (serialized) {
+ const { type, data } = serialized
+
+ const Keyring = this.getKeyringClassForType(type)
+ const keyring = new Keyring()
+ return keyring.deserialize(data)
+ .then(() => {
+ return keyring.getAccounts()
+ })
+ .then((accounts) => {
+ return this.setupAccounts(accounts)
+ })
+ .then(() => {
+ this.keyrings.push(keyring)
+ return keyring
+ })
}
- clearSeedWordCache(cb) {
- this.configManager.setSeedWords(null)
- cb(null, this.configManager.getSelectedAccount())
+ // Get Keyring Class For Type
+ // @string type
+ //
+ // Returns @class Keyring
+ //
+ // Searches the current `keyringTypes` array
+ // for a Keyring class whose unique `type` property
+ // matches the provided `type`,
+ // returning it if it exists.
+ getKeyringClassForType (type) {
+ return this.keyringTypes.find(kr => kr.type === type)
+ }
+
+ // Get Accounts
+ // returns Promise( @Array[ @string accounts ] )
+ //
+ // Returns the public addresses of all current accounts
+ // managed by all currently unlocked keyrings.
+ getAccounts () {
+ const keyrings = this.keyrings || []
+ return Promise.all(keyrings.map(kr => kr.getAccounts()))
+ .then((keyringArrays) => {
+ return keyringArrays.reduce((res, arr) => {
+ return res.concat(arr)
+ }, [])
+ })
}
- clearKeyrings() {
+ // Get Keyring For Account
+ // @string address
+ //
+ // returns Promise(@Keyring keyring)
+ //
+ // Returns the currently initialized keyring that manages
+ // the specified `address` if one exists.
+ getKeyringForAccount (address) {
+ const hexed = normalize(address)
+
+ return Promise.all(this.keyrings.map((keyring) => {
+ return Promise.all([
+ keyring,
+ keyring.getAccounts(),
+ ])
+ }))
+ .then(filter((candidate) => {
+ const accounts = candidate[1].map(normalize)
+ return accounts.includes(hexed)
+ }))
+ .then((winners) => {
+ if (winners && winners.length > 0) {
+ return winners[0][0]
+ } else {
+ throw new Error('No keyring found for the requested account.')
+ }
+ })
+ }
+
+ // Display For Keyring
+ // @Keyring keyring
+ //
+ // returns Promise( @Object { type:String, accounts:Array } )
+ //
+ // Is used for adding the current keyrings to the state object.
+ displayForKeyring (keyring) {
+ return keyring.getAccounts()
+ .then((accounts) => {
+ return {
+ type: keyring.type,
+ accounts: accounts,
+ }
+ })
+ }
+
+ // Add Gas Buffer
+ // @string gas (as hexadecimal value)
+ //
+ // returns @string bufferedGas (as hexadecimal value)
+ //
+ // Adds a healthy buffer of gas to an initial gas estimate.
+ addGasBuffer (gas) {
+ const gasBuffer = new BN('100000', 10)
+ const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
+ const correct = bnGas.add(gasBuffer)
+ return ethUtil.addHexPrefix(correct.toString(16))
+ }
+
+ // Clear Keyrings
+ //
+ // Deallocates all currently managed keyrings and accounts.
+ // Used before initializing a new vault.
+ clearKeyrings () {
let accounts
try {
accounts = Object.keys(this.ethStore._currentState.accounts)
@@ -563,9 +677,5 @@ module.exports = class KeyringController extends EventEmitter {
}
-function normalize(address) {
- if (!address) return
- return ethUtil.addHexPrefix(address.toLowerCase())
-}
function noop () {}
diff --git a/app/scripts/keyrings/hd.js b/app/scripts/keyrings/hd.js
index 4bfc56c15..1b9796e07 100644
--- a/app/scripts/keyrings/hd.js
+++ b/app/scripts/keyrings/hd.js
@@ -2,106 +2,110 @@ const EventEmitter = require('events').EventEmitter
const hdkey = require('ethereumjs-wallet/hdkey')
const bip39 = require('bip39')
const ethUtil = require('ethereumjs-util')
-const type = 'HD Key Tree'
+
+// *Internal Deps
const sigUtil = require('../lib/sig-util')
+// Options:
const hdPathString = `m/44'/60'/0'/0`
+const type = 'HD Key Tree'
-module.exports = class HdKeyring extends EventEmitter {
+class HdKeyring extends EventEmitter {
- static type() {
- return type
- }
+ /* PUBLIC METHODS */
- constructor(opts = {}) {
+ constructor (opts = {}) {
super()
this.type = type
this.deserialize(opts)
}
- deserialize(opts = {}) {
+ serialize () {
+ return Promise.resolve({
+ mnemonic: this.mnemonic,
+ numberOfAccounts: this.wallets.length,
+ })
+ }
+
+ deserialize (opts = {}) {
this.opts = opts || {}
this.wallets = []
this.mnemonic = null
this.root = null
- if ('mnemonic' in opts) {
- this.initFromMnemonic(opts.mnemonic)
+ if (opts.mnemonic) {
+ this._initFromMnemonic(opts.mnemonic)
}
- if ('n' in opts) {
- this.addAccounts(opts.n)
- }
- }
-
- initFromMnemonic(mnemonic) {
- this.mnemonic = mnemonic
- const seed = bip39.mnemonicToSeed(mnemonic)
- this.hdWallet = hdkey.fromMasterSeed(seed)
- this.root = this.hdWallet.derivePath(hdPathString)
- }
-
- serialize() {
- return {
- mnemonic: this.mnemonic,
- n: this.wallets.length,
+ if (opts.numberOfAccounts) {
+ return this.addAccounts(opts.numberOfAccounts)
}
- }
- exportAccount(address) {
- const wallet = this.getWalletForAccount(address)
- return wallet.getPrivateKey().toString('hex')
+ return Promise.resolve([])
}
- addAccounts(n = 1) {
+ addAccounts (numberOfAccounts = 1) {
if (!this.root) {
- this.initFromMnemonic(bip39.generateMnemonic())
+ this._initFromMnemonic(bip39.generateMnemonic())
}
const oldLen = this.wallets.length
const newWallets = []
- for (let i = oldLen; i < n + oldLen; i++) {
+ for (let i = oldLen; i < numberOfAccounts + oldLen; i++) {
const child = this.root.deriveChild(i)
const wallet = child.getWallet()
newWallets.push(wallet)
this.wallets.push(wallet)
}
- return newWallets.map(w => w.getAddress().toString('hex'))
+ const hexWallets = newWallets.map(w => w.getAddress().toString('hex'))
+ return Promise.resolve(hexWallets)
}
- getAccounts() {
- return this.wallets.map(w => w.getAddress().toString('hex'))
+ getAccounts () {
+ return Promise.resolve(this.wallets.map(w => w.getAddress().toString('hex')))
}
// tx is an instance of the ethereumjs-transaction class.
- signTransaction(address, tx) {
- const wallet = this.getWalletForAccount(address)
+ signTransaction (address, tx) {
+ const wallet = this._getWalletForAccount(address)
var privKey = wallet.getPrivateKey()
tx.sign(privKey)
- return tx
+ return Promise.resolve(tx)
}
// For eth_sign, we need to sign transactions:
- signMessage(withAccount, data) {
- const wallet = this.getWalletForAccount(withAccount)
- const message = ethUtil.removeHexPrefix(data)
+ signMessage (withAccount, data) {
+ const wallet = this._getWalletForAccount(withAccount)
+ const message = ethUtil.stripHexPrefix(data)
var privKey = wallet.getPrivateKey()
var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey)
var rawMsgSig = ethUtil.bufferToHex(sigUtil.concatSig(msgSig.v, msgSig.r, msgSig.s))
- return rawMsgSig
+ return Promise.resolve(rawMsgSig)
}
- getWalletForAccount(account) {
- return this.wallets.find((w) => {
- const address = w.getAddress().toString('hex')
- return ((address === account) || (normalize(address) === account))
- })
+ exportAccount (address) {
+ const wallet = this._getWalletForAccount(address)
+ return Promise.resolve(wallet.getPrivateKey().toString('hex'))
}
+ /* PRIVATE METHODS */
-}
+ _initFromMnemonic (mnemonic) {
+ this.mnemonic = mnemonic
+ const seed = bip39.mnemonicToSeed(mnemonic)
+ this.hdWallet = hdkey.fromMasterSeed(seed)
+ this.root = this.hdWallet.derivePath(hdPathString)
+ }
-function normalize(address) {
- return ethUtil.addHexPrefix(address.toLowerCase())
+
+ _getWalletForAccount (account) {
+ return this.wallets.find((w) => {
+ const address = w.getAddress().toString('hex')
+ return ((address === account) || (sigUtil.normalize(address) === account))
+ })
+ }
}
+
+HdKeyring.type = type
+module.exports = HdKeyring
diff --git a/app/scripts/keyrings/simple.js b/app/scripts/keyrings/simple.js
index 9e832f274..d604430b8 100644
--- a/app/scripts/keyrings/simple.js
+++ b/app/scripts/keyrings/simple.js
@@ -4,65 +4,78 @@ const ethUtil = require('ethereumjs-util')
const type = 'Simple Key Pair'
const sigUtil = require('../lib/sig-util')
-module.exports = class SimpleKeyring extends EventEmitter {
+class SimpleKeyring extends EventEmitter {
- static type() {
- return type
- }
+ /* PUBLIC METHODS */
- constructor(opts) {
+ constructor (opts) {
super()
this.type = type
this.opts = opts || {}
this.wallets = []
}
- serialize() {
- return this.wallets.map(w => w.getPrivateKey().toString('hex'))
+ serialize () {
+ return Promise.resolve(this.wallets.map(w => w.getPrivateKey().toString('hex')))
}
- deserialize(wallets = []) {
- this.wallets = wallets.map((w) => {
- var b = new Buffer(w, 'hex')
- const wallet = Wallet.fromPrivateKey(b)
+ deserialize (privateKeys = []) {
+ this.wallets = privateKeys.map((privateKey) => {
+ const stripped = ethUtil.stripHexPrefix(privateKey)
+ const buffer = new Buffer(stripped, 'hex')
+ const wallet = Wallet.fromPrivateKey(buffer)
return wallet
})
+ return Promise.resolve()
}
- addAccounts(n = 1) {
+ addAccounts (n = 1) {
var newWallets = []
for (var i = 0; i < n; i++) {
newWallets.push(Wallet.generate())
}
this.wallets = this.wallets.concat(newWallets)
- return newWallets.map(w => w.getAddress().toString('hex'))
+ const hexWallets = newWallets.map(w => ethUtil.bufferToHex(w.getAddress()))
+ return Promise.resolve(hexWallets)
}
- getAccounts() {
- return this.wallets.map(w => w.getAddress().toString('hex'))
+ getAccounts () {
+ return Promise.resolve(this.wallets.map(w => ethUtil.bufferToHex(w.getAddress())))
}
// tx is an instance of the ethereumjs-transaction class.
- signTransaction(address, tx) {
- const wallet = this.getWalletForAccount(address)
+ signTransaction (address, tx) {
+ const wallet = this._getWalletForAccount(address)
var privKey = wallet.getPrivateKey()
tx.sign(privKey)
- return tx
+ return Promise.resolve(tx)
}
// For eth_sign, we need to sign transactions:
- signMessage(withAccount, data) {
- const wallet = this.getWalletForAccount(withAccount)
- const message = ethUtil.removeHexPrefix(data)
+ signMessage (withAccount, data) {
+ const wallet = this._getWalletForAccount(withAccount)
+ const message = ethUtil.stripHexPrefix(data)
var privKey = wallet.getPrivateKey()
var msgSig = ethUtil.ecsign(new Buffer(message, 'hex'), privKey)
var rawMsgSig = ethUtil.bufferToHex(sigUtil.concatSig(msgSig.v, msgSig.r, msgSig.s))
- return rawMsgSig
+ return Promise.resolve(rawMsgSig)
+ }
+
+ exportAccount (address) {
+ const wallet = this._getWalletForAccount(address)
+ return Promise.resolve(wallet.getPrivateKey().toString('hex'))
}
- getWalletForAccount(account) {
- return this.wallets.find(w => w.getAddress().toString('hex') === account)
+
+ /* PRIVATE METHODS */
+
+ _getWalletForAccount (account) {
+ let wallet = this.wallets.find(w => ethUtil.bufferToHex(w.getAddress()) === account)
+ if (!wallet) throw new Error('Simple Keyring - Unable to find matching address.')
+ return wallet
}
}
+SimpleKeyring.type = type
+module.exports = SimpleKeyring
diff --git a/app/scripts/lib/auto-reload.js b/app/scripts/lib/auto-reload.js
index 3c90905db..1302df35f 100644
--- a/app/scripts/lib/auto-reload.js
+++ b/app/scripts/lib/auto-reload.js
@@ -18,17 +18,16 @@ function setupDappAutoReload (web3) {
return handleResetRequest
- function handleResetRequest() {
+ function handleResetRequest () {
resetWasRequested = true
// ignore if web3 was not used
if (!pageIsUsingWeb3) return
// reload after short timeout
setTimeout(triggerReset, 500)
}
-
}
// reload the page
function triggerReset () {
global.location.reload()
-} \ No newline at end of file
+}
diff --git a/app/scripts/lib/config-manager.js b/app/scripts/lib/config-manager.js
index f50d95c12..e927c78ec 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -1,12 +1,12 @@
const Migrator = require('pojo-migrator')
const MetamaskConfig = require('../config.js')
const migrations = require('./migrations')
-const rp = require('request-promise')
const ethUtil = require('ethereumjs-util')
+const normalize = require('./sig-util').normalize
const TESTNET_RPC = MetamaskConfig.network.testnet
const MAINNET_RPC = MetamaskConfig.network.mainnet
-const txLimit = 40
+const MORDEN_RPC = MetamaskConfig.network.morden
/* The config-manager is a convenience object
* wrapping a pojo-migrator.
@@ -17,8 +17,6 @@ const txLimit = 40
*/
module.exports = ConfigManager
function ConfigManager (opts) {
- this.txLimit = txLimit
-
// ConfigManager is observable and will emit updates
this._subs = []
@@ -119,7 +117,7 @@ ConfigManager.prototype.setVault = function (encryptedString) {
ConfigManager.prototype.getVault = function () {
var data = this.getData()
- return ('vault' in data) && data.vault
+ return data.vault
}
ConfigManager.prototype.getKeychains = function () {
@@ -182,6 +180,9 @@ ConfigManager.prototype.getCurrentRpcAddress = function () {
case 'testnet':
return TESTNET_RPC
+ case 'morden':
+ return MORDEN_RPC
+
default:
return provider && provider.rpcTarget ? provider.rpcTarget : TESTNET_RPC
}
@@ -204,61 +205,12 @@ ConfigManager.prototype.getTxList = function () {
}
}
-ConfigManager.prototype.unconfirmedTxs = function () {
- var transactions = this.getTxList()
- return transactions.filter(tx => tx.status === 'unconfirmed')
- .reduce((result, tx) => { result[tx.id] = tx; return result }, {})
-}
-
-ConfigManager.prototype._saveTxList = function (txList) {
+ConfigManager.prototype.setTxList = function (txList) {
var data = this.migrator.getData()
data.transactions = txList
this.setData(data)
}
-ConfigManager.prototype.addTx = function (tx) {
- var transactions = this.getTxList()
- while (transactions.length > this.txLimit - 1) {
- transactions.shift()
- }
- transactions.push(tx)
- this._saveTxList(transactions)
-}
-
-ConfigManager.prototype.getTx = function (txId) {
- var transactions = this.getTxList()
- var matching = transactions.filter(tx => tx.id === txId)
- return matching.length > 0 ? matching[0] : null
-}
-
-ConfigManager.prototype.confirmTx = function (txId) {
- this._setTxStatus(txId, 'confirmed')
-}
-
-ConfigManager.prototype.rejectTx = function (txId) {
- this._setTxStatus(txId, 'rejected')
-}
-
-ConfigManager.prototype._setTxStatus = function (txId, status) {
- var tx = this.getTx(txId)
- tx.status = status
- this.updateTx(tx)
-}
-
-ConfigManager.prototype.updateTx = function (tx) {
- var transactions = this.getTxList()
- var found, index
- transactions.forEach((otherTx, i) => {
- if (otherTx.id === tx.id) {
- found = true
- index = i
- }
- })
- if (found) {
- transactions[index] = tx
- }
- this._saveTxList(transactions)
-}
// wallet nickname methods
@@ -269,13 +221,13 @@ ConfigManager.prototype.getWalletNicknames = function () {
}
ConfigManager.prototype.nicknameForWallet = function (account) {
- const address = ethUtil.addHexPrefix(account.toLowerCase())
+ const address = normalize(account)
const nicknames = this.getWalletNicknames()
return nicknames[address]
}
ConfigManager.prototype.setNicknameForWallet = function (account, nickname) {
- const address = ethUtil.addHexPrefix(account.toLowerCase())
+ const address = normalize(account)
const nicknames = this.getWalletNicknames()
nicknames[address] = nickname
var data = this.getData()
@@ -290,7 +242,7 @@ ConfigManager.prototype.getSalt = function () {
return ('salt' in data) && data.salt
}
-ConfigManager.prototype.setSalt = function(salt) {
+ConfigManager.prototype.setSalt = function (salt) {
var data = this.getData()
data.salt = salt
this.setData(data)
@@ -313,15 +265,15 @@ ConfigManager.prototype._emitUpdates = function (state) {
})
}
-ConfigManager.prototype.setConfirmed = function (confirmed) {
+ConfigManager.prototype.setConfirmedDisclaimer = function (confirmed) {
var data = this.getData()
- data.isConfirmed = confirmed
+ data.isDisclaimerConfirmed = confirmed
this.setData(data)
}
-ConfigManager.prototype.getConfirmed = function () {
+ConfigManager.prototype.getConfirmedDisclaimer = function () {
var data = this.getData()
- return ('isConfirmed' in data) && data.isConfirmed
+ return ('isDisclaimerConfirmed' in data) && data.isDisclaimerConfirmed
}
ConfigManager.prototype.setTOSHash = function (hash) {
@@ -348,17 +300,16 @@ ConfigManager.prototype.getCurrentFiat = function () {
ConfigManager.prototype.updateConversionRate = function () {
var data = this.getData()
- return rp(`https://www.cryptonator.com/api/ticker/eth-${data.fiatCurrency}`)
- .then((response) => {
- const parsedResponse = JSON.parse(response)
+ return fetch(`https://www.cryptonator.com/api/ticker/eth-${data.fiatCurrency}`)
+ .then(response => response.json())
+ .then((parsedResponse) => {
this.setConversionPrice(parsedResponse.ticker.price)
this.setConversionDate(parsedResponse.timestamp)
}).catch((err) => {
- console.error('Error in conversion.', err)
+ console.warn('MetaMask - Failed to query currency conversion.')
this.setConversionPrice(0)
this.setConversionDate('N/A')
})
-
}
ConfigManager.prototype.setConversionPrice = function (price) {
@@ -428,3 +379,14 @@ ConfigManager.prototype.setGasMultiplier = function (gasMultiplier) {
data.gasMultiplier = gasMultiplier
this.setData(data)
}
+
+ConfigManager.prototype.setLostAccounts = function (lostAccounts) {
+ var data = this.getData()
+ data.lostAccounts = lostAccounts
+ this.setData(data)
+}
+
+ConfigManager.prototype.getLostAccounts = function () {
+ var data = this.getData()
+ return data.lostAccounts || []
+}
diff --git a/app/scripts/lib/encryptor.js b/app/scripts/lib/encryptor.js
deleted file mode 100644
index fe83b86dd..000000000
--- a/app/scripts/lib/encryptor.js
+++ /dev/null
@@ -1,149 +0,0 @@
-var ethUtil = require('ethereumjs-util')
-
-module.exports = {
-
- // Simple encryption methods:
- encrypt,
- decrypt,
-
- // More advanced encryption methods:
- keyFromPassword,
- encryptWithKey,
- decryptWithKey,
-
- // Buffer <-> String methods
- convertArrayBufferViewtoString,
- convertStringToArrayBufferView,
-
- // Buffer <-> Hex string methods
- serializeBufferForStorage,
- serializeBufferFromStorage,
-
- // Buffer <-> base64 string methods
- encodeBufferToBase64,
- decodeBase64ToBuffer,
-
- generateSalt,
-}
-
-// Takes a Pojo, returns encrypted text.
-function encrypt (password, dataObj) {
- return keyFromPassword(password)
- .then(function (passwordDerivedKey) {
- return encryptWithKey(passwordDerivedKey, dataObj)
- })
-}
-
-function encryptWithKey (key, dataObj) {
- var data = JSON.stringify(dataObj)
- var dataBuffer = convertStringToArrayBufferView(data)
- var vector = global.crypto.getRandomValues(new Uint8Array(16))
-
- return global.crypto.subtle.encrypt({
- name: 'AES-GCM',
- iv: vector,
- }, key, dataBuffer).then(function(buf){
- var buffer = new Uint8Array(buf)
- var vectorStr = encodeBufferToBase64(vector)
- var vaultStr = encodeBufferToBase64(buffer)
- return `${vaultStr}\\${vectorStr}`
- })
-}
-
-// Takes encrypted text, returns the restored Pojo.
-function decrypt (password, text) {
- return keyFromPassword(password)
- .then(function (key) {
- return decryptWithKey(key, text)
- })
-}
-
-function decryptWithKey (key, text) {
- const parts = text.split('\\')
- const encryptedData = decodeBase64ToBuffer(parts[0])
- const vector = decodeBase64ToBuffer(parts[1])
- return crypto.subtle.decrypt({name: 'AES-GCM', iv: vector}, key, encryptedData)
- .then(function(result){
- const decryptedData = new Uint8Array(result)
- const decryptedStr = convertArrayBufferViewtoString(decryptedData)
- const decryptedObj = JSON.parse(decryptedStr)
- return decryptedObj
- })
- .catch(function(reason) {
- throw new Error('Incorrect password')
- })
-}
-
-function convertStringToArrayBufferView (str) {
- var bytes = new Uint8Array(str.length)
- for (var i = 0; i < str.length; i++) {
- bytes[i] = str.charCodeAt(i)
- }
-
- return bytes
-}
-
-function convertArrayBufferViewtoString (buffer) {
- var str = ''
- for (var i = 0; i < buffer.byteLength; i++) {
- str += String.fromCharCode(buffer[i])
- }
-
- return str
-}
-
-function keyFromPassword (password) {
- var passBuffer = convertStringToArrayBufferView(password)
- return global.crypto.subtle.digest('SHA-256', passBuffer)
- .then(function (passHash){
- return global.crypto.subtle.importKey('raw', passHash, {name: 'AES-GCM'}, false, ['encrypt', 'decrypt'])
- })
-}
-
-function serializeBufferFromStorage (str) {
- str = ethUtil.stripHexPrefix(str)
- var buf = new Uint8Array(str.length / 2)
- for (var i = 0; i < str.length; i += 2) {
- var seg = str.substr(i, 2)
- buf[i / 2] = parseInt(seg, 16)
- }
- return buf
-}
-
-// Should return a string, ready for storage, in hex format.
-function serializeBufferForStorage (buffer) {
- var result = '0x'
- var len = buffer.length || buffer.byteLength
- for (var i = 0; i < len; i++) {
- result += unprefixedHex(buffer[i])
- }
- return result
-}
-
-function unprefixedHex (num) {
- var hex = num.toString(16)
- while (hex.length < 2) {
- hex = '0' + hex
- }
- return hex
-}
-
-function encodeBufferToBase64 (buf) {
- var b64encoded = btoa(String.fromCharCode.apply(null, buf))
- return b64encoded
-}
-
-function decodeBase64ToBuffer (base64) {
- var buf = new Uint8Array(atob(base64).split('')
- .map(function(c) {
- return c.charCodeAt(0)
- }))
- return buf
-}
-
-function generateSalt (byteCount = 32) {
- var view = new Uint8Array(byteCount)
- global.crypto.getRandomValues(view)
- var b64encoded = btoa(String.fromCharCode.apply(null, view))
- return b64encoded
-}
diff --git a/app/scripts/lib/eth-store.js b/app/scripts/lib/eth-store.js
new file mode 100644
index 000000000..7e2caf884
--- /dev/null
+++ b/app/scripts/lib/eth-store.js
@@ -0,0 +1,146 @@
+/* Ethereum Store
+ *
+ * This module is responsible for tracking any number of accounts
+ * and caching their current balances & transaction counts.
+ *
+ * It also tracks transaction hashes, and checks their inclusion status
+ * on each new block.
+ */
+
+const EventEmitter = require('events').EventEmitter
+const inherits = require('util').inherits
+const async = require('async')
+const clone = require('clone')
+const EthQuery = require('eth-query')
+
+module.exports = EthereumStore
+
+
+inherits(EthereumStore, EventEmitter)
+function EthereumStore(engine) {
+ const self = this
+ EventEmitter.call(self)
+ self._currentState = {
+ accounts: {},
+ transactions: {},
+ }
+ self._query = new EthQuery(engine)
+
+ engine.on('block', self._updateForBlock.bind(self))
+}
+
+//
+// public
+//
+
+EthereumStore.prototype.getState = function () {
+ const self = this
+ return clone(self._currentState)
+}
+
+EthereumStore.prototype.addAccount = function (address) {
+ const self = this
+ self._currentState.accounts[address] = {}
+ self._didUpdate()
+ if (!self.currentBlockNumber) return
+ self._updateAccount(address, () => {
+ self._didUpdate()
+ })
+}
+
+EthereumStore.prototype.removeAccount = function (address) {
+ const self = this
+ delete self._currentState.accounts[address]
+ self._didUpdate()
+}
+
+EthereumStore.prototype.addTransaction = function (txHash) {
+ const self = this
+ self._currentState.transactions[txHash] = {}
+ self._didUpdate()
+ if (!self.currentBlockNumber) return
+ self._updateTransaction(self.currentBlockNumber, txHash, noop)
+}
+
+EthereumStore.prototype.removeTransaction = function (address) {
+ const self = this
+ delete self._currentState.transactions[address]
+ self._didUpdate()
+}
+
+
+//
+// private
+//
+
+EthereumStore.prototype._didUpdate = function () {
+ const self = this
+ var state = self.getState()
+ self.emit('update', state)
+}
+
+EthereumStore.prototype._updateForBlock = function (block) {
+ const self = this
+ var blockNumber = '0x' + block.number.toString('hex')
+ self.currentBlockNumber = blockNumber
+ async.parallel([
+ self._updateAccounts.bind(self),
+ self._updateTransactions.bind(self, blockNumber),
+ ], function (err) {
+ if (err) return console.error(err)
+ self.emit('block', self.getState())
+ self._didUpdate()
+ })
+}
+
+EthereumStore.prototype._updateAccounts = function (cb) {
+ var accountsState = this._currentState.accounts
+ var addresses = Object.keys(accountsState)
+ async.each(addresses, this._updateAccount.bind(this), cb)
+}
+
+EthereumStore.prototype._updateAccount = function (address, cb) {
+ var accountsState = this._currentState.accounts
+ this.getAccount(address, function (err, result) {
+ if (err) return cb(err)
+ result.address = address
+ // only populate if the entry is still present
+ if (accountsState[address]) {
+ accountsState[address] = result
+ }
+ cb(null, result)
+ })
+}
+
+EthereumStore.prototype.getAccount = function (address, cb) {
+ const query = this._query
+ async.parallel({
+ balance: query.getBalance.bind(query, address),
+ nonce: query.getTransactionCount.bind(query, address),
+ code: query.getCode.bind(query, address),
+ }, cb)
+}
+
+EthereumStore.prototype._updateTransactions = function (block, cb) {
+ const self = this
+ var transactionsState = self._currentState.transactions
+ var txHashes = Object.keys(transactionsState)
+ async.each(txHashes, self._updateTransaction.bind(self, block), cb)
+}
+
+EthereumStore.prototype._updateTransaction = function (block, txHash, cb) {
+ const self = this
+ // would use the block here to determine how many confirmations the tx has
+ var transactionsState = self._currentState.transactions
+ self._query.getTransaction(txHash, function (err, result) {
+ if (err) return cb(err)
+ // only populate if the entry is still present
+ if (transactionsState[txHash]) {
+ transactionsState[txHash] = result
+ self._didUpdate()
+ }
+ cb(null, result)
+ })
+}
+
+function noop() {}
diff --git a/app/scripts/lib/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js
index 2d1826641..655aed0af 100644
--- a/app/scripts/lib/idStore-migrator.js
+++ b/app/scripts/lib/idStore-migrator.js
@@ -1,5 +1,8 @@
const IdentityStore = require('./idStore')
-
+const HdKeyring = require('../keyrings/hd')
+const sigUtil = require('./sig-util')
+const normalize = sigUtil.normalize
+const denodeify = require('denodeify')
module.exports = class IdentityStoreMigrator {
@@ -11,7 +14,7 @@ module.exports = class IdentityStoreMigrator {
}
}
- oldSeedForPassword( password ) {
+ migratedVaultForPassword (password) {
const hasOldVault = this.hasOldVault()
const configManager = this.configManager
@@ -23,29 +26,54 @@ module.exports = class IdentityStoreMigrator {
return Promise.resolve(null)
}
- return new Promise((resolve, reject) => {
- this.idStore.submitPassword(password, (err) => {
- if (err) return reject(err)
- try {
- resolve(this.serializeVault())
- } catch (e) {
- reject(e)
- }
- })
+ const idStore = this.idStore
+ const submitPassword = denodeify(idStore.submitPassword.bind(idStore))
+
+ return submitPassword(password)
+ .then(() => {
+ const serialized = this.serializeVault()
+ return this.checkForLostAccounts(serialized)
})
}
- serializeVault() {
+ serializeVault () {
const mnemonic = this.idStore._idmgmt.getSeed()
- const n = this.idStore._getAddresses().length
+ const numberOfAccounts = this.idStore._getAddresses().length
return {
type: 'HD Key Tree',
- data: { mnemonic, n },
+ data: { mnemonic, numberOfAccounts },
}
}
- hasOldVault() {
+ checkForLostAccounts (serialized) {
+ const hd = new HdKeyring()
+ return hd.deserialize(serialized.data)
+ .then((hexAccounts) => {
+ const newAccounts = hexAccounts.map(normalize)
+ const oldAccounts = this.idStore._getAddresses().map(normalize)
+ const lostAccounts = oldAccounts.reduce((result, account) => {
+ if (newAccounts.includes(account)) {
+ return result
+ } else {
+ result.push(account)
+ return result
+ }
+ }, [])
+
+ return {
+ serialized,
+ lostAccounts: lostAccounts.map((address) => {
+ return {
+ address,
+ privateKey: this.idStore.exportAccount(address),
+ }
+ }),
+ }
+ })
+ }
+
+ hasOldVault () {
const wallet = this.configManager.getWallet()
return wallet
}
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index c566907b9..e4cbca456 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -1,19 +1,14 @@
const EventEmitter = require('events').EventEmitter
const inherits = require('util').inherits
-const async = require('async')
const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
-const EthQuery = require('eth-query')
const KeyStore = require('eth-lightwallet').keystore
const clone = require('clone')
const extend = require('xtend')
-const createId = require('web3-provider-engine/util/random-id')
-const ethBinToOps = require('eth-bin-to-ops')
const autoFaucet = require('./auto-faucet')
-const messageManager = require('./message-manager')
const DEFAULT_RPC = 'https://testrpc.metamask.io/'
const IdManagement = require('./id-management')
+
module.exports = IdentityStore
inherits(IdentityStore, EventEmitter)
@@ -34,17 +29,14 @@ function IdentityStore (opts = {}) {
selectedAddress: null,
identities: {},
}
-
// not part of serilized metamask state - only kept in memory
- this._unconfTxCbs = {}
- this._unconfMsgCbs = {}
}
//
// public
//
-IdentityStore.prototype.createNewVault = function (password, entropy, cb) {
+IdentityStore.prototype.createNewVault = function (password, cb) {
delete this._keyStore
var serializedKeystore = this.configManager.getWallet()
@@ -53,7 +45,7 @@ IdentityStore.prototype.createNewVault = function (password, entropy, cb) {
}
this.purgeCache()
- this._createVault(password, null, entropy, (err) => {
+ this._createVault(password, null, (err) => {
if (err) return cb(err)
this._autoFaucet()
@@ -77,7 +69,7 @@ IdentityStore.prototype.recoverSeed = function (cb) {
IdentityStore.prototype.recoverFromSeed = function (password, seed, cb) {
this.purgeCache()
- this._createVault(password, seed, null, (err) => {
+ this._createVault(password, seed, (err) => {
if (err) return cb(err)
this._loadIdentities()
@@ -102,11 +94,7 @@ IdentityStore.prototype.getState = function () {
isInitialized: !!configManager.getWallet() && !seedWords,
isUnlocked: this._isUnlocked(),
seedWords: seedWords,
- isConfirmed: configManager.getConfirmed(),
- unconfTxs: configManager.unconfirmedTxs(),
- transactions: configManager.getTxList(),
- unconfMsgs: messageManager.unconfirmedMsgs(),
- messages: messageManager.getMsgList(),
+ isDisclaimerConfirmed: configManager.getConfirmedDisclaimer(),
selectedAddress: configManager.getSelectedAccount(),
shapeShiftTxList: configManager.getShapeShiftTxList(),
currentFiat: configManager.getCurrentFiat(),
@@ -202,206 +190,10 @@ IdentityStore.prototype.submitPassword = function (password, cb) {
IdentityStore.prototype.exportAccount = function (address, cb) {
var privateKey = this._idmgmt.exportPrivateKey(address)
- cb(null, privateKey)
-}
-
-//
-// Transactions
-//
-
-// comes from dapp via zero-client hooked-wallet provider
-IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDoneCb, cb) {
- const configManager = this.configManager
-
- var self = this
- // create txData obj with parameters and meta data
- var time = (new Date()).getTime()
- var txId = createId()
- txParams.metamaskId = txId
- txParams.metamaskNetworkId = self._currentState.network
- var txData = {
- id: txId,
- txParams: txParams,
- time: time,
- status: 'unconfirmed',
- gasMultiplier: configManager.getGasMultiplier() || 1,
- }
-
- console.log('addUnconfirmedTransaction:', txData)
-
- // keep the onTxDoneCb around for after approval/denial (requires user interaction)
- // This onTxDoneCb fires completion to the Dapp's write operation.
- self._unconfTxCbs[txId] = onTxDoneCb
-
- var provider = self._ethStore._query.currentProvider
- var query = new EthQuery(provider)
-
- // calculate metadata for tx
- async.parallel([
- analyzeForDelegateCall,
- estimateGas,
- ], didComplete)
-
- // perform static analyis on the target contract code
- function analyzeForDelegateCall(cb){
- if (txParams.to) {
- query.getCode(txParams.to, (err, result) => {
- if (err) return cb(err)
- var containsDelegateCall = self.checkForDelegateCall(result)
- txData.containsDelegateCall = containsDelegateCall
- cb()
- })
- } else {
- cb()
- }
- }
-
- function estimateGas(cb){
- query.estimateGas(txParams, function(err, result){
- if (err) return cb(err)
- txData.estimatedGas = self.addGasBuffer(result)
- cb()
- })
- }
-
- function didComplete (err) {
- if (err) return cb(err)
- configManager.addTx(txData)
- // signal update
- self._didUpdate()
- // signal completion of add tx
- cb(null, txData)
- }
+ if (cb) cb(null, privateKey)
+ return privateKey
}
-IdentityStore.prototype.checkForDelegateCall = function (codeHex) {
- const code = ethUtil.toBuffer(codeHex)
- if (code !== '0x') {
- const ops = ethBinToOps(code)
- const containsDelegateCall = ops.some((op) => op.name === 'DELEGATECALL')
- return containsDelegateCall
- } else {
- return false
- }
-}
-
-IdentityStore.prototype.addGasBuffer = function (gasHex) {
- var gas = new BN(gasHex, 16)
- var buffer = new BN('100000', 10)
- var result = gas.add(buffer)
- return ethUtil.addHexPrefix(result.toString(16))
-}
-
-// comes from metamask ui
-IdentityStore.prototype.approveTransaction = function (txId, cb) {
- const configManager = this.configManager
- var approvalCb = this._unconfTxCbs[txId] || noop
-
- // accept tx
- cb()
- approvalCb(null, true)
- // clean up
- configManager.confirmTx(txId)
- delete this._unconfTxCbs[txId]
- this._didUpdate()
-}
-
-// comes from metamask ui
-IdentityStore.prototype.cancelTransaction = function (txId) {
- const configManager = this.configManager
- var approvalCb = this._unconfTxCbs[txId] || noop
-
- // reject tx
- approvalCb(null, false)
- // clean up
- configManager.rejectTx(txId)
- delete this._unconfTxCbs[txId]
- this._didUpdate()
-}
-
-// performs the actual signing, no autofill of params
-IdentityStore.prototype.signTransaction = function (txParams, cb) {
- try {
- console.log('signing tx...', txParams)
- var rawTx = this._idmgmt.signTx(txParams)
- cb(null, rawTx)
- } catch (err) {
- cb(err)
- }
-}
-
-//
-// Messages
-//
-
-// comes from dapp via zero-client hooked-wallet provider
-IdentityStore.prototype.addUnconfirmedMessage = function (msgParams, cb) {
- // create txData obj with parameters and meta data
- var time = (new Date()).getTime()
- var msgId = createId()
- var msgData = {
- id: msgId,
- msgParams: msgParams,
- time: time,
- status: 'unconfirmed',
- }
- messageManager.addMsg(msgData)
- console.log('addUnconfirmedMessage:', msgData)
-
- // keep the cb around for after approval (requires user interaction)
- // This cb fires completion to the Dapp's write operation.
- this._unconfMsgCbs[msgId] = cb
-
- // signal update
- this._didUpdate()
-
- return msgId
-}
-
-// comes from metamask ui
-IdentityStore.prototype.approveMessage = function (msgId, cb) {
- var approvalCb = this._unconfMsgCbs[msgId] || noop
-
- // accept msg
- cb()
- approvalCb(null, true)
- // clean up
- messageManager.confirmMsg(msgId)
- delete this._unconfMsgCbs[msgId]
- this._didUpdate()
-}
-
-// comes from metamask ui
-IdentityStore.prototype.cancelMessage = function (msgId) {
- var approvalCb = this._unconfMsgCbs[msgId] || noop
-
- // reject tx
- approvalCb(null, false)
- // clean up
- messageManager.rejectMsg(msgId)
- delete this._unconfTxCbs[msgId]
- this._didUpdate()
-}
-
-// performs the actual signing, no autofill of params
-IdentityStore.prototype.signMessage = function (msgParams, cb) {
- try {
- console.log('signing msg...', msgParams.data)
- var rawMsg = this._idmgmt.signMsg(msgParams.from, msgParams.data)
- if ('metamaskId' in msgParams) {
- var id = msgParams.metamaskId
- delete msgParams.metamaskId
-
- this.approveMessage(id, cb)
- } else {
- cb(null, rawMsg)
- }
- } catch (err) {
- cb(err)
- }
-}
-
-//
// private
//
@@ -481,7 +273,7 @@ IdentityStore.prototype.tryPassword = function (password, cb) {
})
}
-IdentityStore.prototype._createVault = function (password, seedPhrase, entropy, cb) {
+IdentityStore.prototype._createVault = function (password, seedPhrase, cb) {
const opts = {
password,
hdPathString: this.hdPathString,
@@ -556,4 +348,3 @@ IdentityStore.prototype._autoFaucet = function () {
// util
-function noop () {}
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index 052a8f5fe..11bd5cc3a 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -2,6 +2,7 @@ const Streams = require('mississippi')
const StreamProvider = require('web3-stream-provider')
const ObjectMultiplex = require('./obj-multiplex')
const RemoteStore = require('./remote-store.js').RemoteStore
+const createRandomId = require('./random-id')
module.exports = MetamaskInpageProvider
@@ -39,7 +40,7 @@ function MetamaskInpageProvider (connectionStream) {
self.idMap = {}
// handle sendAsync requests via asyncProvider
- self.sendAsync = function(payload, cb){
+ self.sendAsync = function (payload, cb) {
// rewrite request ids
var request = eachJsonMessage(payload, (message) => {
var newId = createRandomId()
@@ -48,7 +49,7 @@ function MetamaskInpageProvider (connectionStream) {
return message
})
// forward to asyncProvider
- asyncProvider.sendAsync(request, function(err, res){
+ asyncProvider.sendAsync(request, function (err, res) {
if (err) return cb(err)
// transform messages to original ids
eachJsonMessage(res, (message) => {
@@ -65,20 +66,25 @@ function MetamaskInpageProvider (connectionStream) {
MetamaskInpageProvider.prototype.send = function (payload) {
const self = this
- let selectedAddress
+ let selectedAccount
let result = null
switch (payload.method) {
case 'eth_accounts':
// read from localStorage
- selectedAddress = self.publicConfigStore.get('selectedAddress')
- result = selectedAddress ? [selectedAddress] : []
+ selectedAccount = self.publicConfigStore.get('selectedAccount')
+ result = selectedAccount ? [selectedAccount] : []
break
case 'eth_coinbase':
// read from localStorage
- selectedAddress = self.publicConfigStore.get('selectedAddress')
- result = selectedAddress || '0x0000000000000000000000000000000000000000'
+ selectedAccount = self.publicConfigStore.get('selectedAccount')
+ result = selectedAccount || '0x0000000000000000000000000000000000000000'
+ break
+
+ case 'eth_uninstallFilter':
+ self.sendAsync(payload, noop)
+ result = true
break
// throw not-supported Error
@@ -105,6 +111,8 @@ MetamaskInpageProvider.prototype.isConnected = function () {
return true
}
+MetamaskInpageProvider.prototype.isMetaMask = true
+
// util
function remoteStoreWithLocalStorageCache (storageKey) {
@@ -119,20 +127,12 @@ function remoteStoreWithLocalStorageCache (storageKey) {
return store
}
-function createRandomId(){
- const extraDigits = 3
- // 13 time digits
- const datePart = new Date().getTime() * Math.pow(10, extraDigits)
- // 3 random digits
- const extraPart = Math.floor(Math.random() * Math.pow(10, extraDigits))
- // 16 digits
- return datePart + extraPart
-}
-
-function eachJsonMessage(payload, transformFn){
+function eachJsonMessage (payload, transformFn) {
if (Array.isArray(payload)) {
return payload.map(transformFn)
} else {
return transformFn(payload)
}
}
+
+function noop () {}
diff --git a/app/scripts/lib/is-popup-or-notification.js b/app/scripts/lib/is-popup-or-notification.js
index 5c38ac823..693fa8751 100644
--- a/app/scripts/lib/is-popup-or-notification.js
+++ b/app/scripts/lib/is-popup-or-notification.js
@@ -1,4 +1,4 @@
-module.exports = function isPopupOrNotification() {
+module.exports = function isPopupOrNotification () {
const url = window.location.href
if (url.match(/popup.html$/)) {
return 'popup'
diff --git a/app/scripts/lib/nodeify.js b/app/scripts/lib/nodeify.js
new file mode 100644
index 000000000..51d89a8fb
--- /dev/null
+++ b/app/scripts/lib/nodeify.js
@@ -0,0 +1,24 @@
+module.exports = function (promiseFn) {
+ return function () {
+ var args = []
+ for (var i = 0; i < arguments.length - 1; i++) {
+ args.push(arguments[i])
+ }
+ var cb = arguments[arguments.length - 1]
+
+ const nodeified = promiseFn.apply(this, args)
+
+ if (!nodeified) {
+ const methodName = String(promiseFn).split('(')[0]
+ throw new Error(`The ${methodName} did not return a Promise, but was nodeified.`)
+ }
+ nodeified.then(function (result) {
+ cb(null, result)
+ })
+ .catch(function (reason) {
+ cb(reason)
+ })
+
+ return nodeified
+ }
+}
diff --git a/app/scripts/lib/notifications.js b/app/scripts/lib/notifications.js
index cd7535232..3db1ac6b5 100644
--- a/app/scripts/lib/notifications.js
+++ b/app/scripts/lib/notifications.js
@@ -15,12 +15,9 @@ function show () {
if (err) throw err
if (popup) {
-
// bring focus to existing popup
extension.windows.update(popup.id, { focused: true })
-
} else {
-
// create new popup
extension.windows.create({
url: 'notification.html',
@@ -29,12 +26,11 @@ function show () {
width,
height,
})
-
}
})
}
-function getWindows(cb) {
+function getWindows (cb) {
// Ignore in test environment
if (!extension.windows) {
return cb()
@@ -45,14 +41,14 @@ function getWindows(cb) {
})
}
-function getPopup(cb) {
+function getPopup (cb) {
getWindows((err, windows) => {
if (err) throw err
cb(null, getPopupIn(windows))
})
}
-function getPopupIn(windows) {
+function getPopupIn (windows) {
return windows ? windows.find((win) => {
return (win && win.type === 'popup' &&
win.height === height &&
@@ -60,7 +56,7 @@ function getPopupIn(windows) {
}) : null
}
-function closePopup() {
+function closePopup () {
getPopup((err, popup) => {
if (err) throw err
if (!popup) return
diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js
index 6f4ccc6ab..607a9c9ed 100644
--- a/app/scripts/lib/port-stream.js
+++ b/app/scripts/lib/port-stream.js
@@ -51,11 +51,11 @@ PortDuplexStream.prototype._write = function (msg, encoding, cb) {
// console.log('PortDuplexStream - sent message', msg)
this._port.postMessage(msg)
}
- cb()
} catch (err) {
// console.error(err)
- cb(new Error('PortDuplexStream - disconnected'))
+ return cb(new Error('PortDuplexStream - disconnected'))
}
+ cb()
}
// util
diff --git a/app/scripts/lib/random-id.js b/app/scripts/lib/random-id.js
new file mode 100644
index 000000000..788f3370f
--- /dev/null
+++ b/app/scripts/lib/random-id.js
@@ -0,0 +1,9 @@
+const MAX = Number.MAX_SAFE_INTEGER
+
+let idCounter = Math.round(Math.random() * MAX)
+function createRandomId () {
+ idCounter = idCounter % MAX
+ return idCounter++
+}
+
+module.exports = createRandomId
diff --git a/app/scripts/lib/sig-util.js b/app/scripts/lib/sig-util.js
index f8748f535..193dda381 100644
--- a/app/scripts/lib/sig-util.js
+++ b/app/scripts/lib/sig-util.js
@@ -12,6 +12,11 @@ module.exports = {
return ethUtil.addHexPrefix(rStr.concat(sStr, vStr)).toString('hex')
},
+ normalize: function (address) {
+ if (!address) return
+ return ethUtil.addHexPrefix(address.toLowerCase())
+ },
+
}
function padWithZeroes (number, length) {
diff --git a/app/scripts/lib/tx-utils.js b/app/scripts/lib/tx-utils.js
new file mode 100644
index 000000000..5116cb93b
--- /dev/null
+++ b/app/scripts/lib/tx-utils.js
@@ -0,0 +1,132 @@
+const async = require('async')
+const EthQuery = require('eth-query')
+const ethUtil = require('ethereumjs-util')
+const Transaction = require('ethereumjs-tx')
+const normalize = require('./sig-util').normalize
+const BN = ethUtil.BN
+
+/*
+tx-utils are utility methods for Transaction manager
+its passed a provider and that is passed to ethquery
+and used to do things like calculate gas of a tx.
+*/
+
+module.exports = class txProviderUtils {
+ constructor (provider) {
+ this.provider = provider
+ this.query = new EthQuery(provider)
+ }
+
+ analyzeGasUsage (txData, cb) {
+ var self = this
+ this.query.getBlockByNumber('latest', true, (err, block) => {
+ if (err) return cb(err)
+ async.waterfall([
+ self.estimateTxGas.bind(self, txData, block.gasLimit),
+ self.setTxGas.bind(self, txData, block.gasLimit),
+ ], cb)
+ })
+ }
+
+ estimateTxGas (txData, blockGasLimitHex, cb) {
+ const txParams = txData.txParams
+ // check if gasLimit is already specified
+ txData.gasLimitSpecified = Boolean(txParams.gas)
+ // if not, fallback to block gasLimit
+ if (!txData.gasLimitSpecified) {
+ txParams.gas = blockGasLimitHex
+ }
+ // run tx, see if it will OOG
+ this.query.estimateGas(txParams, cb)
+ }
+
+ setTxGas (txData, blockGasLimitHex, estimatedGasHex, cb) {
+ txData.estimatedGas = estimatedGasHex
+ const txParams = txData.txParams
+
+ // if gasLimit was specified and doesnt OOG,
+ // use original specified amount
+ if (txData.gasLimitSpecified) {
+ txData.estimatedGas = txParams.gas
+ cb()
+ return
+ }
+ // if gasLimit not originally specified,
+ // try adding an additional gas buffer to our estimation for safety
+ const estimatedGasBn = new BN(ethUtil.stripHexPrefix(txData.estimatedGas), 16)
+ const blockGasLimitBn = new BN(ethUtil.stripHexPrefix(blockGasLimitHex), 16)
+ const estimationWithBuffer = new BN(this.addGasBuffer(estimatedGasBn), 16)
+ // added gas buffer is too high
+ if (estimationWithBuffer.gt(blockGasLimitBn)) {
+ txParams.gas = txData.estimatedGas
+ // added gas buffer is safe
+ } else {
+ const gasWithBufferHex = ethUtil.intToHex(estimationWithBuffer)
+ txParams.gas = gasWithBufferHex
+ }
+ cb()
+ return
+ }
+
+ addGasBuffer (gas) {
+ const gasBuffer = new BN('100000', 10)
+ const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
+ const correct = bnGas.add(gasBuffer)
+ return ethUtil.addHexPrefix(correct.toString(16))
+ }
+
+ fillInTxParams (txParams, cb) {
+ let fromAddress = txParams.from
+ let reqs = {}
+
+ if (isUndef(txParams.gas)) reqs.gas = (cb) => this.query.estimateGas(txParams, cb)
+ if (isUndef(txParams.gasPrice)) reqs.gasPrice = (cb) => this.query.gasPrice(cb)
+ if (isUndef(txParams.nonce)) reqs.nonce = (cb) => this.query.getTransactionCount(fromAddress, 'pending', cb)
+
+ async.parallel(reqs, function(err, result) {
+ if (err) return cb(err)
+ // write results to txParams obj
+ Object.assign(txParams, result)
+ cb()
+ })
+ }
+
+ // builds ethTx from txParams object
+ buildEthTxFromParams (txParams, gasMultiplier = 1) {
+ // apply gas multiplyer
+ let gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice), 16)
+ // multiply and divide by 100 so as to add percision to integer mul
+ gasPrice = gasPrice.mul(new BN(gasMultiplier * 100, 10)).div(new BN(100, 10))
+ txParams.gasPrice = ethUtil.intToHex(gasPrice.toNumber())
+ // normalize values
+ txParams.to = normalize(txParams.to)
+ txParams.from = normalize(txParams.from)
+ txParams.value = normalize(txParams.value)
+ txParams.data = normalize(txParams.data)
+ txParams.gasLimit = normalize(txParams.gasLimit || txParams.gas)
+ txParams.nonce = normalize(txParams.nonce)
+ // build ethTx
+ const ethTx = new Transaction(txParams)
+ return ethTx
+ }
+
+ publishTransaction (rawTx, cb) {
+ this.query.sendRawTransaction(rawTx, cb)
+ }
+
+ validateTxParams (txParams, cb) {
+ if (('value' in txParams) && txParams.value.indexOf('-') === 0) {
+ cb(new Error(`Invalid transaction value of ${txParams.value} not a positive number.`))
+ } else {
+ cb()
+ }
+ }
+
+
+}
+
+// util
+
+function isUndef(value) {
+ return value === undefined
+}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index a165a2e2a..b94b98eac 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -1,28 +1,54 @@
+const EventEmitter = require('events')
const extend = require('xtend')
-const EthStore = require('eth-store')
+const EthStore = require('./lib/eth-store')
const MetaMaskProvider = require('web3-provider-engine/zero.js')
const KeyringController = require('./keyring-controller')
+const NoticeController = require('./notice-controller')
const messageManager = require('./lib/message-manager')
+const TxManager = require('./transaction-manager')
const HostStore = require('./lib/remote-store.js').HostStore
const Web3 = require('web3')
const ConfigManager = require('./lib/config-manager')
const extension = require('./lib/extension')
+const autoFaucet = require('./lib/auto-faucet')
+const nodeify = require('./lib/nodeify')
+const IdStoreMigrator = require('./lib/idStore-migrator')
+const version = require('../manifest.json').version
-module.exports = class MetamaskController {
+module.exports = class MetamaskController extends EventEmitter {
constructor (opts) {
+ super()
this.state = { network: 'loading' }
this.opts = opts
- this.listeners = []
this.configManager = new ConfigManager(opts)
this.keyringController = new KeyringController({
configManager: this.configManager,
+ getNetwork: this.getStateNetwork.bind(this),
})
+ // notices
+ this.noticeController = new NoticeController({
+ configManager: this.configManager,
+ })
+ this.noticeController.updateNoticesList()
+ // to be uncommented when retrieving notices from a remote server.
+ // this.noticeController.startPolling()
this.provider = this.initializeProvider(opts)
this.ethStore = new EthStore(this.provider)
this.keyringController.setStore(this.ethStore)
this.getNetwork()
this.messageManager = messageManager
+ this.txManager = new TxManager({
+ txList: this.configManager.getTxList(),
+ txHistoryLimit: 40,
+ setTxList: this.configManager.setTxList.bind(this.configManager),
+ getSelectedAccount: this.configManager.getSelectedAccount.bind(this.configManager),
+ getGasMultiplier: this.configManager.getGasMultiplier.bind(this.configManager),
+ getNetwork: this.getStateNetwork.bind(this),
+ signTransaction: this.keyringController.signTransaction.bind(this.keyringController),
+ provider: this.provider,
+ blockTracker: this.provider,
+ })
this.publicConfigStore = this.initPublicConfigStore()
var currentFiat = this.configManager.getCurrentFiat() || 'USD'
@@ -32,22 +58,40 @@ module.exports = class MetamaskController {
this.checkTOSChange()
this.scheduleConversionInterval()
+
+ // TEMPORARY UNTIL FULL DEPRECATION:
+ this.idStoreMigrator = new IdStoreMigrator({
+ configManager: this.configManager,
+ })
+
+ this.ethStore.on('update', this.sendUpdate.bind(this))
+ this.keyringController.on('update', this.sendUpdate.bind(this))
+ this.txManager.on('update', this.sendUpdate.bind(this))
}
getState () {
- return extend(
- this.state,
- this.ethStore.getState(),
- this.configManager.getConfig(),
- this.keyringController.getState()
- )
+ return this.keyringController.getState()
+ .then((keyringControllerState) => {
+ return extend(
+ this.state,
+ this.ethStore.getState(),
+ this.configManager.getConfig(),
+ this.txManager.getState(),
+ keyringControllerState,
+ this.noticeController.getState(), {
+ lostAccounts: this.configManager.getLostAccounts(),
+ }
+ )
+ })
}
getApi () {
const keyringController = this.keyringController
+ const txManager = this.txManager
+ const noticeController = this.noticeController
return {
- getState: (cb) => { cb(null, this.getState()) },
+ getState: nodeify(this.getState.bind(this)),
setRpcTarget: this.setRpcTarget.bind(this),
setProviderType: this.setProviderType.bind(this),
useEtherscanProvider: this.useEtherscanProvider.bind(this),
@@ -57,27 +101,39 @@ module.exports = class MetamaskController {
setTOSHash: this.setTOSHash.bind(this),
checkTOSChange: this.checkTOSChange.bind(this),
setGasMultiplier: this.setGasMultiplier.bind(this),
+ markAccountsFound: this.markAccountsFound.bind(this),
// forward directly to keyringController
- placeSeedWords: keyringController.placeSeedWords.bind(keyringController),
- createNewVaultAndKeychain: keyringController.createNewVaultAndKeychain.bind(keyringController),
- createNewVaultAndRestore: keyringController.createNewVaultAndRestore.bind(keyringController),
- clearSeedWordCache: keyringController.clearSeedWordCache.bind(keyringController),
- addNewKeyring: keyringController.addNewKeyring.bind(keyringController),
- addNewAccount: keyringController.addNewAccount.bind(keyringController),
- submitPassword: keyringController.submitPassword.bind(keyringController),
- setSelectedAddress: keyringController.setSelectedAddress.bind(keyringController),
- approveTransaction: keyringController.approveTransaction.bind(keyringController),
- cancelTransaction: keyringController.cancelTransaction.bind(keyringController),
+ createNewVaultAndKeychain: nodeify(keyringController.createNewVaultAndKeychain).bind(keyringController),
+ createNewVaultAndRestore: nodeify(keyringController.createNewVaultAndRestore).bind(keyringController),
+ placeSeedWords: nodeify(keyringController.placeSeedWords).bind(keyringController),
+ clearSeedWordCache: nodeify(keyringController.clearSeedWordCache).bind(keyringController),
+ setLocked: nodeify(keyringController.setLocked).bind(keyringController),
+ submitPassword: (password, cb) => {
+ this.migrateOldVaultIfAny(password)
+ .then(keyringController.submitPassword.bind(keyringController, password))
+ .then((newState) => { cb(null, newState) })
+ .catch((reason) => { cb(reason) })
+ },
+ addNewKeyring: nodeify(keyringController.addNewKeyring).bind(keyringController),
+ addNewAccount: nodeify(keyringController.addNewAccount).bind(keyringController),
+ setSelectedAccount: nodeify(keyringController.setSelectedAccount).bind(keyringController),
+ saveAccountLabel: nodeify(keyringController.saveAccountLabel).bind(keyringController),
+ exportAccount: nodeify(keyringController.exportAccount).bind(keyringController),
+
+ // signing methods
+ approveTransaction: txManager.approveTransaction.bind(txManager),
+ cancelTransaction: txManager.cancelTransaction.bind(txManager),
signMessage: keyringController.signMessage.bind(keyringController),
cancelMessage: keyringController.cancelMessage.bind(keyringController),
- setLocked: keyringController.setLocked.bind(keyringController),
- exportAccount: keyringController.exportAccount.bind(keyringController),
- saveAccountLabel: keyringController.saveAccountLabel.bind(keyringController),
+
// coinbase
buyEth: this.buyEth.bind(this),
// shapeshift
createShapeShiftTx: this.createShapeShiftTx.bind(this),
+ // notices
+ checkNotices: noticeController.updateNoticesList.bind(noticeController),
+ markNoticeRead: noticeController.markNoticeRead.bind(noticeController),
}
}
@@ -86,23 +142,6 @@ module.exports = class MetamaskController {
}
onRpcRequest (stream, originDomain, request) {
-
- /* Commented out for Parity compliance
- * Parity does not permit additional keys, like `origin`,
- * and Infura is not currently filtering this key out.
- var payloads = Array.isArray(request) ? request : [request]
- payloads.forEach(function (payload) {
- // Append origin to rpc payload
- payload.origin = originDomain
- // Append origin to signature request
- if (payload.method === 'eth_sendTransaction') {
- payload.params[0].origin = originDomain
- } else if (payload.method === 'eth_sign') {
- payload.params.push({ origin: originDomain })
- }
- })
- */
-
// handle rpc request
this.provider.sendAsync(request, function onPayloadHandled (err, response) {
logger(err, request, response)
@@ -129,8 +168,9 @@ module.exports = class MetamaskController {
}
sendUpdate () {
- this.listeners.forEach((remote) => {
- remote.sendUpdate(this.getState())
+ this.getState()
+ .then((state) => {
+ this.emit('update', state)
})
}
@@ -138,20 +178,19 @@ module.exports = class MetamaskController {
const keyringController = this.keyringController
var providerOpts = {
+ static: {
+ eth_syncing: false,
+ web3_clientVersion: `MetaMask/v${version}`,
+ },
rpcUrl: this.configManager.getCurrentRpcAddress(),
// account mgmt
getAccounts: (cb) => {
- var selectedAddress = this.configManager.getSelectedAccount()
- var result = selectedAddress ? [selectedAddress] : []
+ var selectedAccount = this.configManager.getSelectedAccount()
+ var result = selectedAccount ? [selectedAccount] : []
cb(null, result)
},
// tx signing
- approveTransaction: this.newUnsignedTransaction.bind(this),
- signTransaction: (...args) => {
- keyringController.signTransaction(...args)
- this.sendUpdate()
- },
-
+ processTransaction: (txParams, cb) => this.newUnapprovedTransaction(txParams, cb),
// msg signing
approveMessage: this.newUnsignedMessage.bind(this),
signMessage: (...args) => {
@@ -164,7 +203,6 @@ module.exports = class MetamaskController {
var web3 = new Web3(provider)
this.web3 = web3
keyringController.web3 = web3
-
provider.on('block', this.processBlock.bind(this))
provider.on('error', this.getNetwork.bind(this))
@@ -173,34 +211,22 @@ module.exports = class MetamaskController {
initPublicConfigStore () {
// get init state
- var initPublicState = extend(
- keyringControllerToPublic(this.keyringController.getState()),
- configToPublic(this.configManager.getConfig())
- )
-
+ var initPublicState = configToPublic(this.configManager.getConfig())
var publicConfigStore = new HostStore(initPublicState)
// subscribe to changes
this.configManager.subscribe(function (state) {
storeSetFromObj(publicConfigStore, configToPublic(state))
})
- this.keyringController.on('update', () => {
- const state = this.keyringController.getState()
- storeSetFromObj(publicConfigStore, keyringControllerToPublic(state))
- this.sendUpdate()
+
+ this.keyringController.on('newAccount', (account) => {
+ autoFaucet(account)
})
- // keyringController substate
- function keyringControllerToPublic (state) {
- return {
- selectedAddress: state.selectedAddress,
- }
- }
// config substate
function configToPublic (state) {
return {
- provider: state.provider,
- selectedAddress: state.selectedAccount,
+ selectedAccount: state.selectedAccount,
}
}
// dump obj into store
@@ -213,26 +239,26 @@ module.exports = class MetamaskController {
return publicConfigStore
}
- newUnsignedTransaction (txParams, onTxDoneCb) {
- const keyringController = this.keyringController
-
- let err = this.enforceTxValidations(txParams)
- if (err) return onTxDoneCb(err)
-
- keyringController.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => {
- if (err) return onTxDoneCb(err)
- this.sendUpdate()
- this.opts.showUnconfirmedTx(txParams, txData, onTxDoneCb)
+ newUnapprovedTransaction (txParams, cb) {
+ const self = this
+ self.txManager.addUnapprovedTransaction(txParams, (err, txMeta) => {
+ if (err) return cb(err)
+ self.sendUpdate()
+ self.opts.showUnapprovedTx(txMeta)
+ // listen for tx completion (success, fail)
+ self.txManager.once(`${txMeta.id}:finished`, (status) => {
+ switch (status) {
+ case 'submitted':
+ return cb(null, txMeta.hash)
+ case 'rejected':
+ return cb(new Error('MetaMask Tx Signature: User denied transaction signature.'))
+ default:
+ return cb(new Error(`MetaMask Tx Signature: Unknown problem: ${JSON.stringify(txMeta.txParams)}`))
+ }
+ })
})
}
- enforceTxValidations (txParams) {
- if (('value' in txParams) && txParams.value.indexOf('-') === 0) {
- const msg = `Invalid transaction value of ${txParams.value} not a positive number.`
- return new Error(msg)
- }
- }
-
newUnsignedMessage (msgParams, cb) {
var state = this.keyringController.getState()
if (!state.isUnlocked) {
@@ -276,7 +302,7 @@ module.exports = class MetamaskController {
setTOSHash (hash) {
try {
this.configManager.setTOSHash(hash)
- } catch (e) {
+ } catch (err) {
console.error('Error in setting terms of service hash.')
}
}
@@ -288,24 +314,25 @@ module.exports = class MetamaskController {
this.resetDisclaimer()
this.setTOSHash(global.TOS_HASH)
}
- } catch (e) {
+ } catch (err) {
console.error('Error in checking TOS change.')
}
-
}
+ // disclaimer
+
agreeToDisclaimer (cb) {
try {
- this.configManager.setConfirmed(true)
+ this.configManager.setConfirmedDisclaimer(true)
cb()
- } catch (e) {
- cb(e)
+ } catch (err) {
+ cb(err)
}
}
resetDisclaimer () {
try {
- this.configManager.setConfirmed(false)
+ this.configManager.setConfirmedDisclaimer(false)
} catch (e) {
console.error(e)
}
@@ -322,8 +349,8 @@ module.exports = class MetamaskController {
conversionDate: this.configManager.getConversionDate(),
}
cb(data)
- } catch (e) {
- cb(null, e)
+ } catch (err) {
+ cb(null, err)
}
}
@@ -360,7 +387,7 @@ module.exports = class MetamaskController {
var network = this.state.network
var url = `https://buy.coinbase.com/?code=9ec56d01-7e81-5017-930c-513daa27bb6a&amount=${amount}&address=${address}&crypto_currency=ETH`
- if (network === '2') {
+ if (network === '3') {
url = 'https://faucet.metamask.io/'
}
@@ -373,7 +400,7 @@ module.exports = class MetamaskController {
this.configManager.createShapeShiftTx(depositAddress, depositType)
}
- getNetwork(err) {
+ getNetwork (err) {
if (err) {
this.state.network = 'loading'
this.sendUpdate()
@@ -396,8 +423,74 @@ module.exports = class MetamaskController {
try {
this.configManager.setGasMultiplier(gasMultiplier)
cb()
- } catch (e) {
- cb(e)
+ } catch (err) {
+ cb(err)
+ }
+ }
+
+ getStateNetwork () {
+ return this.state.network
+ }
+
+ markAccountsFound (cb) {
+ this.configManager.setLostAccounts([])
+ this.sendUpdate()
+ cb(null, this.getState())
+ }
+
+ // Migrate Old Vault If Any
+ // @string password
+ //
+ // returns Promise()
+ //
+ // Temporary step used when logging in.
+ // Checks if old style (pre-3.0.0) Metamask Vault exists.
+ // If so, persists that vault in the new vault format
+ // with the provided password, so the other unlock steps
+ // may be completed without interruption.
+ migrateOldVaultIfAny (password) {
+
+ if (!this.checkIfShouldMigrate()) {
+ return Promise.resolve(password)
+ }
+
+ const keyringController = this.keyringController
+
+ return this.idStoreMigrator.migratedVaultForPassword(password)
+ .then(this.restoreOldVaultAccounts.bind(this))
+ .then(this.restoreOldLostAccounts.bind(this))
+ .then(keyringController.persistAllKeyrings.bind(keyringController, password))
+ .then(() => password)
+ }
+
+ checkIfShouldMigrate() {
+ return !!this.configManager.getWallet() && !this.configManager.getVault()
+ }
+
+ restoreOldVaultAccounts(migratorOutput) {
+ const { serialized } = migratorOutput
+ return this.keyringController.restoreKeyring(serialized)
+ .then(() => migratorOutput)
+ }
+
+ restoreOldLostAccounts(migratorOutput) {
+ const { lostAccounts } = migratorOutput
+ if (lostAccounts) {
+ this.configManager.setLostAccounts(lostAccounts.map(acct => acct.address))
+ return this.importLostAccounts(migratorOutput)
}
+ return Promise.resolve(migratorOutput)
+ }
+
+ // IMPORT LOST ACCOUNTS
+ // @Object with key lostAccounts: @Array accounts <{ address, privateKey }>
+ // Uses the array's private keys to create a new Simple Key Pair keychain
+ // and add it to the keyring controller.
+ importLostAccounts ({ lostAccounts }) {
+ const privKeys = lostAccounts.map(acct => acct.privateKey)
+ return this.keyringController.restoreKeyring({
+ type: 'Simple Key Pair',
+ data: privKeys,
+ })
}
}
diff --git a/app/scripts/notice-controller.js b/app/scripts/notice-controller.js
new file mode 100644
index 000000000..00c87c670
--- /dev/null
+++ b/app/scripts/notice-controller.js
@@ -0,0 +1,96 @@
+const EventEmitter = require('events').EventEmitter
+const hardCodedNotices = require('../../development/notices.json')
+
+module.exports = class NoticeController extends EventEmitter {
+
+ constructor (opts) {
+ super()
+ this.configManager = opts.configManager
+ this.noticePoller = null
+ }
+
+ getState () {
+ var lastUnreadNotice = this.getLatestUnreadNotice()
+
+ return {
+ lastUnreadNotice: lastUnreadNotice,
+ noActiveNotices: !lastUnreadNotice,
+ }
+ }
+
+ getNoticesList () {
+ var data = this.configManager.getData()
+ if ('noticesList' in data) {
+ return data.noticesList
+ } else {
+ return []
+ }
+ }
+
+ setNoticesList (list) {
+ var data = this.configManager.getData()
+ data.noticesList = list
+ this.configManager.setData(data)
+ return Promise.resolve(true)
+ }
+
+ markNoticeRead (notice, cb) {
+ cb = cb || function (err) { if (err) throw err }
+ try {
+ var notices = this.getNoticesList()
+ var id = notice.id
+ notices[id].read = true
+ this.setNoticesList(notices)
+ const latestNotice = this.getLatestUnreadNotice()
+ cb(null, latestNotice)
+ } catch (err) {
+ cb(err)
+ }
+ }
+
+ updateNoticesList () {
+ return this._retrieveNoticeData().then((newNotices) => {
+ var oldNotices = this.getNoticesList()
+ var combinedNotices = this._mergeNotices(oldNotices, newNotices)
+ return Promise.resolve(this.setNoticesList(combinedNotices))
+ })
+ }
+
+ getLatestUnreadNotice () {
+ var notices = this.getNoticesList()
+ var filteredNotices = notices.filter((notice) => {
+ return notice.read === false
+ })
+ return filteredNotices[filteredNotices.length - 1]
+ }
+
+ startPolling () {
+ if (this.noticePoller) {
+ clearInterval(this.noticePoller)
+ }
+ this.noticePoller = setInterval(() => {
+ this.noticeController.updateNoticesList()
+ }, 300000)
+ }
+
+ _mergeNotices (oldNotices, newNotices) {
+ var noticeMap = this._mapNoticeIds(oldNotices)
+ newNotices.forEach((notice) => {
+ if (noticeMap.indexOf(notice.id) === -1) {
+ oldNotices.push(notice)
+ }
+ })
+ return oldNotices
+ }
+
+ _mapNoticeIds (notices) {
+ return notices.map((notice) => notice.id)
+ }
+
+ _retrieveNoticeData () {
+ // Placeholder for the API.
+ return Promise.resolve(hardCodedNotices)
+ }
+
+
+}
diff --git a/app/scripts/popup-core.js b/app/scripts/popup-core.js
index 94413a1c4..0c97a5d19 100644
--- a/app/scripts/popup-core.js
+++ b/app/scripts/popup-core.js
@@ -9,7 +9,7 @@ const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
module.exports = initializePopup
-function initializePopup(connectionStream){
+function initializePopup (connectionStream) {
// setup app
connectToAccountManager(connectionStream, setupApp)
}
@@ -32,7 +32,7 @@ function setupWeb3Connection (connectionStream) {
}
function setupControllerConnection (connectionStream, cb) {
- // this is a really sneaky way of adding EventEmitter api
+ // this is a really sneaky way of adding EventEmitter api
// to a bi-directional dnode instance
var eventEmitter = new EventEmitter()
var accountManagerDnode = Dnode({
diff --git a/app/scripts/popup.js b/app/scripts/popup.js
index e6f149f96..62db68c10 100644
--- a/app/scripts/popup.js
+++ b/app/scripts/popup.js
@@ -18,7 +18,7 @@ var portStream = new PortStream(pluginPort)
startPopup(portStream)
-function closePopupIfOpen(name) {
+function closePopupIfOpen (name) {
if (name !== 'notification') {
notification.closePopup()
}
diff --git a/app/scripts/transaction-manager.js b/app/scripts/transaction-manager.js
new file mode 100644
index 000000000..87f99ce62
--- /dev/null
+++ b/app/scripts/transaction-manager.js
@@ -0,0 +1,362 @@
+const EventEmitter = require('events')
+const async = require('async')
+const extend = require('xtend')
+const Semaphore = require('semaphore')
+const ethUtil = require('ethereumjs-util')
+const BN = require('ethereumjs-util').BN
+const TxProviderUtil = require('./lib/tx-utils')
+const createId = require('./lib/random-id')
+
+module.exports = class TransactionManager extends EventEmitter {
+ constructor (opts) {
+ super()
+ this.txList = opts.txList || []
+ this._setTxList = opts.setTxList
+ this.txHistoryLimit = opts.txHistoryLimit
+ this.getSelectedAccount = opts.getSelectedAccount
+ this.provider = opts.provider
+ this.blockTracker = opts.blockTracker
+ this.txProviderUtils = new TxProviderUtil(this.provider)
+ this.blockTracker.on('block', this.checkForTxInBlock.bind(this))
+ this.getGasMultiplier = opts.getGasMultiplier
+ this.getNetwork = opts.getNetwork
+ this.signEthTx = opts.signTransaction
+ this.nonceLock = Semaphore(1)
+ }
+
+ getState () {
+ var selectedAccount = this.getSelectedAccount()
+ return {
+ transactions: this.getTxList(),
+ unconfTxs: this.getUnapprovedTxList(),
+ selectedAccountTxList: this.getFilteredTxList({metamaskNetworkId: this.getNetwork(), from: selectedAccount}),
+ }
+ }
+
+// Returns the tx list
+ getTxList () {
+ let network = this.getNetwork()
+ return this.txList.filter(txMeta => txMeta.metamaskNetworkId === network)
+ }
+
+ // Adds a tx to the txlist
+ addTx (txMeta) {
+ var txList = this.getTxList()
+ var txHistoryLimit = this.txHistoryLimit
+
+ // checks if the length of th tx history is
+ // longer then desired persistence limit
+ // and then if it is removes only confirmed
+ // or rejected tx's.
+ // not tx's that are pending or unapproved
+ if (txList.length > txHistoryLimit - 1) {
+ var index = txList.findIndex((metaTx) => metaTx.status === 'confirmed' || metaTx.status === 'rejected')
+ txList.splice(index, 1)
+ }
+ txList.push(txMeta)
+
+ this._saveTxList(txList)
+ this.once(`${txMeta.id}:signed`, function (txId) {
+ this.removeAllListeners(`${txMeta.id}:rejected`)
+ })
+ this.once(`${txMeta.id}:rejected`, function (txId) {
+ this.removeAllListeners(`${txMeta.id}:signed`)
+ })
+
+ this.emit('updateBadge')
+ this.emit(`${txMeta.id}:unapproved`, txMeta)
+ }
+
+ // gets tx by Id and returns it
+ getTx (txId, cb) {
+ var txList = this.getTxList()
+ var txMeta = txList.find(txData => txData.id === txId)
+ return cb ? cb(txMeta) : txMeta
+ }
+
+ //
+ updateTx (txMeta) {
+ var txId = txMeta.id
+ var txList = this.getTxList()
+ var index = txList.findIndex(txData => txData.id === txId)
+ txList[index] = txMeta
+ this._saveTxList(txList)
+ this.emit('update')
+ }
+
+ get unapprovedTxCount () {
+ return Object.keys(this.getUnapprovedTxList()).length
+ }
+
+ get pendingTxCount () {
+ return this.getTxsByMetaData('status', 'signed').length
+ }
+
+ addUnapprovedTransaction (txParams, done) {
+ let txMeta
+ async.waterfall([
+ // validate
+ (cb) => this.txProviderUtils.validateTxParams(txParams, cb),
+ // prepare txMeta
+ (cb) => {
+ // create txMeta obj with parameters and meta data
+ let time = (new Date()).getTime()
+ let txId = createId()
+ txParams.metamaskId = txId
+ txParams.metamaskNetworkId = this.getNetwork()
+ txMeta = {
+ id: txId,
+ time: time,
+ status: 'unapproved',
+ gasMultiplier: this.getGasMultiplier() || 1,
+ metamaskNetworkId: this.getNetwork(),
+ txParams: txParams,
+ }
+ // calculate metadata for tx
+ this.txProviderUtils.analyzeGasUsage(txMeta, cb)
+ },
+ // save txMeta
+ (cb) => {
+ this.addTx(txMeta)
+ this.setMaxTxCostAndFee(txMeta)
+ cb(null, txMeta)
+ },
+ ], done)
+ }
+
+ setMaxTxCostAndFee (txMeta) {
+ var txParams = txMeta.txParams
+ var gasMultiplier = txMeta.gasMultiplier
+ var gasCost = new BN(ethUtil.stripHexPrefix(txParams.gas || txMeta.estimatedGas), 16)
+ var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice || '0x4a817c800'), 16)
+ gasPrice = gasPrice.mul(new BN(gasMultiplier * 100), 10).div(new BN(100, 10))
+ var txFee = gasCost.mul(gasPrice)
+ var txValue = new BN(ethUtil.stripHexPrefix(txParams.value || '0x0'), 16)
+ var maxCost = txValue.add(txFee)
+ txMeta.txFee = txFee
+ txMeta.txValue = txValue
+ txMeta.maxCost = maxCost
+ this.updateTx(txMeta)
+ }
+
+ getUnapprovedTxList () {
+ var txList = this.getTxList()
+ return txList.filter((txMeta) => txMeta.status === 'unapproved')
+ .reduce((result, tx) => {
+ result[tx.id] = tx
+ return result
+ }, {})
+ }
+
+ approveTransaction (txId, cb = warn) {
+ const self = this
+ // approve
+ self.setTxStatusApproved(txId)
+ // only allow one tx at a time for atomic nonce usage
+ self.nonceLock.take(() => {
+ // begin signature process
+ async.waterfall([
+ (cb) => self.fillInTxParams(txId, cb),
+ (cb) => self.signTransaction(txId, cb),
+ (rawTx, cb) => self.publishTransaction(txId, rawTx, cb),
+ ], (err) => {
+ self.nonceLock.leave()
+ if (err) {
+ this.setTxStatusFailed(txId)
+ return cb(err)
+ }
+ cb()
+ })
+ })
+ }
+
+ cancelTransaction (txId, cb = warn) {
+ this.setTxStatusRejected(txId)
+ cb()
+ }
+
+ fillInTxParams (txId, cb) {
+ let txMeta = this.getTx(txId)
+ this.txProviderUtils.fillInTxParams(txMeta.txParams, (err) => {
+ if (err) return cb(err)
+ this.updateTx(txMeta)
+ cb()
+ })
+ }
+
+ signTransaction (txId, cb) {
+ let txMeta = this.getTx(txId)
+ let txParams = txMeta.txParams
+ let fromAddress = txParams.from
+ let ethTx = this.txProviderUtils.buildEthTxFromParams(txParams, txMeta.gasMultiplier)
+ this.signEthTx(ethTx, fromAddress).then(() => {
+ this.updateTxAsSigned(txMeta.id, ethTx)
+ cb(null, ethUtil.bufferToHex(ethTx.serialize()))
+ }).catch((err) => {
+ cb(err)
+ })
+ }
+
+ publishTransaction (txId, rawTx, cb) {
+ this.txProviderUtils.publishTransaction(rawTx, (err) => {
+ if (err) return cb(err)
+ this.setTxStatusSubmitted(txId)
+ cb()
+ })
+ }
+
+ // receives a signed tx object and updates the tx hash
+ updateTxAsSigned (txId, ethTx) {
+ // Add the tx hash to the persisted meta-tx object
+ let txHash = ethUtil.bufferToHex(ethTx.hash())
+ let txMeta = this.getTx(txId)
+ txMeta.hash = txHash
+ this.updateTx(txMeta)
+ this.setTxStatusSigned(txMeta.id)
+ }
+
+ /*
+ Takes an object of fields to search for eg:
+ var thingsToLookFor = {
+ to: '0x0..',
+ from: '0x0..',
+ status: 'signed',
+ }
+ and returns a list of tx with all
+ options matching
+
+ this is for things like filtering a the tx list
+ for only tx's from 1 account
+ or for filltering for all txs from one account
+ and that have been 'confirmed'
+ */
+ getFilteredTxList (opts) {
+ var filteredTxList
+ Object.keys(opts).forEach((key) => {
+ filteredTxList = this.getTxsByMetaData(key, opts[key], filteredTxList)
+ })
+ return filteredTxList
+ }
+
+ getTxsByMetaData (key, value, txList = this.getTxList()) {
+ return txList.filter((txMeta) => {
+ if (key in txMeta.txParams) {
+ return txMeta.txParams[key] === value
+ } else {
+ return txMeta[key] === value
+ }
+ })
+ }
+
+ // STATUS METHODS
+ // get::set status
+
+ // should return the status of the tx.
+ getTxStatus (txId) {
+ const txMeta = this.getTx(txId)
+ return txMeta.status
+ }
+
+ // should update the status of the tx to 'rejected'.
+ setTxStatusRejected (txId) {
+ this._setTxStatus(txId, 'rejected')
+ }
+
+ // should update the status of the tx to 'approved'.
+ setTxStatusApproved (txId) {
+ this._setTxStatus(txId, 'approved')
+ }
+
+ // should update the status of the tx to 'signed'.
+ setTxStatusSigned (txId) {
+ this._setTxStatus(txId, 'signed')
+ }
+
+ // should update the status of the tx to 'submitted'.
+ setTxStatusSubmitted (txId) {
+ this._setTxStatus(txId, 'submitted')
+ }
+
+ // should update the status of the tx to 'confirmed'.
+ setTxStatusConfirmed (txId) {
+ this._setTxStatus(txId, 'confirmed')
+ }
+
+ setTxStatusFailed (txId) {
+ this._setTxStatus(txId, 'failed')
+ }
+
+ // merges txParams obj onto txData.txParams
+ // use extend to ensure that all fields are filled
+ updateTxParams (txId, txParams) {
+ var txMeta = this.getTx(txId)
+ txMeta.txParams = extend(txMeta.txParams, txParams)
+ this.updateTx(txMeta)
+ }
+
+ // checks if a signed tx is in a block and
+ // if included sets the tx status as 'confirmed'
+ checkForTxInBlock () {
+ var signedTxList = this.getFilteredTxList({status: 'signed'})
+ if (!signedTxList.length) return
+ signedTxList.forEach((txMeta) => {
+ var txHash = txMeta.hash
+ var txId = txMeta.id
+ if (!txHash) {
+ txMeta.err = {
+ errCode: 'No hash was provided',
+ message: 'We had an error while submitting this transaction, please try again.',
+ }
+ this.updateTx(txMeta)
+ return this.setTxStatusFailed(txId)
+ }
+ this.txProviderUtils.query.getTransactionByHash(txHash, (err, txParams) => {
+ if (err || !txParams) {
+ if (!txParams) return
+ txMeta.err = {
+ isWarning: true,
+ errorCode: err,
+ message: 'There was a problem loading this transaction.',
+ }
+ this.updateTx(txMeta)
+ return console.error(err)
+ }
+ if (txParams.blockNumber) {
+ this.setTxStatusConfirmed(txId)
+ }
+ })
+ })
+ }
+
+ // PRIVATE METHODS
+
+ // Should find the tx in the tx list and
+ // update it.
+ // should set the status in txData
+ // - `'unapproved'` the user has not responded
+ // - `'rejected'` the user has responded no!
+ // - `'approved'` the user has approved the tx
+ // - `'signed'` the tx is signed
+ // - `'submitted'` the tx is sent to a server
+ // - `'confirmed'` the tx has been included in a block.
+ _setTxStatus (txId, status) {
+ var txMeta = this.getTx(txId)
+ txMeta.status = status
+ this.emit(`${txMeta.id}:${status}`, txId)
+ if (status === 'submitted' || status === 'rejected') {
+ this.emit(`${txMeta.id}:finished`, status)
+ }
+ this.updateTx(txMeta)
+ this.emit('updateBadge')
+ }
+
+ // Saves the new/updated txList.
+ // Function is intended only for internal use
+ _saveTxList (txList) {
+ this.txList = txList
+ this._setTxList(txList)
+ }
+}
+
+
+const warn = () => console.warn('warn was used no cb provided')
diff --git a/development/notice-generator.js b/development/notice-generator.js
new file mode 100644
index 000000000..08b0c9843
--- /dev/null
+++ b/development/notice-generator.js
@@ -0,0 +1,36 @@
+var fsp = require('fs-promise')
+var path = require('path')
+var prompt = require('prompt')
+var open = require('open')
+var extend = require('extend')
+var notices = require('./notices.json')
+
+var id = 0
+var date = new Date().toDateString()
+
+var notice = {
+ read: false,
+ date: date,
+}
+
+fsp.readdir('notices')
+ .then((files) => {
+ files.forEach(file => { id ++ })
+ Promise.resolve()
+ }).then(() => {
+ fsp.writeFile(`notices/notice_${id}.md`,'Message goes here. Please write out your notice and save before proceeding at the command line.')
+ .then(() => {
+ open(`notices/notice_${id}.md`)
+ prompt.start()
+ prompt.get(['title'], (err, result) => {
+ notice.title = result.title
+ fsp.readFile(`notices/notice_${id}.md`)
+ .then((body) => {
+ notice.body = body.toString()
+ notice.id = id
+ notices.push(notice)
+ return fsp.writeFile(`development/notices.json`, JSON.stringify(notices))
+ })
+ })
+ })
+ })
diff --git a/development/notices.json b/development/notices.json
new file mode 100644
index 000000000..ffe67097a
--- /dev/null
+++ b/development/notices.json
@@ -0,0 +1 @@
+[{"read":false,"date":"Fri Dec 16 2016","title":"Ending Morden Support","body":"Due to [recent events](https://blog.ethereum.org/2016/11/20/from-morden-to-ropsten/), MetaMask is now deprecating support for the Morden Test Network.\n\nUsers will still be able to access Morden through a locally hosted node, but we will no longer be providing hosted access to this network through [Infura](http://infura.io/).\n\nPlease use the new Ropsten Network as your new default test network.\n\nYou can fund your Ropsten account using the buy button on your account page.\n\nBest wishes!\nThe MetaMask Team\n\n","id":0}]
diff --git a/development/states.js b/development/states.js
deleted file mode 100644
index d096607f9..000000000
--- a/development/states.js
+++ /dev/null
@@ -1 +0,0 @@
-module.exports = {"account detail with shapeshift tx":{"metamask":{"currentFiat":"USD","conversionRate":11.06608791,"conversionDate":1470421024,"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","shapeShiftTxList":[{"depositAddress":"1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw","depositType":"BTC","key":"shapeshift","time":1471564825772,"response":{"status":"complete","outgoingCoin":"100.00","incomingCoin":"1.000","transaction":"0x3701e0ac344a12a1fc5417cf251109a7c41f3edab922310202630d9c012414c8"}},{"depositAddress":"1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw","depositType":"BTC","key":"shapeshift","time":1471566579224,"response":{"status":"no_deposits","depositAddress":"1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw"}},{"depositAddress":"1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw","depositType":"BTC","key":"shapeshift","time":1471566565378,"response":{"status":"received","depositAddress":"1L8BJCR6KHkCiVceDqibt7zJscqPpH7pFw"}}],"transactions":[{"id":1467921503489592,"txParams":{"from":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","to":"0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761","value":"0x66c899104aa57038000","origin":"thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com","metamaskId":1467921503489592,"metamaskNetworkId":"2"},"time":1467921503489,"status":"rejected","containsDelegateCall":false},{"id":1467923203344608,"txParams":{"from":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","to":"0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761","value":"0x0","origin":"thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com","metamaskId":1467923203344608,"metamaskNetworkId":"2"},"time":1467923203344,"status":"confirmed","containsDelegateCall":false,"hash":"0x957bbba51e2732a86c10c5e7e8a484a093795a06f2e2c38ad02da1b20aeca620"},{"id":1467921503489592,"txParams":{"from":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","to":"0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761","value":"0x66c899104aa57038000","origin":"thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com","metamaskId":1467921503489592,"metamaskNetworkId":"2"},"time":1467921503489,"status":"confirmed","containsDelegateCall":false}],"identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","network":"1","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}},"account detail with transaction history":{"metamask":{"currentFiat":"USD","conversionRate":11.06608791,"conversionDate":1470421024,"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[{"id":1467921503489592,"txParams":{"from":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","to":"0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761","value":"0x66c899104aa57038000","origin":"thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com","metamaskId":1467921503489592,"metamaskNetworkId":"2"},"time":1467921503489,"status":"rejected","containsDelegateCall":false},{"id":1467923203344608,"txParams":{"from":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","to":"0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761","value":"0x0","origin":"thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com","metamaskId":1467923203344608,"metamaskNetworkId":"2"},"time":1467923203344,"status":"confirmed","containsDelegateCall":false,"hash":"0x957bbba51e2732a86c10c5e7e8a484a093795a06f2e2c38ad02da1b20aeca620"},{"id":1467921503489592,"txParams":{"from":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","to":"0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761","value":"0x66c899104aa57038000","origin":"thelongestdomainnameintheworldandthensomeandthensomemoreandmore.com","metamaskId":1467921503489592,"metamaskNetworkId":"2"},"time":1467921503489,"status":"confirmed","containsDelegateCall":false}],"selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}},"account detail":{"metamask":{"currentFiat":"USD","conversionRate":11.06608791,"conversionDate":1470421024,"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x100000000000","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","nonce":"0x0","balance":"0x100000000000","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","nonce":"0x0","balance":"0x100000000000","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}},"accounts":{"metamask":{"isInitialized":true,"isUnlocked":true,"rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80":{"name":"Wallet 1","address":"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80","mayBeFauceting":false},"0xc4692812f03d96edf4ac88c9d08106222578407b":{"name":"Wallet 2","address":"0xc4692812f03d96edf4ac88c9d08106222578407b","mayBeFauceting":false},"0x1abda824194d3583509c97e6faefd575e194844d":{"name":"Wallet 3","address":"0x1abda824194d3583509c97e6faefd575e194844d","mayBeFauceting":false},"0xa7ea108f933abe81ddafc0b2279b1d828dd0e8d6":{"name":"Wallet 4","address":"0xa7ea108f933abe81ddafc0b2279b1d828dd0e8d6","mayBeFauceting":false},"0xab64bed4528feed6a85ab3f3da91479954da9e46":{"name":"Wallet 5","address":"0xab64bed4528feed6a85ab3f3da91479954da9e46","mayBeFauceting":false},"0x69e90083dabd9acc9ea6d706eb6dccf245ae4d6b":{"name":"Wallet 6","address":"0x69e90083dabd9acc9ea6d706eb6dccf245ae4d6b","mayBeFauceting":false},"0xebcc86684ef70e0ec3ad85f996b22e1bdad2d024":{"name":"Wallet 7","address":"0xebcc86684ef70e0ec3ad85f996b22e1bdad2d024","mayBeFauceting":false}},"unconfTxs":{},"currentFiat":"USD","conversionRate":11.84461814,"conversionDate":1476226414,"accounts":{"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80":{"balance":"0x0de0b6b3a7640000","nonce":"0x100000","code":"0x","address":"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80"},"0xc4692812f03d96edf4ac88c9d08106222578407b":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0xc4692812f03d96edf4ac88c9d08106222578407b"},"0x1abda824194d3583509c97e6faefd575e194844d":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0x1abda824194d3583509c97e6faefd575e194844d"},"0xa7ea108f933abe81ddafc0b2279b1d828dd0e8d6":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0xa7ea108f933abe81ddafc0b2279b1d828dd0e8d6"},"0xab64bed4528feed6a85ab3f3da91479954da9e46":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0xab64bed4528feed6a85ab3f3da91479954da9e46"},"0x69e90083dabd9acc9ea6d706eb6dccf245ae4d6b":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0x69e90083dabd9acc9ea6d706eb6dccf245ae4d6b"},"0xebcc86684ef70e0ec3ad85f996b22e1bdad2d024":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0xebcc86684ef70e0ec3ad85f996b22e1bdad2d024"}},"transactions":[],"selectedAddress":"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80","network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"shapeShiftTxList":[],"provider":{"type":"testnet"},"selectedAccount":"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"accounts"},"accountDetail":{"subview":"transactions"},"transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}},"config":{"metamask":{"currentFiat":"USD","conversionRate":11.06608791,"conversionDate":1470421024,"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Wallet 1","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Wallet 2","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"name":"Wallet 4","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"config"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"testfaucet.metamask.io","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}},"create vault password":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"accounts":{},"transactions":[],"network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":false,"isLoading":false,"warning":null},"identities":{}},"custom rpc":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false},"0x18c643c9cf21027339c8648fbaa2f348ddcbe00a":{"name":"Wallet 4","address":"0x18c643c9cf21027339c8648fbaa2f348ddcbe00a","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{},"0x18c643c9cf21027339c8648fbaa2f348ddcbe00a":{}},"transactions":[{"id":1470676748243181,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161097d38038061097d83398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b50505050505061070c806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610618575b610000610002565b61064c60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156106ef5780601f106106c4576101008083540402835291602001916106ef565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561070757816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35060016106fb565b6106ba60045460ff1681565b61064c60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156106ef5780601f106106c4576101008083540402835291602001916106ef565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61064c60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156106ef5780601f106106c4576101008083540402835291602001916106ef565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561070257604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c948235946024803595606494939101919081908382808284375094965050505050505033600160a060020a03908116600081815260016020908152604080832094881680845294825280832087905580518781529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a383600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105f05780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f19250505015156106f757610002565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106d257829003601f168201915b505050505081565b5060015b9392505050565b610157565b6106fb5600000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000084d536674436f696e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d53465400000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1470676748243181,"metamaskNetworkId":"2"},"time":1470676748243,"status":"confirmed","estimatedGas":"0xa9442","hash":"0xce6f9e068c780a1197117ec9e2103c33ac21bc8d5822aa2293c9c84e72229d88"},{"id":1470682363931487,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","nonce":"0x2","gasPrice":"0x4a817c800","to":"0x059f1e6f420d6fee280bb83e2702dcd06a2ce9c8","value":"0x3e2c284391c0000","data":"0xd92ed13700000000000000000000000000000000000000000000000000000000000000620000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000224d6574614d61736b3a20457468657265756d20696e20796f75722042726f777365720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000052416e7920696e746572657374696e672064657461696c732061626f757420796f752c207468617420796f7520776f756c64206c696b6520746f20736861726520776974682074686520636f6d6d756e697479000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000137777772e796f7572776562736974652e636f6d00000000000000000000000000","gasLimit":"0x5ce40","origin":"www.etherfaces.com","metamaskId":1470682363931487,"metamaskNetworkId":"1"},"time":1470682363931,"status":"confirmed","estimatedGas":"0x447a0","containsDelegateCall":false,"hash":"0x4aa629bdc0710f9048c2dd8c35883338de681aff50998b0e14f1079e41e7b3bf"},{"id":1470682617417416,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","nonce":"0x3","gasPrice":"0x4a817c800","to":"0x059f1e6f420d6fee280bb83e2702dcd06a2ce9c8","value":"0x3e2c284391c0000","data":"0xd92ed137000000000000000000000000000000000000000000000000000000000000006200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d6574614d61736b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e566973697420457468657265756d2044617070732077697468696e206e6f726d616c207765622062726f77736572732077697468204d6574614d61736b210000000000000000000000000000000000000000000000000000000000000000001368747470733a2f2f6d6574616d61736b2e696f00000000000000000000000000","gasLimit":"0x2fc7720","origin":"www.etherfaces.com","metamaskId":1470682617417416,"metamaskNetworkId":"1"},"time":1470682617417,"status":"confirmed","containsDelegateCall":false,"estimatedGas":"0x2faf080","hash":"0x88bd8c6276854039ea416a8c38e867546cc928670758aebb8db44b9120f7dad2"},{"id":1470682742887332,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","nonce":"0x3","gasPrice":"0x4a817c800","to":"0x059f1e6f420d6fee280bb83e2702dcd06a2ce9c8","value":"0x470de4df8200000","data":"0xd92ed137000000000000000000000000000000000000000000000000000000000000006200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000084d6574614d61736b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029566973697420457468657265756d20446170707320696e2061206e6f726d616c2042726f777365722e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f7777772e6d6574616d61736b2e696f0000000000000000000000000000000000","gasLimit":"0x2fc7720","origin":"www.etherfaces.com","metamaskId":1470682742887332,"metamaskNetworkId":"1"},"time":1470682742887,"status":"confirmed","containsDelegateCall":false,"estimatedGas":"0x2faf080","hash":"0xc716c9ce00d48edf04ec64ab07ea7b413dd49ffd744359213fe8da69246aad10"},{"id":1470692493483229,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161097d38038061097d83398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b50505050505061070c806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610618575b610000610002565b61064c60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156106ef5780601f106106c4576101008083540402835291602001916106ef565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561070757816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a35060016106fb565b6106ba60045460ff1681565b61064c60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156106ef5780601f106106c4576101008083540402835291602001916106ef565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61064c60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156106ef5780601f106106c4576101008083540402835291602001916106ef565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561070257604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c948235946024803595606494939101919081908382808284375094965050505050505033600160a060020a03908116600081815260016020908152604080832094881680845294825280832087905580518781529051929493927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a383600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105f05780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f19250505015156106f757610002565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106ac5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106d257829003601f168201915b505050505081565b5060015b9392505050565b610157565b6106fb5600000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000084d5346542062757800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044d53465400000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1470692493483229,"metamaskNetworkId":"1"},"time":1470692493483,"status":"confirmed","estimatedGas":"0xa9482","hash":"0xe539d7b39c2742261b9b3d1cdb22940275c6cc4d8b80a8a0222f6d2b0b549311"},{"id":1470962599348486,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x69eabf45623e5b53683924dff98309eb39af1a89","value":"0x2","origin":"localhost","metamaskId":1470962599348486,"metamaskNetworkId":"1"},"time":1470962599348,"status":"rejected","containsDelegateCall":false,"estimatedGas":"0x5208"},{"id":1470963263070463,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x69eabf45623e5b53683924dff98309eb39af1a89","value":"0x2","origin":"localhost","metamaskId":1470963263070463,"metamaskNetworkId":"1"},"time":1470963263070,"status":"rejected","containsDelegateCall":false,"estimatedGas":"0x5208"}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"166","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"rpc","rpcTarget":"555.203.16.244"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"accountDetail":{"subview":"transactions"},"currentDomain":"localhost:8080","transForward":true,"isLoading":false,"warning":null},"identities":{}},"empty account detail":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x01","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","nonce":"0x0","balance":"0x01","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","nonce":"0x0","balance":"0x01","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}},"first time":{"metamask":{"isInitialized":false,"isUnlocked":false,"rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"currentFiat":"USD","conversionRate":11.47635827,"conversionDate":1477606503,"network":null,"accounts":{},"transactions":[],"isConfirmed":true,"unconfMsgs":{},"messages":[],"shapeShiftTxList":[],"keyringTypes":["Simple Key Pair"],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"transForward":true,"isLoading":false,"warning":null},"identities":{}},"help":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"info"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}},"locked":{"metamask":{"isInitialized":true,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"currentFiat":"USD","conversionRate":11.4379398,"conversionDate":1473358355,"accounts":{},"transactions":[],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1473186153102","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"shapeShiftTxList":[],"provider":{"type":"rpc","rpcTarget":"http://localhost:8545"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}},"new account":{"metamask":{"isInitialized":true,"isUnlocked":true,"rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xa6ef573d60594731178b7f85d80da13cc2af52dd":{"address":"0xa6ef573d60594731178b7f85d80da13cc2af52dd","name":"Dan! 1"},"0xf9f52e84ad2c9122caa87478d27041ddaa215666":{"address":"0xf9f52e84ad2c9122caa87478d27041ddaa215666","name":"Account 2"}},"unconfTxs":{},"currentFiat":"USD","conversionRate":10.92067835,"conversionDate":1478282884,"network":null,"accounts":{"0xa6ef573d60594731178b7f85d80da13cc2af52dd":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0xa6ef573d60594731178b7f85d80da13cc2af52dd"},"0xf9f52e84ad2c9122caa87478d27041ddaa215666":{"balance":"0x00","nonce":"0x100000","code":"0x","address":"0xf9f52e84ad2c9122caa87478d27041ddaa215666"}},"transactions":[],"provider":{"type":"testnet"},"selectedAccount":"0xa6ef573d60594731178b7f85d80da13cc2af52dd","isConfirmed":true,"unconfMsgs":{},"messages":[],"selectedAddress":"0xa6ef573d60594731178b7f85d80da13cc2af52dd","shapeShiftTxList":[],"keyringTypes":["Simple Key Pair","HD Key Tree"]},"appState":{"menuOpen":false,"currentView":{"name":"new-account"},"accountDetail":{"subview":"transactions"},"transForward":true,"isLoading":false,"warning":null,"forgottenPassword":null,"detailView":{},"scrollToBottom":false},"identities":{}},"new vault":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"accounts":{},"transactions":[],"network":"2","seedWords":null,"isConfirmed":false,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}},"pending crash":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{"1467755147235616":{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"tokenfactory.surge.sh","transForward":true,"isLoading":false,"warning":null},"identities":{}},"pending signature":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{},"currentFiat":"USD","conversionRate":11.02269525,"conversionDate":1472076963,"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"balance":"0x056ace16d84b1c7e78","nonce":"0x17","code":"0x0","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"balance":"0x00000000000000056bc75e2d63100000","nonce":"0x0","code":"0x0","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"balance":"0x00000000000000056bc75e2d63100000","nonce":"0x0","code":"0x0","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1471975421223082,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a","origin":"localhost","metamaskId":1471975421223082,"metamaskNetworkId":"1471904489432"},"time":1471975421223,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xd0fe393e2586ebded866c9f13b90494e902bc49047fbf25ba2ac96c805a2f5d3"},{"id":1471975427199819,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a","origin":"localhost","metamaskId":1471975427199819,"metamaskNetworkId":"1471904489432"},"time":1471975427199,"status":"rejected","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xb1f2f63f3e265f05d7c353ab38dd8b73fce8e7214489037311ee1f58a994dae3"},{"id":1471975806981442,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a","origin":"localhost","metamaskId":1471975806981442,"metamaskNetworkId":"1471904489432"},"time":1471975806981,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xeeb89e91aaeea14c4950016c45d60df8ee8874daa6f414de5cf267ea2c17bc6e"},{"id":1471975810133789,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a","origin":"localhost","metamaskId":1471975810133789,"metamaskNetworkId":"1471904489432"},"time":1471975810133,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xe54cab2e54b8495691b6d8315ca24a190cba546a9fcb056642479ce5770cec8b"},{"id":1471976546865348,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a","origin":"localhost","metamaskId":1471976546865348,"metamaskNetworkId":"1471904489432"},"time":1471976546865,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0x54e10f77e17f28f4d12751749a2ca22f9b528592d1140ef53c6430a68e731542"},{"id":1471976930101889,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005","origin":"localhost","metamaskId":1471976930101889,"metamaskNetworkId":"1471904489432"},"time":1471976930101,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0x60b5af26fad18c5549949064b67c8f965c9f20cd3e890c69512ca3acad10ed8b"},{"id":1471977268048169,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000002","origin":"localhost","metamaskId":1471977268048169,"metamaskNetworkId":"1471904489432"},"time":1471977268048,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0x1f96e29305ef11a9c993302c29e5419d87017e8222d4034daea0d86e155dc3aa"},{"id":1471977310778630,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005","origin":"localhost","metamaskId":1471977310778630,"metamaskNetworkId":"1471904489432"},"time":1471977310778,"status":"rejected","containsDelegateCall":true,"estimatedGas":"0x89ef"},{"id":1471977316241561,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005","origin":"localhost","metamaskId":1471977316241561,"metamaskNetworkId":"1471904489432"},"time":1471977316240,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xdbd610c92d77a07c76b82e14e32674d382c45c4780dd2a550888b5cc40d54bcc"},{"id":1471977344018510,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000004","origin":"localhost","metamaskId":1471977344018510,"metamaskNetworkId":"1471904489432"},"time":1471977344018,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0x709d871d9ded0108de9f7718a7490b19d45e5e7562b1ba6c5bf6cce56e767d48"},{"id":1471977403830380,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000001","origin":"localhost","metamaskId":1471977403830380,"metamaskNetworkId":"1471904489432"},"time":1471977403830,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0x94f5088a127bba181b303d6427ae93cbfa9867997bea1326f30da311e36c6aca"},{"id":1471977431563703,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000001","origin":"localhost","metamaskId":1471977431563703,"metamaskNetworkId":"1471904489432"},"time":1471977431563,"status":"rejected","containsDelegateCall":true,"estimatedGas":"0x89ef"},{"id":1471977436074587,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000001","origin":"localhost","metamaskId":1471977436074587,"metamaskNetworkId":"1471904489432"},"time":1471977436074,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0x5f514dfe3bd48f6f301c809a7a75f73f0fc93bc3a0e469368b84dce032aff9ec"},{"id":1471991826717707,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000004","origin":"localhost","metamaskId":1471991826717707,"metamaskNetworkId":"1471904489432"},"time":1471991826717,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xab1e706f8981680a6c921f9f57f8ce573392bbb4f0fe85cf45e5cbf858fa5f3e"},{"id":1471991851917592,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000004","origin":"localhost","metamaskId":1471991851917592,"metamaskNetworkId":"1471904489432"},"time":1471991851917,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xdea144f7a6f06969739f676d8702a9a11efc689e032f1981fe67afc9261dd4de"},{"id":1471992032999543,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005","origin":"localhost","metamaskId":1471992032999543,"metamaskNetworkId":"1471904489432"},"time":1471992032999,"status":"confirmed","containsDelegateCall":true,"estimatedGas":"0x89ef","hash":"0xdf31b8cc0fbd2ab6727e0b63536bd4eab51a147aa29e04691e68fae28b866fb3"},{"id":1471992043490878,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","to":"0x48ff0cbac0acefedf152281ee80e9a0a01d5da63","data":"0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb0000000000000000000000000000000000000000000000000000000000000005","origin":"localhost","metamaskId":1471992043490878,"metamaskNetworkId":"1471904489432"},"time":1471992043490,"status":"rejected","containsDelegateCall":true,"estimatedGas":"0x89ef"},{"id":1472068030402279,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x3782dace9d90000","gas":"0x493e0","to":"0x18a672e11d637fffadccc99b152f4895da069601","data":"0x5b7d47a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001","origin":"www.rouleth.com","metamaskId":1472068030402279,"metamaskNetworkId":"1"},"time":1472068030402,"status":"rejected","containsDelegateCall":false,"estimatedGas":"0x24704"},{"id":1472068061833258,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","gas":"0x493e0","to":"0x18a672e11d637fffadccc99b152f4895da069601","data":"0x5b7d47a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001","origin":"www.rouleth.com","metamaskId":1472068061833258,"metamaskNetworkId":"1"},"time":1472068061833,"status":"confirmed","containsDelegateCall":false,"estimatedGas":"0x24704","hash":"0xb6e6ff57e7b5f6bd7f2e6dc44c39f4e858a227c9509586634ca547179345a13e"}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1471904489432","seedWords":null,"isConfirmed":true,"unconfMsgs":{"1472076978535283":{"id":1472076978535283,"msgParams":{"origin":"localhost","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"hello"},"time":1472076978535,"status":"unconfirmed"}},"messages":[{"id":1472076978535283,"msgParams":{"origin":"localhost","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"hello"},"time":1472076978535,"status":"unconfirmed"}],"shapeShiftTxList":[],"provider":{"type":"rpc","rpcTarget":"http://localhost:8545"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","detailView":null,"context":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"accountDetail":{"subview":"transactions"},"currentDomain":"ebjbdknjcgcbchkagneicjfpneaghdhb","transForward":true,"isLoading":false,"warning":null},"identities":{}},"pending tx contract":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467755147235616":{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x1000000","nonce":"0x0","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","nonce":"0x0","balance":"0x1000000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","balance":"0x1000000","nonce":"0x0","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}},"pending tx send coin":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"data":"0xa9059cbb0000000000000000000000008deb4d106090c3eb8f1950f727e87c4f884fb06f0000000000000000000000000000000000000000000000000000000000000064","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xbeb0ed3034c4155f3d16a64a5c5e7c8d4ea9e9c9","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}},"pending tx value":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"rejected"},{"id":1467868023090690,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}},"restore vault":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"currentFiat":"USD","conversionRate":0,"conversionDate":"N/A","accounts":{},"transactions":[],"seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"shapeShiftTxList":[],"provider":{"type":"testnet"},"network":"2"},"appState":{"menuOpen":false,"currentView":{"name":"restoreVault"},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}},"send":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{},"currentFiat":"USD","conversionRate":11.21283484,"conversionDate":1472158984,"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x34693f54a1e25900","nonce":"0x100013","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","nonce":"0x100000","balance":"0x18af912cee770000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"shapeShiftTxList":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"sendTransaction"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null,"detailView":{}},"identities":{}},"shapeshift":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{},"currentFiat":"USD","conversionRate":11.21274318,"conversionDate":1472159644,"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","nonce":"0x13","balance":"0x461d4a64e937d3d1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"shapeShiftTxList":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"buyEth","context":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"detailView":{},"buyView":{"subview":"buyForm","formView":{"coinbase":false,"shapeshift":true,"marketinfo":{"pair":"btc_eth","rate":51.14252949,"minerFee":0.01,"limit":2.60306578,"minimum":0.00038935,"maxLimit":8.67688592},"coinOptions":{"BTC":{"name":"Bitcoin","symbol":"BTC","image":"https://shapeshift.io/images/coins/bitcoin.png","status":"available"},"BCY":{"name":"BitCrystals","symbol":"BCY","image":"https://shapeshift.io/images/coins/bitcrystals.png","status":"available"},"BLK":{"name":"Blackcoin","symbol":"BLK","image":"https://shapeshift.io/images/coins/blackcoin.png","status":"available"},"BTS":{"name":"Bitshares","symbol":"BTS","specialReturn":false,"specialOutgoing":true,"specialIncoming":true,"fieldName":"destTag","fieldKey":"destTag","image":"https://shapeshift.io/images/coins/bitshares.png","status":"available"},"CLAM":{"name":"Clams","symbol":"CLAM","image":"https://shapeshift.io/images/coins/clams.png","status":"available"},"DASH":{"name":"Dash","symbol":"DASH","image":"https://shapeshift.io/images/coins/dash.png","status":"available"},"DGB":{"name":"Digibyte","symbol":"DGB","image":"https://shapeshift.io/images/coins/digibyte.png","status":"available"},"DAO":{"name":"TheDao","symbol":"DAO","image":"https://shapeshift.io/images/coins/thedao.png","status":"available"},"DGD":{"name":"DigixDao","symbol":"DGD","image":"https://shapeshift.io/images/coins/digixdao.png","status":"available"},"DOGE":{"name":"Dogecoin","symbol":"DOGE","image":"https://shapeshift.io/images/coins/dogecoin.png","status":"available"},"EMC":{"name":"Emercoin","symbol":"EMC","image":"https://shapeshift.io/images/coins/emercoin.png","status":"available"},"ETH":{"name":"Ether","symbol":"ETH","image":"https://shapeshift.io/images/coins/ether.png","status":"available"},"ETC":{"name":"Ether Classic","symbol":"ETC","image":"https://shapeshift.io/images/coins/etherclassic.png","status":"available"},"FCT":{"name":"Factoids","symbol":"FCT","image":"https://shapeshift.io/images/coins/factoids.png","status":"available"},"LBC":{"name":"LBRY Credits","symbol":"LBC","image":"https://shapeshift.io/images/coins/lbry.png","status":"available"},"LSK":{"name":"Lisk","symbol":"LSK","image":"https://shapeshift.io/images/coins/lisk.png","status":"available"},"LTC":{"name":"Litecoin","symbol":"LTC","image":"https://shapeshift.io/images/coins/litecoin.png","status":"available"},"MAID":{"name":"Maidsafe","symbol":"MAID","image":"https://shapeshift.io/images/coins/maidsafe.png","status":"available"},"MINT":{"name":"Mintcoin","symbol":"MINT","image":"https://shapeshift.io/images/coins/mintcoin.png","status":"available"},"MONA":{"name":"Monacoin","symbol":"MONA","image":"https://shapeshift.io/images/coins/monacoin.png","status":"available"},"MSC":{"name":"Omni","symbol":"MSC","image":"https://shapeshift.io/images/coins/mastercoin.png","status":"available"},"NBT":{"name":"Nubits","symbol":"NBT","image":"https://shapeshift.io/images/coins/nubits.png","status":"available"},"NMC":{"name":"Namecoin","symbol":"NMC","image":"https://shapeshift.io/images/coins/namecoin.png","status":"available"},"NVC":{"name":"Novacoin","symbol":"NVC","image":"https://shapeshift.io/images/coins/novacoin.png","status":"available"},"NXT":{"name":"Nxt","symbol":"NXT","specialReturn":false,"specialOutgoing":true,"specialIncoming":true,"specialIncomingStatus":false,"fieldName":"Public Key (only for unfunded accounts!)","fieldKey":"rsAddress","image":"https://shapeshift.io/images/coins/nxt.png","status":"available"},"PPC":{"name":"Peercoin","symbol":"PPC","image":"https://shapeshift.io/images/coins/peercoin.png","status":"available"},"RDD":{"name":"Reddcoin","symbol":"RDD","image":"https://shapeshift.io/images/coins/reddcoin.png","status":"available"},"SDC":{"name":"Shadowcash","symbol":"SDC","image":"https://shapeshift.io/images/coins/shadowcash.png","status":"available"},"SC":{"name":"Siacoin","symbol":"SC","image":"https://shapeshift.io/images/coins/siacoin.png","status":"available"},"SJCX":{"name":"StorjX","symbol":"SJCX","image":"https://shapeshift.io/images/coins/storjcoinx.png","status":"available"},"START":{"name":"Startcoin","symbol":"START","image":"https://shapeshift.io/images/coins/startcoin.png","status":"available"},"STEEM":{"name":"Steem","symbol":"STEEM","specialReturn":false,"specialOutgoing":true,"specialIncoming":true,"fieldName":"destTag","fieldKey":"destTag","image":"https://shapeshift.io/images/coins/steem.png","status":"available"},"USDT":{"name":"Tether","symbol":"USDT","image":"https://shapeshift.io/images/coins/tether.png","status":"available"},"VOX":{"name":"Voxels","symbol":"VOX","image":"https://shapeshift.io/images/coins/voxels.png","status":"available"},"VRC":{"name":"Vericoin","symbol":"VRC","image":"https://shapeshift.io/images/coins/vericoin.png","status":"available"},"VTC":{"name":"Vertcoin","symbol":"VTC","image":"https://shapeshift.io/images/coins/vertcoin.png","status":"available"},"XCP":{"name":"Counterparty","symbol":"XCP","image":"https://shapeshift.io/images/coins/counterparty.png","status":"available"},"XMR":{"name":"Monero","symbol":"XMR","specialReturn":false,"specialOutgoing":true,"specialIncoming":true,"fieldName":"Payment Id","qrName":"tx_payment_id","fieldKey":"paymentId","image":"https://shapeshift.io/images/coins/monero.png","status":"available"}}},"buyAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","amount":"5.00","warning":null},"isSubLoading":false},"identities":{}},"show seed words":{"metamask":{"isInitialized":false,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"}},"transactions":[],"network":"2","seedWords":"debris dizzy just program just float decrease vacant alarm reduce speak stadium","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"createVaultComplete","seedWords":"debris dizzy just program just float decrease vacant alarm reduce speak stadium"},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}} \ No newline at end of file
diff --git a/development/states.json b/development/states.json
index b2776edcc..0e87fb7ae 100644
--- a/development/states.json
+++ b/development/states.json
@@ -1 +1 @@
-module.exports = [{"account detail":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Secret Wallet!","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Main Wallet","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0x843963b837841dad3b0f5969ff271108776616df"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}}},{"accounts":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"balance":"0x0","code":"0x","nonce":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"accounts"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}}},{"config":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Wallet 1","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Wallet 2","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"name":"Wallet 4","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"accounts"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"testfaucet.metamask.io","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}}},{"create vault password":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"accounts":{},"transactions":[],"network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":false,"isLoading":false,"warning":null},"identities":{}}},{"help":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"info"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}}},{"locked":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Wallet 1","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Wallet 2","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"name":"Wallet 4","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"testfaucet.metamask.io","transForward":false,"isLoading":false,"warning":null,"scrollToBottom":false},"identities":{}}},{"new vault":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"accounts":{},"transactions":[],"network":"2","seedWords":null,"isConfirmed":false,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}},{"show seed words":{"metamask":{"isInitialized":false,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"}},"transactions":[],"network":"2","seedWords":"debris dizzy just program just float decrease vacant alarm reduce speak stadium","isConfirmed":false,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"createVaultComplete","seedWords":"debris dizzy just program just float decrease vacant alarm reduce speak stadium"},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}},{"terms":{"metamask":{"accounts":{},"transactions":[],"identities":{},"network":"2","isInitialized":false,"isUnlocked":false,"seedWords":null,"isConfirmed":false,"unconfTxs":{},"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"currentDomain":"extensions"}}}] \ No newline at end of file
+module.exports = [{"account detail":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Secret Wallet!","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Main Wallet","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail","detailView":null,"context":"0x843963b837841dad3b0f5969ff271108776616df"},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}}},{"accounts":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"balance":"0x0","code":"0x","nonce":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"network":"2","isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"accounts"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}}},{"config":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Wallet 1","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Wallet 2","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"name":"Wallet 4","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"accounts"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"testfaucet.metamask.io","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}}},{"create vault password":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"accounts":{},"transactions":[],"network":"2","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":false,"isLoading":false,"warning":null},"identities":{}}},{"help":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"name":"Wallet 4","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"code":"0x","balance":"0x0","nonce":"0x0","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"},"0x704107d04affddd9b66ab9de3dd7b095852e9b69":{"code":"0x","nonce":"0x0","balance":"0x0","address":"0x704107d04affddd9b66ab9de3dd7b095852e9b69"}},"transactions":[],"network":"2","isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","selectedAddress":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","seedWords":null},"appState":{"menuOpen":false,"currentView":{"name":"info"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null,"scrollToBottom":true},"identities":{}}},{"locked":{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"name":"Wallet 1","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6","mayBeFauceting":false},"0x843963b837841dad3b0f5969ff271108776616df":{"name":"Wallet 2","address":"0x843963b837841dad3b0f5969ff271108776616df","mayBeFauceting":false},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"name":"Wallet 3","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a","mayBeFauceting":false},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"name":"Wallet 4","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x5f11b68b7d41633e74c6b18d8b8d147da52aedd6"},"0x843963b837841dad3b0f5969ff271108776616df":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x843963b837841dad3b0f5969ff271108776616df"},"0x2cb215323857bec1c91e5db10fe87379a5cf129a":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x2cb215323857bec1c91e5db10fe87379a5cf129a"},"0xc5091450b7548b0dce3a76b8d325929c39e648d1":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xc5091450b7548b0dce3a76b8d325929c39e648d1"}},"transactions":[],"selectedAddress":"0x843963b837841dad3b0f5969ff271108776616df","network":"2","isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0x843963b837841dad3b0f5969ff271108776616df"},"appState":{"menuOpen":false,"currentView":{"name":"accountDetail"},"accountDetail":{"subview":"transactions","accountExport":"none","privateKey":""},"currentDomain":"testfaucet.metamask.io","transForward":false,"isLoading":false,"warning":null,"scrollToBottom":false},"identities":{}}},{"new vault":{"metamask":{"isInitialized":false,"isUnlocked":false,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{},"accounts":{},"transactions":[],"network":"2","seedWords":null,"isDisclaimerConfirmed":false,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"accounts","detailView":null},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}},{"show seed words":{"metamask":{"isInitialized":false,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"name":"Wallet 1","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc","mayBeFauceting":false},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"name":"Wallet 2","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b","mayBeFauceting":false},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"name":"Wallet 3","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823","mayBeFauceting":false}},"unconfTxs":{},"accounts":{"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"},"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"},"0xeb9e64b93097bc15f01f13eae97015c57ab64823":{"balance":"0x0","nonce":"0x0","code":"0x","address":"0xeb9e64b93097bc15f01f13eae97015c57ab64823"}},"transactions":[],"network":"2","seedWords":"debris dizzy just program just float decrease vacant alarm reduce speak stadium","isDisclaimerConfirmed":false,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"menuOpen":false,"currentView":{"name":"createVaultComplete","seedWords":"debris dizzy just program just float decrease vacant alarm reduce speak stadium"},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}},{"terms":{"metamask":{"accounts":{},"transactions":[],"identities":{},"network":"2","isInitialized":false,"isUnlocked":false,"seedWords":null,"isDisclaimerConfirmed":false,"unconfTxs":{},"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"}},"appState":{"currentDomain":"extensions"}}}] \ No newline at end of file
diff --git a/development/states/account-detail-with-shapeshift-tx.json b/development/states/account-detail-with-shapeshift-tx.json
index 027062979..1335ba2c3 100644
--- a/development/states/account-detail-with-shapeshift-tx.json
+++ b/development/states/account-detail-with-shapeshift-tx.json
@@ -133,10 +133,10 @@
"address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69"
}
},
- "selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "1",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/account-detail-with-transaction-history.json b/development/states/account-detail-with-transaction-history.json
index 69af85623..3847e341e 100644
--- a/development/states/account-detail-with-transaction-history.json
+++ b/development/states/account-detail-with-transaction-history.json
@@ -99,10 +99,10 @@
"status": "confirmed",
"containsDelegateCall": false
}],
- "selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "2",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/account-detail.json b/development/states/account-detail.json
index e51e31587..23729f37a 100644
--- a/development/states/account-detail.json
+++ b/development/states/account-detail.json
@@ -57,10 +57,10 @@
}
},
"transactions": [],
- "selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "2",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/accounts-loose.json b/development/states/accounts-loose.json
new file mode 100644
index 000000000..fd0c93c9c
--- /dev/null
+++ b/development/states/accounts-loose.json
@@ -0,0 +1,126 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9": {
+ "address": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9",
+ "name": "Account 1"
+ },
+ "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4": {
+ "address": "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4",
+ "name": "Account 2"
+ },
+ "0x1acfb961c5a8268eac8e09d6241a26cbeff42241": {
+ "address": "0x1acfb961c5a8268eac8e09d6241a26cbeff42241",
+ "name": "Account 3"
+ },
+ "0xe15d894becb0354c501ae69429b05143679f39e0": {
+ "address": "0xe15d894becb0354c501ae69429b05143679f39e0",
+ "name": "Account 4"
+ },
+ "0x87658c15aefe7448008a28513a11b6b130ef4cd0": {
+ "address": "0x87658c15aefe7448008a28513a11b6b130ef4cd0",
+ "name": "Account 5"
+ },
+ "0xaa25854c0379e53c957ac9382e720c577fa31fd5": {
+ "address": "0xaa25854c0379e53c957ac9382e720c577fa31fd5",
+ "name": "Account 6"
+ }
+ },
+ "unconfTxs": {},
+ "currentFiat": "USD",
+ "conversionRate": 0,
+ "conversionDate": "N/A",
+ "noActiveNotices": true,
+ "network": "3",
+ "accounts": {
+ "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9": {
+ "code": "0x",
+ "balance": "0x11f646fe14c9c000",
+ "nonce": "0x3",
+ "address": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9"
+ },
+ "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4"
+ },
+ "0x1acfb961c5a8268eac8e09d6241a26cbeff42241": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0x1acfb961c5a8268eac8e09d6241a26cbeff42241"
+ },
+ "0xe15d894becb0354c501ae69429b05143679f39e0": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xe15d894becb0354c501ae69429b05143679f39e0"
+ },
+ "0x87658c15aefe7448008a28513a11b6b130ef4cd0": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0x87658c15aefe7448008a28513a11b6b130ef4cd0"
+ },
+ "0xaa25854c0379e53c957ac9382e720c577fa31fd5": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xaa25854c0379e53c957ac9382e720c577fa31fd5"
+ }
+ },
+ "transactions": [],
+ "provider": {
+ "type": "testnet"
+ },
+ "selectedAccount": "0x87658c15aefe7448008a28513a11b6b130ef4cd0",
+ "isDisclaimerConfirmed": true,
+ "unconfMsgs": {},
+ "messages": [],
+ "shapeShiftTxList": [],
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "keyrings": [
+ {
+ "type": "HD Key Tree",
+ "accounts": [
+ "ac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9",
+ "d7c0cd9e7d2701c710d64fc492c7086679bdf7b4",
+ "1acfb961c5a8268eac8e09d6241a26cbeff42241"
+ ]
+ },
+ {
+ "type": "Simple Key Pair",
+ "accounts": [
+ "e15d894becb0354c501ae69429b05143679f39e0",
+ "87658c15aefe7448008a28513a11b6b130ef4cd0",
+ "aa25854c0379e53c957ac9382e720c577fa31fd5"
+ ]
+ }
+ ],
+ "lostAccounts": []
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accounts"
+ },
+ "accountDetail": {
+ "subview": "transactions",
+ "accountExport": "none",
+ "privateKey": ""
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false,
+ "forgottenPassword": false
+ },
+ "identities": {}
+} \ No newline at end of file
diff --git a/development/states/accounts.json b/development/states/accounts.json
index f09ea8f36..02c11cd98 100644
--- a/development/states/accounts.json
+++ b/development/states/accounts.json
@@ -89,9 +89,9 @@
}
},
"transactions": [],
- "selectedAddress": "0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80",
+ "selectedAccount": "0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80",
"network": "2",
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
diff --git a/development/states/compilation-bug.json b/development/states/compilation-bug.json
new file mode 100644
index 000000000..a9dfc4d4e
--- /dev/null
+++ b/development/states/compilation-bug.json
@@ -0,0 +1,124 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9": {
+ "address": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9",
+ "name": "Account 1"
+ },
+ "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4": {
+ "address": "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4",
+ "name": "Account 2"
+ },
+ "0x1acfb961c5a8268eac8e09d6241a26cbeff42241": {
+ "address": "0x1acfb961c5a8268eac8e09d6241a26cbeff42241",
+ "name": "Account 3"
+ },
+ "0xabc2bca51709b8615147352c62420f547a63a00c": {
+ "address": "0xabc2bca51709b8615147352c62420f547a63a00c",
+ "name": "Account 4"
+ }
+ },
+ "unconfTxs": {
+ "7992944905869041": {
+ "id": 7992944905869041,
+ "txParams": {
+ "from": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9",
+ "value": "0x0",
+ "data": "0x606060405234610000575b60da806100186000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630dbe671f14603c575b6000565b3460005760466088565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a72305820a99dfa6091771f518dd1ae8d1ee347bae3304dffd98fd24b1b99a8380bc60a750029",
+ "gas": "0x1af75",
+ "metamaskId": 7992944905869041,
+ "metamaskNetworkId": "3"
+ },
+ "time": 1482279685589,
+ "status": "unconfirmed",
+ "gasMultiplier": 1,
+ "metamaskNetworkId": "3",
+ "gasLimitSpecified": true,
+ "estimatedGas": "0x1af75",
+ "simulationFails": true
+ }
+ },
+ "currentFiat": "USD",
+ "conversionRate": 7.69158136,
+ "conversionDate": 1482279663,
+ "noActiveNotices": true,
+ "network": "3",
+ "accounts": {
+ "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9": {
+ "code": "0x",
+ "nonce": "0x3",
+ "balance": "0x11f646fe14c9c000",
+ "address": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9"
+ },
+ "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4": {
+ "code": "0x",
+ "nonce": "0x0",
+ "balance": "0x0",
+ "address": "0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4"
+ },
+ "0x1acfb961c5a8268eac8e09d6241a26cbeff42241": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0x1acfb961c5a8268eac8e09d6241a26cbeff42241"
+ },
+ "0xabc2bca51709b8615147352c62420f547a63a00c": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0xabc2bca51709b8615147352c62420f547a63a00c"
+ }
+ },
+ "transactions": [
+ {
+ "id": 7992944905869041,
+ "txParams": {
+ "from": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9",
+ "value": "0x0",
+ "data": "0x606060405234610000575b60da806100186000396000f30060606040526000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680630dbe671f14603c575b6000565b3460005760466088565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a72305820a99dfa6091771f518dd1ae8d1ee347bae3304dffd98fd24b1b99a8380bc60a750029",
+ "gas": "0x1af75",
+ "metamaskId": 7992944905869041,
+ "metamaskNetworkId": "3"
+ },
+ "time": 1482279685589,
+ "status": "unconfirmed",
+ "gasMultiplier": 1,
+ "metamaskNetworkId": "3",
+ "gasLimitSpecified": true,
+ "estimatedGas": "0x1af75",
+ "simulationFails": true
+ }
+ ],
+ "provider": {
+ "type": "testnet"
+ },
+ "selectedAccount": "0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9",
+ "seedWords": false,
+ "isDisclaimerConfirmed": true,
+ "unconfMsgs": {},
+ "messages": [],
+ "shapeShiftTxList": [],
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ],
+ "lostAccounts": []
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "confTx",
+ "context": 0
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null
+ },
+ "identities": {}
+} \ No newline at end of file
diff --git a/development/states/config.json b/development/states/config.json
index 22d999158..195e13bbb 100644
--- a/development/states/config.json
+++ b/development/states/config.json
@@ -57,9 +57,9 @@
}
},
"transactions": [],
- "selectedAddress": "0x843963b837841dad3b0f5969ff271108776616df",
+ "selectedAccount": "0x843963b837841dad3b0f5969ff271108776616df",
"network": "2",
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/create-vault-password.json b/development/states/create-vault-password.json
index 2253ba639..69daec818 100644
--- a/development/states/create-vault-password.json
+++ b/development/states/create-vault-password.json
@@ -10,7 +10,7 @@
"transactions": [],
"network": "2",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/custom-rpc.json b/development/states/custom-rpc.json
index 8025225fa..79c2d667a 100644
--- a/development/states/custom-rpc.json
+++ b/development/states/custom-rpc.json
@@ -157,10 +157,10 @@
"estimatedGas": "0x5208"
}
],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "166",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/empty-account-detail.json b/development/states/empty-account-detail.json
index f95a4b251..d4e94b566 100644
--- a/development/states/empty-account-detail.json
+++ b/development/states/empty-account-detail.json
@@ -54,10 +54,10 @@
}
},
"transactions": [],
- "selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"network": "2",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/first-time.json b/development/states/first-time.json
index 49fcea72c..d6d95fe06 100644
--- a/development/states/first-time.json
+++ b/development/states/first-time.json
@@ -11,7 +11,7 @@
"network": null,
"accounts": {},
"transactions": [],
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
diff --git a/development/states/help.json b/development/states/help.json
index 9c2c4f0d3..b0c9903ac 100644
--- a/development/states/help.json
+++ b/development/states/help.json
@@ -55,14 +55,14 @@
},
"transactions": [],
"network": "2",
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
"type": "testnet"
},
"selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
- "selectedAddress": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
"seedWords": null
},
"appState": {
diff --git a/development/states/locked.json b/development/states/locked.json
index 060d5e48c..d1eab125a 100644
--- a/development/states/locked.json
+++ b/development/states/locked.json
@@ -11,10 +11,10 @@
"conversionDate": 1473358355,
"accounts": {},
"transactions": [],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1473186153102",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
diff --git a/development/states/lost-accounts.json b/development/states/lost-accounts.json
new file mode 100644
index 000000000..9f1764c82
--- /dev/null
+++ b/development/states/lost-accounts.json
@@ -0,0 +1,91 @@
+{
+ "metamask": {
+ "currentFiat": "USD",
+ "lostAccounts": [
+ "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"
+ ],
+ "conversionRate": 11.06608791,
+ "conversionDate": 1470421024,
+ "isInitialized": true,
+ "isUnlocked": true,
+ "currentDomain": "example.com",
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": {
+ "name": "Wallet 1",
+ "address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "mayBeFauceting": false
+ },
+ "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b": {
+ "name": "Wallet 2",
+ "address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b",
+ "mayBeFauceting": false
+ },
+ "0xeb9e64b93097bc15f01f13eae97015c57ab64823": {
+ "name": "Wallet 3",
+ "address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823",
+ "mayBeFauceting": false
+ },
+ "0x704107d04affddd9b66ab9de3dd7b095852e9b69": {
+ "name": "Wallet 4",
+ "address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69",
+ "mayBeFauceting": false
+ }
+ },
+ "unconfTxs": {},
+ "accounts": {
+ "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc": {
+ "code": "0x",
+ "balance": "0x100000000000",
+ "nonce": "0x0",
+ "address": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
+ },
+ "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b": {
+ "code": "0x",
+ "nonce": "0x0",
+ "balance": "0x100000000000",
+ "address": "0xec1adf982415d2ef5ec55899b9bfb8bc0f29251b"
+ },
+ "0xeb9e64b93097bc15f01f13eae97015c57ab64823": {
+ "code": "0x",
+ "nonce": "0x0",
+ "balance": "0x100000000000",
+ "address": "0xeb9e64b93097bc15f01f13eae97015c57ab64823"
+ },
+ "0x704107d04affddd9b66ab9de3dd7b095852e9b69": {
+ "code": "0x",
+ "balance": "0x0",
+ "nonce": "0x0",
+ "address": "0x704107d04affddd9b66ab9de3dd7b095852e9b69"
+ }
+ },
+ "transactions": [],
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc",
+ "network": "2",
+ "seedWords": null,
+ "isDisclaimerConfirmed": true,
+ "unconfMsgs": {},
+ "messages": [],
+ "provider": {
+ "type": "testnet"
+ },
+ "selectedAccount": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accountDetail",
+ "detailView": null,
+ "context": "0x0dcd5d886577d5081b0c52e242ef29e70be3e7bc"
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "currentDomain": "127.0.0.1:9966",
+ "transForward": true,
+ "isLoading": false,
+ "warning": null
+ },
+ "identities": {}
+}
diff --git a/development/states/new-vault.json b/development/states/new-vault.json
index 18b4e7427..b9d7c845b 100644
--- a/development/states/new-vault.json
+++ b/development/states/new-vault.json
@@ -10,7 +10,7 @@
"transactions": [],
"network": "2",
"seedWords": null,
- "isConfirmed": false,
+ "isDisclaimerConfirmed": false,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/notice.json b/development/states/notice.json
new file mode 100644
index 000000000..f974d358e
--- /dev/null
+++ b/development/states/notice.json
@@ -0,0 +1,62 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "identities": {
+ "0x24a1d059462456aa332d6da9117aa7f91a46f2ac": {
+ "address": "0x24a1d059462456aa332d6da9117aa7f91a46f2ac",
+ "name": "Account 1"
+ }
+ },
+ "unconfTxs": {},
+ "currentFiat": "USD",
+ "conversionRate": 8.3533002,
+ "conversionDate": 1481671082,
+ "noActiveNotices": false,
+ "lastUnreadNotice": {
+ "read": false,
+ "date": "Tue Dec 13 2016",
+ "title": "MultiVault Support",
+ "body": "# Multi\n# Line\n## Support\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tincidunt dapibus justo a auctor. Sed luctus metus non mi laoreet, sit amet placerat nibh ultricies. Cras fringilla, urna sit amet sodales porttitor, lacus risus lacinia lorem, non euismod magna felis id ex. Nam iaculis, ante nec imperdiet suscipit, nisi quam fringilla nisl, sed fringilla turpis lectus et nibh. Pellentesque sed neque pretium nulla elementum lacinia eu eget felis. Nulla facilisi. Pellentesque id mi tempor, tempus sapien id, ultricies nibh. Integer faucibus elit non orci dapibus porttitor. Pellentesque rutrum hendrerit sapien ut lacinia. Nunc elementum eget arcu eu volutpat. Integer ullamcorper aliquam metus, eu malesuada tellus vestibulum a.\n",
+ "id": 0
+ },
+ "network": "3",
+ "accounts": {
+ "0x24a1d059462456aa332d6da9117aa7f91a46f2ac": {
+ "code": "0x",
+ "nonce": "0x0",
+ "balance": "0x0",
+ "address": "0x24a1d059462456aa332d6da9117aa7f91a46f2ac"
+ }
+ },
+ "transactions": [],
+ "provider": {
+ "type": "testnet"
+ },
+ "selectedAccount": "0x24a1d059462456aa332d6da9117aa7f91a46f2ac",
+ "seedWords": null,
+ "isDisclaimerConfirmed": true,
+ "unconfMsgs": {},
+ "messages": [],
+ "shapeShiftTxList": [],
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ]
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accountDetail",
+ "detailView": null,
+ "context": "0x24a1d059462456aa332d6da9117aa7f91a46f2ac"
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null
+ },
+ "identities": {}
+}
diff --git a/development/states/pending-crash.json b/development/states/pending-crash.json
index 086238d62..6c25323ea 100644
--- a/development/states/pending-crash.json
+++ b/development/states/pending-crash.json
@@ -1 +1 @@
-{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{"1467755147235616":{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"tokenfactory.surge.sh","transForward":true,"isLoading":false,"warning":null},"identities":{}} \ No newline at end of file
+{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{},"unconfTxs":{"1467755147235616":{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}],"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"tokenfactory.surge.sh","transForward":true,"isLoading":false,"warning":null},"identities":{}} \ No newline at end of file
diff --git a/development/states/pending-signature.json b/development/states/pending-signature.json
index dceff7a15..bc233a0ad 100644
--- a/development/states/pending-signature.json
+++ b/development/states/pending-signature.json
@@ -351,10 +351,10 @@
"hash": "0xb6e6ff57e7b5f6bd7f2e6dc44c39f4e858a227c9509586634ca547179345a13e"
}
],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1471904489432",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {
"1472076978535283": {
"id": 1472076978535283,
diff --git a/development/states/pending-tx-contract.json b/development/states/pending-tx-contract.json
index 5599f3753..f60198032 100644
--- a/development/states/pending-tx-contract.json
+++ b/development/states/pending-tx-contract.json
@@ -1 +1 @@
-{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467755147235616":{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x1000000","nonce":"0x0","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","nonce":"0x0","balance":"0x1000000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","balance":"0x1000000","nonce":"0x0","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}}
+{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467755147235616":{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x1000000","nonce":"0x0","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","nonce":"0x0","balance":"0x1000000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","balance":"0x1000000","nonce":"0x0","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"unconfirmed"}],"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"1","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"mainnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"127.0.0.1:9966","transForward":true,"isLoading":false,"warning":null},"identities":{}}
diff --git a/development/states/pending-tx-send-coin.json b/development/states/pending-tx-send-coin.json
index 262d791bb..6d447996a 100644
--- a/development/states/pending-tx-send-coin.json
+++ b/development/states/pending-tx-send-coin.json
@@ -1 +1 @@
-{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"data":"0xa9059cbb0000000000000000000000008deb4d106090c3eb8f1950f727e87c4f884fb06f0000000000000000000000000000000000000000000000000000000000000064","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xbeb0ed3034c4155f3d16a64a5c5e7c8d4ea9e9c9","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}
+{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"data":"0xa9059cbb0000000000000000000000008deb4d106090c3eb8f1950f727e87c4f884fb06f0000000000000000000000000000000000000000000000000000000000000064","from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xbeb0ed3034c4155f3d16a64a5c5e7c8d4ea9e9c9","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[],"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}}
diff --git a/development/states/pending-tx-value.json b/development/states/pending-tx-value.json
index 61fe7fa34..8bbf14b4b 100644
--- a/development/states/pending-tx-value.json
+++ b/development/states/pending-tx-value.json
@@ -1 +1 @@
-{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"rejected"},{"id":1467868023090690,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}],"selectedAddress":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}} \ No newline at end of file
+{"metamask":{"isInitialized":true,"isUnlocked":true,"currentDomain":"example.com","rpcTarget":"https://rawtestrpc.metamask.io/","identities":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"name":"Wallet 1","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","mayBeFauceting":false},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"name":"Wallet 2","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb","mayBeFauceting":false},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"name":"Wallet 3","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d","mayBeFauceting":false}},"unconfTxs":{"1467868023090690":{"id":1467868023090690,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}},"accounts":{"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825":{"code":"0x","balance":"0x38326dc32cf80800","nonce":"0x10000c","address":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb":{"code":"0x","balance":"0x15e578bd8e9c8000","nonce":"0x100000","address":"0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"},"0x2f8d4a878cfa04a6e60d46362f5644deab66572d":{"code":"0x","nonce":"0x100000","balance":"0x2386f26fc10000","address":"0x2f8d4a878cfa04a6e60d46362f5644deab66572d"}},"transactions":[{"id":1467742640796159,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742640796159,"metamaskNetworkId":"2"},"time":1467742640796,"status":"rejected"},{"id":1467742652846512,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000186a00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e6275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467742652846512,"metamaskNetworkId":"2"},"time":1467742652846,"status":"confirmed","hash":"0xa991793a6918aea6d58c30934dab5ca4c0a47c2444e5b60769637491f118de26"},{"id":1467755147235616,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","data":"0x60a060405260046060527f48302e31000000000000000000000000000000000000000000000000000000006080526006805460008290527f48302e310000000000000000000000000000000000000000000000000000000882556100b5907ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f602060026001841615610100026000190190931692909204601f01919091048101905b8082111561017957600081556001016100a1565b505060405161099338038061099383398101604052808051906020019091908051820191906020018051906020019091908051820191906020015050836000600050600033600160a060020a0316815260200190815260200160002060005081905550836002600050819055508260036000509080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061017d57805160ff19168380011785555b506101ad9291506100a1565b5090565b8280016001018555821561016d579182015b8281111561016d57825182600050559160200191906001019061018f565b50506004805460ff19168317905560058054825160008390527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0602060026001851615610100026000190190941693909304601f90810184900482019386019083901061022d57805160ff19168380011785555b5061025d9291506100a1565b82800160010185558215610221579182015b8281111561022157825182600050559160200191906001019061023f565b505050505050610722806102716000396000f36060604052361561008d5760e060020a600035046306fdde038114610095578063095ea7b3146100f257806318160ddd1461015d57806323b872dd14610166578063313ce567146102c757806354fd4d50146102d357806370a082311461033057806395d89b411461035e578063a9059cbb146103bb578063cae9ca511461044d578063dd62ed3e14610639575b610000610002565b61066d60038054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03908116600081815260016020908152604080832094871680845294825282208590556060858152919392917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259190a35060015b92915050565b61034c60025481565b61034c600435602435604435600160a060020a0383166000908152602081905260408120548290108015906101b9575060016020908152604080832033600160a060020a03168452909152812054829010155b80156101c55750600082115b1561071d57816000600050600085600160a060020a03168152602001908152602001600020600082828250540192505081905550816000600050600086600160a060020a03168152602001908152602001600020600082828250540392505081905550816001600050600086600160a060020a03168152602001908152602001600020600050600033600160a060020a0316815260200190815260200160002060008282825054039250508190555082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3506001610632565b6106db60045460ff1681565b61066d60068054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b600160a060020a03600435166000908152602081905260409020545b60408051918252519081900360200190f35b61066d60058054602060026001831615610100026000190190921691909104601f810182900490910260809081016040526060828152929190828280156107105780601f106106e557610100808354040283529160200191610710565b61034c60043560243533600160a060020a03166000908152602081905260408120548290108015906103ed5750600082115b1561071857604080822080548490039055600160a060020a03808516808452918320805485019055606084815233909116907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602090a3506001610157565b60806020604435600481810135601f81018490049093028401604052606083815261034c94823594602480359560649493910191908190838280828437509496505050505050506000826001600050600033600160a060020a03168152602001908152602001600020600050600086600160a060020a031681526020019081526020016000206000508190555083600160a060020a031660405180807f72656365697665417070726f76616c28616464726573732c75696e743235362c81526020017f616464726573732c627974657329000000000000000000000000000000000000815260200150602e019050604051809103902060e060020a8091040260e060020a9004338530866040518560e060020a0281526004018085600160a060020a0316815260200184815260200183600160a060020a031681526020018280519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d45780820380516001836020036101000a031916815260200191505b509450505050506000604051808303816000876161da5a03f1505060408051868152905133600160a060020a031692507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b9392505050565b61034c600435602435600160a060020a03808316600090815260016020908152604080832093851683529290522054610157565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156106cd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6060908152602090f35b820191906000526020600020905b8154815290600101906020018083116106f357829003601f168201915b505050505081565b610157565b6106325600000000000000000000000000000000000000000000000000000000000f42400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000844616e4275636b7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000034442580000000000000000000000000000000000000000000000000000000000","gasPrice":"0xba43b7400","gas":"0xf4240","origin":"tokenfactory.surge.sh","metamaskId":1467755147235616,"metamaskNetworkId":"1"},"time":1467755147235,"status":"rejected"},{"id":1467868023090690,"txParams":{"from":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","value":"0x16345785d8a0000","to":"0xC5b8dBAc4c1d3F152cDeb400E2313F309c410aCb","origin":"MetaMask","metamaskId":1467868023090690,"metamaskNetworkId":"2"},"time":1467868023090,"status":"unconfirmed","containsDelegateCall":false}],"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825","network":"2","seedWords":null,"isDisclaimerConfirmed":true,"unconfMsgs":{},"messages":[],"provider":{"type":"testnet"},"selectedAccount":"0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"},"appState":{"menuOpen":false,"currentView":{"name":"confTx","context":0},"accountDetail":{"subview":"transactions"},"currentDomain":"extensions","transForward":true,"isLoading":false,"warning":null},"identities":{}} \ No newline at end of file
diff --git a/development/states/private-network.json b/development/states/private-network.json
new file mode 100644
index 000000000..7d24533c5
--- /dev/null
+++ b/development/states/private-network.json
@@ -0,0 +1,86 @@
+{
+ "metamask": {
+ "isInitialized": true,
+ "isUnlocked": true,
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "name": "Account 1",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "mayBeFauceting": false
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "name": "Account 2",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb",
+ "mayBeFauceting": false
+ }
+ },
+ "unconfTxs": {},
+ "currentFiat": "USD",
+ "conversionRate": 9.52855776,
+ "conversionDate": 1479756513,
+ "accounts": {
+ "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825": {
+ "balance": "0x0",
+ "nonce": "0x0",
+ "code": "0x0",
+ "address": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825"
+ },
+ "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb": {
+ "balance": "0x0",
+ "nonce": "0x0",
+ "code": "0x0",
+ "address": "0xc5b8dbac4c1d3f152cdeb400e2313f309c410acb"
+ }
+ },
+ "transactions": [
+ {
+ "id": 5551995700357153,
+ "txParams": {
+ "from": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "to": "0x48ff0cbac0acefedf152281ee80e9a0a01d5da63",
+ "data": "0x90b98a11000000000000000000000000c5b8dbac4c1d3f152cdeb400e2313f309c410acb000000000000000000000000000000000000000000000000000000000000000a",
+ "metamaskId": 5551995700357153,
+ "metamaskNetworkId": "1479490588308"
+ },
+ "time": 1479498745949,
+ "status": "confirmed",
+ "gasMultiplier": 1,
+ "metamaskNetworkId": "1479490588308",
+ "containsDelegateCall": true,
+ "estimatedGas": "0x24b33",
+ "hash": "0xad609a6931f54a575ad71222ffc27cd6746017106d5b89f4ad300b37b273f8ac"
+ }
+ ],
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "network": "1479753732793",
+ "isConfirmed": true,
+ "isEthConfirmed": true,
+ "unconfMsgs": {},
+ "messages": [],
+ "shapeShiftTxList": [],
+ "gasMultiplier": false,
+ "provider": {
+ "type": "rpc",
+ "rpcTarget": "http://localhost:8545"
+ },
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "isDisclaimerConfirmed": true
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accountDetail"
+ },
+ "accountDetail": {
+ "subview": "transactions",
+ "accountExport": "none",
+ "privateKey": ""
+ },
+ "transForward": false,
+ "isLoading": false,
+ "warning": null,
+ "scrollToBottom": false
+ },
+ "identities": {}
+} \ No newline at end of file
diff --git a/development/states/restore-vault.json b/development/states/restore-vault.json
index d796676a8..bde15d861 100644
--- a/development/states/restore-vault.json
+++ b/development/states/restore-vault.json
@@ -12,7 +12,7 @@
"accounts": {},
"transactions": [],
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
diff --git a/development/states/send.json b/development/states/send.json
index 1d6a5504c..3e1aa88ba 100644
--- a/development/states/send.json
+++ b/development/states/send.json
@@ -48,7 +48,7 @@
"transactions": [],
"network": "2",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
diff --git a/development/states/shapeshift.json b/development/states/shapeshift.json
index 31b8cadec..7004e83be 100644
--- a/development/states/shapeshift.json
+++ b/development/states/shapeshift.json
@@ -46,10 +46,10 @@
}
},
"transactions": [],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
diff --git a/development/states/show-seed-words.json b/development/states/show-seed-words.json
index 19be51fbd..ddf1f9fba 100644
--- a/development/states/show-seed-words.json
+++ b/development/states/show-seed-words.json
@@ -45,7 +45,7 @@
"transactions": [],
"network": "2",
"seedWords": "debris dizzy just program just float decrease vacant alarm reduce speak stadium",
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"provider": {
diff --git a/development/states/terms-and-conditions.json b/development/states/terms-and-conditions.json
new file mode 100644
index 000000000..b20f819ed
--- /dev/null
+++ b/development/states/terms-and-conditions.json
@@ -0,0 +1,40 @@
+{
+ "metamask": {
+ "isInitialized": false,
+ "isUnlocked": false,
+ "rpcTarget": "https://rawtestrpc.metamask.io/",
+ "identities": {},
+ "unconfTxs": {},
+ "currentFiat": "USD",
+ "conversionRate": 8.18703468,
+ "conversionDate": 1481755832,
+ "network": "3",
+ "accounts": {},
+ "transactions": [],
+ "provider": {
+ "type": "testnet"
+ },
+ "isDisclaimerConfirmed": false,
+ "unconfMsgs": {},
+ "messages": [],
+ "shapeShiftTxList": [],
+ "keyringTypes": [
+ "Simple Key Pair",
+ "HD Key Tree"
+ ]
+ },
+ "appState": {
+ "menuOpen": false,
+ "currentView": {
+ "name": "accounts",
+ "detailView": null
+ },
+ "accountDetail": {
+ "subview": "transactions"
+ },
+ "transForward": true,
+ "isLoading": false,
+ "warning": null
+ },
+ "identities": {}
+} \ No newline at end of file
diff --git a/development/test.html b/development/test.html
new file mode 100644
index 000000000..702be7fa0
--- /dev/null
+++ b/development/test.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>MetaMask</title>
+
+ <script>
+ window.METAMASK_DEBUG = true
+ window.TEST_MODE = true
+ </script>
+ </head>
+ <body>
+
+ <!-- app content -->
+ <div id="app-content" style="height: 100%"></div>
+ <script src="./bundle.js" type="text/javascript" charset="utf-8"></script>
+
+ </body>
+
+<style>
+html, body, #app-content, .super-dev-container {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ background: white;
+}
+.mock-app-root {
+ background: #F7F7F7;
+}
+</style>
+</html>
diff --git a/gulpfile.js b/gulpfile.js
index 4d4fcaeee..1ea431aef 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -1,6 +1,6 @@
var watchify = require('watchify')
var browserify = require('browserify')
-var babelify = require('babelify')
+var disc = require('disc')
var gulp = require('gulp')
var source = require('vinyl-source-stream')
var buffer = require('vinyl-buffer')
@@ -11,7 +11,6 @@ var jsoneditor = require('gulp-json-editor')
var zip = require('gulp-zip')
var assign = require('lodash.assign')
var livereload = require('gulp-livereload')
-var brfs = require('gulp-brfs')
var del = require('del')
var eslint = require('gulp-eslint')
var fs = require('fs')
@@ -22,6 +21,7 @@ var replace = require('gulp-replace')
var disclaimer = fs.readFileSync(path.join(__dirname, 'USER_AGREEMENT.md')).toString()
var crypto = require('crypto')
var hash = crypto.createHash('sha256')
+var mkdirp = require('mkdirp')
hash.update(disclaimer)
var tosHash = hash.digest('hex')
@@ -34,7 +34,6 @@ var debug = gutil.env.debug
gulp.task('dev:reload', function() {
livereload.listen({
port: 35729,
- // basePath: './dist/firefox/'
})
})
@@ -47,6 +46,7 @@ gulp.task('copy:locales', copyTask({
'./dist/firefox/_locales',
'./dist/chrome/_locales',
'./dist/edge/_locales',
+ './dist/opera/_locales',
]
}))
gulp.task('copy:images', copyTask({
@@ -55,6 +55,7 @@ gulp.task('copy:images', copyTask({
'./dist/firefox/images',
'./dist/chrome/images',
'./dist/edge/images',
+ './dist/opera/images',
],
}))
gulp.task('copy:fonts', copyTask({
@@ -63,6 +64,7 @@ gulp.task('copy:fonts', copyTask({
'./dist/firefox/fonts',
'./dist/chrome/fonts',
'./dist/edge/fonts',
+ './dist/opera/fonts',
],
}))
gulp.task('copy:reload', copyTask({
@@ -71,6 +73,7 @@ gulp.task('copy:reload', copyTask({
'./dist/firefox/scripts',
'./dist/chrome/scripts',
'./dist/edge/scripts',
+ './dist/opera/scripts',
],
pattern: '/chromereload.js',
}))
@@ -80,6 +83,7 @@ gulp.task('copy:root', copyTask({
'./dist/firefox',
'./dist/chrome',
'./dist/edge',
+ './dist/opera',
],
pattern: '/*',
}))
@@ -93,6 +97,21 @@ gulp.task('manifest:chrome', function() {
.pipe(gulp.dest('./dist/chrome', { overwrite: true }))
})
+gulp.task('manifest:opera', function() {
+ return gulp.src('./dist/opera/manifest.json')
+ .pipe(jsoneditor(function(json) {
+ json.permissions = [
+ "storage",
+ "tabs",
+ "clipboardWrite",
+ "clipboardRead",
+ "http://localhost:8545/"
+ ]
+ return json
+ }))
+ .pipe(gulp.dest('./dist/opera', { overwrite: true }))
+})
+
gulp.task('manifest:production', function() {
return gulp.src([
'./dist/firefox/manifest.json',
@@ -119,7 +138,7 @@ if (!disableLiveReload) {
copyStrings.push('copy:reload')
}
-gulp.task('copy', gulp.series(gulp.parallel(...copyStrings), 'manifest:production', 'manifest:chrome'))
+gulp.task('copy', gulp.series(gulp.parallel(...copyStrings), 'manifest:production', 'manifest:chrome', 'manifest:opera'))
gulp.task('copy:watch', function(){
gulp.watch(['./app/{_locales,images}/*', './app/scripts/chromereload.js', './app/*.{html,json}'], gulp.series('copy'))
})
@@ -153,18 +172,27 @@ const jsFiles = [
'popup',
]
+// bundle tasks
+
var jsDevStrings = jsFiles.map(jsFile => `dev:js:${jsFile}`)
var jsBuildStrings = jsFiles.map(jsFile => `build:js:${jsFile}`)
jsFiles.forEach((jsFile) => {
- gulp.task(`dev:js:${jsFile}`, bundleTask({ watch: true, filename: `${jsFile}.js` }))
- gulp.task(`build:js:${jsFile}`, bundleTask({ watch: false, filename: `${jsFile}.js` }))
+ gulp.task(`dev:js:${jsFile}`, bundleTask({ watch: true, label: jsFile, filename: `${jsFile}.js` }))
+ gulp.task(`build:js:${jsFile}`, bundleTask({ watch: false, label: jsFile, filename: `${jsFile}.js` }))
})
gulp.task('dev:js', gulp.parallel(...jsDevStrings))
-
gulp.task('build:js', gulp.parallel(...jsBuildStrings))
+// disc bundle analyzer tasks
+
+jsFiles.forEach((jsFile) => {
+ gulp.task(`disc:${jsFile}`, bundleTask({ label: jsFile, filename: `${jsFile}.js` }))
+})
+
+gulp.task('disc', gulp.parallel(jsFiles.map(jsFile => `disc:${jsFile}`)))
+
// clean dist
@@ -174,22 +202,11 @@ gulp.task('clean', function clean() {
})
// zip tasks for distribution
-gulp.task('zip:chrome', () => {
- return gulp.src('dist/chrome/**')
- .pipe(zip(`metamask-chrome-${manifest.version}.zip`))
- .pipe(gulp.dest('builds'));
-})
-gulp.task('zip:firefox', () => {
- return gulp.src('dist/firefox/**')
- .pipe(zip(`metamask-firefox-${manifest.version}.zip`))
- .pipe(gulp.dest('builds'));
-})
-gulp.task('zip:edge', () => {
- return gulp.src('dist/edge/**')
- .pipe(zip(`metamask-edge-${manifest.version}.zip`))
- .pipe(gulp.dest('builds'));
-})
-gulp.task('zip', gulp.parallel('zip:chrome', 'zip:firefox', 'zip:edge'))
+gulp.task('zip:chrome', zipTask('chrome'))
+gulp.task('zip:firefox', zipTask('firefox'))
+gulp.task('zip:edge', zipTask('edge'))
+gulp.task('zip:opera', zipTask('opera'))
+gulp.task('zip', gulp.parallel('zip:chrome', 'zip:firefox', 'zip:edge', 'zip:opera'))
// high level tasks
@@ -219,24 +236,65 @@ function copyTask(opts){
}
}
-function bundleTask(opts) {
+function zipTask(target) {
+ return () => {
+ return gulp.src(`dist/${target}/**`)
+ .pipe(zip(`metamask-${target}-${manifest.version}.zip`))
+ .pipe(gulp.dest('builds'));
+ }
+}
+
+function generateBundler(opts) {
var browserifyOpts = assign({}, watchify.args, {
entries: ['./app/scripts/'+opts.filename],
- debug: true,
plugin: 'browserify-derequire',
+ debug: debug,
+ fullPaths: debug,
})
- var bundler = browserify(browserifyOpts)
- bundler.transform(babelify.configure({
- presets: ['es2015'],
- }))
- bundler.transform('brfs')
+ return browserify(browserifyOpts)
+}
+
+function discTask(opts) {
+ let bundler = generateBundler(opts)
+
+ if (opts.watch) {
+ bundler = watchify(bundler)
+ // on any dep update, runs the bundler
+ bundler.on('update', performBundle)
+ }
+
+ // output build logs to terminal
+ bundler.on('log', gutil.log)
+
+ return performBundle
+
+ function performBundle(){
+ // start "disc" build
+ let discDir = path.join(__dirname, 'disc')
+ mkdirp.sync(discDir)
+ let discPath = path.join(discDir, `${opts.label}.html`)
+
+ return (
+ bundler.bundle()
+ .pipe(disc())
+ .pipe(fs.createWriteStream(discPath))
+ )
+ }
+}
+
+
+function bundleTask(opts) {
+ let bundler = generateBundler(opts)
+
if (opts.watch) {
bundler = watchify(bundler)
- bundler.on('update', performBundle) // on any dep update, runs the bundler
+ // on any file update, re-runs the bundler
+ bundler.on('update', performBundle)
}
- bundler.on('log', gutil.log) // output build logs to terminal
+ // output build logs to terminal
+ bundler.on('log', gutil.log)
return performBundle
@@ -246,20 +304,25 @@ function bundleTask(opts) {
bundler.bundle()
// log errors if they happen
.on('error', gutil.log.bind(gutil, 'Browserify Error'))
+ // convert bundle stream to gulp vinyl stream
.pipe(source(opts.filename))
- .pipe(brfs())
+ // inject variables into bundle
.pipe(replace('GULP_TOS_HASH', tosHash))
.pipe(replace('\'GULP_METAMASK_DEBUG\'', debug))
- // optional, remove if you don't need to buffer file contents
+ // buffer file contents (?)
.pipe(buffer())
- // optional, remove if you dont want sourcemaps
- .pipe(sourcemaps.init({loadMaps: true})) // loads map from browserify file
- // Add transformation tasks to the pipeline here.
- .pipe(sourcemaps.write('./')) // writes .map file
+ // sourcemaps
+ // loads map from browserify file
+ .pipe(sourcemaps.init({loadMaps: true}))
+ // writes .map file
+ .pipe(sourcemaps.write('./'))
+ // write completed bundles
.pipe(gulp.dest('./dist/firefox/scripts'))
.pipe(gulp.dest('./dist/chrome/scripts'))
.pipe(gulp.dest('./dist/edge/scripts'))
- .pipe(gulpif(!disableLiveReload,livereload()))
+ .pipe(gulp.dest('./dist/opera/scripts'))
+ // finally, trigger live reload
+ .pipe(gulpif(!disableLiveReload, livereload()))
)
}
diff --git a/library/controller.js b/library/controller.js
index 07419550a..5823287cc 100644
--- a/library/controller.js
+++ b/library/controller.js
@@ -21,7 +21,7 @@ function initializeZeroClient() {
// User confirmation callbacks:
showUnconfirmedMessage,
unlockAccountMessage,
- showUnconfirmedTx,
+ showUnapprovedTx,
// Persistence Methods:
setData,
loadData,
@@ -36,8 +36,8 @@ function initializeZeroClient() {
console.log('notif stub - showUnconfirmedMessage')
}
- function showUnconfirmedTx (txParams, txData, onTxDoneCb) {
- console.log('notif stub - showUnconfirmedTx')
+ function showUnapprovedTx (txParams, txData, onTxDoneCb) {
+ console.log('notif stub - showUnapprovedTx')
}
//
@@ -156,4 +156,4 @@ function initializeZeroClient() {
}
}
-} \ No newline at end of file
+}
diff --git a/mock-dev.js b/mock-dev.js
index 99aec9a65..283bc2c79 100644
--- a/mock-dev.js
+++ b/mock-dev.js
@@ -26,7 +26,7 @@ const extension = require('./development/mockExtension')
// Query String
const qs = require('qs')
let queryString = qs.parse(window.location.href.split('#')[1])
-let selectedView = queryString.view || 'terms'
+let selectedView = queryString.view || 'first time'
const firstState = states[selectedView]
updateQueryParams(selectedView)
@@ -46,7 +46,7 @@ const controller = new MetamaskController({
// User confirmation callbacks:
showUnconfirmedMessage: noop,
unlockAccountMessage: noop,
- showUnconfirmedTx: noop,
+ showUnapprovedTx: noop,
// Persistence Methods:
setData,
loadData,
diff --git a/package.json b/package.json
index 36cc3f02a..2c0c30523 100644
--- a/package.json
+++ b/package.json
@@ -8,16 +8,19 @@
"lint": "gulp lint",
"buildCiUnits": "node test/integration/index.js",
"dev": "gulp dev --debug",
+ "disc": "gulp disc --debug",
"dist": "gulp dist --disableLiveReload",
"test": "npm run fastTest && npm run ci && npm run lint",
"fastTest": "METAMASK_ENV=test mocha --require test/helper.js --compilers js:babel-register --recursive \"test/unit/**/*.js\"",
"watch": "mocha watch --compilers js:babel-register --recursive \"test/unit/**/*.js\"",
- "ui": "node development/genStates.js && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
+ "genStates": "node development/genStates.js",
+ "ui": "npm run genStates && beefy ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
"mock": "beefy mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./",
- "buildMock": "browserify ./mock-dev.js -o ./development/bundle.js",
+ "buildMock": "npm run genStates && browserify ./mock-dev.js -o ./development/bundle.js",
"testem": "npm run buildMock && testem",
"ci": "npm run buildMock && npm run buildCiUnits && testem ci -P 2",
- "announce": "node development/announcer.js"
+ "announce": "node development/announcer.js",
+ "generateNotice": "node development/notice-generator.js"
},
"browserify": {
"transform": [
@@ -35,21 +38,25 @@
"dependencies": {
"async": "^1.5.2",
"bip39": "^2.2.0",
+ "browser-passworder": "^2.0.3",
"browserify-derequire": "^0.9.4",
"clone": "^1.0.2",
"copy-to-clipboard": "^2.0.0",
"debounce": "^1.0.0",
+ "denodeify": "^1.2.1",
+ "disc": "^1.3.2",
"dnode": "^1.2.2",
"end-of-stream": "^1.1.0",
"ensnare": "^1.0.0",
"eth-bin-to-ops": "^1.0.1",
"eth-lightwallet": "^2.3.3",
"eth-query": "^1.0.3",
- "eth-store": "^1.1.0",
"ethereumjs-tx": "^1.0.0",
"ethereumjs-util": "^4.4.0",
"ethereumjs-wallet": "^0.6.0",
"express": "^4.14.0",
+ "extension-link-enabler": "^1.0.0",
+ "extensionizer": "^1.0.0",
"gulp-eslint": "^2.0.0",
"hat": "0.0.3",
"identicon.js": "^1.2.1",
@@ -60,12 +67,14 @@
"menu-droppo": "^1.1.0",
"metamask-logo": "^2.1.2",
"mississippi": "^1.2.0",
+ "mkdirp": "^0.5.1",
"multiplex": "^6.7.0",
"once": "^1.3.3",
"ping-pong-stream": "^1.0.0",
"pojo-migrator": "^2.1.0",
"polyfill-crypto.getrandomvalues": "^1.0.0",
"post-message-stream": "^1.0.0",
+ "promise-filter": "^1.1.0",
"pumpify": "^1.3.4",
"qrcode-npm": "0.0.3",
"react": "^15.0.2",
@@ -80,14 +89,15 @@
"redux": "^3.0.5",
"redux-logger": "^2.3.1",
"redux-thunk": "^1.0.2",
- "request-promise": "^4.1.1",
"sandwich-expando": "^1.0.5",
+ "semaphore": "^1.0.5",
"textarea-caret": "^3.0.1",
"three.js": "^0.73.2",
"through2": "^2.0.1",
+ "valid-url": "^1.0.9",
"vreme": "^3.0.2",
"web3": "0.17.0-beta",
- "web3-provider-engine": "^8.1.5",
+ "web3-provider-engine": "^8.4.0",
"web3-stream-provider": "^2.0.6",
"xtend": "^4.0.1"
},
@@ -101,8 +111,8 @@
"chai": "^3.5.0",
"deep-freeze-strict": "^1.1.1",
"del": "^2.2.0",
+ "fs-promise": "^1.0.0",
"gulp": "github:gulpjs/gulp#4.0",
- "gulp-brfs": "^0.1.0",
"gulp-if": "^2.0.1",
"gulp-json-editor": "^2.2.1",
"gulp-livereload": "^3.8.1",
@@ -111,6 +121,7 @@
"gulp-util": "^3.0.7",
"gulp-watch": "^4.3.5",
"gulp-zip": "^3.2.0",
+ "isomorphic-fetch": "^2.2.1",
"jsdom": "^8.1.0",
"jsdom-global": "^1.7.0",
"jshint-stylish": "~0.1.5",
@@ -120,6 +131,8 @@
"mocha-jsdom": "^1.1.0",
"mocha-sinon": "^1.1.5",
"nock": "^8.0.0",
+ "open": "0.0.5",
+ "prompt": "^1.0.0",
"qs": "^6.2.0",
"qunit": "^0.9.1",
"sinon": "^1.17.3",
diff --git a/test/integration/helpers.js b/test/integration/helpers.js
index 95c36017a..eede103b4 100644
--- a/test/integration/helpers.js
+++ b/test/integration/helpers.js
@@ -1,7 +1,7 @@
-function wait() {
+function wait(time) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
resolve()
- }, 500)
+ }, time * 3 || 1500)
})
}
diff --git a/test/integration/index.html b/test/integration/index.html
index ad4b4eb14..8a54cb829 100644
--- a/test/integration/index.html
+++ b/test/integration/index.html
@@ -15,7 +15,7 @@
<script src="bundle.js"></script>
<script src="/testem.js"></script>
- <iframe src="/development/index.html" height="500px" width="360px">
+ <iframe src="/development/test.html" height="500px" width="360px">
<p>Your browser does not support iframes</p>
</iframe>
</body>
diff --git a/test/integration/lib/encryptor-test.js b/test/integration/lib/encryptor-test.js
deleted file mode 100644
index d42608152..000000000
--- a/test/integration/lib/encryptor-test.js
+++ /dev/null
@@ -1,67 +0,0 @@
-var encryptor = require('../../../app/scripts/lib/encryptor')
-
-QUnit.test('encryptor:serializeBufferForStorage', function (assert) {
- assert.expect(1)
- var buf = new Buffer(2)
- buf[0] = 16
- buf[1] = 1
-
- var output = encryptor.serializeBufferForStorage(buf)
-
- var expect = '0x1001'
- assert.equal(expect, output)
-})
-
-QUnit.test('encryptor:serializeBufferFromStorage', function (assert) {
- assert.expect(2)
- var input = '0x1001'
- var output = encryptor.serializeBufferFromStorage(input)
-
- assert.equal(output[0], 16)
- assert.equal(output[1], 1)
-})
-
-QUnit.test('encryptor:encrypt & decrypt', function(assert) {
- var done = assert.async();
- var password, data, encrypted
-
- password = 'a sample passw0rd'
- data = { foo: 'data to encrypt' }
-
- encryptor.encrypt(password, data)
- .then(function(encryptedStr) {
- assert.equal(typeof encryptedStr, 'string', 'returns a string')
- return encryptor.decrypt(password, encryptedStr)
- })
- .then(function (decryptedObj) {
- assert.deepEqual(decryptedObj, data, 'decrypted what was encrypted')
- done()
- })
- .catch(function(reason) {
- assert.ifError(reason, 'threw an error')
- done(reason)
- })
-
-})
-
-QUnit.test('encryptor:encrypt & decrypt with wrong password', function(assert) {
- var done = assert.async();
- var password, data, encrypted, wrongPassword
-
- password = 'a sample passw0rd'
- wrongPassword = 'a wrong password'
- data = { foo: 'data to encrypt' }
-
- encryptor.encrypt(password, data)
- .then(function(encryptedStr) {
- assert.equal(typeof encryptedStr, 'string', 'returns a string')
- return encryptor.decrypt(wrongPassword, encryptedStr)
- })
- .then(function (decryptedObj) {
- assert.equal(!decryptedObj, true, 'Wrong password should not decrypt')
- done()
- })
- .catch(function(reason) {
- done()
- })
-})
diff --git a/test/integration/lib/first-time.js b/test/integration/lib/first-time.js
index 7cabf1f0a..1811ccbd4 100644
--- a/test/integration/lib/first-time.js
+++ b/test/integration/lib/first-time.js
@@ -1,23 +1,90 @@
+const PASSWORD = 'password123'
+
+QUnit.module('first time usage')
+
QUnit.test('agree to terms', function (assert) {
var done = assert.async()
+ let app
- // Select the mock app root
- var app = $('iframe').contents().find('#app-content .mock-app-root')
-
- app.find('.markdown').prop('scrollTop', 100000000)
wait().then(function() {
- app.find('button').click()
- }).then(function() {
+ app = $('iframe').contents().find('#app-content .mock-app-root')
+ app.find('.markdown').prop('scrollTop', 100000000)
return wait()
+
}).then(function() {
+
var title = app.find('h1').text()
assert.equal(title, 'MetaMask', 'title screen')
- var buttons = app.find('button')
- assert.equal(buttons.length, 1, 'one button: create new vault')
+ var pwBox = app.find('#password-box')[0]
+ var confBox = app.find('#password-box-confirm')[0]
+
+ pwBox.value = PASSWORD
+ confBox.value = PASSWORD
+ return wait()
+
+ }).then(function() {
+
+ var createButton = app.find('button.primary')[0]
+ createButton.click()
+
+ return wait(1500)
+ }).then(function() {
+
+ var terms = app.find('h3.terms-header')[0]
+ assert.equal(terms.textContent, 'MetaMask Terms & Conditions', 'Showing TOS')
+
+ // Scroll through terms
+ var scrollable = app.find('.markdown')[0]
+ scrollable.scrollTop = scrollable.scrollHeight
+
+ return wait(10)
+ }).then(function() {
+
+ var button = app.find('button')[0] // Agree button
+ button.click()
+
+ return wait(1000)
+ }).then(function() {
+
+ var created = app.find('h3')[0]
+ assert.equal(created.textContent, 'Vault Created', 'Vault created screen')
+
+ var button = app.find('button')[0] // Agree button
+ button.click()
+
+ return wait(1000)
+ }).then(function() {
+
+ var detail = app.find('.account-detail-section')[0]
+ assert.ok(detail, 'Account detail section loaded.')
+
+ var sandwich = app.find('.sandwich-expando')[0]
+ sandwich.click()
+
+ return wait()
+ }).then(function() {
+
+ var sandwich = app.find('.menu-droppo')[0]
+ var lock = sandwich.children[2]
+ assert.ok(lock, 'Lock menu item found')
+ lock.click()
+
+ return wait(1000)
+ }).then(function() {
+
+ var pwBox = app.find('#password-box')[0]
+ pwBox.value = PASSWORD
+
+ var createButton = app.find('button.primary')[0]
+ createButton.click()
+
+ return wait(1000)
+ }).then(function() {
+
+ var detail = app.find('.account-detail-section')[0]
+ assert.ok(detail, 'Account detail section loaded again.')
done()
})
-
- // Wait for view to transition:
})
diff --git a/test/integration/lib/idStore-migrator-test.js b/test/integration/lib/idStore-migrator-test.js
new file mode 100644
index 000000000..4ae30411d
--- /dev/null
+++ b/test/integration/lib/idStore-migrator-test.js
@@ -0,0 +1,91 @@
+var ConfigManager = require('../../../app/scripts/lib/config-manager')
+var IdStoreMigrator = require('../../../app/scripts/lib/idStore-migrator')
+var SimpleKeyring = require('../../../app/scripts/keyrings/simple')
+var normalize = require('../../../app/scripts/lib/sig-util').normalize
+
+var oldStyleVault = require('../mocks/oldVault.json')
+var badStyleVault = require('../mocks/badVault.json')
+
+var STORAGE_KEY = 'metamask-config'
+var PASSWORD = '12345678'
+var FIRST_ADDRESS = '0x4dd5d356c5A016A220bCD69e82e5AF680a430d00'.toLowerCase()
+var SEED = 'fringe damage bounce extend tunnel afraid alert sound all soldier all dinner'
+
+var BAD_STYLE_FIRST_ADDRESS = '0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9'
+
+QUnit.module('Old Style Vaults', {
+ beforeEach: function () {
+ window.localStorage[STORAGE_KEY] = JSON.stringify(oldStyleVault)
+
+ this.configManager = new ConfigManager({
+ loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) },
+ setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) },
+ })
+
+ this.migrator = new IdStoreMigrator({
+ configManager: this.configManager,
+ })
+ }
+})
+
+QUnit.test('migrator:isInitialized', function (assert) {
+ assert.ok(this.migrator)
+})
+
+QUnit.test('migrator:migratedVaultForPassword', function (assert) {
+ var done = assert.async()
+
+ this.migrator.migratedVaultForPassword(PASSWORD)
+ .then((result) => {
+ const { serialized, lostAccounts } = result
+ assert.equal(serialized.data.mnemonic, SEED, 'seed phrase recovered')
+ assert.equal(lostAccounts.length, 0, 'no lost accounts')
+ done()
+ })
+})
+
+QUnit.module('Old Style Vaults with bad HD seed', {
+ beforeEach: function () {
+ window.localStorage[STORAGE_KEY] = JSON.stringify(badStyleVault)
+
+ this.configManager = new ConfigManager({
+ loadData: () => { return JSON.parse(window.localStorage[STORAGE_KEY]) },
+ setData: (data) => { window.localStorage[STORAGE_KEY] = JSON.stringify(data) },
+ })
+
+ this.migrator = new IdStoreMigrator({
+ configManager: this.configManager,
+ })
+ }
+})
+
+QUnit.test('migrator:migratedVaultForPassword', function (assert) {
+ var done = assert.async()
+
+ this.migrator.migratedVaultForPassword(PASSWORD)
+ .then((result) => {
+ const { serialized, lostAccounts } = result
+
+ assert.equal(lostAccounts.length, 1, 'one lost account')
+ assert.equal(lostAccounts[0].address, '0xe15D894BeCB0354c501AE69429B05143679F39e0'.toLowerCase())
+ assert.ok(lostAccounts[0].privateKey, 'private key exported')
+
+ var lostAccount = lostAccounts[0]
+ var privateKey = lostAccount.privateKey
+
+ var simple = new SimpleKeyring()
+ simple.deserialize([privateKey])
+ .then(() => {
+ return simple.getAccounts()
+ })
+ .then((accounts) => {
+ assert.equal(normalize(accounts[0]), lostAccount.address, 'recovered address.')
+ done()
+ })
+ .catch((reason) => {
+ assert.ifError(reason)
+ done(reason)
+ })
+ })
+})
+
diff --git a/test/integration/mocks/badVault.json b/test/integration/mocks/badVault.json
new file mode 100644
index 000000000..a59e4626a
--- /dev/null
+++ b/test/integration/mocks/badVault.json
@@ -0,0 +1 @@
+{"meta":{"version":4},"data":{"fiatCurrency":"USD","conversionRate":8.34908448,"conversionDate":1481227505,"isConfirmed":true,"wallet":"{\"encSeed\":{\"encStr\":\"Te2KyAGY3S01bgUJ+7d4y3BOvr/8TKrXrkRZ29cGI6dgyedtN+YgTQxElC2td/pzuoXm7KeSfr+yAoFCvMgqFAJwRcX3arHOsMFQie8kp8mL5I65zwdg/HB2QecB4OJHytrxgApv2zZiKEo0kbu2cs8zYIn5wNlCBIHwgylYmHpUDIJcO1B4zg==\",\"nonce\":\"xnxqk4iy70bjt721F+KPLV4PNfBFNyct\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"vNrSjekRKLmaGFf77Uca9+aAebmDlvrBwtAV8YthpQ4OX/mXtLSycmnLsYdk4schaByfJvrm6/Mf9fxzOSaScJk+XvKw5XqNXedkDHtbWrmNnxFpuT+9tuB8Nupr3D9GZK9PgXhJD99/7Bn6Wk7/ne+PIDmbtdmx/SWmrdo3pg==\",\"nonce\":\"zqWq/gtJ5zfUVRWQQJkP/zoYjer6Rozj\"},\"hdIndex\":1,\"encPrivKeys\":{\"e15d894becb0354c501ae69429b05143679f39e0\":{\"key\":\"jBLQ9v1l5LOEY1C3kI8z7LpbJKHP1vpVfPAlz90MNSfa8Oe+XlxKQAGYs8Zb4fWm\",\"nonce\":\"fJyrSRo1t0RMNqp2MsneoJnYJWHQnSVY\"}},\"addresses\":[\"e15d894becb0354c501ae69429b05143679f39e0\"]}},\"encHdRootPriv\":{\"encStr\":\"mbvwiFBQGbjj4BJLmdeYzfYi8jb7gtFtwiCQOPfvmyz4h2/KMbHNGzumM16qRKpifioQXkhnBulMIQHaYg0Jwv1MoFsqHxHmuIAT+QP5XvJjz0MRl6708pHowmIVG+R8CZNTLqzE7XS8YkZ4ElRpTvLEM8Wngi5Sg287mQMP9w==\",\"nonce\":\"i5Tp2lQe92rXQzNhjZcu9fNNhfux6Wf4\"},\"salt\":\"FQpA8D9R/5qSp9WtQ94FILyfWZHMI6YZw6RmBYqK0N0=\",\"version\":2}","config":{"provider":{"type":"testnet"},"selectedAccount":"0xe15d894becb0354c501ae69429b05143679f39e0"},"isEthConfirmed":true,"transactions":[],"TOSHash":"a4f4e23f823a7ac51783e7ffba7914a911b09acdb97263296b7e14b527f80c5b","gasMultiplier":1}}
diff --git a/test/integration/mocks/badVault2.json b/test/integration/mocks/badVault2.json
new file mode 100644
index 000000000..4b7aec386
--- /dev/null
+++ b/test/integration/mocks/badVault2.json
@@ -0,0 +1 @@
+{"meta":{"version":4},"data":{"fiatCurrency":"USD","isConfirmed":true,"TOSHash":"a4f4e23f823a7ac51783e7ffba7914a911b09acdb97263296b7e14b527f80c5b","noticesList":[{"read":true,"date":"Fri Dec 16 2016","title":"Ending Morden Support","body":"Due to [recent events](https://blog.ethereum.org/2016/11/20/from-morden-to-ropsten/), MetaMask is now deprecating support for the Morden Test Network.\n\nUsers will still be able to access Morden through a locally hosted node, but we will no longer be providing hosted access to this network through [Infura](http://infura.io/).\n\nPlease use the new Ropsten Network as your new default test network.\n\nYou can fund your Ropsten account using the buy button on your account page.\n\nBest wishes!\nThe MetaMask Team\n\n","id":0}],"conversionRate":7.07341909,"conversionDate":1482539284,"wallet":"{\"encSeed\":{\"encStr\":\"LZsdN8lJzYkUe1UpmAalnERdgkBFt25gWDdK8kfQUwMAk/27XR+dc+8n5swgoF5qgwhc9LBgliEGNDs1Q/lnuld3aQLabkOeAW4BHS1vS7FxqKrzDS3iyzSuQO6wDQmGno/buuknVgDsKiyjW22hpt7vtVVWA+ZL1P3x6M0+AxGJjeGVrG+E8Q==\",\"nonce\":\"T6O9BmwmTj214XUK3KF0s3iCKo3OlrUD\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"GNNfZevCMlgMVh9y21y1UwrC9qcmH6XYq7v+9UoqbHnzPQJFlxidN5+x/Sldo72a6+5zJpQkkdZ+Q0lePrzvXfuSd3D/RO7WKFIKo9nAQI5+JWwz4INuCmVcmqCv2J4BTLGjrG8fp5pDJ62Bn0XHqkJo3gx3fpvs3cS66+ZKwg==\",\"nonce\":\"HRTlGj44khQs2veYHEF/GqTI1t0yYvyd\"},\"hdIndex\":3,\"encPrivKeys\":{\"e15d894becb0354c501ae69429b05143679f39e0\":{\"key\":\"ZAeZL9VcRUtiiO4VXOQKBFg787PR5R3iymjUeU5vpDRIqOXbjWN6N4ZNR8YpSXl+\",\"nonce\":\"xLsADagS8uqDYae6cImyhxF7o1kBDbPe\"},\"87658c15aefe7448008a28513a11b6b130ef4cd0\":{\"key\":\"ku0mm5s1agRJNAMYIJO0qeoDe+FqcbqdQI6azXF3GL1OLo6uMlt6I4qS+eeravFi\",\"nonce\":\"xdGfSUPKtkW8ge0SWIbbpahs/NyEMzn5\"},\"aa25854c0379e53c957ac9382e720c577fa31fd5\":{\"key\":\"NjpYC9FbiC95CTx/1kwgOHk5LSN9vl4RULEBbvwfVOjqSH8WixNoP3R6I/QyNIs2\",\"nonce\":\"M/HWpXXA9QvuZxEykkGQPJKKdz33ovQr\"}},\"addresses\":[\"e15d894becb0354c501ae69429b05143679f39e0\",\"87658c15aefe7448008a28513a11b6b130ef4cd0\",\"aa25854c0379e53c957ac9382e720c577fa31fd5\"]}},\"encHdRootPriv\":{\"encStr\":\"f+3prUOzl+95aNAV+ad6lZdsYZz120ZsL67ucjj3tiMXf/CC4X8XB9N2QguhoMy6fW+fATUsTdJe8+CbAAyb79V9HY0Pitzq9Yw/g1g0/Ii2JzsdGBriuMsPdwZSVqz+rvQFw/6Qms1xjW6cqa8S7kM2WA5l8RB1Ck6r5zaqbA==\",\"nonce\":\"oGahxNFekVxH9sg6PUCCHIByvo4WFSqm\"},\"salt\":\"N7xYoEA53yhSweOsEphku1UKkIEuZtX2MwLBhVM6RR8=\",\"version\":2}","config":{"provider":{"type":"testnet"},"selectedAccount":"0xe15d894becb0354c501ae69429b05143679f39e0"},"isDisclaimerConfirmed":true,"walletNicknames":{"0xac39b311dceb2a4b2f5d8461c1cdaf756f4f7ae9":"Account 1","0xd7c0cd9e7d2701c710d64fc492c7086679bdf7b4":"Account 2","0x1acfb961c5a8268eac8e09d6241a26cbeff42241":"Account 3"},"lostAccounts":["0xe15d894becb0354c501ae69429b05143679f39e0","0x87658c15aefe7448008a28513a11b6b130ef4cd0","0xaa25854c0379e53c957ac9382e720c577fa31fd5"]}} \ No newline at end of file
diff --git a/test/integration/mocks/oldVault.json b/test/integration/mocks/oldVault.json
new file mode 100644
index 000000000..5861c41d7
--- /dev/null
+++ b/test/integration/mocks/oldVault.json
@@ -0,0 +1,21 @@
+{
+ "meta": {
+ "version": 4
+ },
+ "data": {
+ "fiatCurrency": "USD",
+ "isConfirmed": true,
+ "TOSHash": "a4f4e23f823a7ac51783e7ffba7914a911b09acdb97263296b7e14b527f80c5b",
+ "conversionRate": 9.47316629,
+ "conversionDate": 1479510994,
+ "wallet": "{\"encSeed\":{\"encStr\":\"a5tjKtDGlHkua+6Ta5s3wMFWPmsBqaPdMKGmqeI2z1kMbNs3V03HBaCptU7NtMra1DjHKbSNsUToxFUrmrvWBmUejamN16+l1CviwqASsv7kKzpot00/dfyyJgtZwwFP5Je+TAB1V231nRbPidOfeE1cDec5V8KTF8epl6qzsbA25pjeW76Dfw==\",\"nonce\":\"RzID6bAhWfGTSR74xdIh3RaT1+1sLk6F\"},\"ksData\":{\"m/44'/60'/0'/0\":{\"info\":{\"curve\":\"secp256k1\",\"purpose\":\"sign\"},\"encHdPathPriv\":{\"encStr\":\"6nlYAopRbmGcqerRZO08XwgeYaCJg9XRhh4oiYiVVdQtyNPdxvOI9TcE/mqvBiatMwBwA+TmsqTV6eZZe/VDZKYIGajKulQbScd0xQ71JhYfqqmzSG6EH2Pnzwa+aSAsfARgN1JJSaff2+p6wV6Zg5BUDtl72OGEIEfXhcUGwg==\",\"nonce\":\"Ee1KiDqtx7NvYToQUFvjEhKNinNQcXlK\"},\"hdIndex\":1,\"encPrivKeys\":{\"4dd5d356c5a016a220bcd69e82e5af680a430d00\":{\"key\":\"htGRGAH10lGF4M+fvioznmYVIUSWAzwp/yWSIo85psgZZwmCdJY72oyGanYsrFO8\",\"nonce\":\"PkP8XeZ+ok215rzEorvJu9nYTWzkOVr0\"}},\"addresses\":[\"4dd5d356c5a016a220bcd69e82e5af680a430d00\"]}},\"encHdRootPriv\":{\"encStr\":\"TAZAo71a+4IlAaoA66f0w4ts2f+V7ArTSUHRIrMltfAPXz7GfJBmKXNtHPORUYAjRiKqWK6FZnhKLf7Vcng2LG7VnDQwC4xPxzSRZzSEilnoY3V+zRY0HD7Wb/pndb4FliA/buZQmjohO4vezeX0hl70rJlPJEZTyYoWgxbxFA==\",\"nonce\":\"FlJOaLyBEHMaH5fEnYjdHc6nn18+WkRj\"},\"salt\":\"CmuCcWpbqpKUUv+1aE2ZwvQl7EIQ731uFibSq++vwtY=\",\"version\":2}",
+ "config": {
+ "provider": {
+ "type": "testnet"
+ },
+ "selectedAccount": "0x4dd5d356c5a016a220bcd69e82e5af680a430d00"
+ },
+ "showSeedWords": false,
+ "isEthConfirmed": true
+ }
+}
diff --git a/test/lib/mock-config-manager.js b/test/lib/mock-config-manager.js
index ccd518c68..b79f63090 100644
--- a/test/lib/mock-config-manager.js
+++ b/test/lib/mock-config-manager.js
@@ -9,6 +9,7 @@ module.exports = function() {
function loadData () {
var oldData = getOldStyleData()
var newData
+
try {
newData = JSON.parse(window.localStorage[STORAGE_KEY])
} catch (e) {}
diff --git a/test/unit/account-link-test.js b/test/unit/account-link-test.js
index 39889b6be..4ea12e002 100644
--- a/test/unit/account-link-test.js
+++ b/test/unit/account-link-test.js
@@ -3,9 +3,15 @@ var linkGen = require('../../ui/lib/account-link')
describe('account-link', function() {
- it('adds testnet prefix to morden test network', function() {
+ it('adds morden prefix to morden test network', function() {
var result = linkGen('account', '2')
- assert.notEqual(result.indexOf('testnet'), -1, 'testnet injected')
+ assert.notEqual(result.indexOf('morden'), -1, 'testnet included')
+ assert.notEqual(result.indexOf('account'), -1, 'account included')
+ })
+
+ it('adds testnet prefix to ropsten test network', function() {
+ var result = linkGen('account', '3')
+ assert.notEqual(result.indexOf('testnet'), -1, 'testnet included')
assert.notEqual(result.indexOf('account'), -1, 'account included')
})
diff --git a/test/unit/actions/set_selected_account_test.js b/test/unit/actions/set_selected_account_test.js
index 69eb11e47..f72ca82e4 100644
--- a/test/unit/actions/set_selected_account_test.js
+++ b/test/unit/actions/set_selected_account_test.js
@@ -44,6 +44,5 @@ describe('SHOW_ACCOUNT_DETAIL', function() {
var resultingState = reducers(initialState, action)
assert.equal(resultingState.metamask.selectedAccount, action.value)
- assert.equal(resultingState.metamask.selectedAddress, action.value)
})
})
diff --git a/test/unit/config-manager-test.js b/test/unit/config-manager-test.js
index 6aa7146f0..77d431d5f 100644
--- a/test/unit/config-manager-test.js
+++ b/test/unit/config-manager-test.js
@@ -1,12 +1,14 @@
+// polyfill fetch
+global.fetch = global.fetch || require('isomorphic-fetch')
const assert = require('assert')
const extend = require('xtend')
-const STORAGE_KEY = 'metamask-persistance-key'
-var configManagerGen = require('../lib/mock-config-manager')
-var configManager
const rp = require('request-promise')
const nock = require('nock')
+const configManagerGen = require('../lib/mock-config-manager')
+const STORAGE_KEY = 'metamask-persistance-key'
describe('config-manager', function() {
+ var configManager
beforeEach(function() {
window.localStorage = {} // Hacking localStorage support into JSDom
@@ -100,31 +102,31 @@ describe('config-manager', function() {
describe('confirmation', function() {
- describe('#getConfirmed', function() {
+ describe('#getConfirmedDisclaimer', function() {
it('should return false if no previous key exists', function() {
- var result = configManager.getConfirmed()
+ var result = configManager.getConfirmedDisclaimer()
assert.ok(!result)
})
})
- describe('#setConfirmed', function() {
- it('should make getConfirmed return true once set', function() {
- assert.equal(configManager.getConfirmed(), false)
- configManager.setConfirmed(true)
- var result = configManager.getConfirmed()
+ describe('#setConfirmedDisclaimer', function() {
+ it('should make getConfirmedDisclaimer return true once set', function() {
+ assert.equal(configManager.getConfirmedDisclaimer(), false)
+ configManager.setConfirmedDisclaimer(true)
+ var result = configManager.getConfirmedDisclaimer()
assert.equal(result, true)
})
it('should be able to set false', function() {
- configManager.setConfirmed(false)
- var result = configManager.getConfirmed()
+ configManager.setConfirmedDisclaimer(false)
+ var result = configManager.getConfirmedDisclaimer()
assert.equal(result, false)
})
it('should persist to local storage', function() {
- configManager.setConfirmed(true)
+ configManager.setConfirmedDisclaimer(true)
var data = configManager.getData()
- assert.equal(data.isConfirmed, true)
+ assert.equal(data.isDisclaimerConfirmed, true)
})
})
})
@@ -153,7 +155,7 @@ describe('config-manager', function() {
rpcTarget: 'foobar'
},
}
- configManager.setConfirmed(true)
+ configManager.setConfirmedDisclaimer(true)
configManager.setConfig(testConfig)
var testWallet = {
@@ -164,7 +166,7 @@ describe('config-manager', function() {
var result = configManager.getData()
assert.equal(result.wallet.name, testWallet.name, 'wallet name is set')
assert.equal(result.config.provider.rpcTarget, testConfig.provider.rpcTarget)
- assert.equal(configManager.getConfirmed(), true)
+ assert.equal(configManager.getConfirmedDisclaimer(), true)
testConfig.provider.type = 'something else!'
configManager.setConfig(testConfig)
@@ -173,7 +175,7 @@ describe('config-manager', function() {
assert.equal(result.wallet.name, testWallet.name, 'wallet name is set')
assert.equal(result.config.provider.rpcTarget, testConfig.provider.rpcTarget)
assert.equal(result.config.provider.type, testConfig.provider.type)
- assert.equal(configManager.getConfirmed(), true)
+ assert.equal(configManager.getConfirmedDisclaimer(), true)
})
})
@@ -215,7 +217,7 @@ describe('config-manager', function() {
describe('transactions', function() {
beforeEach(function() {
- configManager._saveTxList([])
+ configManager.setTxList([])
})
describe('#getTxList', function() {
@@ -226,90 +228,13 @@ describe('config-manager', function() {
})
})
- describe('#_saveTxList', function() {
+ describe('#setTxList', function() {
it('saves the submitted data to the tx list', function() {
var target = [{ foo: 'bar' }]
- configManager._saveTxList(target)
+ configManager.setTxList(target)
var result = configManager.getTxList()
assert.equal(result[0].foo, 'bar')
})
})
-
- describe('#addTx', function() {
- it('adds a tx returned in getTxList', function() {
- var tx = { id: 1 }
- configManager.addTx(tx)
- var result = configManager.getTxList()
- assert.ok(Array.isArray(result))
- assert.equal(result.length, 1)
- assert.equal(result[0].id, 1)
- })
-
- it('cuts off early txs beyond a limit', function() {
- const limit = configManager.txLimit
- for (let i = 0; i < limit + 1; i++) {
- let tx = { id: i }
- configManager.addTx(tx)
- }
- var result = configManager.getTxList()
- assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
- assert.equal(result[0].id, 1, 'early txs truncted')
- })
- })
-
- describe('#confirmTx', function() {
- it('sets the tx status to confirmed', function() {
- var tx = { id: 1, status: 'unconfirmed' }
- configManager.addTx(tx)
- configManager.confirmTx(1)
- var result = configManager.getTxList()
- assert.ok(Array.isArray(result))
- assert.equal(result.length, 1)
- assert.equal(result[0].status, 'confirmed')
- })
- })
-
- describe('#rejectTx', function() {
- it('sets the tx status to rejected', function() {
- var tx = { id: 1, status: 'unconfirmed' }
- configManager.addTx(tx)
- configManager.rejectTx(1)
- var result = configManager.getTxList()
- assert.ok(Array.isArray(result))
- assert.equal(result.length, 1)
- assert.equal(result[0].status, 'rejected')
- })
- })
-
- describe('#updateTx', function() {
- it('replaces the tx with the same id', function() {
- configManager.addTx({ id: '1', status: 'unconfirmed' })
- configManager.addTx({ id: '2', status: 'confirmed' })
- configManager.updateTx({ id: '1', status: 'blah', hash: 'foo' })
- var result = configManager.getTx('1')
- assert.equal(result.hash, 'foo')
- })
- })
-
- describe('#unconfirmedTxs', function() {
- it('returns unconfirmed txs in a hash', function() {
- configManager.addTx({ id: '1', status: 'unconfirmed' })
- configManager.addTx({ id: '2', status: 'confirmed' })
- let result = configManager.unconfirmedTxs()
- assert.equal(typeof result, 'object')
- assert.equal(result['1'].status, 'unconfirmed')
- assert.equal(result['0'], undefined)
- assert.equal(result['2'], undefined)
- })
- })
-
- describe('#getTx', function() {
- it('returns a tx with the requested id', function() {
- configManager.addTx({ id: '1', status: 'unconfirmed' })
- configManager.addTx({ id: '2', status: 'confirmed' })
- assert.equal(configManager.getTx('1').status, 'unconfirmed')
- assert.equal(configManager.getTx('2').status, 'confirmed')
- })
- })
})
})
diff --git a/test/unit/explorer-link-test.js b/test/unit/explorer-link-test.js
index 961b400fd..8aa58bff9 100644
--- a/test/unit/explorer-link-test.js
+++ b/test/unit/explorer-link-test.js
@@ -4,7 +4,7 @@ var linkGen = require('../../ui/lib/explorer-link')
describe('explorer-link', function() {
it('adds testnet prefix to morden test network', function() {
- var result = linkGen('hash', '2')
+ var result = linkGen('hash', '3')
assert.notEqual(result.indexOf('testnet'), -1, 'testnet injected')
})
diff --git a/test/unit/idStore-migration-test.js b/test/unit/idStore-migration-test.js
index 59801c868..54f38fb2f 100644
--- a/test/unit/idStore-migration-test.js
+++ b/test/unit/idStore-migration-test.js
@@ -21,6 +21,10 @@ const mockVault = {
account: '0x5d8de92c205279c10e5669f797b853ccef4f739a',
}
+const badVault = {
+ seed: 'radar blur cabbage chef fix engine embark joy scheme fiction master release',
+}
+
describe('IdentityStore to KeyringController migration', function() {
// The stars of the show:
@@ -52,7 +56,7 @@ describe('IdentityStore to KeyringController migration', function() {
},
})
- idStore._createVault(password, mockVault.seed, null, (err) => {
+ idStore._createVault(password, mockVault.seed, (err) => {
assert.ifError(err, 'createNewVault threw error')
originalKeystore = idStore._idmgmt.keyStore
@@ -64,6 +68,10 @@ describe('IdentityStore to KeyringController migration', function() {
addAccount(acct) { newAccounts.push(ethUtil.addHexPrefix(acct)) },
del(acct) { delete newAccounts[acct] },
},
+ txManager: {
+ getTxList: () => [],
+ getUnapprovedTxList: () => []
+ },
})
// Stub out the browser crypto for a mock encryptor.
@@ -75,37 +83,15 @@ describe('IdentityStore to KeyringController migration', function() {
})
describe('entering a password', function() {
- it('should identify an old wallet as an initialized keyring', function() {
+ it('should identify an old wallet as an initialized keyring', function(done) {
keyringController.configManager.setWallet('something')
- const state = keyringController.getState()
- assert(state.isInitialized, 'old vault counted as initialized.')
- })
-
- /*
- it('should use the password to migrate the old vault', function(done) {
- this.timeout(5000)
- console.log('calling submitPassword')
- console.dir(keyringController)
- keyringController.submitPassword(password, function (err, state) {
- assert.ifError(err, 'submitPassword threw error')
-
- function log(str, dat) { console.log(str + ': ' + JSON.stringify(dat)) }
-
- let newAccounts = keyringController.getAccounts()
- log('new accounts: ', newAccounts)
-
- let newAccount = ethUtil.addHexPrefix(newAccounts[0])
- assert.equal(ethUtil.addHexPrefix(newAccount), mockVault.account, 'restored the correct account')
- const newSeed = keyringController.keyrings[0].mnemonic
- log('keyringController keyrings', keyringController.keyrings)
- assert.equal(newSeed, mockVault.seed, 'seed phrase transferred.')
-
- assert(configManager.getVault(), 'new type of vault is persisted')
+ keyringController.getState()
+ .then((state) => {
+ assert(state.isInitialized, 'old vault counted as initialized.')
+ assert(!state.lostAccounts, 'no lost accounts')
done()
})
})
- */
-
})
})
diff --git a/test/unit/idStore-test.js b/test/unit/idStore-test.js
index da465f511..000c58a82 100644
--- a/test/unit/idStore-test.js
+++ b/test/unit/idStore-test.js
@@ -11,7 +11,6 @@ describe('IdentityStore', function() {
describe('#createNewVault', function () {
let idStore
let password = 'password123'
- let entropy = 'entripppppyy duuude'
let seedWords
let accounts = []
let originalKeystore
@@ -26,7 +25,7 @@ describe('IdentityStore', function() {
},
})
- idStore.createNewVault(password, entropy, (err, seeds) => {
+ idStore.createNewVault(password, (err, seeds) => {
assert.ifError(err, 'createNewVault threw error')
seedWords = seeds
originalKeystore = idStore._idmgmt.keyStore
@@ -140,33 +139,4 @@ describe('IdentityStore', function() {
})
})
})
-
- describe('#addGasBuffer', function() {
- const idStore = new IdentityStore({
- configManager: configManagerGen(),
- ethStore: {
- addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
- },
- })
-
- const gas = '0x01'
- const bnGas = new BN(gas, 16)
- const result = idStore.addGasBuffer(gas)
- const bnResult = new BN(result, 16)
-
- assert.ok(bnResult.gt(gas), 'added more gas as buffer.')
- assert.equal(result.indexOf('0x'), 0, 'include hex prefix')
- })
-
- describe('#checkForDelegateCall', function() {
- const idStore = new IdentityStore({
- configManager: configManagerGen(),
- ethStore: {
- addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
- },
- })
-
- var result = idStore.checkForDelegateCall(delegateCallCode)
- assert.equal(result, true, 'no delegate call in provided code')
- })
})
diff --git a/test/unit/keyring-controller-test.js b/test/unit/keyring-controller-test.js
index 0076d9ebe..37fd7175e 100644
--- a/test/unit/keyring-controller-test.js
+++ b/test/unit/keyring-controller-test.js
@@ -2,6 +2,7 @@ var assert = require('assert')
var KeyringController = require('../../app/scripts/keyring-controller')
var configManagerGen = require('../lib/mock-config-manager')
const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
const async = require('async')
const mockEncryptor = require('../lib/mock-encryptor')
const MockSimpleKeychain = require('../lib/mock-simple-keychain')
@@ -11,7 +12,6 @@ describe('KeyringController', function() {
let keyringController, state
let password = 'password123'
- let entropy = 'entripppppyy duuude'
let seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway'
let addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()]
let accounts = []
@@ -23,6 +23,10 @@ describe('KeyringController', function() {
keyringController = new KeyringController({
configManager: configManagerGen(),
+ txManager: {
+ getTxList: () => [],
+ getUnapprovedTxList: () => []
+ },
ethStore: {
addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
},
@@ -32,8 +36,8 @@ describe('KeyringController', function() {
// Browser crypto is tested in the integration test suite.
keyringController.encryptor = mockEncryptor
- keyringController.createNewVaultAndKeychain(password, null, function (err, newState) {
- assert.ifError(err)
+ keyringController.createNewVaultAndKeychain(password)
+ .then(function (newState) {
state = newState
done()
})
@@ -50,43 +54,46 @@ describe('KeyringController', function() {
it('should set a vault on the configManager', function(done) {
keyringController.configManager.setVault(null)
assert(!keyringController.configManager.getVault(), 'no previous vault')
- keyringController.createNewVaultAndKeychain(password, null, (err, state) => {
- assert.ifError(err)
+ keyringController.createNewVaultAndKeychain(password)
+ .then(() => {
const vault = keyringController.configManager.getVault()
assert(vault, 'vault created')
done()
})
+ .catch((reason) => {
+ assert.ifError(reason)
+ done()
+ })
})
})
describe('#restoreKeyring', function() {
- it(`should pass a keyring's serialized data back to the correct type.`, function() {
+ it(`should pass a keyring's serialized data back to the correct type.`, function(done) {
const mockSerialized = {
type: 'HD Key Tree',
data: {
mnemonic: seedWords,
- n: 1,
+ numberOfAccounts: 1,
}
}
const mock = this.sinon.mock(keyringController)
- mock.expects('loadBalanceAndNickname')
+ mock.expects('getBalanceAndNickname')
.exactly(1)
- var keyring = keyringController.restoreKeyring(mockSerialized)
- assert.equal(keyring.wallets.length, 1, 'one wallet restored')
- assert.equal(keyring.getAccounts()[0], addresses[0])
- mock.verify()
- })
-
- })
-
- describe('#migrateAndGetKey', function() {
- it('should return the key for that password', function(done) {
- keyringController.migrateAndGetKey(password)
- .then((key) => {
- assert(key, 'a key is returned')
+ keyringController.restoreKeyring(mockSerialized)
+ .then((keyring) => {
+ assert.equal(keyring.wallets.length, 1, 'one wallet restored')
+ return keyring.getAccounts()
+ })
+ .then((accounts) => {
+ assert.equal(accounts[0], addresses[0])
+ mock.verify()
+ done()
+ })
+ .catch((reason) => {
+ assert.ifError(reason)
done()
})
})
@@ -106,14 +113,21 @@ describe('KeyringController', function() {
})
describe('#saveAccountLabel', function() {
- it ('sets the nickname', function() {
+ it ('sets the nickname', function(done) {
const account = addresses[0]
var nick = 'Test nickname'
- const label = keyringController.saveAccountLabel(account, nick)
- assert.equal(label, nick)
-
- const persisted = keyringController.configManager.nicknameForWallet(account)
- assert.equal(persisted, nick)
+ keyringController.identities[ethUtil.addHexPrefix(account)] = {}
+ keyringController.saveAccountLabel(account, nick)
+ .then((label) => {
+ assert.equal(label, nick)
+ const persisted = keyringController.configManager.nicknameForWallet(account)
+ assert.equal(persisted, nick)
+ done()
+ })
+ .catch((reason) => {
+ assert.ifError(reason)
+ done()
+ })
})
this.timeout(10000)
@@ -121,10 +135,8 @@ describe('KeyringController', function() {
const account = addresses[0]
var nick = 'Test nickname'
keyringController.configManager.setNicknameForWallet(account, nick)
- console.log('calling to restore')
- keyringController.createNewVaultAndRestore(password, seedWords, (err, state) => {
- console.dir({err})
- assert.ifError(err)
+ keyringController.createNewVaultAndRestore(password, seedWords)
+ .then((state) => {
const identity = keyringController.identities['0x' + account]
assert.equal(identity.name, nick)
@@ -132,24 +144,46 @@ describe('KeyringController', function() {
assert(accounts)
done()
})
+ .catch((reason) => {
+ assert.ifError(reason)
+ done()
+ })
})
})
describe('#getAccounts', function() {
it('returns the result of getAccounts for each keyring', function() {
keyringController.keyrings = [
- { getAccounts() { return [1,2,3] } },
- { getAccounts() { return [4,5,6] } },
+ { getAccounts() { return Promise.resolve([1,2,3]) } },
+ { getAccounts() { return Promise.resolve([4,5,6]) } },
]
- const result = keyringController.getAccounts()
- assert.deepEqual(result, [1,2,3,4,5,6])
+ keyringController.getAccounts()
+ .then((result) => {
+ assert.deepEqual(result, [1,2,3,4,5,6])
+ done()
+ })
})
})
-})
-
-
+ describe('#addGasBuffer', function() {
+ it('adds 100k gas buffer to estimates', function() {
+ const gas = '0x04ee59' // Actual estimated gas example
+ const tooBigOutput = '0x80674f9' // Actual bad output
+ const bnGas = new BN(ethUtil.stripHexPrefix(gas), 16)
+ const correctBuffer = new BN('100000', 10)
+ const correct = bnGas.add(correctBuffer)
+ const tooBig = new BN(tooBigOutput, 16)
+ const result = keyringController.addGasBuffer(gas)
+ const bnResult = new BN(ethUtil.stripHexPrefix(result), 16)
+ assert.equal(result.indexOf('0x'), 0, 'included hex prefix')
+ assert(bnResult.gt(bnGas), 'Estimate increased in value.')
+ assert.equal(bnResult.sub(bnGas).toString(10), '100000', 'added 100k gas')
+ assert.equal(result, '0x' + correct.toString(16), 'Added the right amount')
+ assert.notEqual(result, tooBigOutput, 'not that bad estimate')
+ })
+ })
+})
diff --git a/test/unit/keyrings/hd-test.js b/test/unit/keyrings/hd-test.js
index 5d7fbe3db..dfc0ec908 100644
--- a/test/unit/keyrings/hd-test.js
+++ b/test/unit/keyrings/hd-test.js
@@ -16,20 +16,23 @@ describe('hd-keyring', function() {
keyring = new HdKeyring()
})
- describe('constructor', function() {
+ describe('constructor', function(done) {
keyring = new HdKeyring({
mnemonic: sampleMnemonic,
- n: 2,
+ numberOfAccounts: 2,
})
const accounts = keyring.getAccounts()
- assert.equal(accounts[0], firstAcct)
- assert.equal(accounts[1], secondAcct)
+ .then((accounts) => {
+ assert.equal(accounts[0], firstAcct)
+ assert.equal(accounts[1], secondAcct)
+ done()
+ })
})
- describe('Keyring.type()', function() {
- it('is a class method that returns the type string.', function() {
- const type = HdKeyring.type()
+ describe('Keyring.type', function() {
+ it('is a class property that returns the type string.', function() {
+ const type = HdKeyring.type
assert.equal(typeof type, 'string')
})
})
@@ -37,56 +40,69 @@ describe('hd-keyring', function() {
describe('#type', function() {
it('returns the correct value', function() {
const type = keyring.type
- const correct = HdKeyring.type()
+ const correct = HdKeyring.type
assert.equal(type, correct)
})
})
describe('#serialize empty wallets.', function() {
it('serializes a new mnemonic', function() {
- const output = keyring.serialize()
- assert.equal(output.n, 0)
- assert.equal(output.mnemonic, null)
+ keyring.serialize()
+ .then((output) => {
+ assert.equal(output.numberOfAccounts, 0)
+ assert.equal(output.mnemonic, null)
+ })
})
})
describe('#deserialize a private key', function() {
- it('serializes what it deserializes', function() {
+ it('serializes what it deserializes', function(done) {
keyring.deserialize({
mnemonic: sampleMnemonic,
- n: 1
+ numberOfAccounts: 1
+ })
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1, 'restores two accounts')
+ return keyring.addAccounts(1)
+ }).then(() => {
+ return keyring.getAccounts()
+ }).then((accounts) => {
+ assert.equal(accounts[0], firstAcct)
+ assert.equal(accounts[1], secondAcct)
+ assert.equal(accounts.length, 2)
+
+ return keyring.serialize()
+ }).then((serialized) => {
+ assert.equal(serialized.mnemonic, sampleMnemonic)
+ done()
})
- assert.equal(keyring.wallets.length, 1, 'restores two accounts')
- keyring.addAccounts(1)
-
- const accounts = keyring.getAccounts()
- assert.equal(accounts[0], firstAcct)
- assert.equal(accounts[1], secondAcct)
- assert.equal(accounts.length, 2)
-
- const serialized = keyring.serialize()
- assert.equal(serialized.mnemonic, sampleMnemonic)
})
})
describe('#addAccounts', function() {
describe('with no arguments', function() {
- it('creates a single wallet', function() {
+ it('creates a single wallet', function(done) {
keyring.addAccounts()
- assert.equal(keyring.wallets.length, 1)
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1)
+ done()
+ })
})
})
describe('with a numeric argument', function() {
- it('creates that number of wallets', function() {
+ it('creates that number of wallets', function(done) {
keyring.addAccounts(3)
- assert.equal(keyring.wallets.length, 3)
+ .then(() => {
+ assert.equal(keyring.wallets.length, 3)
+ done()
+ })
})
})
})
describe('#getAccounts', function() {
- it('calls getAddress on each wallet', function() {
+ it('calls getAddress on each wallet', function(done) {
// Push a mock wallet
const desiredOutput = 'foo'
@@ -101,8 +117,11 @@ describe('hd-keyring', function() {
})
const output = keyring.getAccounts()
- assert.equal(output[0], desiredOutput)
- assert.equal(output.length, 1)
+ .then((output) => {
+ assert.equal(output[0], desiredOutput)
+ assert.equal(output.length, 1)
+ done()
+ })
})
})
})
diff --git a/test/unit/keyrings/simple-test.js b/test/unit/keyrings/simple-test.js
index ba000a7a8..77eeb834c 100644
--- a/test/unit/keyrings/simple-test.js
+++ b/test/unit/keyrings/simple-test.js
@@ -1,5 +1,6 @@
const assert = require('assert')
const extend = require('xtend')
+const ethUtil = require('ethereumjs-util')
const SimpleKeyring = require('../../../app/scripts/keyrings/simple')
const TYPE_STR = 'Simple Key Pair'
@@ -13,9 +14,9 @@ describe('simple-keyring', function() {
keyring = new SimpleKeyring()
})
- describe('Keyring.type()', function() {
- it('is a class method that returns the type string.', function() {
- const type = SimpleKeyring.type()
+ describe('Keyring.type', function() {
+ it('is a class property that returns the type string.', function() {
+ const type = SimpleKeyring.type
assert.equal(type, TYPE_STR)
})
})
@@ -28,19 +29,41 @@ describe('simple-keyring', function() {
})
describe('#serialize empty wallets.', function() {
- it('serializes an empty array', function() {
- const output = keyring.serialize()
- assert.deepEqual(output, [])
+ it('serializes an empty array', function(done) {
+ keyring.serialize()
+ .then((output) => {
+ assert.deepEqual(output, [])
+ done()
+ })
})
})
describe('#deserialize a private key', function() {
it('serializes what it deserializes', function() {
keyring.deserialize([privKeyHex])
- assert.equal(keyring.wallets.length, 1, 'has one wallet')
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1, 'has one wallet')
+ const serialized = keyring.serialize()
+ assert.equal(serialized[0], privKeyHex)
+ })
+ })
+ })
- const serialized = keyring.serialize()
- assert.equal(serialized[0], privKeyHex)
+ describe('#signMessage', function() {
+ const address = '0x9858e7d8b79fc3e6d989636721584498926da38a'
+ const message = '0x879a053d4800c6354e76c7985a865d2922c82fb5b3f4577b2fe08b998954f2e0'
+ const privateKey = '0x7dd98753d7b4394095de7d176c58128e2ed6ee600abe97c9f6d9fd65015d9b18'
+ const expectedResult = '0x28fcb6768e5110144a55b2e6ce9d1ea5a58103033632d272d2b5cf506906f7941a00b539383fd872109633d8c71c404e13dba87bc84166ee31b0e36061a69e161c'
+
+ it('passes the dennis test', function(done) {
+ keyring.deserialize([ privateKey ])
+ .then(() => {
+ return keyring.signMessage(address, message)
+ })
+ .then((result) => {
+ assert.equal(result, expectedResult)
+ done()
+ })
})
})
@@ -48,36 +71,39 @@ describe('simple-keyring', function() {
describe('with no arguments', function() {
it('creates a single wallet', function() {
keyring.addAccounts()
- assert.equal(keyring.wallets.length, 1)
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1)
+ })
})
})
describe('with a numeric argument', function() {
it('creates that number of wallets', function() {
keyring.addAccounts(3)
- assert.equal(keyring.wallets.length, 3)
+ .then(() => {
+ assert.equal(keyring.wallets.length, 3)
+ })
})
})
})
describe('#getAccounts', function() {
- it('calls getAddress on each wallet', function() {
+ it('calls getAddress on each wallet', function(done) {
// Push a mock wallet
- const desiredOutput = 'foo'
+ const desiredOutput = '0x18a3462427bcc9133bb46e88bcbe39cd7ef0e761'
keyring.wallets.push({
getAddress() {
- return {
- toString() {
- return desiredOutput
- }
- }
+ return ethUtil.toBuffer(desiredOutput)
}
})
- const output = keyring.getAccounts()
- assert.equal(output[0], desiredOutput)
- assert.equal(output.length, 1)
+ keyring.getAccounts()
+ .then((output) => {
+ assert.equal(output[0], desiredOutput)
+ assert.equal(output.length, 1)
+ done()
+ })
})
})
})
diff --git a/test/unit/metamask-controller-test.js b/test/unit/metamask-controller-test.js
index b87169ca2..a6164c9a0 100644
--- a/test/unit/metamask-controller-test.js
+++ b/test/unit/metamask-controller-test.js
@@ -9,7 +9,7 @@ describe('MetaMaskController', function() {
let controller = new MetaMaskController({
showUnconfirmedMessage: noop,
unlockAccountMessage: noop,
- showUnconfirmedTx: noop,
+ showUnapprovedTx: noop,
setData,
loadData,
})
@@ -25,24 +25,6 @@ describe('MetaMaskController', function() {
this.sinon.restore()
})
- describe('#enforceTxValidations', function () {
- it('returns null for positive values', function() {
- var sample = {
- value: '0x01'
- }
- var res = controller.enforceTxValidations(sample)
- assert.equal(res, null, 'no error')
- })
-
-
- it('returns error for negative values', function() {
- var sample = {
- value: '-0x01'
- }
- var res = controller.enforceTxValidations(sample)
- assert.ok(res, 'error')
- })
- })
})
diff --git a/test/unit/nodeify-test.js b/test/unit/nodeify-test.js
new file mode 100644
index 000000000..a14d34338
--- /dev/null
+++ b/test/unit/nodeify-test.js
@@ -0,0 +1,22 @@
+const assert = require('assert')
+const nodeify = require('../../app/scripts/lib/nodeify')
+
+describe('nodeify', function() {
+
+ var obj = {
+ foo: 'bar',
+ promiseFunc: function (a) {
+ var solution = this.foo + a
+ return Promise.resolve(solution)
+ }
+ }
+
+ it('should retain original context', function(done) {
+ var nodified = nodeify(obj.promiseFunc).bind(obj)
+ nodified('baz', function (err, res) {
+ assert.equal(res, 'barbaz')
+ done()
+ })
+ })
+
+})
diff --git a/test/unit/notice-controller-test.js b/test/unit/notice-controller-test.js
new file mode 100644
index 000000000..cf00daeba
--- /dev/null
+++ b/test/unit/notice-controller-test.js
@@ -0,0 +1,116 @@
+const assert = require('assert')
+const extend = require('xtend')
+const rp = require('request-promise')
+const nock = require('nock')
+const configManagerGen = require('../lib/mock-config-manager')
+const NoticeController = require('../../app/scripts/notice-controller')
+const STORAGE_KEY = 'metamask-persistance-key'
+
+describe('notice-controller', function() {
+ var noticeController
+
+ beforeEach(function() {
+ // simple localStorage polyfill
+ window.localStorage = {}
+ if (window.localStorage.clear) window.localStorage.clear()
+ let configManager = configManagerGen()
+ noticeController = new NoticeController({
+ configManager: configManager,
+ })
+ })
+
+ describe('notices', function() {
+ describe('#getNoticesList', function() {
+ it('should return an empty array when new', function() {
+ var testList = [{
+ id:0,
+ read:false,
+ title:"Futuristic Notice"
+ }]
+ var result = noticeController.getNoticesList()
+ assert.equal(result.length, 0)
+ })
+ })
+
+ describe('#setNoticesList', function() {
+ it('should set data appropriately', function () {
+ var testList = [{
+ id:0,
+ read:false,
+ title:"Futuristic Notice"
+ }]
+ noticeController.setNoticesList(testList)
+ var testListId = noticeController.getNoticesList()[0].id
+ assert.equal(testListId, 0)
+ })
+ })
+
+ describe('#updateNoticeslist', function() {
+ it('should integrate the latest changes from the source', function() {
+ var testList = [{
+ id:55,
+ read:false,
+ title:"Futuristic Notice"
+ }]
+ noticeController.setNoticesList(testList)
+ noticeController.updateNoticesList().then(() => {
+ var newList = noticeController.getNoticesList()
+ assert.ok(newList[0].id === 55)
+ assert.ok(newList[1])
+ })
+ })
+ it('should not overwrite any existing fields', function () {
+ var testList = [{
+ id:0,
+ read:false,
+ title:"Futuristic Notice"
+ }]
+ noticeController.setNoticesList(testList)
+ noticeController.updateNoticesList().then(() => {
+ var newList = noticeController.getNoticesList()
+ assert.equal(newList[0].id, 0)
+ assert.equal(newList[0].title, "Futuristic Notice")
+ assert.equal(newList.length, 1)
+ })
+ })
+ })
+
+ describe('#markNoticeRead', function () {
+ it('should mark a notice as read', function () {
+ var testList = [{
+ id:0,
+ read:false,
+ title:"Futuristic Notice"
+ }]
+ noticeController.setNoticesList(testList)
+ noticeController.markNoticeRead(testList[0])
+ var newList = noticeController.getNoticesList()
+ assert.ok(newList[0].read)
+ })
+ })
+
+ describe('#getLatestUnreadNotice', function () {
+ it('should retrieve the latest unread notice', function () {
+ var testList = [
+ {id:0,read:true,title:"Past Notice"},
+ {id:1,read:false,title:"Current Notice"},
+ {id:2,read:false,title:"Future Notice"},
+ ]
+ noticeController.setNoticesList(testList)
+ var latestUnread = noticeController.getLatestUnreadNotice()
+ assert.equal(latestUnread.id, 2)
+ })
+ it('should return undefined if no unread notices exist.', function () {
+ var testList = [
+ {id:0,read:true,title:"Past Notice"},
+ {id:1,read:true,title:"Current Notice"},
+ {id:2,read:true,title:"Future Notice"},
+ ]
+ noticeController.setNoticesList(testList)
+ var latestUnread = noticeController.getLatestUnreadNotice()
+ assert.ok(!latestUnread)
+ })
+ })
+ })
+
+})
diff --git a/test/unit/tx-manager-test.js b/test/unit/tx-manager-test.js
new file mode 100644
index 000000000..a66003f85
--- /dev/null
+++ b/test/unit/tx-manager-test.js
@@ -0,0 +1,215 @@
+const assert = require('assert')
+const extend = require('xtend')
+const EventEmitter = require('events')
+const STORAGE_KEY = 'metamask-persistance-key'
+const TransactionManager = require('../../app/scripts/transaction-manager')
+
+describe('Transaction Manager', function() {
+ let txManager
+
+ const onTxDoneCb = () => true
+ beforeEach(function() {
+ txManager = new TransactionManager ({
+ txList: [],
+ setTxList: () => {},
+ provider: "testnet",
+ txHistoryLimit: 10,
+ blockTracker: new EventEmitter(),
+ getNetwork: function(){ return 'unit test' }
+ })
+ })
+
+ describe('#validateTxParams', function () {
+ it('returns null for positive values', function() {
+ var sample = {
+ value: '0x01'
+ }
+ var res = txManager.txProviderUtils.validateTxParams(sample, (err) => {
+ assert.equal(err, null, 'no error')
+ })
+ })
+
+
+ it('returns error for negative values', function() {
+ var sample = {
+ value: '-0x01'
+ }
+ var res = txManager.txProviderUtils.validateTxParams(sample, (err) => {
+ assert.ok(err, 'error')
+ })
+ })
+ })
+
+ describe('#getTxList', function() {
+ it('when new should return empty array', function() {
+ var result = txManager.getTxList()
+ assert.ok(Array.isArray(result))
+ assert.equal(result.length, 0)
+ })
+ it('should also return transactions from local storage if any', function() {
+
+ })
+ })
+
+ describe('#_saveTxList', function() {
+ it('saves the submitted data to the tx list', function() {
+ var target = [{ foo: 'bar', metamaskNetworkId: 'unit test' }]
+ txManager._saveTxList(target)
+ var result = txManager.getTxList()
+ assert.equal(result[0].foo, 'bar')
+ })
+ })
+
+ describe('#addTx', function() {
+ it('adds a tx returned in getTxList', function() {
+ var tx = { id: 1, status: 'confirmed', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx, onTxDoneCb)
+ var result = txManager.getTxList()
+ assert.ok(Array.isArray(result))
+ assert.equal(result.length, 1)
+ assert.equal(result[0].id, 1)
+ })
+
+ it('cuts off early txs beyond a limit', function() {
+ const limit = txManager.txHistoryLimit
+ for (let i = 0; i < limit + 1; i++) {
+ let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx, onTxDoneCb)
+ }
+ var result = txManager.getTxList()
+ assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
+ assert.equal(result[0].id, 1, 'early txs truncted')
+ })
+
+ it('cuts off early txs beyond a limit whether or not it is confirmed or rejected', function() {
+ const limit = txManager.txHistoryLimit
+ for (let i = 0; i < limit + 1; i++) {
+ let tx = { id: i, time: new Date(), status: 'rejected', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx, onTxDoneCb)
+ }
+ var result = txManager.getTxList()
+ assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
+ assert.equal(result[0].id, 1, 'early txs truncted')
+ })
+
+ it('cuts off early txs beyond a limit but does not cut unapproved txs', function() {
+ var unconfirmedTx = { id: 0, time: new Date(), status: 'unapproved', metamaskNetworkId: 'unit test' }
+ txManager.addTx(unconfirmedTx, onTxDoneCb)
+ const limit = txManager.txHistoryLimit
+ for (let i = 1; i < limit + 1; i++) {
+ let tx = { id: i, time: new Date(), status: 'confirmed', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx, onTxDoneCb)
+ }
+ var result = txManager.getTxList()
+ assert.equal(result.length, limit, `limit of ${limit} txs enforced`)
+ assert.equal(result[0].id, 0, 'first tx should still be there')
+ assert.equal(result[0].status, 'unapproved', 'first tx should be unapproved')
+ assert.equal(result[1].id, 2, 'early txs truncted')
+ })
+ })
+
+ describe('#setTxStatusSigned', function() {
+ it('sets the tx status to signed', function() {
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx, onTxDoneCb)
+ txManager.setTxStatusSigned(1)
+ var result = txManager.getTxList()
+ assert.ok(Array.isArray(result))
+ assert.equal(result.length, 1)
+ assert.equal(result[0].status, 'signed')
+ })
+
+ it('should emit a signed event to signal the exciton of callback', (done) => {
+ this.timeout(10000)
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
+ let onTxDoneCb = function () {
+ assert(true, 'event listener has been triggered and onTxDoneCb executed')
+ done()
+ }
+ txManager.addTx(tx)
+ txManager.on('1:signed', onTxDoneCb)
+ txManager.setTxStatusSigned(1)
+ })
+ })
+
+ describe('#setTxStatusRejected', function() {
+ it('sets the tx status to rejected', function() {
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx)
+ txManager.setTxStatusRejected(1)
+ var result = txManager.getTxList()
+ assert.ok(Array.isArray(result))
+ assert.equal(result.length, 1)
+ assert.equal(result[0].status, 'rejected')
+ })
+
+ it('should emit a rejected event to signal the exciton of callback', (done) => {
+ this.timeout(10000)
+ var tx = { id: 1, status: 'unapproved', metamaskNetworkId: 'unit test' }
+ txManager.addTx(tx)
+ let onTxDoneCb = function (err, txId) {
+ assert(true, 'event listener has been triggered and onTxDoneCb executed')
+ done()
+ }
+ txManager.on('1:rejected', onTxDoneCb)
+ txManager.setTxStatusRejected(1)
+ })
+
+ })
+
+ describe('#updateTx', function() {
+ it('replaces the tx with the same id', function() {
+ txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ txManager.updateTx({ id: '1', status: 'blah', hash: 'foo', metamaskNetworkId: 'unit test' })
+ var result = txManager.getTx('1')
+ assert.equal(result.hash, 'foo')
+ })
+ })
+
+ describe('#getUnapprovedTxList', function() {
+ it('returns unapproved txs in a hash', function() {
+ txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ let result = txManager.getUnapprovedTxList()
+ assert.equal(typeof result, 'object')
+ assert.equal(result['1'].status, 'unapproved')
+ assert.equal(result['2'], undefined)
+ })
+ })
+
+ describe('#getTx', function() {
+ it('returns a tx with the requested id', function() {
+ txManager.addTx({ id: '1', status: 'unapproved', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ txManager.addTx({ id: '2', status: 'confirmed', metamaskNetworkId: 'unit test' }, onTxDoneCb)
+ assert.equal(txManager.getTx('1').status, 'unapproved')
+ assert.equal(txManager.getTx('2').status, 'confirmed')
+ })
+ })
+
+ describe('#getFilteredTxList', function() {
+ it('returns a tx with the requested data', function() {
+ var foop = 0
+ var zoop = 0
+ for (let i = 0; i < 10; ++i ){
+ let everyOther = i % 2
+ txManager.addTx({ id: i,
+ status: everyOther ? 'unapproved' : 'confirmed',
+ metamaskNetworkId: 'unit test',
+ txParams: {
+ from: everyOther ? 'foop' : 'zoop',
+ to: everyOther ? 'zoop' : 'foop',
+ }
+ }, onTxDoneCb)
+ everyOther ? ++foop : ++zoop
+ }
+ assert.equal(txManager.getFilteredTxList({status: 'confirmed', from: 'zoop'}).length, zoop)
+ assert.equal(txManager.getFilteredTxList({status: 'confirmed', to: 'foop'}).length, zoop)
+ assert.equal(txManager.getFilteredTxList({status: 'confirmed', from: 'foop'}).length, 0)
+ assert.equal(txManager.getFilteredTxList({status: 'confirmed'}).length, zoop)
+ assert.equal(txManager.getFilteredTxList({from: 'foop'}).length, foop)
+ assert.equal(txManager.getFilteredTxList({from: 'zoop'}).length, zoop)
+ })
+ })
+
+})
diff --git a/ui-dev.js b/ui-dev.js
index e48122970..e39340859 100644
--- a/ui-dev.js
+++ b/ui-dev.js
@@ -25,7 +25,7 @@ const Selector = require('./development/selector')
// Query String
const qs = require('qs')
let queryString = qs.parse(window.location.href.split('#')[1])
-let selectedView = queryString.view || 'account detail'
+let selectedView = queryString.view || 'first time'
const firstState = states[selectedView]
updateQueryParams(selectedView)
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index c41ba61fd..7a0c599ba 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -26,11 +26,10 @@ function mapStateToProps (state) {
accounts: state.metamask.accounts,
address: state.metamask.selectedAccount,
accountDetail: state.appState.accountDetail,
- transactions: state.metamask.transactions,
network: state.metamask.network,
- unconfTxs: valuesFor(state.metamask.unconfTxs),
unconfMsgs: valuesFor(state.metamask.unconfMsgs),
shapeShiftTxList: state.metamask.shapeShiftTxList,
+ transactions: state.metamask.selectedAccountTxList || [],
}
}
@@ -248,20 +247,10 @@ AccountDetailScreen.prototype.subview = function () {
}
AccountDetailScreen.prototype.transactionList = function () {
- const { transactions, unconfTxs, unconfMsgs, address, network, shapeShiftTxList } = this.props
-
- var txsToRender = transactions.concat(unconfTxs)
- // only transactions that are from the current address
- .filter(tx => tx.txParams.from === address)
- // only transactions that are on the current network
- .filter(tx => tx.txParams.metamaskNetworkId === network)
- // sort by recency
- .sort((a, b) => b.time - a.time)
-
+ const {transactions, unconfMsgs, address, network, shapeShiftTxList } = this.props
return h(TransactionList, {
- txsToRender,
+ transactions: transactions.sort((a, b) => b.time - a.time),
network,
- unconfTxs,
unconfMsgs,
address,
shapeShiftTxList,
diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js
index 4e0d69ed7..16019c88a 100644
--- a/ui/app/accounts/account-list-item.js
+++ b/ui/app/accounts/account-list-item.js
@@ -15,19 +15,21 @@ function AccountListItem () {
}
AccountListItem.prototype.render = function () {
- const identity = this.props.identity
- var isSelected = this.props.selectedAddress === identity.address
- var account = this.props.accounts[identity.address]
+ const { identity, selectedAccount, accounts, onShowDetail } = this.props
+
+ const isSelected = selectedAccount === identity.address
+ const account = accounts[identity.address]
const selectedClass = isSelected ? '.selected' : ''
return (
h(`.accounts-list-option.flex-row.flex-space-between.pointer.hover-white${selectedClass}`, {
key: `account-panel-${identity.address}`,
- onClick: (event) => this.props.onShowDetail(identity.address, event),
+ onClick: (event) => onShowDetail(identity.address, event),
}, [
h('.identicon-wrapper.flex-column.flex-center.select-none', [
this.pendingOrNot(),
+ this.indicateIfLoose(),
h(Identicon, {
address: identity.address,
imageify: true,
@@ -48,7 +50,7 @@ AccountListItem.prototype.render = function () {
},
}, ethUtil.toChecksumAddress(identity.address)),
h(EthBalance, {
- value: account.balance,
+ value: account && account.balance,
style: {
lineHeight: '7px',
marginTop: '10px',
@@ -70,6 +72,14 @@ AccountListItem.prototype.render = function () {
)
}
+AccountListItem.prototype.indicateIfLoose = function () {
+ try { // Sometimes keyrings aren't loaded yet:
+ const type = this.props.keyring.type
+ const isLoose = type !== 'HD Key Tree'
+ return isLoose ? h('.keyring-label', 'LOOSE') : null
+ } catch (e) { return }
+}
+
AccountListItem.prototype.pendingOrNot = function () {
const pending = this.props.pending
if (pending.length === 0) return null
diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js
index 65cf82b2c..5ab31a1c0 100644
--- a/ui/app/accounts/index.js
+++ b/ui/app/accounts/index.js
@@ -19,9 +19,10 @@ function mapStateToProps (state) {
accounts: state.metamask.accounts,
identities: state.metamask.identities,
unconfTxs: state.metamask.unconfTxs,
- selectedAddress: state.metamask.selectedAddress,
+ selectedAccount: state.metamask.selectedAccount,
scrollToBottom: state.appState.scrollToBottom,
pending,
+ keyrings: state.metamask.keyrings,
}
}
@@ -31,9 +32,10 @@ function AccountsScreen () {
}
AccountsScreen.prototype.render = function () {
- var state = this.props
- var identityList = valuesFor(state.identities)
- var unconfTxList = valuesFor(state.unconfTxs)
+ const props = this.props
+ const { keyrings } = props
+ const identityList = valuesFor(props.identities)
+ const unconfTxList = valuesFor(props.unconfTxs)
return (
@@ -69,13 +71,19 @@ AccountsScreen.prototype.render = function () {
}
})
+ const simpleAddress = identity.address.substring(2).toLowerCase()
+ const keyring = keyrings.find((kr) => {
+ return kr.accounts.includes(simpleAddress)
+ })
+
return h(AccountListItem, {
key: `acct-panel-${identity.address}`,
identity,
- selectedAddress: this.props.selectedAddress,
+ selectedAccount: this.props.selectedAccount,
accounts: this.props.accounts,
onShowDetail: this.onShowDetail.bind(this),
pending,
+ keyring,
})
}),
@@ -133,8 +141,8 @@ AccountsScreen.prototype.navigateToConfTx = function () {
AccountsScreen.prototype.onSelect = function (address, event) {
event.stopPropagation()
// if already selected, deselect
- if (this.props.selectedAddress === address) address = null
- this.props.dispatch(actions.setSelectedAddress(address))
+ if (this.props.selectedAccount === address) address = null
+ this.props.dispatch(actions.setSelectedAccount(address))
}
AccountsScreen.prototype.onShowDetail = function (address, event) {
@@ -143,8 +151,15 @@ AccountsScreen.prototype.onShowDetail = function (address, event) {
}
AccountsScreen.prototype.addNewAccount = function () {
+ this.props.dispatch(actions.addNewAccount(0))
+}
+
+/* An optional view proposed in this design:
+ * https://consensys.quip.com/zZVrAysM5znY
+AccountsScreen.prototype.addNewAccount = function () {
this.props.dispatch(actions.navigateToNewAccountScreen())
}
+*/
AccountsScreen.prototype.goHome = function () {
this.props.dispatch(actions.goHome())
diff --git a/ui/app/actions.js b/ui/app/actions.js
index f5456e0d2..87b02966b 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -5,24 +5,40 @@ var actions = {
goHome: goHome,
// menu state
getNetworkStatus: 'getNetworkStatus',
-
+ // transition state
+ TRANSITION_FORWARD: 'TRANSITION_FORWARD',
+ TRANSITION_BACKWARD: 'TRANSITION_BACKWARD',
+ transitionForward,
+ transitionBackward,
// remote state
UPDATE_METAMASK_STATE: 'UPDATE_METAMASK_STATE',
updateMetamaskState: updateMetamaskState,
+ // notices
+ MARK_NOTICE_READ: 'MARK_NOTICE_READ',
+ markNoticeRead: markNoticeRead,
+ SHOW_NOTICE: 'SHOW_NOTICE',
+ showNotice: showNotice,
+ CLEAR_NOTICES: 'CLEAR_NOTICES',
+ clearNotices: clearNotices,
+ markAccountsFound,
// intialize screen
AGREE_TO_DISCLAIMER: 'AGREE_TO_DISCLAIMER',
agreeToDisclaimer: agreeToDisclaimer,
CREATE_NEW_VAULT_IN_PROGRESS: 'CREATE_NEW_VAULT_IN_PROGRESS',
SHOW_CREATE_VAULT: 'SHOW_CREATE_VAULT',
SHOW_RESTORE_VAULT: 'SHOW_RESTORE_VAULT',
+ FORGOT_PASSWORD: 'FORGOT_PASSWORD',
+ forgotPassword: forgotPassword,
SHOW_INIT_MENU: 'SHOW_INIT_MENU',
SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED',
SHOW_INFO_PAGE: 'SHOW_INFO_PAGE',
+ SHOW_IMPORT_PAGE: 'SHOW_IMPORT_PAGE',
unlockMetamask: unlockMetamask,
unlockFailed: unlockFailed,
showCreateVault: showCreateVault,
showRestoreVault: showRestoreVault,
showInitializeMenu: showInitializeMenu,
+ showImportPage,
createNewVaultAndKeychain: createNewVaultAndKeychain,
createNewVaultAndRestore: createNewVaultAndRestore,
createNewVaultInProgress: createNewVaultInProgress,
@@ -46,7 +62,6 @@ var actions = {
unlockInProgress: unlockInProgress,
// error handling
displayWarning: displayWarning,
- showWarning: showWarning, // alias
DISPLAY_WARNING: 'DISPLAY_WARNING',
HIDE_WARNING: 'HIDE_WARNING',
hideWarning: hideWarning,
@@ -74,7 +89,7 @@ var actions = {
TRANSACTION_ERROR: 'TRANSACTION_ERROR',
NEXT_TX: 'NEXT_TX',
PREVIOUS_TX: 'PREV_TX',
- setSelectedAddress: setSelectedAddress,
+ setSelectedAccount: setSelectedAccount,
signMsg: signMsg,
cancelMsg: cancelMsg,
sendTx: sendTx,
@@ -142,13 +157,13 @@ var actions = {
SHOW_NEW_KEYCHAIN: 'SHOW_NEW_KEYCHAIN',
showNewKeychain: showNewKeychain,
-
+ callBackgroundThenUpdate,
}
module.exports = actions
var background = null
-function _setBackgroundConnection(backgroundConnection) {
+function _setBackgroundConnection (backgroundConnection) {
background = backgroundConnection
}
@@ -169,24 +184,32 @@ function tryUnlockMetamask (password) {
if (err) {
dispatch(actions.unlockFailed(err.message))
} else {
- dispatch(this.updateMetamaskState(newState))
- let selectedAccount
- try {
- selectedAccount = newState.metamask.selectedAccount
- } catch (e) {}
- dispatch(actions.unlockMetamask(selectedAccount))
+ dispatch(actions.transitionForward())
+ dispatch(actions.updateMetamaskState(newState))
}
})
}
}
+function transitionForward () {
+ return {
+ type: this.TRANSITION_FORWARD,
+ }
+}
+
+function transitionBackward () {
+ return {
+ type: this.TRANSITION_BACKWARD,
+ }
+}
+
function confirmSeedWords () {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
background.clearSeedWordCache((err, account) => {
dispatch(actions.hideLoadingIndication())
if (err) {
- return dispatch(actions.showWarning(err.message))
+ return dispatch(actions.displayWarning(err.message))
}
console.log('Seed word cache cleared. ' + account)
@@ -198,25 +221,16 @@ function confirmSeedWords () {
function createNewVaultAndRestore (password, seed) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.createNewVaultAndRestore(password, seed, (err, newState) => {
+ background.createNewVaultAndRestore(password, seed, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(this.updateMetamaskState(newState))
+ dispatch(actions.showAccountsPage())
})
}
}
-function createNewVaultAndKeychain (password, entropy) {
- return (dispatch) => {
- background.createNewVaultAndKeychain(password, entropy, (err, newState) => {
- if (err) {
- return dispatch(actions.showWarning(err.message))
- }
-
- dispatch(this.updateMetamaskState(newState))
- dispatch(this.showNewVaultSeed())
- })
- }
+function createNewVaultAndKeychain (password) {
+ return callBackgroundThenUpdate(background.createNewVaultAndKeychain, password)
}
function revealSeedConfirmation () {
@@ -228,28 +242,18 @@ function revealSeedConfirmation () {
function requestRevealSeed (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.submitPassword(password, (err, newState) => {
- dispatch(actions.hideLoadingIndication())
+ background.submitPassword(password, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
- background.placeSeedWords()
- dispatch(actions.showNewVaultSeed())
+ background.placeSeedWords((err) => {
+ if (err) return dispatch(actions.displayWarning(err.message))
+ dispatch(actions.hideLoadingIndication())
+ })
})
}
}
-
function addNewKeyring (type, opts) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- background.addNewKeyring(type, opts, (err, newState) => {
- dispatch(this.hideLoadingIndication())
- if (err) {
- return dispatch(actions.showWarning(err))
- }
- dispatch(this.updateMetamaskState(newState))
- dispatch(this.showAccountsPage())
- })
- }
+ return callBackgroundThenUpdate(background.addNewKeyring, type, opts)
}
function navigateToNewAccountScreen() {
@@ -259,16 +263,7 @@ function navigateToNewAccountScreen() {
}
function addNewAccount (ringNumber = 0) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- background.addNewAccount(ringNumber, (err, newState) => {
- dispatch(this.hideLoadingIndication())
- if (err) {
- return dispatch(actions.showWarning(err))
- }
- dispatch(this.updateMetamaskState(newState))
- })
- }
+ return callBackgroundThenUpdate(background.addNewAccount, ringNumber)
}
function showInfoPage () {
@@ -277,10 +272,8 @@ function showInfoPage () {
}
}
-function setSelectedAddress (address) {
- return (dispatch) => {
- background.setSelectedAddress(address)
- }
+function setSelectedAccount (address) {
+ return callBackgroundThenUpdate(background.setSelectedAccount, address)
}
function setCurrentFiat (fiat) {
@@ -381,18 +374,30 @@ function showRestoreVault () {
}
}
+function forgotPassword () {
+ return {
+ type: actions.FORGOT_PASSWORD,
+ }
+}
+
function showInitializeMenu () {
return {
type: actions.SHOW_INIT_MENU,
}
}
+function showImportPage () {
+ return {
+ type: actions.SHOW_IMPORT_PAGE,
+ }
+}
+
function agreeToDisclaimer () {
return (dispatch) => {
dispatch(this.showLoadingIndication())
background.agreeToDisclaimer((err) => {
if (err) {
- return dispatch(actions.showWarning(err.message))
+ return dispatch(actions.displayWarning(err.message))
}
dispatch(this.hideLoadingIndication())
@@ -460,32 +465,22 @@ function updateMetamaskState (newState) {
}
function lockMetamask () {
- return (dispatch) => {
- background.setLocked((err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.showWarning(err.message))
- }
-
- dispatch({
- type: actions.LOCK_METAMASK,
- })
- })
- }
+ return callBackgroundThenUpdate(background.setLocked)
}
function showAccountDetail (address) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- background.setSelectedAddress(address, (err, address) => {
+ background.setSelectedAccount(address, (err, newState) => {
dispatch(actions.hideLoadingIndication())
if (err) {
- return dispatch(actions.showWarning(err.message))
+ return dispatch(actions.displayWarning(err.message))
}
+ dispatch(actions.updateMetamaskState(newState))
dispatch({
type: actions.SHOW_ACCOUNT_DETAIL,
- value: address,
+ value: newState.selectedAccount,
})
})
}
@@ -544,6 +539,47 @@ function goBackToInitView () {
}
//
+// notice
+//
+
+function markNoticeRead (notice) {
+ return (dispatch) => {
+ dispatch(this.showLoadingIndication())
+ background.markNoticeRead(notice, (err, notice) => {
+ dispatch(this.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.displayWarning(err))
+ }
+ if (notice) {
+ return dispatch(actions.showNotice(notice))
+ } else {
+ dispatch(this.clearNotices())
+ return {
+ type: actions.SHOW_ACCOUNTS_PAGE,
+ }
+ }
+ })
+ }
+}
+
+function showNotice (notice) {
+ return {
+ type: actions.SHOW_NOTICE,
+ value: notice,
+ }
+}
+
+function clearNotices () {
+ return {
+ type: actions.CLEAR_NOTICES,
+ }
+}
+
+function markAccountsFound() {
+ return callBackgroundThenUpdate(background.markAccountsFound)
+}
+
+//
// config
//
@@ -594,10 +630,6 @@ function hideSubLoadingIndication () {
}
}
-function showWarning (text) {
- return this.displayWarning(text)
-}
-
function displayWarning (text) {
return {
type: actions.DISPLAY_WARNING,
@@ -649,7 +681,7 @@ function saveAccountLabel (account, label) {
background.saveAccountLabel(account, label, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
- return dispatch(actions.showWarning(err.message))
+ return dispatch(actions.displayWarning(err.message))
}
dispatch({
type: actions.SAVE_ACCOUNT_LABEL,
@@ -725,7 +757,7 @@ function shapeShiftSubview (network) {
shapeShiftRequest('marketinfo', {pair}, (mktResponse) => {
shapeShiftRequest('getcoins', {}, (response) => {
dispatch(actions.hideSubLoadingIndication())
- if (mktResponse.error) return dispatch(actions.showWarning(mktResponse.error))
+ if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error))
dispatch({
type: actions.SHAPESHIFT_SUBVIEW,
value: {
@@ -742,7 +774,7 @@ function coinShiftRquest (data, marketData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
shapeShiftRequest('shift', { method: 'POST', data}, (response) => {
- if (response.error) return dispatch(actions.showWarning(response.error))
+ if (response.error) return dispatch(actions.displayWarning(response.error))
var message = `
Deposit your ${response.depositType} to the address bellow:`
background.createShapeShiftTx(response.deposit, response.depositType)
@@ -764,7 +796,7 @@ function reshowQrCode (data, coin) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => {
- if (mktResponse.error) return dispatch(actions.showWarning(mktResponse.error))
+ if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error))
var message = [
`Deposit your ${coin} to the address bellow:`,
@@ -801,3 +833,24 @@ function shapeShiftRequest (query, options, cb) {
return shapShiftReq.send()
}
}
+
+// Call Background Then Update
+//
+// A function generator for a common pattern wherein:
+// We show loading indication.
+// We call a background method.
+// We hide loading indication.
+// If it errored, we show a warning.
+// If it didn't, we update the state.
+function callBackgroundThenUpdate (method, ...args) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ method.call(background, ...args, (err, newState) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.displayWarning(err.message))
+ }
+ dispatch(actions.updateMetamaskState(newState))
+ })
+ }
+}
diff --git a/ui/app/app.js b/ui/app/app.js
index ad56df8db..67c78b31c 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -15,8 +15,12 @@ const AccountsScreen = require('./accounts')
const AccountDetailScreen = require('./account-detail')
const SendTransactionScreen = require('./send')
const ConfirmTxScreen = require('./conf-tx')
+// notice
+const NoticeScreen = require('./components/notice')
+const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
// other views
const ConfigScreen = require('./config')
+const Import = require('./accounts/import')
const InfoScreen = require('./info')
const LoadingIndicator = require('./components/loading')
const SandwichExpando = require('sandwich-expando')
@@ -40,7 +44,8 @@ function mapStateToProps (state) {
return {
// state from plugin
isLoading: state.appState.isLoading,
- isConfirmed: state.metamask.isConfirmed,
+ isDisclaimerConfirmed: state.metamask.isDisclaimerConfirmed,
+ noActiveNotices: state.metamask.noActiveNotices,
isInitialized: state.metamask.isInitialized,
isUnlocked: state.metamask.isUnlocked,
currentView: state.appState.currentView,
@@ -53,6 +58,8 @@ function mapStateToProps (state) {
network: state.metamask.network,
provider: state.metamask.provider,
forgottenPassword: state.appState.forgottenPassword,
+ lastUnreadNotice: state.metamask.lastUnreadNotice,
+ lostAccounts: state.metamask.lostAccounts,
}
}
@@ -91,7 +98,6 @@ App.prototype.render = function () {
transitionLeaveTimeout: 300,
}, [
this.renderPrimary(),
- this.renderBackToInitButton(),
]),
]),
])
@@ -99,7 +105,6 @@ App.prototype.render = function () {
}
App.prototype.renderAppBar = function () {
-
if (window.METAMASK_UI_TYPE === 'notification') {
return null
}
@@ -138,15 +143,21 @@ App.prototype.renderAppBar = function () {
src: '/images/icon-128.png',
}),
- h(NetworkIndicator, {
- network: this.props.network,
- provider: this.props.provider,
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
+ h('#network-spacer.flex-center', {
+ style: {
+ marginRight: '-72px',
},
- }),
+ }, [
+ h(NetworkIndicator, {
+ network: this.props.network,
+ provider: this.props.provider,
+ onClick: (event) => {
+ event.preventDefault()
+ event.stopPropagation()
+ this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
+ },
+ }),
+ ]),
]),
// metamask name
@@ -235,7 +246,7 @@ App.prototype.renderNetworkDropdown = function () {
}),
h(DropMenuItem, {
- label: 'Morden Test Network',
+ label: 'Ropsten Test Network',
closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
action: () => props.dispatch(actions.setProviderType('testnet')),
icon: h('.menu-icon.red-dot'),
@@ -251,7 +262,15 @@ App.prototype.renderNetworkDropdown = function () {
activeNetworkRender: props.provider.rpcTarget,
}),
- this.renderCustomOption(props.provider.rpcTarget),
+ this.renderCustomOption(props.provider),
+
+ h(DropMenuItem, {
+ label: 'Custom RPC',
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ action: () => this.props.dispatch(actions.showConfigPage()),
+ icon: h('i.fa.fa-question-circle.fa-lg'),
+ }),
+
])
}
@@ -288,6 +307,13 @@ App.prototype.renderDropdown = function () {
}),
h(DropMenuItem, {
+ label: 'Import Account',
+ closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
+ action: () => this.props.dispatch(actions.showImportPage()),
+ icon: h('i.fa.fa-arrow-circle-o-up.fa-lg'),
+ }),
+
+ h(DropMenuItem, {
label: 'Lock',
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
action: () => this.props.dispatch(actions.lockMetamask()),
@@ -322,43 +348,10 @@ App.prototype.renderBackButton = function (style, justArrow = false) {
)
}
-App.prototype.renderBackToInitButton = function () {
- var props = this.props
- var button = null
- if (!props.isConfirmed) return button
-
- if (!props.isUnlocked) {
- if (props.currentView.name === 'InitMenu') {
- button = props.forgottenPassword ? h('.flex-row', {
- key: 'rightArrow',
- style: {
- position: 'absolute',
- bottom: '10px',
- right: '15px',
- fontSize: '21px',
- fontFamily: 'Montserrat Light',
- color: '#7F8082',
- width: '77.578px',
- alignItems: 'flex-end',
- },
- }, [
- h('div.cursor-pointer', {
- style: {
- marginRight: '3px',
- },
- onClick: () => props.dispatch(actions.backToUnlockView()),
- }, 'LOGIN'),
- h('i.fa.fa-arrow-right.cursor-pointer'),
- ]) : null
- }
- }
- return button
-}
-
App.prototype.renderPrimary = function () {
var props = this.props
- if (!props.isConfirmed) {
+ if (!props.isDisclaimerConfirmed) {
return h(DisclaimerScreen, {key: 'disclaimerScreen'})
}
@@ -368,7 +361,6 @@ App.prototype.renderPrimary = function () {
// show initialize screen
if (!props.isInitialized || props.forgottenPassword) {
-
// show current view
switch (props.currentView.name) {
@@ -392,6 +384,21 @@ App.prototype.renderPrimary = function () {
}
}
+ // notices
+ if (!props.noActiveNotices) {
+ return h(NoticeScreen, {
+ notice: props.lastUnreadNotice,
+ key: 'NoticeScreen',
+ onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
+ })
+ } else if (props.lostAccounts && props.lostAccounts.length > 0) {
+ return h(NoticeScreen, {
+ notice: generateLostAccountsNotice(props.lostAccounts),
+ key: 'LostAccountsNotice',
+ onConfirm: () => props.dispatch(actions.markAccountsFound()),
+ })
+ }
+
// show current view
switch (props.currentView.name) {
@@ -416,6 +423,9 @@ App.prototype.renderPrimary = function () {
case 'config':
return h(ConfigScreen, {key: 'config'})
+ case 'import-menu':
+ return h(Import, {key: 'import-menu'})
+
case 'reveal-seed-conf':
return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
@@ -469,15 +479,11 @@ App.prototype.toggleMetamaskActive = function () {
}
}
-App.prototype.renderCustomOption = function (rpcTarget) {
+App.prototype.renderCustomOption = function (provider) {
+ const { rpcTarget, type } = provider
+ if (type !== 'rpc') return null
+
switch (rpcTarget) {
- case undefined:
- return h(DropMenuItem, {
- label: 'Custom RPC',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => this.props.dispatch(actions.showConfigPage()),
- icon: h('i.fa.fa-question-circle.fa-lg'),
- })
case 'http://localhost:8545':
return null
diff --git a/ui/app/components/buy-button-subview.js b/ui/app/components/buy-button-subview.js
index 4678168bb..afda5bf59 100644
--- a/ui/app/components/buy-button-subview.js
+++ b/ui/app/components/buy-button-subview.js
@@ -123,9 +123,9 @@ BuyButtonSubview.prototype.formVersionSubview = function () {
style: {
width: '225px',
},
- }, 'In order to access this feature please switch to the Main Network'),
- h('h3.text-transform-uppercase', 'or:'),
- this.props.network === '2' ? h('button.text-transform-uppercase', {
+ }, 'In order to access this feature, please switch to the Main Network'),
+ (this.props.network === '3') ? h('h3.text-transform-uppercase', 'or:') : null,
+ (this.props.network === '3') ? h('button.text-transform-uppercase', {
onClick: () => this.props.dispatch(actions.buyEth()),
style: {
marginTop: '15px',
diff --git a/ui/app/components/coinbase-form.js b/ui/app/components/coinbase-form.js
index efd05ec96..430a3eead 100644
--- a/ui/app/components/coinbase-form.js
+++ b/ui/app/components/coinbase-form.js
@@ -7,7 +7,7 @@ const actions = require('../actions')
const isValidAddress = require('../util').isValidAddress
module.exports = connect(mapStateToProps)(CoinbaseForm)
-function mapStateToProps(state) {
+function mapStateToProps (state) {
return {
selectedAccount: state.selectedAccount,
warning: state.appState.warning,
@@ -16,7 +16,7 @@ function mapStateToProps(state) {
inherits(CoinbaseForm, Component)
-function CoinbaseForm() {
+function CoinbaseForm () {
Component.call(this)
}
@@ -72,7 +72,7 @@ CoinbaseForm.prototype.render = function () {
lineHeight: '13px',
},
},
- `there is a USD$ 5 a day max and a USD$ 50
+ `there is a USD$ 15 a day max and a USD$ 50
dollar limit per the life time of an account without a
coinbase account. A fee of 3.75% will be aplied to debit/credit cards.`),
@@ -116,15 +116,14 @@ CoinbaseForm.prototype.toCoinbase = function () {
props.dispatch(actions.buyEth(address, props.buyView.amount))
} else if (!isValidAmountforCoinBase(amount).valid) {
message = isValidAmountforCoinBase(amount).message
- return props.dispatch(actions.showWarning(message))
+ return props.dispatch(actions.displayWarning(message))
} else {
message = 'Receiving address is invalid.'
- return props.dispatch(actions.showWarning(message))
+ return props.dispatch(actions.displayWarning(message))
}
}
CoinbaseForm.prototype.renderLoading = function () {
-
return h('img', {
style: {
width: '27px',
@@ -134,18 +133,17 @@ CoinbaseForm.prototype.renderLoading = function () {
})
}
-function isValidAmountforCoinBase(amount) {
+function isValidAmountforCoinBase (amount) {
amount = parseFloat(amount)
-
if (amount) {
- if (amount <= 5 && amount > 0) {
+ if (amount <= 15 && amount > 0) {
return {
valid: true,
}
- } else if (amount > 5) {
+ } else if (amount > 15) {
return {
valid: false,
- message: 'The amount can not be greater then $5',
+ message: 'The amount can not be greater then $15',
}
} else {
return {
diff --git a/ui/app/components/copyButton.js b/ui/app/components/copyButton.js
index a01603585..a25d0719c 100644
--- a/ui/app/components/copyButton.js
+++ b/ui/app/components/copyButton.js
@@ -50,12 +50,10 @@ CopyButton.prototype.render = function () {
])
}
-CopyButton.prototype.debounceRestore = function() {
-
+CopyButton.prototype.debounceRestore = function () {
this.setState({ copied: true })
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.setState({ copied: false })
}, 850)
-
}
diff --git a/ui/app/components/drop-menu-item.js b/ui/app/components/drop-menu-item.js
index 8088680c0..9f002234e 100644
--- a/ui/app/components/drop-menu-item.js
+++ b/ui/app/components/drop-menu-item.js
@@ -32,16 +32,16 @@ DropMenuItem.prototype.render = function () {
}
DropMenuItem.prototype.activeNetworkRender = function () {
- let activeNetwork = this.props.activeNetworkRender
- let { provider } = this.props
- let providerType = provider ? provider.type : null
+ const activeNetwork = this.props.activeNetworkRender
+ const { provider } = this.props
+ const providerType = provider ? provider.type : null
if (activeNetwork === undefined) return
switch (this.props.label) {
case 'Main Ethereum Network':
if (providerType === 'mainnet') return h('.check', '✓')
break
- case 'Morden Test Network':
+ case 'Ropsten Test Network':
if (provider.type === 'testnet') return h('.check', '✓')
break
case 'Localhost 8545':
diff --git a/ui/app/components/eth-balance.js b/ui/app/components/eth-balance.js
index 46127bed5..57ca84564 100644
--- a/ui/app/components/eth-balance.js
+++ b/ui/app/components/eth-balance.js
@@ -15,9 +15,10 @@ function EthBalanceComponent () {
EthBalanceComponent.prototype.render = function () {
var props = this.props
+ let { value } = props
var style = props.style
var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
- const value = formatBalance(props.value, 6, needsParse)
+ value = value ? formatBalance(value, 6, needsParse) : '...'
var width = props.width
return (
@@ -38,6 +39,7 @@ EthBalanceComponent.prototype.render = function () {
EthBalanceComponent.prototype.renderBalance = function (value) {
var props = this.props
if (value === 'None') return value
+ if (value === '...') return value
var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3)
var balance
var splitBalance = value.split(' ')
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index ff5aefd41..77805fd57 100644
--- a/ui/app/components/network.js
+++ b/ui/app/components/network.js
@@ -22,7 +22,6 @@ Network.prototype.render = function () {
let iconName, hoverText
if (networkNumber === 'loading') {
-
return h('img.network-indicator', {
title: 'Attempting to connect to blockchain.',
onClick: (event) => this.props.onClick(event),
@@ -32,24 +31,22 @@ Network.prototype.render = function () {
},
src: 'images/loading.svg',
})
-
} else if (providerName === 'mainnet') {
hoverText = 'Main Ethereum Network'
iconName = 'ethereum-network'
} else if (providerName === 'testnet') {
- hoverText = 'Morden Test Network'
- iconName = 'morden-test-network'
+ hoverText = 'Ropsten Test Network'
+ iconName = 'ropsten-test-network'
+ } else if (parseInt(networkNumber) === 3) {
+ hoverText = 'Ropsten Test Network'
+ iconName = 'ropsten-test-network'
} else {
hoverText = 'Unknown Private Network'
iconName = 'unknown-private-network'
}
return (
- h('#network_component.flex-center.pointer', {
- style: {
- marginRight: '-27px',
- marginLeft: '-3px',
- },
+ h('#network_component.pointer', {
title: hoverText,
onClick: (event) => this.props.onClick(event),
}, [
@@ -64,14 +61,14 @@ Network.prototype.render = function () {
}},
'Ethereum Main Net'),
])
- case 'morden-test-network':
+ case 'ropsten-test-network':
return h('.network-indicator', [
h('.menu-icon.red-dot'),
h('.network-name', {
style: {
color: '#ff6666',
}},
- 'Morden Test Net'),
+ 'Ropsten Test Net'),
])
default:
return h('.network-indicator', [
diff --git a/ui/app/components/notice.js b/ui/app/components/notice.js
new file mode 100644
index 000000000..00db734d7
--- /dev/null
+++ b/ui/app/components/notice.js
@@ -0,0 +1,110 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const ReactMarkdown = require('react-markdown')
+const linker = require('extension-link-enabler')
+const findDOMNode = require('react-dom').findDOMNode
+
+module.exports = Notice
+
+inherits(Notice, Component)
+function Notice () {
+ Component.call(this)
+}
+
+Notice.prototype.render = function () {
+ const { notice, onConfirm } = this.props
+ const { title, date, body } = notice
+
+ return (
+ h('.flex-column.flex-center.flex-grow', [
+ h('h3.flex-center.text-transform-uppercacse.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ title,
+ ]),
+
+ h('h5.flex-center.text-transform-uppercacse.terms-header', {
+ style: {
+ background: '#EBEBEB',
+ color: '#AEAEAE',
+ marginBottom: 24,
+ width: '100%',
+ fontSize: '20px',
+ textAlign: 'center',
+ padding: 6,
+ },
+ }, [
+ date,
+ ]),
+
+ h('style', `
+
+ .markdown {
+ overflow-x: hidden;
+ }
+
+ .markdown h1, .markdown h2, .markdown h3 {
+ margin: 10px 0;
+ font-weight: bold;
+ }
+
+ .markdown strong {
+ font-weight: bold;
+ }
+ .markdown em {
+ font-style: italic;
+ }
+
+ .markdown p {
+ margin: 10px 0;
+ }
+
+ .markdown a {
+ color: #df6b0e;
+ }
+
+ `),
+
+ h('div.markdown', {
+ style: {
+ background: 'rgb(235, 235, 235)',
+ height: '310px',
+ padding: '6px',
+ width: '90%',
+ overflowY: 'scroll',
+ scroll: 'auto',
+ },
+ }, [
+ h(ReactMarkdown, {
+ source: body,
+ skipHtml: true,
+ }),
+ ]),
+
+ h('button', {
+ onClick: onConfirm,
+ style: {
+ marginTop: '18px',
+ },
+ }, 'Continue'),
+ ])
+ )
+}
+
+Notice.prototype.componentDidMount = function () {
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+}
+
+Notice.prototype.componentWillUnmount = function () {
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+}
diff --git a/ui/app/components/pending-msg-details.js b/ui/app/components/pending-msg-details.js
index 16308d121..404cb8ae2 100644
--- a/ui/app/components/pending-msg-details.js
+++ b/ui/app/components/pending-msg-details.js
@@ -16,7 +16,7 @@ PendingMsgDetails.prototype.render = function () {
var msgData = state.txData
var msgParams = msgData.msgParams || {}
- var address = msgParams.from || state.selectedAddress
+ var address = msgParams.from || state.selectedAccount
var identity = state.identities[address] || { address: address }
var account = state.accounts[address] || { address: address }
diff --git a/ui/app/components/pending-tx-details.js b/ui/app/components/pending-tx-details.js
index 545302098..286931f6f 100644
--- a/ui/app/components/pending-tx-details.js
+++ b/ui/app/components/pending-tx-details.js
@@ -7,8 +7,6 @@ const EthBalance = require('./eth-balance')
const util = require('../util')
const addressSummary = util.addressSummary
const nameForAddress = require('../../lib/contract-namer')
-const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
module.exports = PendingTxDetails
@@ -24,20 +22,14 @@ PTXP.render = function () {
var txData = props.txData
var txParams = txData.txParams || {}
- var address = txParams.from || props.selectedAddress
+ var address = txParams.from || props.selectedAccount
var identity = props.identities[address] || { address: address }
var account = props.accounts[address]
var balance = account ? account.balance : '0x0'
- var gasMultiplier = txData.gasMultiplier
- var gasCost = new BN(ethUtil.stripHexPrefix(txParams.gas || txData.estimatedGas), 16)
- var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice || '0x4a817c800'), 16)
- gasPrice = gasPrice.mul(new BN(gasMultiplier * 100), 10).div(new BN(100, 10))
- var txFee = gasCost.mul(gasPrice)
- var txValue = new BN(ethUtil.stripHexPrefix(txParams.value || '0x0'), 16)
- var maxCost = txValue.add(txFee)
+ var txFee = txData.txFee || ''
+ var maxCost = txData.maxCost || ''
var dataLength = txParams.data ? (txParams.data.length - 2) / 2 : 0
-
var imageify = props.imageifyIdenticons === undefined ? true : props.imageifyIdenticons
return (
@@ -154,8 +146,6 @@ PTXP.render = function () {
]),
]), // End of Table
- this.warnIfNeeded(),
-
])
)
}
@@ -201,29 +191,6 @@ PTXP.miniAccountPanelForRecipient = function () {
}
}
-// Should analyze if there is a DELEGATECALL opcode
-// in the recipient contract, and show a warning if so.
-PTXP.warnIfNeeded = function () {
- const containsDelegateCall = !!this.props.txData.containsDelegateCall
-
- if (!containsDelegateCall) {
- return null
- }
-
- return h('span.error', {
- style: {
- fontFamily: 'Montserrat Light',
- fontSize: '13px',
- display: 'flex',
- justifyContent: 'center',
- },
- }, [
- h('i.fa.fa-lg.fa-info-circle', { style: { margin: '5px' } }),
- h('span', ' Your identity may be used in other contracts!'),
- ])
-}
-
-
function forwardCarrat () {
return (
diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js
index 4c27a8092..96f968929 100644
--- a/ui/app/components/pending-tx.js
+++ b/ui/app/components/pending-tx.js
@@ -30,6 +30,15 @@ PendingTx.prototype.render = function () {
}
`),
+ txData.simulationFails ?
+ h('.error', {
+ style: {
+ marginLeft: 50,
+ fontSize: '0.9em',
+ },
+ }, 'Transaction Error. Exception thrown in contract code.')
+ : null,
+
state.insufficientBalance ?
h('span.error', {
style: {
diff --git a/ui/app/components/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index 2bb384b94..383d5b623 100644
--- a/ui/app/components/shapeshift-form.js
+++ b/ui/app/components/shapeshift-form.js
@@ -8,7 +8,7 @@ const Qr = require('./qr-code')
const isValidAddress = require('../util').isValidAddress
module.exports = connect(mapStateToProps)(ShapeshiftForm)
-function mapStateToProps(state) {
+function mapStateToProps (state) {
return {
selectedAccount: state.selectedAccount,
warning: state.appState.warning,
@@ -25,7 +25,6 @@ function ShapeshiftForm () {
}
ShapeshiftForm.prototype.render = function () {
-
return h(ReactCSSTransitionGroup, {
className: 'css-transition-group',
transitionName: 'main',
@@ -34,7 +33,6 @@ ShapeshiftForm.prototype.render = function () {
}, [
this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain(),
])
-
}
ShapeshiftForm.prototype.renderMain = function () {
@@ -244,7 +242,7 @@ ShapeshiftForm.prototype.updateCoin = function (event) {
if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
var message = 'Not a valid coin'
- return props.dispatch(actions.showWarning(message))
+ return props.dispatch(actions.displayWarning(message))
} else {
return props.dispatch(actions.pairUpdate(coin))
}
diff --git a/ui/app/components/shift-list-item.js b/ui/app/components/shift-list-item.js
index 38c19eb28..e0243e247 100644
--- a/ui/app/components/shift-list-item.js
+++ b/ui/app/components/shift-list-item.js
@@ -26,7 +26,6 @@ function ShiftListItem () {
}
ShiftListItem.prototype.render = function () {
-
return (
h('.transaction-list-item.flex-row', {
style: {
diff --git a/ui/app/components/tooltip.js b/ui/app/components/tooltip.js
index 757ad0cd6..edbc074bb 100644
--- a/ui/app/components/tooltip.js
+++ b/ui/app/components/tooltip.js
@@ -11,7 +11,6 @@ function Tooltip () {
}
Tooltip.prototype.render = function () {
-
const props = this.props
const { position, title, children } = props
@@ -20,5 +19,4 @@ Tooltip.prototype.render = function () {
title,
fixed: false,
}, children)
-
}
diff --git a/ui/app/components/transaction-list-item-icon.js b/ui/app/components/transaction-list-item-icon.js
index 8b118b1d4..eca0d693a 100644
--- a/ui/app/components/transaction-list-item-icon.js
+++ b/ui/app/components/transaction-list-item-icon.js
@@ -13,13 +13,40 @@ function TransactionIcon () {
TransactionIcon.prototype.render = function () {
const { transaction, txParams, isMsg } = this.props
+ switch (transaction.status) {
+ case 'unapproved':
+ return h('.unapproved-tx', {
+ style: {
+ width: '24px',
+ height: '24px',
+ background: '#4dffff',
+ border: 'solid',
+ borderColor: '#AEAEAE',
+ borderWidth: '0.5px',
+ borderRadius: '13px',
+ },
+ })
- if (transaction.status === 'rejected') {
- return h('i.fa.fa-exclamation-triangle.fa-lg.warning', {
- style: {
- width: '24px',
- },
- })
+ case 'rejected':
+ return h('i.fa.fa-exclamation-triangle.fa-lg.warning', {
+ style: {
+ width: '24px',
+ },
+ })
+
+ case 'failed':
+ return h('i.fa.fa-exclamation-triangle.fa-lg.error', {
+ style: {
+ width: '24px',
+ },
+ })
+
+ case 'signed':
+ return h('i.fa.fa-ellipsis-h', {
+ style: {
+ fontSize: '27px',
+ },
+ })
}
if (isMsg) {
diff --git a/ui/app/components/transaction-list-item.js b/ui/app/components/transaction-list-item.js
index 491e90c7c..95e850264 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -8,6 +8,7 @@ const explorerLink = require('../../lib/explorer-link')
const CopyButton = require('./copyButton')
const vreme = new (require('vreme'))
const extension = require('../../../app/scripts/lib/extension')
+const Tooltip = require('./tooltip')
const TransactionIcon = require('./transaction-list-item-icon')
const ShiftListItem = require('./shift-list-item')
@@ -27,11 +28,11 @@ TransactionListItem.prototype.render = function () {
let isLinkable = false
const numericNet = parseInt(network)
- isLinkable = numericNet === 1 || numericNet === 2
+ isLinkable = numericNet === 1 || numericNet === 3
var isMsg = ('msgParams' in transaction)
var isTx = ('txParams' in transaction)
- var isPending = transaction.status === 'unconfirmed'
+ var isPending = transaction.status === 'unapproved'
let txParams
if (isTx) {
@@ -41,7 +42,6 @@ TransactionListItem.prototype.render = function () {
}
const isClickable = ('hash' in transaction && isLinkable) || isPending
-
return (
h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, {
onClick: (event) => {
@@ -59,11 +59,7 @@ TransactionListItem.prototype.render = function () {
}, [
h('.identicon-wrapper.flex-column.flex-center.select-none', [
- transaction.status === 'unconfirmed' ? h('i.fa.fa-ellipsis-h', {
- style: {
- fontSize: '27px',
- },
- }) : h( '.pop-hover', {
+ h('.pop-hover', {
onClick: (event) => {
event.stopPropagation()
if (!isTx || isPending) return
@@ -139,7 +135,14 @@ function failIfFailed (transaction) {
if (transaction.status === 'rejected') {
return h('span.error', ' (Rejected)')
}
- if (transaction.status === 'failed') {
- return h('span.error', ' (Failed)')
+ if (transaction.err) {
+
+ return h(Tooltip, {
+ title: transaction.err.message,
+ position: 'bottom',
+ }, [
+ h('span.error', ' (Failed)'),
+ ])
}
+
}
diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js
index 7e1bedb05..b055ca9d5 100644
--- a/ui/app/components/transaction-list.js
+++ b/ui/app/components/transaction-list.js
@@ -13,12 +13,13 @@ function TransactionList () {
}
TransactionList.prototype.render = function () {
- const { txsToRender, network, unconfMsgs } = this.props
+ const { transactions, network, unconfMsgs } = this.props
+
var shapeShiftTxList
if (network === '1') {
shapeShiftTxList = this.props.shapeShiftTxList
}
- const transactions = !shapeShiftTxList ? txsToRender.concat(unconfMsgs) : txsToRender.concat(unconfMsgs, shapeShiftTxList)
+ const txsToRender = !shapeShiftTxList ? transactions.concat(unconfMsgs) : transactions.concat(unconfMsgs, shapeShiftTxList)
.sort((a, b) => b.time - a.time)
return (
@@ -55,8 +56,8 @@ TransactionList.prototype.render = function () {
},
}, [
- transactions.length
- ? transactions.map((transaction, i) => {
+ txsToRender.length
+ ? txsToRender.map((transaction, i) => {
let key
switch (transaction.key) {
case 'shapeshift':
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index f4ca52860..a6e03c3ed 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -4,6 +4,7 @@ const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('./actions')
+const NetworkIndicator = require('./components/network')
const txHelper = require('../lib/tx-helper')
const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
const ethUtil = require('ethereumjs-util')
@@ -18,12 +19,13 @@ function mapStateToProps (state) {
return {
identities: state.metamask.identities,
accounts: state.metamask.accounts,
- selectedAddress: state.metamask.selectedAddress,
+ selectedAccount: state.metamask.selectedAccount,
unconfTxs: state.metamask.unconfTxs,
unconfMsgs: state.metamask.unconfMsgs,
index: state.appState.currentView.context,
warning: state.appState.warning,
network: state.metamask.network,
+ provider: state.metamask.provider,
}
}
@@ -36,13 +38,16 @@ ConfirmTxScreen.prototype.render = function () {
var state = this.props
var network = state.network
+ var provider = state.provider
var unconfTxs = state.unconfTxs
var unconfMsgs = state.unconfMsgs
+
var unconfTxList = txHelper(unconfTxs, unconfMsgs, network)
- var index = state.index !== undefined ? state.index : 0
- var txData = unconfTxList[index] || unconfTxList[0] || {}
- var txParams = txData.txParams || {}
+ var index = state.index !== undefined && unconfTxList[index] ? state.index : 0
+ var txData = unconfTxList[index] || {}
+ var txParams = txData.params || {}
var isNotification = isPopupOrNotification() === 'notification'
+ if (unconfTxList.length === 0) return null
return (
@@ -54,6 +59,10 @@ ConfirmTxScreen.prototype.render = function () {
onClick: this.goHome.bind(this),
}) : null,
h('h2.page-subtitle', 'Confirm Transaction'),
+ isNotification ? h(NetworkIndicator, {
+ network: network,
+ provider: provider,
+ }) : null,
]),
h('h3', {
@@ -90,12 +99,12 @@ ConfirmTxScreen.prototype.render = function () {
// Properties
txData: txData,
key: txData.id,
- selectedAddress: state.selectedAddress,
+ selectedAccount: state.selectedAccount,
accounts: state.accounts,
identities: state.identities,
- insufficientBalance: this.checkBalnceAgainstTx(txData),
+ insufficientBalance: this.checkBalanceAgainstTx(txData),
// Actions
- buyEth: this.buyEth.bind(this, txParams.from || state.selectedAddress),
+ buyEth: this.buyEth.bind(this, txParams.from || state.selectedAccount),
sendTransaction: this.sendTransaction.bind(this, txData),
cancelTransaction: this.cancelTransaction.bind(this, txData),
signMessage: this.signMessage.bind(this, txData),
@@ -108,27 +117,24 @@ ConfirmTxScreen.prototype.render = function () {
}
function currentTxView (opts) {
- if ('txParams' in opts.txData) {
+ const { txData } = opts
+ const { txParams, msgParams } = txData
+
+ if (txParams) {
// This is a pending transaction
return h(PendingTx, opts)
- } else if ('msgParams' in opts.txData) {
+ } else if (msgParams) {
// This is a pending message to sign
return h(PendingMsg, opts)
}
}
-ConfirmTxScreen.prototype.checkBalnceAgainstTx = function (txData) {
+ConfirmTxScreen.prototype.checkBalanceAgainstTx = function (txData) {
+ if (!txData.txParams) return false
var state = this.props
-
- var txParams = txData.txParams || {}
- var address = txParams.from || state.selectedAddress
+ var address = txData.txParams.from || state.selectedAccount
var account = state.accounts[address]
var balance = account ? account.balance : '0x0'
-
- var gasCost = new BN(ethUtil.stripHexPrefix(txParams.gas || txData.estimatedGas), 16)
- var gasPrice = new BN(ethUtil.stripHexPrefix(txParams.gasPrice || '0x4a817c800'), 16)
- var txFee = gasCost.mul(gasPrice)
- var txValue = new BN(ethUtil.stripHexPrefix(txParams.value || '0x0'), 16)
- var maxCost = txValue.add(txFee)
+ var maxCost = new BN(txData.maxCost)
var balanceBn = new BN(ethUtil.stripHexPrefix(balance), 16)
return maxCost.gt(balanceBn)
@@ -170,6 +176,10 @@ function warningIfExists (warning) {
if (warning &&
// Do not display user rejections on this screen:
warning.indexOf('User denied transaction signature') === -1) {
- return h('span.error', { style: { margin: 'auto' } }, warning)
+ return h('.error', {
+ style: {
+ margin: 'auto',
+ },
+ }, warning)
}
}
diff --git a/ui/app/config.js b/ui/app/config.js
index e09a38cd8..65b1ed712 100644
--- a/ui/app/config.js
+++ b/ui/app/config.js
@@ -3,12 +3,14 @@ const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('./actions')
-const currencies = require('./conversion-util').availableCurrencies.rows
+const currencies = require('./conversion.json').rows
+const validUrl = require('valid-url')
module.exports = connect(mapStateToProps)(ConfigScreen)
function mapStateToProps (state) {
return {
metamask: state.metamask,
+ warning: state.appState.warning,
}
}
@@ -20,6 +22,7 @@ function ConfigScreen () {
ConfigScreen.prototype.render = function () {
var state = this.props
var metamaskState = state.metamask
+ var warning = state.warning
return (
h('.flex-column.flex-grow', [
@@ -34,6 +37,14 @@ ConfigScreen.prototype.render = function () {
h('h2.page-subtitle', 'Settings'),
]),
+ h('.error', {
+ style: {
+ display: warning ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
+ },
+ }, warning),
+
// conf view
h('.flex-column.flex-justify-center.flex-grow.select-none', [
h('.flex-space-around', {
@@ -57,7 +68,7 @@ ConfigScreen.prototype.render = function () {
if (event.key === 'Enter') {
var element = event.target
var newRpc = element.value
- state.dispatch(actions.setRpcTarget(newRpc))
+ rpcValidation(newRpc, state)
}
},
}),
@@ -69,7 +80,7 @@ ConfigScreen.prototype.render = function () {
event.preventDefault()
var element = document.querySelector('input#new_rpc')
var newRpc = element.value
- state.dispatch(actions.setRpcTarget(newRpc))
+ rpcValidation(newRpc, state)
},
}, 'Save'),
]),
@@ -99,6 +110,19 @@ ConfigScreen.prototype.render = function () {
)
}
+function rpcValidation (newRpc, state) {
+ if (validUrl.isWebUri(newRpc)) {
+ state.dispatch(actions.setRpcTarget(newRpc))
+ } else {
+ var appendedRpc = `http://${newRpc}`
+ if (validUrl.isWebUri(appendedRpc)) {
+ state.dispatch(actions.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.'))
+ } else {
+ state.dispatch(actions.displayWarning('Invalid RPC URI'))
+ }
+ }
+}
+
function currentConversionInformation (metamaskState, state) {
var currentFiat = metamaskState.currentFiat
var conversionDate = metamaskState.conversionDate
@@ -133,7 +157,7 @@ function currentProviderDisplay (metamaskState) {
case 'testnet':
title = 'Current Network'
- value = 'Morden Test Network'
+ value = 'Ropsten Test Network'
break
default:
diff --git a/ui/app/conversion-util.js b/ui/app/conversion-util.js
deleted file mode 100644
index 19259602a..000000000
--- a/ui/app/conversion-util.js
+++ /dev/null
@@ -1,5 +0,0 @@
-var availableCurrencies = {"rows":[{"code":"007","name":"007","statuses":["primary"]},{"code":"1337","name":"1337","statuses":["primary"]},{"code":"1CR","name":"1CR","statuses":["primary"]},{"code":"256","name":"256","statuses":["primary"]},{"code":"2FLAV","name":"2FLAV","statuses":["primary"]},{"code":"2GIVE","name":"2GIVE","statuses":["primary"]},{"code":"404","name":"404","statuses":["primary"]},{"code":"611","name":"611","statuses":["primary"]},{"code":"888","name":"888","statuses":["primary"]},{"code":"8BIT","name":"8Bit","statuses":["primary"]},{"code":"ACLR","name":"ACLR","statuses":["primary"]},{"code":"ACOIN","name":"ACOIN","statuses":["primary"]},{"code":"ACP","name":"ACP","statuses":["primary"]},{"code":"ADC","name":"ADC","statuses":["primary"]},{"code":"ADZ","name":"Adzcoin","statuses":["primary"]},{"code":"AEC","name":"AEC","statuses":["primary"]},{"code":"AEON","name":"Aeon","statuses":["primary"]},{"code":"AGRS","name":"Agoras Tokens","statuses":["primary"]},{"code":"AIB","name":"AIB","statuses":["primary"]},{"code":"ADN","name":"Aiden","statuses":["primary"]},{"code":"AIR","name":"AIR","statuses":["primary"]},{"code":"ALC","name":"ALC","statuses":["primary"]},{"code":"ALTC","name":"ALTC","statuses":["primary"]},{"code":"AM","name":"AM","statuses":["primary"]},{"code":"AMBER","name":"AMBER","statuses":["primary"]},{"code":"AMS","name":"AMS","statuses":["primary"]},{"code":"ANAL","name":"ANAL","statuses":["primary"]},{"code":"AND","name":"AND","statuses":["primary"]},{"code":"ANI","name":"ANI","statuses":["primary"]},{"code":"ANC","name":"Anoncoin","statuses":["primary"]},{"code":"ANTI","name":"AntiBitcoin","statuses":["primary"]},{"code":"APEX","name":"APEX","statuses":["primary"]},{"code":"APC","name":"Applecoin","statuses":["primary"]},{"code":"APT","name":"APT","statuses":["primary"]},{"code":"AR2","name":"AR2","statuses":["primary"]},{"code":"ARB","name":"ARB","statuses":["primary"]},{"code":"ARC","name":"ARC","statuses":["primary"]},{"code":"ARCH","name":"ARCH","statuses":["primary"]},{"code":"ABY","name":"ArtByte","statuses":["primary"]},{"code":"ARTC","name":"ARTC","statuses":["primary"]},{"code":"ADCN","name":"Asiadigicoin","statuses":["primary"]},{"code":"ATEN","name":"ATEN","statuses":["primary"]},{"code":"REP","name":"Augur","statuses":["primary"]},{"code":"AUR","name":"Auroracoin","statuses":["primary"]},{"code":"AUD","name":"Australian Dollar","statuses":["secondary"]},{"code":"AV","name":"AV","statuses":["primary"]},{"code":"BA","name":"BA","statuses":["primary"]},{"code":"BAC","name":"BAC","statuses":["primary"]},{"code":"BTA","name":"Bata","statuses":["primary"]},{"code":"BAY","name":"BAY","statuses":["primary"]},{"code":"BBCC","name":"BBCC","statuses":["primary"]},{"code":"BQC","name":"BBQCoin","statuses":["primary"]},{"code":"BDC","name":"BDC","statuses":["primary"]},{"code":"BEC","name":"BEC","statuses":["primary"]},{"code":"BEEZ","name":"BEEZ","statuses":["primary"]},{"code":"BELA","name":"BellaCoin","statuses":["primary"]},{"code":"BERN","name":"BERNcash","statuses":["primary"]},{"code":"BILL","name":"BILL","statuses":["primary"]},{"code":"BILS","name":"BILS","statuses":["primary"]},{"code":"BIOS","name":"BiosCrypto","statuses":["primary"]},{"code":"BIT","name":"BIT","statuses":["primary"]},{"code":"BIT16","name":"BIT16","statuses":["primary"]},{"code":"BITB","name":"BitBean","statuses":["primary"]},{"code":"BTC","name":"Bitcoin","statuses":["primary","secondary"]},{"code":"XBC","name":"Bitcoin Plus","statuses":["primary"]},{"code":"BTCD","name":"BitcoinDark","statuses":["primary"]},{"code":"BCY","name":"Bitcrystals","statuses":["primary"]},{"code":"BTM","name":"Bitmark","statuses":["primary"]},{"code":"BTQ","name":"BitQuark","statuses":["primary"]},{"code":"BITS","name":"BITS","statuses":["primary"]},{"code":"BSD","name":"BitSend","statuses":["primary"]},{"code":"BTS","name":"BitShares","statuses":["primary"]},{"code":"PTS","name":"BitShares PTS","statuses":["primary"]},{"code":"SWIFT","name":"BitSwift","statuses":["primary"]},{"code":"BITZ","name":"Bitz","statuses":["primary"]},{"code":"BLK","name":"Blackcoin","statuses":["primary"]},{"code":"JACK","name":"BlackJack","statuses":["primary"]},{"code":"BLC","name":"Blakecoin","statuses":["primary"]},{"code":"BLEU","name":"BLEU","statuses":["primary"]},{"code":"BLITZ","name":"Blitzcoin","statuses":["primary"]},{"code":"BLOCK","name":"Blocknet","statuses":["primary"]},{"code":"BLRY","name":"BLRY","statuses":["primary"]},{"code":"BLU","name":"BLU","statuses":["primary"]},{"code":"BM","name":"BM","statuses":["primary"]},{"code":"BNT","name":"BNT","statuses":["primary"]},{"code":"BOB","name":"BOB","statuses":["primary"]},{"code":"BON","name":"BON","statuses":["primary"]},{"code":"BBR","name":"Boolberry","statuses":["primary"]},{"code":"BOST","name":"BoostCoin","statuses":["primary"]},{"code":"BOSS","name":"BOSS","statuses":["primary"]},{"code":"BPOK","name":"BPOK","statuses":["primary"]},{"code":"BRAIN","name":"BRAIN","statuses":["primary"]},{"code":"BRC","name":"BRC","statuses":["primary"]},{"code":"BRDD","name":"BRDD","statuses":["primary"]},{"code":"BRIT","name":"BRIT","statuses":["primary"]},{"code":"GBP","name":"British Pound Sterling","statuses":["secondary"]},{"code":"BRK","name":"BRK","statuses":["primary"]},{"code":"BRX","name":"BRX","statuses":["primary"]},{"code":"BSC","name":"BSC","statuses":["primary"]},{"code":"BST","name":"BST","statuses":["primary"]},{"code":"BTCHC","name":"BTCHC","statuses":["primary"]},{"code":"BTCR","name":"BTCR","statuses":["primary"]},{"code":"BTCS","name":"BTCS","statuses":["primary"]},{"code":"BTCU","name":"BTCU","statuses":["primary"]},{"code":"BTTF","name":"BTTF","statuses":["primary"]},{"code":"BTX","name":"BTX","statuses":["primary"]},{"code":"BUCKS","name":"BUCKS","statuses":["primary"]},{"code":"BUN","name":"BUN","statuses":["primary"]},{"code":"BURST","name":"Burst","statuses":["primary"]},{"code":"BUZZ","name":"BUZZ","statuses":["primary"]},{"code":"BVC","name":"BVC","statuses":["primary"]},{"code":"BYC","name":"Bytecent","statuses":["primary"]},{"code":"BCN","name":"Bytecoin","statuses":["primary"]},{"code":"XCT","name":"C-Bit","statuses":["primary"]},{"code":"C0C0","name":"C0C0","statuses":["primary"]},{"code":"CAB","name":"Cabbage Unit","statuses":["primary"]},{"code":"CAD","name":"CAD","statuses":["primary","secondary"]},{"code":"CAGE","name":"CAGE","statuses":["primary"]},{"code":"CANN","name":"CannabisCoin","statuses":["primary"]},{"code":"CCN","name":"Cannacoin","statuses":["primary"]},{"code":"CPC","name":"Capricoin","statuses":["primary"]},{"code":"DIEM","name":"CarpeDiemCoin","statuses":["primary"]},{"code":"CASH","name":"CASH","statuses":["primary"]},{"code":"CBIT","name":"CBIT","statuses":["primary"]},{"code":"CC","name":"CC","statuses":["primary"]},{"code":"CCB","name":"CCB","statuses":["primary"]},{"code":"CD","name":"CD","statuses":["primary"]},{"code":"CDN","name":"CDN","statuses":["primary"]},{"code":"CF","name":"CF","statuses":["primary"]},{"code":"CFC","name":"CFC","statuses":["primary"]},{"code":"CGA","name":"CGA","statuses":["primary"]},{"code":"CHC","name":"CHC","statuses":["primary"]},{"code":"CKC","name":"Checkcoin","statuses":["primary"]},{"code":"CHEMX","name":"CHEMX","statuses":["primary"]},{"code":"CHESS","name":"CHESS","statuses":["primary"]},{"code":"CHF","name":"CHF","statuses":["primary","secondary"]},{"code":"CNY","name":"Chinese Yuan","statuses":["secondary"]},{"code":"CHRG","name":"CHRG","statuses":["primary"]},{"code":"CJ","name":"CJ","statuses":["primary"]},{"code":"CLAM","name":"Clams","statuses":["primary"]},{"code":"CLICK","name":"CLICK","statuses":["primary"]},{"code":"CLINT","name":"CLINT","statuses":["primary"]},{"code":"CLOAK","name":"Cloakcoin","statuses":["primary"]},{"code":"CLR","name":"CLR","statuses":["primary"]},{"code":"CLUB","name":"CLUB","statuses":["primary"]},{"code":"CLUD","name":"CLUD","statuses":["primary"]},{"code":"CMT","name":"CMT","statuses":["primary"]},{"code":"CNC","name":"CNC","statuses":["primary"]},{"code":"COXST","name":"CoExistCoin","statuses":["primary"]},{"code":"COIN","name":"COIN","statuses":["primary"]},{"code":"C2","name":"Coin2.1","statuses":["primary"]},{"code":"CNMT","name":"Coinomat","statuses":["primary"]},{"code":"CV2","name":"Colossuscoin2.0","statuses":["primary"]},{"code":"CON","name":"CON","statuses":["primary"]},{"code":"XCP","name":"Counterparty","statuses":["primary"]},{"code":"COV","name":"COV","statuses":["primary"]},{"code":"CRAFT","name":"CRAFT","statuses":["primary"]},{"code":"CRAVE","name":"CRAVE","statuses":["primary"]},{"code":"CRC","name":"CRC","statuses":["primary"]},{"code":"CRE","name":"CRE","statuses":["primary"]},{"code":"CRBIT","name":"Creditbit","statuses":["primary"]},{"code":"CREVA","name":"CrevaCoin","statuses":["primary"]},{"code":"CRIME","name":"CRIME","statuses":["primary"]},{"code":"CRT","name":"CRT","statuses":["primary"]},{"code":"CRW","name":"CRW","statuses":["primary"]},{"code":"CRY","name":"CRY","statuses":["primary"]},{"code":"XCR","name":"Crypti","statuses":["primary"]},{"code":"CBX","name":"Crypto Bullion","statuses":["primary"]},{"code":"CESC","name":"CryptoEscudo","statuses":["primary"]},{"code":"XCN","name":"Cryptonite","statuses":["primary"]},{"code":"CSMIC","name":"CSMIC","statuses":["primary"]},{"code":"CST","name":"CST","statuses":["primary"]},{"code":"CTC","name":"CTC","statuses":["primary"]},{"code":"CTO","name":"CTO","statuses":["primary"]},{"code":"CURE","name":"Curecoin","statuses":["primary"]},{"code":"CYP","name":"Cypher","statuses":["primary"]},{"code":"CZC","name":"CZC","statuses":["primary"]},{"code":"CZECO","name":"CZECO","statuses":["primary"]},{"code":"CZR","name":"CZR","statuses":["primary"]},{"code":"DAO","name":"DAO","statuses":["primary"]},{"code":"DGD","name":"DarkGoldCoin","statuses":["primary"]},{"code":"DNET","name":"Darknet","statuses":["primary"]},{"code":"DASH","name":"Dash","statuses":["primary"]},{"code":"DTC","name":"Datacoin","statuses":["primary"]},{"code":"DBG","name":"DBG","statuses":["primary"]},{"code":"DBLK","name":"DBLK","statuses":["primary"]},{"code":"DBTC","name":"DBTC","statuses":["primary"]},{"code":"DCK","name":"DCK","statuses":["primary"]},{"code":"DCR","name":"Decred","statuses":["primary"]},{"code":"DES","name":"Destiny","statuses":["primary"]},{"code":"DETH","name":"DETH","statuses":["primary"]},{"code":"DEUR","name":"DEUR","statuses":["primary"]},{"code":"DEM","name":"Deutsche eMark","statuses":["primary"]},{"code":"DVC","name":"Devcoin","statuses":["primary"]},{"code":"DGCS","name":"DGCS","statuses":["primary"]},{"code":"DGMS","name":"DGMS","statuses":["primary"]},{"code":"DGORE","name":"DGORE","statuses":["primary"]},{"code":"DMD","name":"Diamond","statuses":["primary"]},{"code":"DGB","name":"Digibyte","statuses":["primary"]},{"code":"CUBE","name":"DigiCube","statuses":["primary"]},{"code":"DGC","name":"Digitalcoin","statuses":["primary"]},{"code":"XDN","name":"DigitalNote","statuses":["primary"]},{"code":"DP","name":"DigitalPrice","statuses":["primary"]},{"code":"DIGS","name":"DIGS","statuses":["primary"]},{"code":"DIME","name":"Dimecoin","statuses":["primary"]},{"code":"DISK","name":"DISK","statuses":["primary"]},{"code":"DLISK","name":"DLISK","statuses":["primary"]},{"code":"NOTE","name":"DNotes","statuses":["primary"]},{"code":"DOGE","name":"Dogecoin","statuses":["primary","secondary"]},{"code":"DON","name":"DON","statuses":["primary"]},{"code":"DOPE","name":"DopeCoin","statuses":["primary"]},{"code":"DOX","name":"DOX","statuses":["primary"]},{"code":"DRACO","name":"DRACO","statuses":["primary"]},{"code":"DRM","name":"DRM","statuses":["primary"]},{"code":"DROP","name":"DROP","statuses":["primary"]},{"code":"DRZ","name":"DRZ","statuses":["primary"]},{"code":"DSH","name":"DSH","statuses":["primary"]},{"code":"DBIC","name":"DubaiCoin","statuses":["primary"]},{"code":"DUO","name":"DUO","statuses":["primary"]},{"code":"DUST","name":"DUST","statuses":["primary"]},{"code":"EAC","name":"Earthcoin","statuses":["primary"]},{"code":"ECCHI","name":"ECCHI","statuses":["primary"]},{"code":"ECC","name":"ECCoin","statuses":["primary"]},{"code":"ECOS","name":"ECOS","statuses":["primary"]},{"code":"EDC","name":"EDC","statuses":["primary"]},{"code":"EDRC","name":"EDRC","statuses":["primary"]},{"code":"EGG","name":"EGG","statuses":["primary"]},{"code":"EMC2","name":"Einsteinium","statuses":["primary"]},{"code":"EKO","name":"EKO","statuses":["primary"]},{"code":"EL","name":"EL","statuses":["primary"]},{"code":"ELCO","name":"ELcoin","statuses":["primary"]},{"code":"ELE","name":"ELE","statuses":["primary"]},{"code":"EFL","name":"Electronic Gulden","statuses":["primary"]},{"code":"EMC","name":"Emercoin","statuses":["primary"]},{"code":"EMIRG","name":"EMIRG","statuses":["primary"]},{"code":"ENE","name":"ENE","statuses":["primary"]},{"code":"ENRG","name":"Energycoin","statuses":["primary"]},{"code":"EPC","name":"EPC","statuses":["primary"]},{"code":"EPY","name":"EPY","statuses":["primary"]},{"code":"ERC","name":"ERC","statuses":["primary"]},{"code":"ERC3","name":"ERC3","statuses":["primary"]},{"code":"ESC","name":"ESC","statuses":["primary"]},{"code":"ETC","name":"Ethereum Classic","statuses":["primary"]},{"code":"ETHS","name":"ETHS","statuses":["primary"]},{"code":"EURC","name":"EURC","statuses":["primary"]},{"code":"EUR","name":"Euro","statuses":["primary","secondary"]},{"code":"EGC","name":"EvergreenCoin","statuses":["primary"]},{"code":"EVIL","name":"EVIL","statuses":["primary"]},{"code":"EVO","name":"EVO","statuses":["primary"]},{"code":"EXCL","name":"EXCL","statuses":["primary"]},{"code":"EXIT","name":"EXIT","statuses":["primary"]},{"code":"EXP","name":"Expanse","statuses":["primary"]},{"code":"FCT","name":"Factom","statuses":["primary"]},{"code":"FAIR","name":"Faircoin","statuses":["primary"]},{"code":"FC2","name":"FC2","statuses":["primary"]},{"code":"FCN","name":"FCN","statuses":["primary"]},{"code":"FTC","name":"Feathercoin","statuses":["primary"]},{"code":"TIPS","name":"Fedoracoin","statuses":["primary"]},{"code":"FFC","name":"FFC","statuses":["primary"]},{"code":"FIBRE","name":"Fibre","statuses":["primary"]},{"code":"FIT","name":"FIT","statuses":["primary"]},{"code":"FJC","name":"FJC","statuses":["primary"]},{"code":"FLO","name":"Florincoin","statuses":["primary"]},{"code":"FLOZ","name":"FLOZ","statuses":["primary"]},{"code":"FLT","name":"FlutterCoin","statuses":["primary"]},{"code":"FLX","name":"FLX","statuses":["primary"]},{"code":"FLY","name":"Flycoin","statuses":["primary"]},{"code":"FLDC","name":"FoldingCoin","statuses":["primary"]},{"code":"FONZ","name":"FONZ","statuses":["primary"]},{"code":"FRK","name":"Franko","statuses":["primary"]},{"code":"FRC","name":"Freicoin","statuses":["primary"]},{"code":"FRN","name":"FRN","statuses":["primary"]},{"code":"FRWC","name":"FRWC","statuses":["primary"]},{"code":"FSC2","name":"FSC2","statuses":["primary"]},{"code":"FST","name":"FST","statuses":["primary"]},{"code":"FTP","name":"FTP","statuses":["primary"]},{"code":"FUN","name":"FUN","statuses":["primary"]},{"code":"FUTC","name":"FUTC","statuses":["primary"]},{"code":"FUZZ","name":"FUZZ","statuses":["primary"]},{"code":"GAIA","name":"GAIA","statuses":["primary"]},{"code":"GAIN","name":"GAIN","statuses":["primary"]},{"code":"GAKH","name":"GAKH","statuses":["primary"]},{"code":"GAM","name":"GAM","statuses":["primary"]},{"code":"GBT","name":"GameBet Coin","statuses":["primary"]},{"code":"GAME","name":"GameCredits","statuses":["primary"]},{"code":"GAP","name":"Gapcoin","statuses":["primary"]},{"code":"GARY","name":"GARY","statuses":["primary"]},{"code":"GB","name":"GB","statuses":["primary"]},{"code":"GBC","name":"GBC","statuses":["primary"]},{"code":"GBIT","name":"GBIT","statuses":["primary"]},{"code":"GCC","name":"GCC","statuses":["primary"]},{"code":"GCN","name":"GCN","statuses":["primary"]},{"code":"GEO","name":"GeoCoin","statuses":["primary"]},{"code":"GEMZ","name":"GetGems","statuses":["primary"]},{"code":"GHOST","name":"GHOST","statuses":["primary"]},{"code":"GHS","name":"GHS","statuses":["primary"]},{"code":"GIFT","name":"GIFT","statuses":["primary"]},{"code":"GIG","name":"GIG","statuses":["primary"]},{"code":"GLC","name":"GLC","statuses":["primary"]},{"code":"BSTY","name":"GlobalBoost-Y","statuses":["primary"]},{"code":"GML","name":"GML","statuses":["primary"]},{"code":"GMX","name":"GMX","statuses":["primary"]},{"code":"GCR","name":"GoCoineR","statuses":["primary"]},{"code":"GLD","name":"GoldCoin","statuses":["primary"]},{"code":"GOON","name":"GOON","statuses":["primary"]},{"code":"GP","name":"GP","statuses":["primary"]},{"code":"GPU","name":"GPU","statuses":["primary"]},{"code":"GRAM","name":"GRAM","statuses":["primary"]},{"code":"GRT","name":"Grantcoin","statuses":["primary"]},{"code":"GRE","name":"GRE","statuses":["primary"]},{"code":"GRC","name":"Gridcoin","statuses":["primary"]},{"code":"GRN","name":"GRN","statuses":["primary"]},{"code":"GRS","name":"Groestlcoin","statuses":["primary"]},{"code":"GRW","name":"GRW","statuses":["primary"]},{"code":"GSM","name":"GSM","statuses":["primary"]},{"code":"GSX","name":"GSX","statuses":["primary"]},{"code":"GUA","name":"GUA","statuses":["primary"]},{"code":"NLG","name":"Gulden","statuses":["primary"]},{"code":"GUN","name":"GUN","statuses":["primary"]},{"code":"HAM","name":"HAM","statuses":["primary"]},{"code":"HAWK","name":"HAWK","statuses":["primary"]},{"code":"HCC","name":"HCC","statuses":["primary"]},{"code":"HEAT","name":"HEAT","statuses":["primary"]},{"code":"HMP","name":"HempCoin","statuses":["primary"]},{"code":"XHI","name":"HiCoin","statuses":["primary"]},{"code":"HIFUN","name":"HIFUN","statuses":["primary"]},{"code":"HILL","name":"HILL","statuses":["primary"]},{"code":"HIRE","name":"HIRE","statuses":["primary"]},{"code":"HNC","name":"HNC","statuses":["primary"]},{"code":"HODL","name":"HOdlcoin","statuses":["primary"]},{"code":"HKD","name":"Hong Kong Dollar","statuses":["secondary"]},{"code":"HZ","name":"Horizon","statuses":["primary"]},{"code":"HTC","name":"HTC","statuses":["primary"]},{"code":"HTML5","name":"HTMLCOIN","statuses":["primary"]},{"code":"HUC","name":"HUC","statuses":["primary"]},{"code":"HVCO","name":"HVCO","statuses":["primary"]},{"code":"HYPER","name":"Hyper","statuses":["primary"]},{"code":"HYP","name":"HyperStake","statuses":["primary"]},{"code":"I0C","name":"I0C","statuses":["primary"]},{"code":"IBANK","name":"IBANK","statuses":["primary"]},{"code":"ICASH","name":"iCash","statuses":["primary"]},{"code":"ICN","name":"ICN","statuses":["primary"]},{"code":"IEC","name":"IEC","statuses":["primary"]},{"code":"IFC","name":"Infinitecoin","statuses":["primary"]},{"code":"INFX","name":"Influxcoin","statuses":["primary"]},{"code":"INV","name":"INV","statuses":["primary"]},{"code":"IOC","name":"IO Coin","statuses":["primary"]},{"code":"ION","name":"ION","statuses":["primary"]},{"code":"IRL","name":"IRL","statuses":["primary"]},{"code":"ISL","name":"IslaCoin","statuses":["primary"]},{"code":"IVZ","name":"IVZ","statuses":["primary"]},{"code":"IXC","name":"IXC","statuses":["primary"]},{"code":"JIF","name":"JIF","statuses":["primary"]},{"code":"JPC","name":"JPC","statuses":["primary"]},{"code":"JPY","name":"JPY","statuses":["primary","secondary"]},{"code":"JBS","name":"Jumbucks","statuses":["primary"]},{"code":"KAT","name":"KAT","statuses":["primary"]},{"code":"KGC","name":"KGC","statuses":["primary"]},{"code":"KNC","name":"KhanCoin","statuses":["primary"]},{"code":"KLC","name":"KLC","statuses":["primary"]},{"code":"KOBO","name":"KOBO","statuses":["primary"]},{"code":"KORE","name":"KoreCoin","statuses":["primary"]},{"code":"KRAK","name":"KRAK","statuses":["primary"]},{"code":"KRYP","name":"KRYP","statuses":["primary"]},{"code":"KR","name":"Krypton","statuses":["primary"]},{"code":"KTK","name":"KTK","statuses":["primary"]},{"code":"KUBO","name":"KUBO","statuses":["primary"]},{"code":"LANA","name":"LANA","statuses":["primary"]},{"code":"LBC","name":"LBC","statuses":["primary"]},{"code":"LC","name":"LC","statuses":["primary"]},{"code":"LEA","name":"LeaCoin","statuses":["primary"]},{"code":"LEMON","name":"LEMON","statuses":["primary"]},{"code":"LEO","name":"LEO","statuses":["primary"]},{"code":"LFC","name":"LFC","statuses":["primary"]},{"code":"LFO","name":"LFO","statuses":["primary"]},{"code":"LFTC","name":"LFTC","statuses":["primary"]},{"code":"LQD","name":"LIQUID","statuses":["primary"]},{"code":"LIR","name":"LIR","statuses":["primary"]},{"code":"LSK","name":"Lisk","statuses":["primary"]},{"code":"LTC","name":"Litecoin","statuses":["primary","secondary"]},{"code":"LTCR","name":"Litecred","statuses":["primary"]},{"code":"LDOGE","name":"LiteDoge","statuses":["primary"]},{"code":"LKC","name":"LKC","statuses":["primary"]},{"code":"LOC","name":"LOC","statuses":["primary"]},{"code":"LOOT","name":"LOOT","statuses":["primary"]},{"code":"LTBC","name":"LTBcoin","statuses":["primary"]},{"code":"LTH","name":"LTH","statuses":["primary"]},{"code":"LTS","name":"LTS","statuses":["primary"]},{"code":"LUN","name":"LUN","statuses":["primary"]},{"code":"LXC","name":"LXC","statuses":["primary"]},{"code":"LYB","name":"LYB","statuses":["primary"]},{"code":"M1","name":"M1","statuses":["primary"]},{"code":"MAD","name":"MAD","statuses":["primary"]},{"code":"XMG","name":"Magi","statuses":["primary"]},{"code":"MAID","name":"MaidSafeCoin","statuses":["primary"]},{"code":"MXT","name":"MarteXcoin","statuses":["primary"]},{"code":"MARV","name":"MARV","statuses":["primary"]},{"code":"MARYJ","name":"MARYJ","statuses":["primary"]},{"code":"OMNI","name":"Mastercoin (Omni)","statuses":["primary"]},{"code":"MTR","name":"MasterTraderCoin","statuses":["primary"]},{"code":"MAX","name":"Maxcoin","statuses":["primary"]},{"code":"MZC","name":"Mazacoin","statuses":["primary"]},{"code":"MBL","name":"MBL","statuses":["primary"]},{"code":"MCAR","name":"MCAR","statuses":["primary"]},{"code":"MCN","name":"MCN","statuses":["primary"]},{"code":"MCZ","name":"MCZ","statuses":["primary"]},{"code":"MED","name":"MediterraneanCoin","statuses":["primary"]},{"code":"MEC","name":"Megacoin","statuses":["primary"]},{"code":"MEME","name":"Memetic","statuses":["primary"]},{"code":"METAL","name":"METAL","statuses":["primary"]},{"code":"MND","name":"MindCoin","statuses":["primary"]},{"code":"MINT","name":"Mintcoin","statuses":["primary"]},{"code":"MIS","name":"MIS","statuses":["primary"]},{"code":"MM","name":"MM","statuses":["primary"]},{"code":"MMC","name":"MMC","statuses":["primary"]},{"code":"MMNXT","name":"MMNXT","statuses":["primary"]},{"code":"MMXVI","name":"MMXVI","statuses":["primary"]},{"code":"MNM","name":"MNM","statuses":["primary"]},{"code":"MOIN","name":"MOIN","statuses":["primary"]},{"code":"MOJO","name":"MojoCoin","statuses":["primary"]},{"code":"MONA","name":"MonaCoin","statuses":["primary"]},{"code":"XMR","name":"Monero","statuses":["primary","secondary"]},{"code":"MNTA","name":"Moneta","statuses":["primary"]},{"code":"MUE","name":"MonetaryUnit","statuses":["primary"]},{"code":"MOON","name":"Mooncoin","statuses":["primary"]},{"code":"MOOND","name":"MOOND","statuses":["primary"]},{"code":"MOTO","name":"MOTO","statuses":["primary"]},{"code":"MPRO","name":"MPRO","statuses":["primary"]},{"code":"MRB","name":"MRB","statuses":["primary"]},{"code":"MRP","name":"MRP","statuses":["primary"]},{"code":"MSC","name":"MSC","statuses":["primary"]},{"code":"MYR","name":"Myriadcoin","statuses":["primary"]},{"code":"NMC","name":"Namecoin","statuses":["primary"]},{"code":"NAUT","name":"Nautiluscoin","statuses":["primary"]},{"code":"NAV","name":"NAV Coin","statuses":["primary"]},{"code":"NCS","name":"NCS","statuses":["primary"]},{"code":"XEM","name":"NEM","statuses":["primary"]},{"code":"NEOS","name":"NeosCoin","statuses":["primary"]},{"code":"NETC","name":"NETC","statuses":["primary"]},{"code":"NET","name":"NetCoin","statuses":["primary"]},{"code":"NEU","name":"NeuCoin","statuses":["primary"]},{"code":"NTRN","name":"Neutron","statuses":["primary"]},{"code":"NEVA","name":"NevaCoin","statuses":["primary"]},{"code":"NEWB","name":"NEWB","statuses":["primary"]},{"code":"NIRO","name":"Nexus","statuses":["primary"]},{"code":"NIC","name":"NIC","statuses":["primary"]},{"code":"NKA","name":"NKA","statuses":["primary"]},{"code":"NKC","name":"NKC","statuses":["primary"]},{"code":"NOBL","name":"NobleCoin","statuses":["primary"]},{"code":"NODE","name":"NODE","statuses":["primary"]},{"code":"NODES","name":"NODES","statuses":["primary"]},{"code":"NOO","name":"NOO","statuses":["primary"]},{"code":"NVC","name":"Novacoin","statuses":["primary"]},{"code":"NRC","name":"NRC","statuses":["primary"]},{"code":"NRS","name":"NRS","statuses":["primary"]},{"code":"NUBIS","name":"NUBIS","statuses":["primary"]},{"code":"NBT","name":"NuBits","statuses":["primary"]},{"code":"NUM","name":"NUM","statuses":["primary"]},{"code":"NSR","name":"NuShares","statuses":["primary"]},{"code":"NXE","name":"NXE","statuses":["primary"]},{"code":"NXT","name":"NXT","statuses":["primary"]},{"code":"NXTTY","name":"Nxttycoin","statuses":["primary"]},{"code":"NYC","name":"NYC","statuses":["primary"]},{"code":"NZC","name":"NZC","statuses":["primary"]},{"code":"NZD","name":"NZD","statuses":["primary","secondary"]},{"code":"OC","name":"OC","statuses":["primary"]},{"code":"OCOW","name":"OCOW","statuses":["primary"]},{"code":"OK","name":"OKCash","statuses":["primary"]},{"code":"OMA","name":"OMA","statuses":["primary"]},{"code":"ONE","name":"ONE","statuses":["primary"]},{"code":"ONEC","name":"ONEC","statuses":["primary"]},{"code":"OP","name":"OP","statuses":["primary"]},{"code":"OPAL","name":"OPAL","statuses":["primary"]},{"code":"OPES","name":"OPES","statuses":["primary"]},{"code":"ORB","name":"Orbitcoin","statuses":["primary"]},{"code":"ORLY","name":"Orlycoin","statuses":["primary"]},{"code":"OS76","name":"OS76","statuses":["primary"]},{"code":"OZC","name":"OZC","statuses":["primary"]},{"code":"PAC","name":"PAC","statuses":["primary"]},{"code":"PAK","name":"PAK","statuses":["primary"]},{"code":"PND","name":"Pandacoin","statuses":["primary"]},{"code":"PAPAF","name":"PAPAF","statuses":["primary"]},{"code":"XPY","name":"Paycoin","statuses":["primary"]},{"code":"PBC","name":"PBC","statuses":["primary"]},{"code":"PDC","name":"PDC","statuses":["primary"]},{"code":"XPB","name":"Pebblecoin","statuses":["primary"]},{"code":"PPC","name":"Peercoin","statuses":["primary"]},{"code":"PEN","name":"PEN","statuses":["primary"]},{"code":"PHR","name":"PHR","statuses":["primary"]},{"code":"PIGGY","name":"Piggycoin","statuses":["primary"]},{"code":"PC","name":"Pinkcoin","statuses":["primary"]},{"code":"PKB","name":"PKB","statuses":["primary"]},{"code":"PLN","name":"PLN","statuses":["primary","secondary"]},{"code":"PLNC","name":"PLNC","statuses":["primary"]},{"code":"PNC","name":"PNC","statuses":["primary"]},{"code":"PNK","name":"PNK","statuses":["primary"]},{"code":"POKE","name":"POKE","statuses":["primary"]},{"code":"PONZ2","name":"PONZ2","statuses":["primary"]},{"code":"PONZI","name":"PONZI","statuses":["primary"]},{"code":"PEX","name":"PosEx","statuses":["primary"]},{"code":"POST","name":"POST","statuses":["primary"]},{"code":"POT","name":"Potcoin","statuses":["primary"]},{"code":"PRES","name":"PRES","statuses":["primary"]},{"code":"PXI","name":"Prime-XI","statuses":["primary"]},{"code":"PRIME","name":"PrimeChain","statuses":["primary"]},{"code":"XPM","name":"Primecoin","statuses":["primary"]},{"code":"PRM","name":"PRM","statuses":["primary"]},{"code":"PRT","name":"PRT","statuses":["primary"]},{"code":"PSP","name":"PSP","statuses":["primary"]},{"code":"PTC","name":"PTC","statuses":["primary"]},{"code":"PULSE","name":"PULSE","statuses":["primary"]},{"code":"PURE","name":"PURE","statuses":["primary"]},{"code":"PUTIN","name":"PUTIN","statuses":["primary"]},{"code":"PWR","name":"PWR","statuses":["primary"]},{"code":"PXL","name":"PXL","statuses":["primary"]},{"code":"QBC","name":"QBC","statuses":["primary"]},{"code":"QBK","name":"QBK","statuses":["primary"]},{"code":"QCN","name":"QCN","statuses":["primary"]},{"code":"QORA","name":"Qora","statuses":["primary"]},{"code":"QTZ","name":"QTZ","statuses":["primary"]},{"code":"QRK","name":"Quark","statuses":["primary"]},{"code":"QTL","name":"Quatloo","statuses":["primary"]},{"code":"RADI","name":"RADI","statuses":["primary"]},{"code":"RADS","name":"Radium","statuses":["primary"]},{"code":"RED","name":"RED","statuses":["primary"]},{"code":"RDD","name":"Reddcoin","statuses":["primary"]},{"code":"REE","name":"REE","statuses":["primary"]},{"code":"REV","name":"Revenu","statuses":["primary"]},{"code":"RBR","name":"RibbitRewards","statuses":["primary"]},{"code":"RICHX","name":"RICHX","statuses":["primary"]},{"code":"RIC","name":"Riecoin","statuses":["primary"]},{"code":"RBT","name":"Rimbit","statuses":["primary"]},{"code":"RIO","name":"RIO","statuses":["primary"]},{"code":"XRP","name":"Ripple","statuses":["primary"]},{"code":"RISE","name":"RISE","statuses":["primary"]},{"code":"RMS","name":"RMS","statuses":["primary"]},{"code":"RONIN","name":"RONIN","statuses":["primary"]},{"code":"ROOT","name":"ROOT","statuses":["primary"]},{"code":"ROS","name":"RosCoin","statuses":["primary"]},{"code":"RPC","name":"RPC","statuses":["primary"]},{"code":"RBIES","name":"Rubies","statuses":["primary"]},{"code":"RUBIT","name":"RUBIT","statuses":["primary"]},{"code":"RUR","name":"Ruble","statuses":["secondary"]},{"code":"RBY","name":"Rubycoin","statuses":["primary"]},{"code":"RUST","name":"RUST","statuses":["primary"]},{"code":"SEC","name":"Safe Exchange Coin","statuses":["primary"]},{"code":"SAK","name":"SAK","statuses":["primary"]},{"code":"SAR","name":"SAR","statuses":["primary"]},{"code":"SBD","name":"SBD","statuses":["primary"]},{"code":"SBIT","name":"SBIT","statuses":["primary"]},{"code":"SCAN","name":"SCAN","statuses":["primary"]},{"code":"SCOT","name":"Scotcoin","statuses":["primary"]},{"code":"SCRPT","name":"SCRPT","statuses":["primary"]},{"code":"SCRT","name":"SCRT","statuses":["primary"]},{"code":"SRC","name":"SecureCoin","statuses":["primary"]},{"code":"SXC","name":"Sexcoin","statuses":["primary"]},{"code":"SFE","name":"SFE","statuses":["primary"]},{"code":"SFR","name":"SFR","statuses":["primary"]},{"code":"SGD","name":"SGD","statuses":["primary","secondary"]},{"code":"SDC","name":"ShadowCash","statuses":["primary"]},{"code":"SHELL","name":"SHELL","statuses":["primary"]},{"code":"SHF","name":"SHF","statuses":["primary"]},{"code":"SHI","name":"SHI","statuses":["primary"]},{"code":"SHIFT","name":"Shift","statuses":["primary"]},{"code":"SHREK","name":"SHREK","statuses":["primary"]},{"code":"SC","name":"Siacoin","statuses":["primary"]},{"code":"SIB","name":"Siberian chervonets","statuses":["primary"]},{"code":"SIC","name":"SIC","statuses":["primary"]},{"code":"SIGU","name":"SIGU","statuses":["primary"]},{"code":"SILK","name":"Silkcoin","statuses":["primary"]},{"code":"SIX","name":"SIX","statuses":["primary"]},{"code":"SLING","name":"Sling","statuses":["primary"]},{"code":"SLS","name":"SLS","statuses":["primary"]},{"code":"SMBR","name":"SMBR","statuses":["primary"]},{"code":"SMC","name":"SMC","statuses":["primary"]},{"code":"SMLY","name":"SmileyCoin","statuses":["primary"]},{"code":"SNRG","name":"SNRG","statuses":["primary"]},{"code":"SOIL","name":"SOILcoin","statuses":["primary"]},{"code":"SLR","name":"Solarcoin","statuses":["primary"]},{"code":"SOLO","name":"SOLO","statuses":["primary"]},{"code":"SONG","name":"SongCoin","statuses":["primary"]},{"code":"SOON","name":"SOON","statuses":["primary"]},{"code":"SPC","name":"SPC","statuses":["primary"]},{"code":"SPEX","name":"SPEX","statuses":["primary"]},{"code":"SPHR","name":"Sphere","statuses":["primary"]},{"code":"SPM","name":"SPM","statuses":["primary"]},{"code":"SPN","name":"SPN","statuses":["primary"]},{"code":"SPOTS","name":"SPOTS","statuses":["primary"]},{"code":"SPR","name":"SpreadCoin","statuses":["primary"]},{"code":"SPRTS","name":"Sprouts","statuses":["primary"]},{"code":"SQC","name":"SQC","statuses":["primary"]},{"code":"SSC","name":"SSC","statuses":["primary"]},{"code":"SSTC","name":"SSTC","statuses":["primary"]},{"code":"STA","name":"STA","statuses":["primary"]},{"code":"START","name":"Startcoin","statuses":["primary"]},{"code":"XST","name":"Stealthcoin","statuses":["primary"]},{"code":"STEEM","name":"Steem","statuses":["primary"]},{"code":"XLM","name":"Stellar","statuses":["primary"]},{"code":"STR","name":"Stellar","statuses":["primary"]},{"code":"STEPS","name":"Steps","statuses":["primary"]},{"code":"SLG","name":"Sterlingcoin","statuses":["primary"]},{"code":"STL","name":"STL","statuses":["primary"]},{"code":"SJCX","name":"Storjcoin X","statuses":["primary"]},{"code":"STP","name":"STP","statuses":["primary"]},{"code":"STRB","name":"STRB","statuses":["primary"]},{"code":"STS","name":"Stress","statuses":["primary"]},{"code":"STRP","name":"STRP","statuses":["primary"]},{"code":"STV","name":"STV","statuses":["primary"]},{"code":"SUB","name":"Subcriptio","statuses":["primary"]},{"code":"SUPER","name":"SUPER","statuses":["primary"]},{"code":"UNITY","name":"SuperNET","statuses":["primary"]},{"code":"SWARM","name":"Swarm","statuses":["primary"]},{"code":"SWING","name":"SWING","statuses":["primary"]},{"code":"SDP","name":"SydPak Coin","statuses":["primary"]},{"code":"SYNC","name":"SYNC","statuses":["primary"]},{"code":"AMP","name":"Synereo","statuses":["primary"]},{"code":"SYS","name":"Syscoin","statuses":["primary"]},{"code":"TAG","name":"TagCoin","statuses":["primary"]},{"code":"TAJ","name":"TAJ","statuses":["primary"]},{"code":"TAK","name":"TAK","statuses":["primary"]},{"code":"TAM","name":"TAM","statuses":["primary"]},{"code":"TAO","name":"TAO","statuses":["primary"]},{"code":"TBC","name":"TBC","statuses":["primary"]},{"code":"TBCX","name":"TBCX","statuses":["primary"]},{"code":"TCR","name":"TCR","statuses":["primary"]},{"code":"TDFB","name":"TDFB","statuses":["primary"]},{"code":"TDY","name":"TDY","statuses":["primary"]},{"code":"TEK","name":"TEKcoin","statuses":["primary"]},{"code":"TRC","name":"Terracoin","statuses":["primary"]},{"code":"TESLA","name":"TESLA","statuses":["primary"]},{"code":"TES","name":"TeslaCoin","statuses":["primary"]},{"code":"TET","name":"TET","statuses":["primary"]},{"code":"USDT","name":"Tether","statuses":["primary","secondary"]},{"code":"THC","name":"THC","statuses":["primary"]},{"code":"THS","name":"THS","statuses":["primary"]},{"code":"TIX","name":"Tickets","statuses":["primary"]},{"code":"XTC","name":"TileCoin","statuses":["primary"]},{"code":"TIT","name":"Titcoin","statuses":["primary"]},{"code":"TTC","name":"TittieCoin","statuses":["primary"]},{"code":"TMC","name":"TMC","statuses":["primary"]},{"code":"TODAY","name":"TODAY","statuses":["primary"]},{"code":"TOKEN","name":"TOKEN","statuses":["primary"]},{"code":"TP1","name":"TP1","statuses":["primary"]},{"code":"TPC","name":"TPC","statuses":["primary"]},{"code":"TPG","name":"TPG","statuses":["primary"]},{"code":"TX","name":"Transfercoin","statuses":["primary"]},{"code":"TRAP","name":"TRAP","statuses":["primary"]},{"code":"TRICK","name":"TRICK","statuses":["primary"]},{"code":"TROLL","name":"TROLL","statuses":["primary"]},{"code":"TRK","name":"Truckcoin","statuses":["primary"]},{"code":"TRUMP","name":"TrumpCoin","statuses":["primary"]},{"code":"TRUST","name":"TRUST","statuses":["primary"]},{"code":"UAE","name":"UAE","statuses":["primary"]},{"code":"UFO","name":"UFO Coin","statuses":["primary"]},{"code":"UIS","name":"UIS","statuses":["primary"]},{"code":"UTC","name":"UltraCoin","statuses":["primary"]},{"code":"UNC","name":"UNC","statuses":["primary"]},{"code":"UNIQ","name":"UNIQ","statuses":["primary"]},{"code":"UNIT","name":"Universal Currency","statuses":["primary"]},{"code":"UNO","name":"Unobtanium","statuses":["primary"]},{"code":"URO","name":"Uro","statuses":["primary"]},{"code":"USD","name":"US Dollar","statuses":["primary","secondary"]},{"code":"USDE","name":"USDE","statuses":["primary"]},{"code":"UTH","name":"UTH","statuses":["primary"]},{"code":"VAL","name":"VAL","statuses":["primary"]},{"code":"XVC","name":"Vcash","statuses":["primary"]},{"code":"VCN","name":"VCN","statuses":["primary"]},{"code":"VEG","name":"VEG","statuses":["primary"]},{"code":"VENE","name":"VENE","statuses":["primary"]},{"code":"XVG","name":"Verge","statuses":["primary"]},{"code":"VRC","name":"VeriCoin","statuses":["primary"]},{"code":"VTC","name":"Vertcoin","statuses":["primary"]},{"code":"VIA","name":"Viacoin","statuses":["primary"]},{"code":"VIOR","name":"Viorcoin","statuses":["primary"]},{"code":"VIP","name":"VIP Tokens","statuses":["primary"]},{"code":"VIRAL","name":"Viral","statuses":["primary"]},{"code":"VOOT","name":"VootCoin","statuses":["primary"]},{"code":"VOX","name":"Voxels","statuses":["primary"]},{"code":"VOYA","name":"VOYA","statuses":["primary"]},{"code":"VPN","name":"VPNCoin","statuses":["primary"]},{"code":"VPRC","name":"VPRC","statuses":["primary"]},{"code":"VTA","name":"VTA","statuses":["primary"]},{"code":"VTN","name":"VTN","statuses":["primary"]},{"code":"VTR","name":"VTR","statuses":["primary"]},{"code":"WAC","name":"WAC","statuses":["primary"]},{"code":"WARP","name":"WARP","statuses":["primary"]},{"code":"WAVES","name":"WAVES","statuses":["primary"]},{"code":"WGC","name":"WGC","statuses":["primary"]},{"code":"XWC","name":"Whitecoin","statuses":["primary"]},{"code":"WBB","name":"Wild Beast Block","statuses":["primary"]},{"code":"WLC","name":"WLC","statuses":["primary"]},{"code":"WMC","name":"WMC","statuses":["primary"]},{"code":"LOG","name":"Woodcoin","statuses":["primary"]},{"code":"WOP","name":"WOP","statuses":["primary"]},{"code":"WDC","name":"Worldcoin","statuses":["primary"]},{"code":"XAB","name":"XAB","statuses":["primary"]},{"code":"XAI","name":"XAI","statuses":["primary"]},{"code":"XAU","name":"Xaurum","statuses":["primary"]},{"code":"XBS","name":"XBS","statuses":["primary"]},{"code":"XBU","name":"XBU","statuses":["primary"]},{"code":"XCO","name":"XCO","statuses":["primary"]},{"code":"XC","name":"XCurrency","statuses":["primary"]},{"code":"XDB","name":"XDB","statuses":["primary"]},{"code":"XEMP","name":"XEMP","statuses":["primary"]},{"code":"XFC","name":"XFC","statuses":["primary"]},{"code":"MI","name":"Xiaomicoin","statuses":["primary"]},{"code":"XID","name":"XID","statuses":["primary"]},{"code":"XJO","name":"XJO","statuses":["primary"]},{"code":"XLTCG","name":"XLTCG","statuses":["primary"]},{"code":"XMS","name":"XMS","statuses":["primary"]},{"code":"XNX","name":"XNX","statuses":["primary"]},{"code":"XPD","name":"XPD","statuses":["primary"]},{"code":"XPOKE","name":"XPOKE","statuses":["primary"]},{"code":"XPRO","name":"XPRO","statuses":["primary"]},{"code":"XQN","name":"XQN","statuses":["primary"]},{"code":"XSEED","name":"XSEED","statuses":["primary"]},{"code":"XSP","name":"XSP","statuses":["primary"]},{"code":"XT","name":"XT","statuses":["primary"]},{"code":"XTP","name":"XTP","statuses":["primary"]},{"code":"XUSD","name":"XUSD","statuses":["primary"]},{"code":"YACC","name":"YACC","statuses":["primary"]},{"code":"YAC","name":"Yacoin","statuses":["primary"]},{"code":"YAY","name":"YAY","statuses":["primary"]},{"code":"YBC","name":"Ybcoin","statuses":["primary"]},{"code":"YOC","name":"YOC","statuses":["primary"]},{"code":"YOVI","name":"YOVI","statuses":["primary"]},{"code":"YUM","name":"YUM","statuses":["primary"]},{"code":"ZCC","name":"ZCC","statuses":["primary"]},{"code":"ZEIT","name":"Zeitcoin","statuses":["primary"]},{"code":"ZET","name":"Zetacoin","statuses":["primary"]},{"code":"ZRC","name":"ZiftrCOIN","statuses":["primary"]},{"code":"ZMC","name":"ZMC","statuses":["primary"]},{"code":"ZNY","name":"ZNY","statuses":["primary"]},{"code":"ZS","name":"ZS","statuses":["primary"]}]}
-
-module.exports = {
- availableCurrencies
-}
diff --git a/ui/app/conversion.json b/ui/app/conversion.json
new file mode 100644
index 000000000..eeca164ce
--- /dev/null
+++ b/ui/app/conversion.json
@@ -0,0 +1,5730 @@
+{
+ "rows":[
+ {
+ "code":"007",
+ "name":"007",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"1337",
+ "name":"1337",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"1CR",
+ "name":"1CR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"256",
+ "name":"256",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"2FLAV",
+ "name":"2FLAV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"2GIVE",
+ "name":"2GIVE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"32BIT",
+ "name":"32BIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"404",
+ "name":"404",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"611",
+ "name":"611",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"888",
+ "name":"888",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"8BIT",
+ "name":"8Bit",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ACES",
+ "name":"ACES",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ACID",
+ "name":"ACID",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ACLR",
+ "name":"ACLR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ACP",
+ "name":"ACP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ADC",
+ "name":"ADC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ADZ",
+ "name":"Adzcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AEON",
+ "name":"Aeon",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AGRS",
+ "name":"Agoras Tokens",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AIB",
+ "name":"AIB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ALC",
+ "name":"ALC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ALTC",
+ "name":"ALTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AM",
+ "name":"AM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AMBER",
+ "name":"AMBER",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AMS",
+ "name":"AMS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ANAL",
+ "name":"ANAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ANI",
+ "name":"ANI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ANC",
+ "name":"Anoncoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ANS",
+ "name":"ANS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ANTI",
+ "name":"AntiBitcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"APEX",
+ "name":"APEX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"APC",
+ "name":"Applecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"APT",
+ "name":"APT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AR2",
+ "name":"AR2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ARB",
+ "name":"ARB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ARC",
+ "name":"ARC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ARCH",
+ "name":"ARCH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ARD",
+ "name":"ARD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ARDR",
+ "name":"ARDR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ABY",
+ "name":"ArtByte",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ARTC",
+ "name":"ARTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ASAFE",
+ "name":"ASAFE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ADCN",
+ "name":"Asiadigicoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ASN",
+ "name":"ASN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ATEN",
+ "name":"ATEN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ATOM",
+ "name":"ATOM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ATX",
+ "name":"ATX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"REP",
+ "name":"Augur",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AUR",
+ "name":"Auroracoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AUD",
+ "name":"Australian Dollar",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"AV",
+ "name":"AV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"B2",
+ "name":"B2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"B3",
+ "name":"B3",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BA",
+ "name":"BA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BAC",
+ "name":"BAC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BASH",
+ "name":"BASH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTA",
+ "name":"Bata",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BAY",
+ "name":"BAY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BBCC",
+ "name":"BBCC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BQC",
+ "name":"BBQCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BEC",
+ "name":"BEC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BEEP",
+ "name":"BEEP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BELA",
+ "name":"BellaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BERN",
+ "name":"BERNcash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BHC",
+ "name":"BHC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BILL",
+ "name":"BILL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BILS",
+ "name":"BILS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BIOS",
+ "name":"BiosCrypto",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BIT",
+ "name":"BIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BIT16",
+ "name":"BIT16",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BITB",
+ "name":"BitBean",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTC",
+ "name":"Bitcoin",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"XBC",
+ "name":"Bitcoin Plus",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTCD",
+ "name":"BitcoinDark",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BCY",
+ "name":"Bitcrystals",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BFX",
+ "name":"Bitfinex Debt token",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTM",
+ "name":"Bitmark",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BITON",
+ "name":"BITON",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTQ",
+ "name":"BitQuark",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BITS",
+ "name":"BITS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BSD",
+ "name":"BitSend",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTS",
+ "name":"BitShares",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SWIFT",
+ "name":"BitSwift",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BITZ",
+ "name":"Bitz",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLK",
+ "name":"Blackcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLC",
+ "name":"Blakecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLEU",
+ "name":"BLEU",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLITZ",
+ "name":"Blitzcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLOCK",
+ "name":"Blocknet",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLRY",
+ "name":"BLRY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLU",
+ "name":"BLU",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BLUS",
+ "name":"BLUS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BNT",
+ "name":"BNT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BOLI",
+ "name":"Bolivarcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BBR",
+ "name":"Boolberry",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BOOM",
+ "name":"BOOM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BOST",
+ "name":"BoostCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BOSS",
+ "name":"BOSS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BPOK",
+ "name":"BPOK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BRAIN",
+ "name":"BRAIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BRC",
+ "name":"BRC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BRDD",
+ "name":"BRDD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BRIT",
+ "name":"BRIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GBP",
+ "name":"British Pound Sterling",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"BRK",
+ "name":"BRK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BRX",
+ "name":"BRX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BS",
+ "name":"BS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BSC",
+ "name":"BSC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BST",
+ "name":"BST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTCHC",
+ "name":"BTCHC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTCR",
+ "name":"BTCR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTCS",
+ "name":"BTCS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTD",
+ "name":"BTD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTLC",
+ "name":"BTLC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTTF",
+ "name":"BTTF",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BTZ",
+ "name":"BTZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BUCKS",
+ "name":"BUCKS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BUN",
+ "name":"BUN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BURST",
+ "name":"Burst",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BUZZ",
+ "name":"BUZZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BVC",
+ "name":"BVC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BXT",
+ "name":"BXT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BYC",
+ "name":"Bytecent",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BCN",
+ "name":"Bytecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CAB",
+ "name":"Cabbage Unit",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CAGE",
+ "name":"CAGE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CAID",
+ "name":"CAID",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CAD",
+ "name":"Canadian Dollar",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"CANN",
+ "name":"CannabisCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CCN",
+ "name":"Cannacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CPC",
+ "name":"Capricoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CAPT",
+ "name":"CAPT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DIEM",
+ "name":"CarpeDiemCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CASH",
+ "name":"CASH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CBD",
+ "name":"CBD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CBIT",
+ "name":"CBIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CCX",
+ "name":"CCX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CD",
+ "name":"CD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CDN",
+ "name":"CDN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CF",
+ "name":"CF",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CGA",
+ "name":"CGA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CKC",
+ "name":"Checkcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CHEMX",
+ "name":"CHEMX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CHESS",
+ "name":"CHESS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CHF",
+ "name":"CHF",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"CNY",
+ "name":"Chinese Yuan",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"CHOOF",
+ "name":"CHOOF",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CJ",
+ "name":"CJ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLAM",
+ "name":"Clams",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLICK",
+ "name":"CLICK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLINT",
+ "name":"CLINT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLOAK",
+ "name":"Cloakcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLR",
+ "name":"CLR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLUB",
+ "name":"CLUB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLUD",
+ "name":"CLUD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CLV",
+ "name":"CLV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CME",
+ "name":"CME",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CMT",
+ "name":"CMT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CNC",
+ "name":"CNC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"COC",
+ "name":"COC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"COXST",
+ "name":"CoExistCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"COIN",
+ "name":"COIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"C2",
+ "name":"Coin2.1",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CV2",
+ "name":"Colossuscoin2.0",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CON",
+ "name":"CON",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XCP",
+ "name":"Counterparty",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"COVAL",
+ "name":"COVAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"COX",
+ "name":"COX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRAB",
+ "name":"CRAB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRC",
+ "name":"CRC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRE",
+ "name":"CRE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRBIT",
+ "name":"Creditbit",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CREVA",
+ "name":"CrevaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRNK",
+ "name":"CRNK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRPC",
+ "name":"CRPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRPS",
+ "name":"CRPS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRT",
+ "name":"CRT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRW",
+ "name":"CRW",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRX",
+ "name":"CRX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CRY",
+ "name":"CRY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CBX",
+ "name":"Crypto Bullion",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CESC",
+ "name":"CryptoEscudo",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XCN",
+ "name":"Cryptonite",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CSH",
+ "name":"CSH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CST",
+ "name":"CST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CTK",
+ "name":"CTK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CTL",
+ "name":"CTL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CTO",
+ "name":"CTO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CURE",
+ "name":"Curecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CYC",
+ "name":"CYC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CYP",
+ "name":"Cypher",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CZC",
+ "name":"CZC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CZR",
+ "name":"CZR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DGD",
+ "name":"DarkGoldCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DNET",
+ "name":"Darknet",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DAS",
+ "name":"DAS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DASH",
+ "name":"Dash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DTC",
+ "name":"Datacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DB",
+ "name":"DB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DBG",
+ "name":"DBG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DBLK",
+ "name":"DBLK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DBTC",
+ "name":"DBTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DC",
+ "name":"DC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DCK",
+ "name":"DCK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DCRE",
+ "name":"DCRE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DCT",
+ "name":"DCT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DCYP",
+ "name":"DCYP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DCR",
+ "name":"Decred",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DES",
+ "name":"Destiny",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DEUR",
+ "name":"DEUR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DEM",
+ "name":"Deutsche eMark",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DVC",
+ "name":"Devcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DGMS",
+ "name":"DGMS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DGORE",
+ "name":"DGORE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DMD",
+ "name":"Diamond",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DGB",
+ "name":"Digibyte",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"CUBE",
+ "name":"DigiCube",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DGC",
+ "name":"Digitalcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XDN",
+ "name":"DigitalNote",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DP",
+ "name":"DigitalPrice",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DIME",
+ "name":"Dimecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DISK",
+ "name":"DISK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DKC",
+ "name":"DKC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DLC",
+ "name":"DLC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DLISK",
+ "name":"DLISK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DMC",
+ "name":"DMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NOTE",
+ "name":"DNotes",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DOGE",
+ "name":"Dogecoin",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"DOPE",
+ "name":"DopeCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DOV",
+ "name":"DOV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DOX",
+ "name":"DOX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DPAY",
+ "name":"DPAY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DRACO",
+ "name":"DRACO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DRM8",
+ "name":"DRM8",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DROP",
+ "name":"DROP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DRZ",
+ "name":"DRZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DSH",
+ "name":"DSH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DTT",
+ "name":"DTT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DBIC",
+ "name":"DubaiCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DUO",
+ "name":"DUO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DUST",
+ "name":"DUST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EAGS",
+ "name":"EAGS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EAC",
+ "name":"Earthcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EBST",
+ "name":"EBST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EC",
+ "name":"EC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ECC",
+ "name":"ECCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ECLI",
+ "name":"ECLI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EDC",
+ "name":"EDC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EDRC",
+ "name":"EDRC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EDR",
+ "name":"EDRCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EGG",
+ "name":"EGG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EGO",
+ "name":"EGO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EMC2",
+ "name":"Einsteinium",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EL",
+ "name":"EL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ELE",
+ "name":"ELE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EFL",
+ "name":"Electronic Gulden",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EMB",
+ "name":"EMB",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"EME",
+ "name":"EME",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"EMC",
+ "name":"Emercoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EMIRG",
+ "name":"EMIRG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EMP",
+ "name":"EMP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EMPC",
+ "name":"EMPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ENRG",
+ "name":"Energycoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ENT",
+ "name":"ENT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EPC",
+ "name":"EPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EQM",
+ "name":"EQM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EQUAL",
+ "name":"EQUAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ERC",
+ "name":"ERC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ERC3",
+ "name":"ERC3",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ESB",
+ "name":"ESB",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"ESC",
+ "name":"ESC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ESP",
+ "name":"ESP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ETCO",
+ "name":"ETCO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ETH",
+ "name":"Ethereum",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"ETC",
+ "name":"Ethereum Classic",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ETHS",
+ "name":"ETHS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EUC",
+ "name":"EUC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EUR",
+ "name":"Euro",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"EGC",
+ "name":"EvergreenCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EVIL",
+ "name":"EVIL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EXCL",
+ "name":"EXCL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"EXP",
+ "name":"Expanse",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FCT",
+ "name":"Factom",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FAIR",
+ "name":"Faircoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FC2",
+ "name":"FC2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FCH",
+ "name":"FCH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FCN",
+ "name":"FCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FCP",
+ "name":"FCP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FTC",
+ "name":"Feathercoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TIPS",
+ "name":"Fedoracoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FIND",
+ "name":"FIND",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FIT",
+ "name":"FIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FJC",
+ "name":"FJC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FLO",
+ "name":"Florincoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FLOZ",
+ "name":"FLOZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FLT",
+ "name":"FlutterCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FLY",
+ "name":"Flycoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FLDC",
+ "name":"FoldingCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FOREX",
+ "name":"FOREX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FRK",
+ "name":"Franko",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FRDC",
+ "name":"FRDC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FRC",
+ "name":"Freicoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FRN",
+ "name":"FRN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FRWC",
+ "name":"FRWC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FSN",
+ "name":"FSN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FST",
+ "name":"FST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FTP",
+ "name":"FTP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FUEL",
+ "name":"FUEL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FUN",
+ "name":"FUN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FUTC",
+ "name":"FUTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FUZZ",
+ "name":"FUZZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"FX",
+ "name":"FX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GAIA",
+ "name":"GAIA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GAIN",
+ "name":"GAIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GAKH",
+ "name":"GAKH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GAM",
+ "name":"GAM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GBT",
+ "name":"GameBet Coin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GAME",
+ "name":"GameCredits",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GAP",
+ "name":"Gapcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GARY",
+ "name":"GARY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GB",
+ "name":"GB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GBC",
+ "name":"GBC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GBIT",
+ "name":"GBIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GBRC",
+ "name":"GBRC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GCN",
+ "name":"GCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GENE",
+ "name":"GENE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GEO",
+ "name":"GeoCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GEMZ",
+ "name":"GetGems",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GHOST",
+ "name":"GHOST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GHS",
+ "name":"GHS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GLC",
+ "name":"GLC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"BSTY",
+ "name":"GlobalBoost-Y",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GMCX",
+ "name":"GMCX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GML",
+ "name":"GML",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GMX",
+ "name":"GMX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GOAT",
+ "name":"GOAT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GCR",
+ "name":"GoCoineR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GLD",
+ "name":"GoldCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GOON",
+ "name":"GOON",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GOTX",
+ "name":"GOTX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GP",
+ "name":"GP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GPU",
+ "name":"GPU",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRF",
+ "name":"Graffiti",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRAM",
+ "name":"GRAM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRT",
+ "name":"Grantcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GREED",
+ "name":"GREED",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRC",
+ "name":"Gridcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRN",
+ "name":"GRN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRS",
+ "name":"Groestlcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GROW",
+ "name":"GrowCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GRW",
+ "name":"GRW",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GSY",
+ "name":"GSY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GUA",
+ "name":"GUA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NLG",
+ "name":"Gulden",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GUM",
+ "name":"GUM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GUN",
+ "name":"GUN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"GYC",
+ "name":"GYC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HALLO",
+ "name":"HALLO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HAM",
+ "name":"HAM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HBT",
+ "name":"HBT",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"HCC",
+ "name":"HCC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HEAT",
+ "name":"HEAT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HMP",
+ "name":"HempCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XHI",
+ "name":"HiCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HILL",
+ "name":"HILL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HODL",
+ "name":"HOdlcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HKD",
+ "name":"Hong Kong Dollar",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"HZ",
+ "name":"Horizon",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HSP",
+ "name":"HSP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HTC",
+ "name":"HTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HTML5",
+ "name":"HTMLCOIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HUC",
+ "name":"HUC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HVCO",
+ "name":"HVCO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HXX",
+ "name":"HXX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HYPER",
+ "name":"Hyper",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"HYP",
+ "name":"HyperStake",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IBANK",
+ "name":"IBANK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ICASH",
+ "name":"iCash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ICN",
+ "name":"iCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IFLT",
+ "name":"IFLT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IMPS",
+ "name":"IMPS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"INCP",
+ "name":"INCP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IFC",
+ "name":"Infinitecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"INFX",
+ "name":"Influxcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IOC",
+ "name":"IO Coin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ION",
+ "name":"ION",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ISL",
+ "name":"IslaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IVZ",
+ "name":"IVZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"IXC",
+ "name":"IXC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"JPY",
+ "name":"Japanese Yen",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"JOBS",
+ "name":"JOBS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"JPC",
+ "name":"JPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"JBS",
+ "name":"Jumbucks",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"JW",
+ "name":"JW",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"JWL",
+ "name":"JWL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KAT",
+ "name":"KAT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KC",
+ "name":"KC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KNC",
+ "name":"KhanCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KLC",
+ "name":"KLC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KOBO",
+ "name":"KOBO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KORE",
+ "name":"KoreCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KRAK",
+ "name":"KRAK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KRB",
+ "name":"KRB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KRC",
+ "name":"KRC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KRYP",
+ "name":"KRYP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KR",
+ "name":"Krypton",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"KTK",
+ "name":"KTK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LANA",
+ "name":"LANA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LAZ",
+ "name":"LAZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LBC",
+ "name":"LBC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LC",
+ "name":"LC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LEA",
+ "name":"LeaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LEAF",
+ "name":"LEAF",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LEO",
+ "name":"LEO",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"LFC",
+ "name":"LFC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LFO",
+ "name":"LFO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LFTC",
+ "name":"LFTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LGBTQ",
+ "name":"LGBTQ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LIR",
+ "name":"LIR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LSK",
+ "name":"Lisk",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LTC",
+ "name":"Litecoin",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"LTCR",
+ "name":"Litecred",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LIV",
+ "name":"LIV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LKC",
+ "name":"LKC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LOC",
+ "name":"LOC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LOOT",
+ "name":"LOOT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LTBC",
+ "name":"LTBcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LTH",
+ "name":"LTH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LTS",
+ "name":"LTS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LUCKY",
+ "name":"LUCKY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LUN",
+ "name":"LUN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LXC",
+ "name":"LXC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MAD",
+ "name":"MAD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XMG",
+ "name":"Magi",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MAID",
+ "name":"MaidSafeCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MXT",
+ "name":"MarteXcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OMNI",
+ "name":"Mastercoin (Omni)",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MTR",
+ "name":"MasterTraderCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MAX",
+ "name":"Maxcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MZC",
+ "name":"Mazacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MBL",
+ "name":"MBL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MCZ",
+ "name":"MCZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MED",
+ "name":"MediterraneanCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MEGA",
+ "name":"MEGA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MEC",
+ "name":"Megacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MEME",
+ "name":"Memetic",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"METAL",
+ "name":"METAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MG",
+ "name":"MG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MND",
+ "name":"MindCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MINT",
+ "name":"Mintcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MIS",
+ "name":"MIS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MMNXT",
+ "name":"MMNXT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MMXVI",
+ "name":"MMXVI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MNM",
+ "name":"MNM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MOIN",
+ "name":"MOIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MOJO",
+ "name":"MojoCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MONA",
+ "name":"MonaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XMR",
+ "name":"Monero",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"MUE",
+ "name":"MonetaryUnit",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MOON",
+ "name":"Mooncoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MOOND",
+ "name":"MOOND",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MPRO",
+ "name":"MPRO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MRB",
+ "name":"MRB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MUDRA",
+ "name":"MUDRA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MYR",
+ "name":"Myriadcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"N2O",
+ "name":"N2O",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"N7",
+ "name":"N7",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NMC",
+ "name":"Namecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NAT",
+ "name":"NAT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NAUT",
+ "name":"Nautiluscoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NAV",
+ "name":"NAV Coin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NBIT",
+ "name":"NBIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NCS",
+ "name":"NCS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NDOGE",
+ "name":"NDOGE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XEM",
+ "name":"NEM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NEOS",
+ "name":"NeosCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NET",
+ "name":"NetCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NEU",
+ "name":"NeuCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NTRN",
+ "name":"Neutron",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NEVA",
+ "name":"NevaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NEWB",
+ "name":"NEWB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NXS",
+ "name":"Nexus",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NIC",
+ "name":"NIC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NICE",
+ "name":"NICE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NKC",
+ "name":"NKC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NLC",
+ "name":"NLC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NOBL",
+ "name":"NobleCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NODES",
+ "name":"NODES",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NVC",
+ "name":"Novacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NRS",
+ "name":"NRS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NTC",
+ "name":"NTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NBT",
+ "name":"NuBits",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NUKE",
+ "name":"NUKE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NUM",
+ "name":"NUM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NSR",
+ "name":"NuShares",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NXE",
+ "name":"NXE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NXT",
+ "name":"NXT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NXTTY",
+ "name":"Nxttycoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NYC",
+ "name":"NYC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NZC",
+ "name":"NZC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"NZD",
+ "name":"NZD",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"OBS",
+ "name":"OBS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OCOW",
+ "name":"OCOW",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OK",
+ "name":"OKCash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OLYMP",
+ "name":"OLYMP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OMC",
+ "name":"OMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ONE",
+ "name":"ONE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OP",
+ "name":"OP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OPAL",
+ "name":"OPAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ORB",
+ "name":"Orbitcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"OZC",
+ "name":"OZC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PAC",
+ "name":"PAC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PAL",
+ "name":"PAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PND",
+ "name":"Pandacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PARA",
+ "name":"PARA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PAY",
+ "name":"PAY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPY",
+ "name":"Paycoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PBC",
+ "name":"PBC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PCM",
+ "name":"PCM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PCS",
+ "name":"PCS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PDC",
+ "name":"PDC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PEC",
+ "name":"PEC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PPC",
+ "name":"Peercoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PEN",
+ "name":"PEN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PHR",
+ "name":"PHR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PIN",
+ "name":"PIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PC",
+ "name":"Pinkcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PIO",
+ "name":"PIO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PIZZA",
+ "name":"PIZZA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PKB",
+ "name":"PKB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PLN",
+ "name":"PLN",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"PLNC",
+ "name":"PLNC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PNK",
+ "name":"PNK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"POKE",
+ "name":"POKE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PONZ2",
+ "name":"PONZ2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PONZI",
+ "name":"PONZI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PEX",
+ "name":"PosEx",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"POST",
+ "name":"POST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"POT",
+ "name":"Potcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PRE",
+ "name":"PRE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PRES",
+ "name":"PRES",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PXI",
+ "name":"Prime-XI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PRIME",
+ "name":"PrimeChain",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPM",
+ "name":"Primecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PRM",
+ "name":"PRM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PRT",
+ "name":"PRT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PSB",
+ "name":"PSB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PSP",
+ "name":"PSP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PSY",
+ "name":"PSY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PTC",
+ "name":"PTC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PURE",
+ "name":"PURE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PUTIN",
+ "name":"PUTIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PWR",
+ "name":"PWR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PX",
+ "name":"PX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"PXL",
+ "name":"PXL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QBC",
+ "name":"QBC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QBK",
+ "name":"QBK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QCN",
+ "name":"QCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QORA",
+ "name":"Qora",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QTZ",
+ "name":"QTZ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QRK",
+ "name":"Quark",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"QTL",
+ "name":"Quatloo",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RADI",
+ "name":"RADI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RADS",
+ "name":"Radium",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XRA",
+ "name":"RateCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RBIT",
+ "name":"RBIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RCN",
+ "name":"RCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RED",
+ "name":"RED",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RDD",
+ "name":"Reddcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"REE",
+ "name":"REE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"REV",
+ "name":"Revenu",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RICHX",
+ "name":"RICHX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RIC",
+ "name":"Riecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RBT",
+ "name":"Rimbit",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"RIO",
+ "name":"RIO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XRP",
+ "name":"Ripple",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RISE",
+ "name":"RISE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RMS",
+ "name":"RMS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RONIN",
+ "name":"RONIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ROYAL",
+ "name":"ROYAL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RPC",
+ "name":"RPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RRT",
+ "name":"RRT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RBIES",
+ "name":"Rubies",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RUBIT",
+ "name":"RUBIT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RUR",
+ "name":"Ruble",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"RBY",
+ "name":"Rubycoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RUST",
+ "name":"RUST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"RYCN",
+ "name":"RYCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SEC",
+ "name":"Safe Exchange Coin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SAK",
+ "name":"SAK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SAR",
+ "name":"SAR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SBD",
+ "name":"SBD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCAN",
+ "name":"SCAN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCB",
+ "name":"SCB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCN",
+ "name":"SCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCOT",
+ "name":"Scotcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCRPT",
+ "name":"SCRPT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCRT",
+ "name":"SCRT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SCT",
+ "name":"SCT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SRC",
+ "name":"SecureCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SED",
+ "name":"SED",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SXC",
+ "name":"Sexcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SGD",
+ "name":"SGD",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"SH",
+ "name":"SH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SDC",
+ "name":"ShadowCash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SHELL",
+ "name":"SHELL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SHI",
+ "name":"SHI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SHIFT",
+ "name":"Shift",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SC",
+ "name":"Siacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SIB",
+ "name":"Siberian chervonets",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SIGU",
+ "name":"SIGU",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SLFI",
+ "name":"SLFI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SLING",
+ "name":"Sling",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SLK",
+ "name":"SLK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SLS",
+ "name":"SLS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SMC",
+ "name":"SMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SMLY",
+ "name":"SmileyCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SNGLS",
+ "name":"SNGLS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SNRG",
+ "name":"SNRG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SOIL",
+ "name":"SOILcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SLR",
+ "name":"Solarcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SONG",
+ "name":"SongCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SOON",
+ "name":"SOON",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SP",
+ "name":"SP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPACE",
+ "name":"SPACE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPEX",
+ "name":"SPEX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPHR",
+ "name":"Sphere",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPKTR",
+ "name":"SPKTR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPN",
+ "name":"SPN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPORT",
+ "name":"SPORT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPR",
+ "name":"SpreadCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPT",
+ "name":"SPT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SPX",
+ "name":"SPX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SSC",
+ "name":"SSC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STA",
+ "name":"STA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STAR",
+ "name":"STAR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"START",
+ "name":"Startcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STE",
+ "name":"STE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XST",
+ "name":"Stealthcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STEEM",
+ "name":"Steem",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XLM",
+ "name":"Stellar",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STR",
+ "name":"Stellar",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STEPS",
+ "name":"Steps",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SLG",
+ "name":"Sterlingcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STHR",
+ "name":"STHR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STL",
+ "name":"STL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STO",
+ "name":"STO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SJCX",
+ "name":"Storjcoin X",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STP",
+ "name":"STP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STRAT",
+ "name":"STRAT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STS",
+ "name":"Stress",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"STV",
+ "name":"STV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SUB",
+ "name":"Subcriptio",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNITY",
+ "name":"SuperNET",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SWEET",
+ "name":"SWEET",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SWING",
+ "name":"SWING",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SYNC",
+ "name":"SYNC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"AMP",
+ "name":"Synereo",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SYNX",
+ "name":"SYNX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"SYS",
+ "name":"Syscoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TAB",
+ "name":"TAB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TAG",
+ "name":"TagCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TAJ",
+ "name":"TAJ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TAK",
+ "name":"TAK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TAO",
+ "name":"TAO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TBC",
+ "name":"TBC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TC",
+ "name":"TC",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"TCOIN",
+ "name":"TCOIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TCR",
+ "name":"TCR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TDFB",
+ "name":"TDFB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TDY",
+ "name":"TDY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TEAM",
+ "name":"TEAM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TEC",
+ "name":"TEC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TECH",
+ "name":"TECH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TEK",
+ "name":"TEKcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRC",
+ "name":"Terracoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TESLA",
+ "name":"TESLA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TES",
+ "name":"TeslaCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TET",
+ "name":"TET",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"THC",
+ "name":"THC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"DAO",
+ "name":"The DAO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TIA",
+ "name":"TIA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TIX",
+ "name":"Tickets",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XTC",
+ "name":"TileCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TIT",
+ "name":"Titcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TMC",
+ "name":"TMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TNG",
+ "name":"TNG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TODAY",
+ "name":"TODAY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TOKEN",
+ "name":"TOKEN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TP1",
+ "name":"TP1",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TPC",
+ "name":"TPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TPG",
+ "name":"TPG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TX",
+ "name":"Transfercoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRAP",
+ "name":"TRAP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRICK",
+ "name":"TRICK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRIG",
+ "name":"TRIG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TROLL",
+ "name":"TROLL",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRK",
+ "name":"Truckcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRUMP",
+ "name":"TrumpCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TRUST",
+ "name":"TRUST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TSC",
+ "name":"TSC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TWERK",
+ "name":"TWERK",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TWIST",
+ "name":"TWIST",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"TWO",
+ "name":"TWO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UAE",
+ "name":"UAE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UB",
+ "name":"UB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UFO",
+ "name":"UFO Coin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UIS",
+ "name":"UIS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UAH",
+ "name":"Ukrainian Hryvnia",
+ "statuses":[
+ "secondary"
+ ]
+ },
+ {
+ "code":"UTC",
+ "name":"UltraCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNB",
+ "name":"UNB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNC",
+ "name":"UNC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNF",
+ "name":"Unfed",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNIQ",
+ "name":"UNIQ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNIT",
+ "name":"Universal Currency",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"UNO",
+ "name":"Unobtanium",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"URC",
+ "name":"URC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"URO",
+ "name":"Uro",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"USD",
+ "name":"US Dollar",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"USDE",
+ "name":"USDE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XVC",
+ "name":"Vcash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VCN",
+ "name":"VCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VCOIN",
+ "name":"VCOIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VEC",
+ "name":"VEC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VEG",
+ "name":"VEG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XVG",
+ "name":"Verge",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VRC",
+ "name":"VeriCoin",
+ "statuses":[
+ "primary",
+ "secondary"
+ ]
+ },
+ {
+ "code":"VTC",
+ "name":"Vertcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VIA",
+ "name":"Viacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VIP",
+ "name":"VIP Tokens",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VIRAL",
+ "name":"Viral",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VLT",
+ "name":"VLT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VOOT",
+ "name":"VootCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VOX",
+ "name":"Voxels",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VOYA",
+ "name":"VOYA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VPN",
+ "name":"VPNCoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VRM",
+ "name":"VRM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VRS",
+ "name":"VRS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VTA",
+ "name":"VTA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VTN",
+ "name":"VTN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VTR",
+ "name":"VTR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"VTY",
+ "name":"VTY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WA",
+ "name":"WA",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WAC",
+ "name":"WAC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WARP",
+ "name":"WARP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WASH",
+ "name":"WASH",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WAV",
+ "name":"WAV",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WAVES",
+ "name":"WAVES",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WAY",
+ "name":"WAY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WCN",
+ "name":"WCN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WEX",
+ "name":"WEX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WGC",
+ "name":"WGC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XWC",
+ "name":"Whitecoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WBB",
+ "name":"Wild Beast Block",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WINE",
+ "name":"WINE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WLC",
+ "name":"WLC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WMC",
+ "name":"WMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"LOG",
+ "name":"Woodcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WDC",
+ "name":"Worldcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"WRP",
+ "name":"WRP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"X2",
+ "name":"X2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"X2C",
+ "name":"X2C",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XAB",
+ "name":"XAB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XAUR",
+ "name":"XAUR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XAU",
+ "name":"Xaurum",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XBS",
+ "name":"XBS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XBTS",
+ "name":"XBTS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XBU",
+ "name":"XBU",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XCO",
+ "name":"XCO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XC",
+ "name":"XCurrency",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XDB",
+ "name":"XDB",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XDE2",
+ "name":"XDE2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"MI",
+ "name":"Xiaomicoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XID",
+ "name":"XID",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XJO",
+ "name":"XJO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XLTCG",
+ "name":"XLTCG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XMINE",
+ "name":"XMINE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XMS",
+ "name":"XMS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XNG",
+ "name":"XNG",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XODUS",
+ "name":"XODUS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPC",
+ "name":"XPC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPO",
+ "name":"XPO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPOKE",
+ "name":"XPOKE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPRO",
+ "name":"XPRO",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XPTX",
+ "name":"XPTX",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XQN",
+ "name":"XQN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XRC",
+ "name":"XRC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XSEED",
+ "name":"XSEED",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XSY",
+ "name":"XSY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XTP",
+ "name":"XTP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XUP",
+ "name":"XUP",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YAC",
+ "name":"Yacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YAY",
+ "name":"YAY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YBC",
+ "name":"Ybcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YMC",
+ "name":"YMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YOC",
+ "name":"YOC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YOVI",
+ "name":"YOVI",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"YUM",
+ "name":"YUM",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZEC",
+ "name":"Zcash",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZCL",
+ "name":"Zcash classic",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZCC",
+ "name":"ZCC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZCOIN",
+ "name":"ZCOIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"XZC",
+ "name":"Zcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZECD",
+ "name":"ZECD",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZEIT",
+ "name":"Zeitcoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZET2",
+ "name":"ZET2",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZET",
+ "name":"Zetacoin",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZRC",
+ "name":"ZiftrCOIN",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZLQ",
+ "name":"ZLQ",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZMC",
+ "name":"ZMC",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZNE",
+ "name":"ZNE",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZNY",
+ "name":"ZNY",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZS",
+ "name":"ZS",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZUR",
+ "name":"ZUR",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZXT",
+ "name":"ZXT",
+ "statuses":[
+ "primary"
+ ]
+ },
+ {
+ "code":"ZYD",
+ "name":"ZYD",
+ "statuses":[
+ "primary"
+ ]
+ }
+ ]
+} \ No newline at end of file
diff --git a/ui/app/css/index.css b/ui/app/css/index.css
index 975a5289b..16e1dbe7e 100644
--- a/ui/app/css/index.css
+++ b/ui/app/css/index.css
@@ -165,9 +165,6 @@ textarea.twelve-word-phrase {
}
.network-name {
- position: absolute;
- top: 8px;
- left: 60px;
width: 5.2em;
line-height: 9px;
text-rendering: geometricPrecision;
diff --git a/ui/app/css/lib.css b/ui/app/css/lib.css
index 95764c2b8..a8df1d115 100644
--- a/ui/app/css/lib.css
+++ b/ui/app/css/lib.css
@@ -204,6 +204,23 @@ hr.horizontal-line {
align-items: center;
justify-content: center;
padding: 4px;
+ z-index: 1;
+}
+
+.keyring-label {
+ z-index: 1;
+ font-size: 11px;
+ background: rgba(255,0,0,0.8);
+ bottom: -47px;
+ color: white;
+ border-radius: 10px;
+ height: 20px;
+ min-width: 20px;
+ position: relative;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 4px;
}
.ether-balance {
@@ -221,7 +238,7 @@ hr.horizontal-line {
background: rgb(0, 163, 68);
border-radius: 20px;
}
-.morden-icon {
+.testnet-icon {
background: #2465E1;
}
diff --git a/ui/app/first-time/disclaimer.js b/ui/app/first-time/disclaimer.js
index 819d4a110..a8bafd39b 100644
--- a/ui/app/first-time/disclaimer.js
+++ b/ui/app/first-time/disclaimer.js
@@ -6,6 +6,8 @@ const actions = require('../actions')
const ReactMarkdown = require('react-markdown')
const fs = require('fs')
const path = require('path')
+const linker = require('extension-link-enabler')
+const findDOMNode = require('react-dom').findDOMNode
const disclaimer = fs.readFileSync(path.join(__dirname, '..', '..', '..', 'USER_AGREEMENT.md')).toString()
module.exports = connect(mapStateToProps)(DisclaimerScreen)
@@ -98,3 +100,13 @@ DisclaimerScreen.prototype.render = function () {
])
)
}
+
+DisclaimerScreen.prototype.componentDidMount = function () {
+ var node = findDOMNode(this)
+ linker.setupListener(node)
+}
+
+DisclaimerScreen.prototype.componentWillUnmount = function () {
+ var node = findDOMNode(this)
+ linker.teardownListener(node)
+}
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index 14a89b988..152d28809 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -125,7 +125,7 @@ InitializeMenuScreen.prototype.renderMenu = function (state) {
color: 'rgb(247, 134, 28)',
textDecoration: 'underline',
},
- }, 'I already have a DEN that I would like to import'),
+ }, 'Import Existing DEN'),
]),
])
@@ -165,7 +165,7 @@ InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
return
}
- this.props.dispatch(actions.createNewVaultAndKeychain(password, ''/* entropy*/))
+ this.props.dispatch(actions.createNewVaultAndKeychain(password))
}
InitializeMenuScreen.prototype.inputChanged = function (event) {
diff --git a/ui/app/info.js b/ui/app/info.js
index 9eb2c2e98..cc753b2ea 100644
--- a/ui/app/info.js
+++ b/ui/app/info.js
@@ -145,7 +145,7 @@ InfoScreen.prototype.render = function () {
h('div.fa.fa-github', [
h('a.info', {
- href: 'https://github.com/metamask/talk/issues',
+ href: 'https://github.com/MetaMask/metamask-plugin/issues',
target: '_blank',
onClick (event) { this.navigateTo(event.target.href) },
}, 'Start a thread on GitHub'),
diff --git a/ui/app/keychains/hd/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js
index 83dbc270f..56ac461ea 100644
--- a/ui/app/keychains/hd/recover-seed/confirmation.js
+++ b/ui/app/keychains/hd/recover-seed/confirmation.js
@@ -5,10 +5,10 @@ const connect = require('react-redux').connect
const h = require('react-hyperscript')
const actions = require('../../../actions')
-module.exports = connect(mapStateToProps)(RevealSeedConfirmatoin)
+module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
-inherits(RevealSeedConfirmatoin, Component)
-function RevealSeedConfirmatoin () {
+inherits(RevealSeedConfirmation, Component)
+function RevealSeedConfirmation () {
Component.call(this)
}
@@ -18,9 +18,9 @@ function mapStateToProps (state) {
}
}
-RevealSeedConfirmatoin.prototype.confirmationPhrase = 'I understand'
+RevealSeedConfirmation.prototype.confirmationPhrase = 'I understand'
-RevealSeedConfirmatoin.prototype.render = function () {
+RevealSeedConfirmation.prototype.render = function () {
const props = this.props
const state = this.state
@@ -116,24 +116,24 @@ RevealSeedConfirmatoin.prototype.render = function () {
)
}
-RevealSeedConfirmatoin.prototype.componentDidMount = function () {
+RevealSeedConfirmation.prototype.componentDidMount = function () {
document.getElementById('password-box').focus()
}
-RevealSeedConfirmatoin.prototype.goHome = function () {
+RevealSeedConfirmation.prototype.goHome = function () {
this.props.dispatch(actions.showConfigPage(false))
}
// create vault
-RevealSeedConfirmatoin.prototype.checkConfirmation = function (event) {
+RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
if (event.key === 'Enter') {
event.preventDefault()
this.revealSeedWords()
}
}
-RevealSeedConfirmatoin.prototype.revealSeedWords = function () {
+RevealSeedConfirmation.prototype.revealSeedWords = function () {
this.setState({ confirmationWrong: false })
const confirmBox = document.getElementById('confirm-box')
diff --git a/ui/app/keychains/hd/restore-vault.js b/ui/app/keychains/hd/restore-vault.js
index 3fa25a2eb..06e51d9b3 100644
--- a/ui/app/keychains/hd/restore-vault.js
+++ b/ui/app/keychains/hd/restore-vault.js
@@ -14,6 +14,7 @@ function RestoreVaultScreen () {
function mapStateToProps (state) {
return {
warning: state.appState.warning,
+ forgottenPassword: state.appState.forgottenPassword,
}
}
@@ -100,14 +101,17 @@ RestoreVaultScreen.prototype.render = function () {
}, 'OK'),
]),
-
])
)
}
RestoreVaultScreen.prototype.showInitializeMenu = function () {
- this.props.dispatch(actions.showInitializeMenu())
+ if (this.props.forgottenPassword) {
+ this.props.dispatch(actions.backToUnlockView())
+ } else {
+ this.props.dispatch(actions.showInitializeMenu())
+ }
}
RestoreVaultScreen.prototype.createOnEnter = function (event) {
diff --git a/ui/app/reducers.js b/ui/app/reducers.js
index a691cf614..4d10e2b39 100644
--- a/ui/app/reducers.js
+++ b/ui/app/reducers.js
@@ -41,7 +41,7 @@ function rootReducer (state, action) {
return state
}
-window.logState = function() {
+window.logState = function () {
var stateString = JSON.stringify(window.METAMASK_CACHED_LOG_STATE, null, 2)
console.log(stateString)
}
diff --git a/ui/app/reducers/app.js b/ui/app/reducers/app.js
index 7f4537510..ae91272cc 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -43,7 +43,19 @@ function reduceApp (state, action) {
switch (action.type) {
- // intialize
+ // transition methods
+
+ case actions.TRANSITION_FORWARD:
+ return extend(appState, {
+ transForward: true,
+ })
+
+ case actions.TRANSITION_BACKWARD:
+ return extend(appState, {
+ transForward: false,
+ })
+
+ // intialize
case actions.SHOW_CREATE_VAULT:
return extend(appState, {
@@ -60,6 +72,16 @@ function reduceApp (state, action) {
name: 'restoreVault',
},
transForward: true,
+ forgottenPassword: true,
+ })
+
+ case actions.FORGOT_PASSWORD:
+ return extend(appState, {
+ currentView: {
+ name: 'restoreVault',
+ },
+ transForward: false,
+ forgottenPassword: true,
})
case actions.SHOW_INIT_MENU:
@@ -77,6 +99,14 @@ function reduceApp (state, action) {
transForward: action.value,
})
+ case actions.SHOW_IMPORT_PAGE:
+ return extend(appState, {
+ currentView: {
+ name: 'import-menu',
+ },
+ transForward: true,
+ })
+
case actions.SHOW_INFO_PAGE:
return extend(appState, {
currentView: {
@@ -166,7 +196,7 @@ function reduceApp (state, action) {
return extend(appState, {
warning: null,
transForward: true,
- forgottenPassword: !appState.forgottenPassword,
+ forgottenPassword: false,
currentView: {
name: 'UnlockScreen',
},
@@ -242,6 +272,13 @@ function reduceApp (state, action) {
isLoading: false,
warning: null,
scrollToBottom: false,
+ forgottenPassword: false,
+ })
+
+ case actions.SHOW_NOTICE:
+ return extend(appState, {
+ transForward: true,
+ isLoading: false,
})
case actions.REVEAL_ACCOUNT:
@@ -287,7 +324,6 @@ function reduceApp (state, action) {
warning: null,
})
} else {
-
notification.closePopup()
return extend(appState, {
@@ -295,7 +331,7 @@ function reduceApp (state, action) {
warning: null,
currentView: {
name: 'accountDetail',
- context: state.metamask.selectedAddress,
+ context: state.metamask.selectedAccount,
},
accountDetail: {
subview: 'transactions',
@@ -427,7 +463,7 @@ function reduceApp (state, action) {
},
buyView: {
subview: 'buyForm',
- amount: '5.00',
+ amount: '15.00',
buyAddress: action.value,
formView: {
coinbase: true,
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index aa809b333..8679ab062 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -16,6 +16,8 @@ function reduceMetamask (state, action) {
currentFiat: 'USD',
conversionRate: 0,
conversionDate: 'N/A',
+ noActiveNotices: true,
+ lastUnreadNotice: undefined,
}, state.metamask)
switch (action.type) {
@@ -25,12 +27,23 @@ function reduceMetamask (state, action) {
delete newState.seedWords
return newState
+ case actions.SHOW_NOTICE:
+ return extend(metamaskState, {
+ noActiveNotices: false,
+ lastUnreadNotice: action.value,
+ })
+
+ case actions.CLEAR_NOTICES:
+ return extend(metamaskState, {
+ noActiveNotices: true,
+ })
+
case actions.UPDATE_METAMASK_STATE:
return extend(metamaskState, action.value)
case actions.AGREE_TO_DISCLAIMER:
return extend(metamaskState, {
- isConfirmed: true,
+ isDisclaimerConfirmed: true,
})
case actions.UNLOCK_METAMASK:
@@ -98,7 +111,6 @@ function reduceMetamask (state, action) {
isUnlocked: true,
isInitialized: true,
selectedAccount: action.value,
- selectedAddress: action.value,
})
delete newState.seedWords
return newState
diff --git a/ui/app/unlock.js b/ui/app/unlock.js
index b2c693493..1aee3c5d0 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -70,7 +70,7 @@ UnlockScreen.prototype.render = function () {
h('.flex-row.flex-center.flex-grow', [
h('p.pointer', {
- onClick: () => this.props.dispatch(actions.showRestoreVault()),
+ onClick: () => this.props.dispatch(actions.forgotPassword()),
style: {
fontSize: '0.8em',
color: 'rgb(247, 134, 28)',
@@ -116,4 +116,3 @@ UnlockScreen.prototype.inputChanged = function (event) {
y: boundingRect.top + coordinates.top - element.scrollTop,
})
}
-
diff --git a/ui/example.js b/ui/example.js
index f4126438c..888748c48 100644
--- a/ui/example.js
+++ b/ui/example.js
@@ -53,14 +53,14 @@ function addUnconfTx (txParams) {
}
var isUnlocked = false
-var selectedAddress = null
+var selectedAccount = null
function getState () {
return {
isUnlocked: isUnlocked,
identities: isUnlocked ? identities : {},
unconfTxs: isUnlocked ? unconfTxs : {},
- selectedAddress: selectedAddress,
+ selectedAccount: selectedAccount,
}
}
@@ -85,8 +85,8 @@ accountManager.submitPassword = function (password, cb) {
}
}
-accountManager.setSelectedAddress = function (address, cb) {
- selectedAddress = address
+accountManager.setSelectedAccount = function (address, cb) {
+ selectedAccount = address
cb(null, getState())
this._didUpdate()
}
diff --git a/ui/lib/account-link.js b/ui/lib/account-link.js
index eb958e22d..77db0851d 100644
--- a/ui/lib/account-link.js
+++ b/ui/lib/account-link.js
@@ -1,4 +1,4 @@
-module.exports = function(address, network) {
+module.exports = function (address, network) {
const net = parseInt(network)
let link
@@ -7,6 +7,9 @@ module.exports = function(address, network) {
link = `http://etherscan.io/address/${address}`
break
case 2: // morden test net
+ link = `http://morden.etherscan.io/address/${address}`
+ break
+ case 3: // ropsten test net
link = `http://testnet.etherscan.io/address/${address}`
break
default:
diff --git a/ui/lib/contract-namer.js b/ui/lib/contract-namer.js
index c99d44de6..a94c62b62 100644
--- a/ui/lib/contract-namer.js
+++ b/ui/lib/contract-namer.js
@@ -8,23 +8,22 @@
// Nickname keys must be stored in lower case.
const nicknames = {}
-module.exports = function(addr, identities = {}) {
-
+module.exports = function (addr, identities = {}) {
const address = addr.toLowerCase()
const ids = hashFromIdentities(identities)
return addrFromHash(address, ids) || addrFromHash(address, nicknames)
}
-function hashFromIdentities(identities) {
+function hashFromIdentities (identities) {
const result = {}
- for (let key in identities) {
+ for (const key in identities) {
result[key] = identities[key].name
}
return result
}
-function addrFromHash(addr, hash) {
+function addrFromHash (addr, hash) {
const address = addr.toLowerCase()
return hash[address] || null
}
diff --git a/ui/lib/explorer-link.js b/ui/lib/explorer-link.js
index 2993d1cf1..dc6be2984 100644
--- a/ui/lib/explorer-link.js
+++ b/ui/lib/explorer-link.js
@@ -5,7 +5,7 @@ module.exports = function (hash, network) {
case 1: // main net
prefix = ''
break
- case 2: // morden test net
+ case 3: // morden test net
prefix = 'testnet.'
break
default:
diff --git a/ui/lib/icon-factory.js b/ui/lib/icon-factory.js
index a30041114..82cc839d6 100644
--- a/ui/lib/icon-factory.js
+++ b/ui/lib/icon-factory.js
@@ -55,6 +55,6 @@ function jsNumberForAddress (address) {
return seed
}
-function toDataUri(identiconSrc){
+function toDataUri (identiconSrc) {
return 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(identiconSrc)
-} \ No newline at end of file
+}
diff --git a/ui/lib/lost-accounts-notice.js b/ui/lib/lost-accounts-notice.js
new file mode 100644
index 000000000..948b13db6
--- /dev/null
+++ b/ui/lib/lost-accounts-notice.js
@@ -0,0 +1,23 @@
+const summary = require('../app/util').addressSummary
+
+module.exports = function (lostAccounts) {
+ return {
+ date: new Date().toDateString(),
+ title: 'Account Problem Caught',
+ body: `MetaMask has fixed a bug where some accounts were previously mis-generated. This was a rare issue, but you were affected!
+
+We have successfully imported the accounts that were mis-generated, but they will no longer be recovered with your normal seed phrase.
+
+We have marked the affected accounts as "Loose", and recommend you transfer ether and tokens away from those accounts, or export & back them up elsewhere.
+
+Your affected accounts are:
+${lostAccounts.map(acct => ` - ${summary(acct)}`).join('\n')}
+
+These accounts have been marked as "Loose" so they will be easy to recognize in the account list.
+
+For more information, please read [our blog post.][1]
+
+[1]: https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd#.7d8ktj4h3
+ `,
+ }
+}