aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintignore1
-rw-r--r--.eslintrc4
-rw-r--r--.gitignore2
-rw-r--r--CHANGELOG.md3
-rw-r--r--README.md19
-rw-r--r--app/scripts/background.js11
-rw-r--r--app/scripts/contentscript.js14
-rw-r--r--app/scripts/inpage.js3
-rw-r--r--app/scripts/keyring-controller.js889
-rw-r--r--app/scripts/keyrings/hd.js111
-rw-r--r--app/scripts/keyrings/simple.js78
-rw-r--r--app/scripts/lib/auto-faucet.js5
-rw-r--r--app/scripts/lib/auto-reload.js5
-rw-r--r--app/scripts/lib/config-manager.js78
-rw-r--r--app/scripts/lib/encryptor.js156
-rw-r--r--app/scripts/lib/idStore-migrator.js52
-rw-r--r--app/scripts/lib/idStore.js20
-rw-r--r--app/scripts/lib/inpage-provider.js16
-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/random-id.js6
-rw-r--r--app/scripts/lib/sig-util.js28
-rw-r--r--app/scripts/metamask-controller.js171
-rw-r--r--app/scripts/popup-core.js4
-rw-r--r--app/scripts/popup.js2
-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.json7
-rw-r--r--development/states/config.json4
-rw-r--r--development/states/create-vault-password.json2
-rw-r--r--development/states/custom-rpc.json5
-rw-r--r--development/states/empty-account-detail.json4
-rw-r--r--development/states/first-time.json (renamed from development/states/terms.json)20
-rw-r--r--development/states/help.json4
-rw-r--r--development/states/locked.json5
-rw-r--r--development/states/new-vault.json2
-rw-r--r--development/states/pending-crash.json2
-rw-r--r--development/states/pending-signature.json7
-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.json5
-rw-r--r--development/states/send.json5
-rw-r--r--development/states/shapeshift.json7
-rw-r--r--development/states/show-seed-words.json2
-rw-r--r--development/test.html31
-rw-r--r--docs/multi_vault_planning.md188
-rw-r--r--mock-dev.js4
-rw-r--r--package.json14
-rw-r--r--test/integration/helpers.js4
-rw-r--r--test/integration/index.html4
-rw-r--r--test/integration/index.js21
-rw-r--r--test/integration/lib/encryptor-test.js71
-rw-r--r--test/integration/lib/first-time.js90
-rw-r--r--test/integration/lib/keyring-controller-test.js62
-rw-r--r--test/integration/mocks/oldVault.json21
-rw-r--r--test/integration/tests.js24
-rw-r--r--test/lib/mock-config-manager.js2
-rw-r--r--test/lib/mock-encryptor.js32
-rw-r--r--test/lib/mock-simple-keychain.js38
-rw-r--r--test/unit/actions/restore_vault_test.js60
-rw-r--r--test/unit/actions/set_selected_account_test.js1
-rw-r--r--test/unit/actions/tx_test.js8
-rw-r--r--test/unit/config-manager-test.js28
-rw-r--r--test/unit/idStore-migration-test.js160
-rw-r--r--test/unit/idStore-test.js3
-rw-r--r--test/unit/keyring-controller-test.js200
-rw-r--r--test/unit/keyrings/hd-test.js127
-rw-r--r--test/unit/keyrings/simple-test.js94
-rw-r--r--test/unit/nodeify-test.js22
-rw-r--r--testem.yml1
-rw-r--r--ui-dev.js4
-rw-r--r--ui/app/account-detail.js1
-rw-r--r--ui/app/accounts/account-list-item.js2
-rw-r--r--ui/app/accounts/index.js22
-rw-r--r--ui/app/actions.js229
-rw-r--r--ui/app/app.js143
-rw-r--r--ui/app/components/coinbase-form.js8
-rw-r--r--ui/app/components/copyButton.js4
-rw-r--r--ui/app/components/drop-menu-item.js6
-rw-r--r--ui/app/components/identicon.js30
-rw-r--r--ui/app/components/network.js2
-rw-r--r--ui/app/components/pending-msg-details.js2
-rw-r--r--ui/app/components/pending-tx-details.js27
-rw-r--r--ui/app/components/shapeshift-form.js4
-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.js2
-rw-r--r--ui/app/conf-tx.js8
-rw-r--r--ui/app/config.js2
-rw-r--r--ui/app/conversion-util.js5
-rw-r--r--ui/app/conversion.json5730
-rw-r--r--ui/app/eth-store-warning.js89
-rw-r--r--ui/app/first-time/create-vault.js129
-rw-r--r--ui/app/first-time/init-menu.js147
-rw-r--r--ui/app/keychains/hd/create-vault-complete.js (renamed from ui/app/first-time/create-vault-complete.js)3
-rw-r--r--ui/app/keychains/hd/recover-seed/confirmation.js (renamed from ui/app/recover-seed/confirmation.js)22
-rw-r--r--ui/app/keychains/hd/restore-vault.js (renamed from ui/app/first-time/restore-vault.js)16
-rw-r--r--ui/app/new-keychain.js29
-rw-r--r--ui/app/reducers.js2
-rw-r--r--ui/app/reducers/app.js35
-rw-r--r--ui/app/reducers/metamask.js9
-rw-r--r--ui/app/unlock.js17
-rw-r--r--ui/example.js8
-rw-r--r--ui/index.js2
-rw-r--r--ui/lib/account-link.js2
-rw-r--r--ui/lib/contract-namer.js9
-rw-r--r--ui/lib/icon-factory.js4
112 files changed, 9041 insertions, 929 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 95eab7337..72b3d3e6d 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -127,9 +127,9 @@
"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", "avoid-escape"],
+ "quotes": [2, "single", {"avoidEscape": true, "allowTemplateLiterals": true}],
"semi": [2, "never"],
"semi-spacing": [2, { "before": false, "after": true }],
"space-before-blocks": [1, "always"],
diff --git a/.gitignore b/.gitignore
index 657c24099..af6449834 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,4 @@
dist
-
npm-debug.log
node_modules
temp
@@ -8,7 +7,6 @@ temp
app/bower_components
test/bower_components
package
-
.DS_Store
builds/
notes.txt
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0fd1e83bf..44f8567e5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -26,6 +26,9 @@
- 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
diff --git a/README.md b/README.md
index afdda4d97..fdbe3c535 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
@@ -90,6 +103,10 @@ You can also test with a continuously watching process, via `npm run watch`.
You can run the linter by itself with `gulp lint`.
+#### Writing Browser Tests
+
+To write tests that will be run in the browser using QUnit, add your test files to `test/integration/lib`.
+
### Deploying the UI
You must be authorized already on the MetaMask plugin.
diff --git a/app/scripts/background.js b/app/scripts/background.js
index 652acc113..7cb25d8bf 100644
--- a/app/scripts/background.js
+++ b/app/scripts/background.js
@@ -10,6 +10,7 @@ const MetamaskController = require('./metamask-controller')
const extension = require('./lib/extension')
const STORAGE_KEY = 'metamask-config'
+const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
var popupIsOpen = false
const controller = new MetamaskController({
@@ -21,7 +22,7 @@ const controller = new MetamaskController({
setData,
loadData,
})
-const idStore = controller.idStore
+const keyringController = controller.keyringController
function triggerUi () {
if (!popupIsOpen) notification.show()
@@ -29,7 +30,7 @@ function triggerUi () {
// On first install, open a window to MetaMask website to how-it-works.
extension.runtime.onInstalled.addListener(function (details) {
- if (details.reason === 'install') {
+ if ((details.reason === 'install') && (!METAMASK_DEBUG)) {
extension.tabs.create({url: 'https://metamask.io/#how-it-works'})
}
})
@@ -82,7 +83,7 @@ function setupControllerConnection (stream) {
// push updates to popup
controller.ethStore.on('update', controller.sendUpdate.bind(controller))
controller.listeners.push(remote)
- idStore.on('update', controller.sendUpdate.bind(controller))
+ keyringController.on('update', controller.sendUpdate.bind(controller))
// teardown on disconnect
eos(stream, () => {
@@ -96,9 +97,9 @@ function setupControllerConnection (stream) {
// plugin badge text
//
-idStore.on('update', updateBadge)
+keyringController.on('update', updateBadge)
-function updateBadge (state) {
+function updateBadge () {
var label = ''
var unconfTxs = controller.configManager.unconfirmedTxs()
var unconfTxLen = Object.keys(unconfTxs).length
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 7d43bd20e..42332d92e 100644
--- a/app/scripts/inpage.js
+++ b/app/scripts/inpage.js
@@ -43,6 +43,7 @@ reloadStream.once('data', triggerReload)
// var pingChannel = inpageProvider.multiStream.createStream('pingpong')
// var pingStream = new PingStream({ objectMode: true })
// wait for first successful reponse
+
// disable pingStream until https://github.com/MetaMask/metamask-plugin/issues/746 is resolved more gracefully
// metamaskStream.once('data', function(){
// pingStream.pipe(pingChannel).pipe(pingStream)
@@ -51,7 +52,7 @@ reloadStream.once('data', 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
new file mode 100644
index 000000000..40c9695dd
--- /dev/null
+++ b/app/scripts/keyring-controller.js
@@ -0,0 +1,889 @@
+const async = require('async')
+const ethUtil = require('ethereumjs-util')
+const EthQuery = require('eth-query')
+const bip39 = require('bip39')
+const Transaction = require('ethereumjs-tx')
+const EventEmitter = require('events').EventEmitter
+const filter = require('promise-filter')
+const normalize = require('./lib/sig-util').normalize
+const encryptor = require('./lib/encryptor')
+const messageManager = require('./lib/message-manager')
+const IdStoreMigrator = require('./lib/idStore-migrator')
+const BN = ethUtil.BN
+
+// Keyrings:
+const SimpleKeyring = require('./keyrings/simple')
+const HdKeyring = require('./keyrings/hd')
+const keyringTypes = [
+ SimpleKeyring,
+ 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.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.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
+ }
+
+ // 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
+
+ return {
+ seedWords: this.configManager.getSeedWords(),
+ isInitialized: (!!wallet || !!vault),
+ isUnlocked: Boolean(this.password),
+ isDisclaimerConfirmed: this.configManager.getConfirmedDisclaimer(), // AUDIT this.configManager.getConfirmedDisclaimer(),
+ unconfTxs: this.configManager.unconfirmedTxs(),
+ transactions: this.configManager.getTxList(),
+ 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,
+ }
+ }
+
+ // 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 Promise.reject('Password must be text.')
+ }
+
+ if (!bip39.validateMnemonic(seed)) {
+ return Promise.reject('Seed phrase is invalid.')
+ }
+
+ this.clearKeyrings()
+
+ return this.persistAllKeyrings(password)
+ .then(() => {
+ return this.addNewKeyring('HD Key Tree', {
+ mnemonic: seed,
+ numberOfAccounts: 1,
+ })
+ }).then(() => {
+ const firstKeyring = this.keyrings[0]
+ return firstKeyring.getAccounts()
+ })
+ .then((accounts) => {
+ const firstAccount = accounts[0]
+ const hexAccount = normalize(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)
+ return this.fullUpdate()
+ })
+ }
+
+ // 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())
+ }
+
+ // 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.migrateOldVaultIfAny(password)
+ .then(() => {
+ return this.unlockKeyrings(password)
+ })
+ .then((keyrings) => {
+ this.keyrings = keyrings
+ return this.fullUpdate()
+ })
+ }
+
+ // 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)
+ return keyring.getAccounts()
+ .then((accounts) => {
+ this.keyrings.push(keyring)
+ return this.setupAccounts(accounts)
+ })
+ .then(() => { return this.password })
+ .then(this.persistAllKeyrings.bind(this))
+ .then(() => {
+ return keyring
+ })
+ }
+
+ // 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 Promise.resolve(addr)
+ }
+
+ // 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
+ 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)
+ }
+ }
+
+
+ // SIGNING RELATED METHODS
+ //
+ // SIGN, SUBMIT TX, CANCEL, AND APPROVE.
+ // THIS SECTION INVOLVES THE REQUEST, STORING, AND SIGNING OF DATA
+ // WITH THE KEYS STORED IN THIS CONTROLLER.
+
+
+ // Add Unconfirmed Transaction
+ // @object txParams
+ // @function onTxDoneCb
+ // @function cb
+ //
+ // Calls back `cb` with @object txData = { txParams }
+ // Calls back `onTxDoneCb` with `true` or an `error` depending on result.
+ //
+ // Prepares the given `txParams` for final confirmation and approval.
+ // Estimates gas and other preparatory steps.
+ // Caches the requesting Dapp's callback, `onTxDoneCb`, for resolution later.
+ addUnconfirmedTransaction (txParams, onTxDoneCb, cb) {
+ 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.getNetwork()
+ var txData = {
+ id: txId,
+ txParams: txParams,
+ time: time,
+ status: 'unconfirmed',
+ gasMultiplier: configManager.getGasMultiplier() || 1,
+ metamaskNetworkId: this.getNetwork(),
+ }
+
+ // 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
+ this.analyzeTxGasUsage(query, txData, this.txDidComplete.bind(this, txData, cb))
+ }
+
+ estimateTxGas (query, 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
+ query.estimateGas(txParams, cb)
+ }
+
+ checkForTxGasError (txData, estimatedGasHex, cb) {
+ txData.estimatedGas = estimatedGasHex
+ // all gas used - must be an error
+ if (estimatedGasHex === txData.txParams.gas) {
+ txData.simulationFails = true
+ }
+ cb()
+ }
+
+ setTxGas (txData, blockGasLimitHex, cb) {
+ const txParams = txData.txParams
+ // if OOG, nothing more to do
+ if (txData.simulationFails) {
+ cb()
+ return
+ }
+ // 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
+ }
+
+ txDidComplete (txData, cb, err) {
+ if (err) return cb(err)
+ const configManager = this.configManager
+ configManager.addTx(txData)
+ // signal update
+ this.emit('update')
+ // signal completion of add tx
+ cb(null, txData)
+ }
+
+ analyzeTxGasUsage (query, txData, cb) {
+ query.getBlockByNumber('latest', true, (err, block) => {
+ if (err) return cb(err)
+ async.waterfall([
+ this.estimateTxGas.bind(this, query, txData, block.gasLimit),
+ this.checkForTxGasError.bind(this, txData),
+ this.setTxGas.bind(this, txData, block.gasLimit),
+ ], cb)
+ })
+ }
+
+ // Cancel Transaction
+ // @string txId
+ // @function cb
+ //
+ // Calls back `cb` with no error if provided.
+ //
+ // Forgets any tx matching `txId`.
+ cancelTransaction (txId, cb) {
+ const configManager = this.configManager
+ var approvalCb = this._unconfTxCbs[txId] || noop
+
+ // reject tx
+ approvalCb(null, false)
+ // clean up
+ configManager.rejectTx(txId)
+ delete this._unconfTxCbs[txId]
+
+ if (cb && typeof cb === 'function') {
+ cb()
+ }
+ }
+
+ // Approve Transaction
+ // @string txId
+ // @function cb
+ //
+ // Calls back `cb` with no error always.
+ //
+ // Attempts to sign a Transaction with `txId`
+ // and submit it to the blockchain.
+ //
+ // Calls back the cached Dapp's confirmation callback, also.
+ 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')
+ }
+
+ signTransaction (txParams, cb) {
+ try {
+ const address = normalize(txParams.from)
+ return this.getKeyringForAccount(address)
+ .then((keyring) => {
+ // 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)
+
+ const tx = new Transaction(txParams)
+ return keyring.signTransaction(address, tx)
+ })
+ .then((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)
+ }
+ }
+
+ // 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()
+ 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.emit('update')
+ return msgId
+ }
+
+ // 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
+ messageManager.rejectMsg(msgId)
+ delete this._unconfTxCbs[msgId]
+
+ if (cb && typeof cb === 'function') {
+ 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 msgId = msgParams.metamaskId
+ delete msgParams.metamaskId
+ const approvalCb = this._unconfMsgCbs[msgId] || noop
+
+ const address = normalize(msgParams.from)
+ return this.getKeyringForAccount(address)
+ .then((keyring) => {
+ return keyring.signMessage(address, msgParams.data)
+ }).then((rawSig) => {
+ cb(null, rawSig)
+ approvalCb(null, true)
+ return rawSig
+ })
+ } catch (e) {
+ cb(e)
+ }
+ }
+
+ // PRIVATE METHODS
+ //
+ // THESE METHODS ARE ONLY USED INTERNALLY TO THE KEYRING-CONTROLLER
+ // AND SO MAY BE CHANGED MORE LIBERALLY THAN THE ABOVE METHODS.
+
+ // 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) {
+ const shouldMigrate = !!this.configManager.getWallet() && !this.configManager.getVault()
+ return this.idStoreMigrator.migratedVaultForPassword(password)
+ .then((serialized) => {
+ this.password = password
+
+ if (serialized && shouldMigrate) {
+ return this.restoreKeyring(serialized)
+ .then(keyring => keyring.getAccounts())
+ .then((accounts) => {
+ this.configManager.setSelectedAccount(accounts[0])
+ return this.persistAllKeyrings()
+ })
+ } else {
+ return Promise.resolve()
+ }
+ })
+ }
+
+ // 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)
+ }))
+ })
+ }
+
+ // 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)
+ }
+
+ // 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
+ })
+ }
+
+ // 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()
+ return this.encryptor.decrypt(password, encryptedVault)
+ .then((vault) => {
+ this.password = password
+ vault.forEach(this.restoreKeyring.bind(this))
+ return this.keyrings
+ })
+ }
+
+ // 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
+ })
+ }
+
+ // 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)
+ }, [])
+ })
+ }
+
+ // 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.')
+ }
+ })
+ }
+
+ // 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)
+ } catch (e) {
+ accounts = []
+ }
+ accounts.forEach((address) => {
+ this.ethStore.removeAccount(address)
+ })
+
+ this.keyrings = []
+ this.identities = {}
+ this.configManager.setSelectedAccount()
+ }
+
+}
+
+
+function noop () {}
diff --git a/app/scripts/keyrings/hd.js b/app/scripts/keyrings/hd.js
new file mode 100644
index 000000000..cfec56561
--- /dev/null
+++ b/app/scripts/keyrings/hd.js
@@ -0,0 +1,111 @@
+const EventEmitter = require('events').EventEmitter
+const hdkey = require('ethereumjs-wallet/hdkey')
+const bip39 = require('bip39')
+const ethUtil = require('ethereumjs-util')
+
+// *Internal Deps
+const sigUtil = require('../lib/sig-util')
+
+// Options:
+const hdPathString = `m/44'/60'/0'/0`
+const type = 'HD Key Tree'
+
+class HdKeyring extends EventEmitter {
+
+ /* PUBLIC METHODS */
+
+ constructor (opts = {}) {
+ super()
+ this.type = type
+ this.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 ('numberOfAccounts' in opts) {
+ this.addAccounts(opts.numberOfAccounts)
+ }
+
+ return Promise.resolve()
+ }
+
+ addAccounts (numberOfAccounts = 1) {
+ if (!this.root) {
+ this._initFromMnemonic(bip39.generateMnemonic())
+ }
+
+ const oldLen = this.wallets.length
+ const newWallets = []
+ 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)
+ }
+ const hexWallets = newWallets.map(w => w.getAddress().toString('hex'))
+ return Promise.resolve(hexWallets)
+ }
+
+ 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)
+ var privKey = wallet.getPrivateKey()
+ tx.sign(privKey)
+ 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)
+ 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 Promise.resolve(rawMsgSig)
+ }
+
+ 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)
+ }
+
+
+ _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
new file mode 100644
index 000000000..8f339cf80
--- /dev/null
+++ b/app/scripts/keyrings/simple.js
@@ -0,0 +1,78 @@
+const EventEmitter = require('events').EventEmitter
+const Wallet = require('ethereumjs-wallet')
+const ethUtil = require('ethereumjs-util')
+const type = 'Simple Key Pair'
+const sigUtil = require('../lib/sig-util')
+
+class SimpleKeyring extends EventEmitter {
+
+ /* PUBLIC METHODS */
+
+ constructor (opts) {
+ super()
+ this.type = type
+ this.opts = opts || {}
+ this.wallets = []
+ }
+
+ 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)
+ return wallet
+ })
+ return Promise.resolve()
+ }
+
+ addAccounts (n = 1) {
+ var newWallets = []
+ for (var i = 0; i < n; i++) {
+ newWallets.push(Wallet.generate())
+ }
+ this.wallets = this.wallets.concat(newWallets)
+ const hexWallets = newWallets.map(w => w.getAddress().toString('hex'))
+ return Promise.resolve(hexWallets)
+ }
+
+ 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)
+ var privKey = wallet.getPrivateKey()
+ tx.sign(privKey)
+ 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)
+ 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 Promise.resolve(rawMsgSig)
+ }
+
+ exportAccount (address) {
+ const wallet = this._getWalletForAccount(address)
+ return Promise.resolve(wallet.getPrivateKey().toString('hex'))
+ }
+
+
+ /* PRIVATE METHODS */
+
+ _getWalletForAccount (account) {
+ return this.wallets.find(w => w.getAddress().toString('hex') === account)
+ }
+
+}
+
+SimpleKeyring.type = type
+module.exports = SimpleKeyring
diff --git a/app/scripts/lib/auto-faucet.js b/app/scripts/lib/auto-faucet.js
index 59cf0ec20..1e86f735e 100644
--- a/app/scripts/lib/auto-faucet.js
+++ b/app/scripts/lib/auto-faucet.js
@@ -1,6 +1,9 @@
-var uri = 'https://faucet.metamask.io/'
+const uri = 'https://faucet.metamask.io/'
+const METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
+const env = process.env.METAMASK_ENV
module.exports = function (address) {
+ if (METAMASK_DEBUG || env === 'test') return // Don't faucet in development or test
var http = new XMLHttpRequest()
var data = address
http.open('POST', uri, true)
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 b8ffb6991..59cc2b63c 100644
--- a/app/scripts/lib/config-manager.js
+++ b/app/scripts/lib/config-manager.js
@@ -2,6 +2,8 @@ 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
@@ -111,6 +113,27 @@ ConfigManager.prototype.setWallet = function (wallet) {
this.setData(data)
}
+ConfigManager.prototype.setVault = function (encryptedString) {
+ var data = this.getData()
+ data.vault = encryptedString
+ this.setData(data)
+}
+
+ConfigManager.prototype.getVault = function () {
+ var data = this.getData()
+ return ('vault' in data) && data.vault
+}
+
+ConfigManager.prototype.getKeychains = function () {
+ return this.migrator.getData().keychains || []
+}
+
+ConfigManager.prototype.setKeychains = function (keychains) {
+ var data = this.migrator.getData()
+ data.keychains = keychains
+ this.setData(data)
+}
+
ConfigManager.prototype.getSelectedAccount = function () {
var config = this.getConfig()
return config.selectedAccount
@@ -118,7 +141,7 @@ ConfigManager.prototype.getSelectedAccount = function () {
ConfigManager.prototype.setSelectedAccount = function (address) {
var config = this.getConfig()
- config.selectedAccount = address
+ config.selectedAccount = ethUtil.addHexPrefix(address)
this.setConfig(config)
}
@@ -133,11 +156,23 @@ ConfigManager.prototype.setShowSeedWords = function (should) {
this.setData(data)
}
+
ConfigManager.prototype.getShouldShowSeedWords = function () {
var data = this.migrator.getData()
return data.showSeedWords
}
+ConfigManager.prototype.setSeedWords = function (words) {
+ var data = this.getData()
+ data.seedWords = words
+ this.setData(data)
+}
+
+ConfigManager.prototype.getSeedWords = function () {
+ var data = this.getData()
+ return ('seedWords' in data) && data.seedWords
+}
+
ConfigManager.prototype.getCurrentRpcAddress = function () {
var provider = this.getProvider()
if (!provider) return null
@@ -239,13 +274,15 @@ ConfigManager.prototype.getWalletNicknames = function () {
}
ConfigManager.prototype.nicknameForWallet = function (account) {
+ const address = normalize(account)
const nicknames = this.getWalletNicknames()
- return nicknames[account]
+ return nicknames[address]
}
ConfigManager.prototype.setNicknameForWallet = function (account, nickname) {
+ const address = normalize(account)
const nicknames = this.getWalletNicknames()
- nicknames[account] = nickname
+ nicknames[address] = nickname
var data = this.getData()
data.walletNicknames = nicknames
this.setData(data)
@@ -253,6 +290,17 @@ ConfigManager.prototype.setNicknameForWallet = function (account, nickname) {
// observable
+ConfigManager.prototype.getSalt = function () {
+ var data = this.getData()
+ return ('salt' in data) && data.salt
+}
+
+ConfigManager.prototype.setSalt = function (salt) {
+ var data = this.getData()
+ data.salt = salt
+ this.setData(data)
+}
+
ConfigManager.prototype.subscribe = function (fn) {
this._subs.push(fn)
var unsubscribe = this.unsubscribe.bind(this, fn)
@@ -270,15 +318,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) {
@@ -315,7 +363,6 @@ ConfigManager.prototype.updateConversionRate = function () {
this.setConversionPrice(0)
this.setConversionDate('N/A')
})
-
}
ConfigManager.prototype.setConversionPrice = function (price) {
@@ -340,21 +387,6 @@ ConfigManager.prototype.getConversionDate = function () {
return (('conversionDate' in data) && data.conversionDate) || 'N/A'
}
-ConfigManager.prototype.setShouldntShowWarning = function () {
- var data = this.getData()
- if (data.isEthConfirmed) {
- data.isEthConfirmed = !data.isEthConfirmed
- } else {
- data.isEthConfirmed = true
- }
- this.setData(data)
-}
-
-ConfigManager.prototype.getShouldntShowWarning = function () {
- var data = this.getData()
- return ('isEthConfirmed' in data) && data.isEthConfirmed
-}
-
ConfigManager.prototype.getShapeShiftTxList = function () {
var data = this.getData()
var shapeShiftTxList = data.shapeShiftTxList ? data.shapeShiftTxList : []
diff --git a/app/scripts/lib/encryptor.js b/app/scripts/lib/encryptor.js
new file mode 100644
index 000000000..4770d2f54
--- /dev/null
+++ b/app/scripts/lib/encryptor.js
@@ -0,0 +1,156 @@
+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 cypher text.
+function encrypt (password, dataObj) {
+ const salt = this.generateSalt()
+
+ return keyFromPassword(password + salt)
+ .then(function (passwordDerivedKey) {
+ return encryptWithKey(passwordDerivedKey, dataObj)
+ })
+ .then(function (payload) {
+ payload.salt = salt
+ return JSON.stringify(payload)
+ })
+}
+
+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 {
+ data: vaultStr,
+ iv: vectorStr,
+ }
+ })
+}
+
+// Takes encrypted text, returns the restored Pojo.
+function decrypt (password, text) {
+ const payload = JSON.parse(text)
+ const salt = payload.salt
+ return keyFromPassword(password + salt)
+ .then(function (key) {
+ return decryptWithKey(key, payload)
+ })
+}
+
+function decryptWithKey (key, payload) {
+ const encryptedData = decodeBase64ToBuffer(payload.data)
+ const vector = decodeBase64ToBuffer(payload.iv)
+ 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) {
+ var stripStr = (str.slice(0, 2) === '0x') ? str.slice(2) : str
+ var buf = new Uint8Array(stripStr.length / 2)
+ for (var i = 0; i < stripStr.length; i += 2) {
+ var seg = stripStr.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/idStore-migrator.js b/app/scripts/lib/idStore-migrator.js
new file mode 100644
index 000000000..40b08efee
--- /dev/null
+++ b/app/scripts/lib/idStore-migrator.js
@@ -0,0 +1,52 @@
+const IdentityStore = require('./idStore')
+
+
+module.exports = class IdentityStoreMigrator {
+
+ constructor ({ configManager }) {
+ this.configManager = configManager
+ const hasOldVault = this.hasOldVault()
+ if (!hasOldVault) {
+ this.idStore = new IdentityStore({ configManager })
+ }
+ }
+
+ migratedVaultForPassword (password) {
+ const hasOldVault = this.hasOldVault()
+ const configManager = this.configManager
+
+ if (!this.idStore) {
+ this.idStore = new IdentityStore({ configManager })
+ }
+
+ if (!hasOldVault) {
+ 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)
+ }
+ })
+ })
+ }
+
+ serializeVault () {
+ const mnemonic = this.idStore._idmgmt.getSeed()
+ const numberOfAccounts = this.idStore._getAddresses().length
+
+ return {
+ type: 'HD Key Tree',
+ data: { mnemonic, numberOfAccounts },
+ }
+ }
+
+ hasOldVault () {
+ const wallet = this.configManager.getWallet()
+ return wallet
+ }
+}
diff --git a/app/scripts/lib/idStore.js b/app/scripts/lib/idStore.js
index 1077d263d..d36504f13 100644
--- a/app/scripts/lib/idStore.js
+++ b/app/scripts/lib/idStore.js
@@ -44,7 +44,7 @@ function IdentityStore (opts = {}) {
// public
//
-IdentityStore.prototype.createNewVault = function (password, entropy, cb) {
+IdentityStore.prototype.createNewVault = function (password, cb) {
delete this._keyStore
var serializedKeystore = this.configManager.getWallet()
@@ -53,7 +53,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 +77,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,8 +102,7 @@ IdentityStore.prototype.getState = function () {
isInitialized: !!configManager.getWallet() && !seedWords,
isUnlocked: this._isUnlocked(),
seedWords: seedWords,
- isConfirmed: configManager.getConfirmed(),
- isEthConfirmed: configManager.getShouldntShowWarning(),
+ isDisclaimerConfirmed: configManager.getConfirmedDisclaimer(),
unconfTxs: configManager.unconfirmedTxs(),
transactions: configManager.getTxList(),
unconfMsgs: messageManager.unconfirmedMsgs(),
@@ -114,7 +113,6 @@ IdentityStore.prototype.getState = function () {
conversionRate: configManager.getConversionRate(),
conversionDate: configManager.getConversionDate(),
gasMultiplier: configManager.getGasMultiplier(),
-
}))
}
@@ -245,7 +243,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone
], didComplete)
// perform static analyis on the target contract code
- function analyzeForDelegateCall(cb){
+ function analyzeForDelegateCall (cb) {
if (txParams.to) {
query.getCode(txParams.to, (err, result) => {
if (err) return cb(err.message || err)
@@ -258,7 +256,7 @@ IdentityStore.prototype.addUnconfirmedTransaction = function (txParams, onTxDone
}
}
- function estimateGas(cb){
+ function estimateGas (cb) {
var estimationParams = extend(txParams)
query.getBlockByNumber('latest', true, function(err, block){
if (err) return cb(err)
@@ -466,7 +464,9 @@ IdentityStore.prototype._loadIdentities = function () {
var addresses = this._getAddresses()
addresses.forEach((address, i) => {
// // add to ethStore
- this._ethStore.addAccount(ethUtil.addHexPrefix(address))
+ if (this._ethStore) {
+ this._ethStore.addAccount(ethUtil.addHexPrefix(address))
+ }
// add to identities
const defaultLabel = 'Account ' + (i + 1)
const nickname = configManager.nicknameForWallet(address)
@@ -523,7 +523,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,
diff --git a/app/scripts/lib/inpage-provider.js b/app/scripts/lib/inpage-provider.js
index 71ac69ad1..30fcbcb66 100644
--- a/app/scripts/lib/inpage-provider.js
+++ b/app/scripts/lib/inpage-provider.js
@@ -40,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()
@@ -49,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) => {
@@ -66,20 +66,20 @@ 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('selectedAddress')
+ result = selectedAccount ? [selectedAccount] : []
break
case 'eth_coinbase':
// read from localStorage
- selectedAddress = self.publicConfigStore.get('selectedAddress')
- result = selectedAddress || '0x0000000000000000000000000000000000000000'
+ selectedAccount = self.publicConfigStore.get('selectedAddress')
+ result = selectedAccount || '0x0000000000000000000000000000000000000000'
break
case 'eth_uninstallFilter':
@@ -125,7 +125,7 @@ function remoteStoreWithLocalStorageCache (storageKey) {
return store
}
-function eachJsonMessage(payload, transformFn){
+function eachJsonMessage (payload, transformFn) {
if (Array.isArray(payload)) {
return payload.map(transformFn)
} else {
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/random-id.js b/app/scripts/lib/random-id.js
index 3c5ae5600..788f3370f 100644
--- a/app/scripts/lib/random-id.js
+++ b/app/scripts/lib/random-id.js
@@ -1,7 +1,7 @@
-const MAX = 1000000000
+const MAX = Number.MAX_SAFE_INTEGER
-let idCounter = Math.round( Math.random() * MAX )
-function createRandomId() {
+let idCounter = Math.round(Math.random() * MAX)
+function createRandomId () {
idCounter = idCounter % MAX
return idCounter++
}
diff --git a/app/scripts/lib/sig-util.js b/app/scripts/lib/sig-util.js
new file mode 100644
index 000000000..193dda381
--- /dev/null
+++ b/app/scripts/lib/sig-util.js
@@ -0,0 +1,28 @@
+const ethUtil = require('ethereumjs-util')
+
+module.exports = {
+
+ concatSig: function (v, r, s) {
+ const rSig = ethUtil.fromSigned(r)
+ const sSig = ethUtil.fromSigned(s)
+ const vSig = ethUtil.bufferToInt(v)
+ const rStr = padWithZeroes(ethUtil.toUnsigned(rSig).toString('hex'), 64)
+ const sStr = padWithZeroes(ethUtil.toUnsigned(sSig).toString('hex'), 64)
+ const vStr = ethUtil.stripHexPrefix(ethUtil.intToHex(vSig))
+ return ethUtil.addHexPrefix(rStr.concat(sStr, vStr)).toString('hex')
+ },
+
+ normalize: function (address) {
+ if (!address) return
+ return ethUtil.addHexPrefix(address.toLowerCase())
+ },
+
+}
+
+function padWithZeroes (number, length) {
+ var myString = '' + number
+ while (myString.length < length) {
+ myString = '0' + myString
+ }
+ return myString
+}
diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js
index 1477ce9e7..4b8fa4323 100644
--- a/app/scripts/metamask-controller.js
+++ b/app/scripts/metamask-controller.js
@@ -1,22 +1,27 @@
const extend = require('xtend')
const EthStore = require('eth-store')
const MetaMaskProvider = require('web3-provider-engine/zero.js')
-const IdentityStore = require('./lib/idStore')
+const KeyringController = require('./keyring-controller')
const NoticeController = require('./notice-controller')
const messageManager = require('./lib/message-manager')
const HostStore = require('./lib/remote-store.js').HostStore
const Web3 = require('web3')
const ConfigManager = require('./lib/config-manager')
const extension = require('./lib/extension')
+const autoFaucet = require('./lib/auto-faucet')
+const nodeify = require('./lib/nodeify')
+
module.exports = class MetamaskController {
constructor (opts) {
+ this.state = { network: 'loading' }
this.opts = opts
this.listeners = []
this.configManager = new ConfigManager(opts)
- this.idStore = new IdentityStore({
+ this.keyringController = new KeyringController({
configManager: this.configManager,
+ getNetwork: this.getStateNetwork.bind(this),
})
// notices
this.noticeController = new NoticeController({
@@ -27,7 +32,8 @@ module.exports = class MetamaskController {
// this.noticeController.startPolling()
this.provider = this.initializeProvider(opts)
this.ethStore = new EthStore(this.provider)
- this.idStore.setStore(this.ethStore)
+ this.keyringController.setStore(this.ethStore)
+ this.getNetwork()
this.messageManager = messageManager
this.publicConfigStore = this.initPublicConfigStore()
@@ -42,15 +48,16 @@ module.exports = class MetamaskController {
getState () {
return extend(
+ this.state,
this.ethStore.getState(),
- this.idStore.getState(),
this.configManager.getConfig(),
+ this.keyringController.getState(),
this.noticeController.getState()
)
}
getApi () {
- const idStore = this.idStore
+ const keyringController = this.keyringController
const noticeController = this.noticeController
return {
@@ -61,27 +68,29 @@ module.exports = class MetamaskController {
agreeToDisclaimer: this.agreeToDisclaimer.bind(this),
resetDisclaimer: this.resetDisclaimer.bind(this),
setCurrentFiat: this.setCurrentFiat.bind(this),
- agreeToEthWarning: this.agreeToEthWarning.bind(this),
setTOSHash: this.setTOSHash.bind(this),
checkTOSChange: this.checkTOSChange.bind(this),
setGasMultiplier: this.setGasMultiplier.bind(this),
- // forward directly to idStore
- createNewVault: idStore.createNewVault.bind(idStore),
- recoverFromSeed: idStore.recoverFromSeed.bind(idStore),
- submitPassword: idStore.submitPassword.bind(idStore),
- setSelectedAddress: idStore.setSelectedAddress.bind(idStore),
- approveTransaction: idStore.approveTransaction.bind(idStore),
- cancelTransaction: idStore.cancelTransaction.bind(idStore),
- signMessage: idStore.signMessage.bind(idStore),
- cancelMessage: idStore.cancelMessage.bind(idStore),
- setLocked: idStore.setLocked.bind(idStore),
- clearSeedWordCache: idStore.clearSeedWordCache.bind(idStore),
- exportAccount: idStore.exportAccount.bind(idStore),
- revealAccount: idStore.revealAccount.bind(idStore),
- saveAccountLabel: idStore.saveAccountLabel.bind(idStore),
- tryPassword: idStore.tryPassword.bind(idStore),
- recoverSeed: idStore.recoverSeed.bind(idStore),
+ // forward directly to 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: nodeify(keyringController.submitPassword).bind(keyringController),
+ 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: keyringController.approveTransaction.bind(keyringController),
+ cancelTransaction: keyringController.cancelTransaction.bind(keyringController),
+ signMessage: keyringController.signMessage.bind(keyringController),
+ cancelMessage: keyringController.cancelMessage.bind(keyringController),
+
// coinbase
buyEth: this.buyEth.bind(this),
// shapeshift
@@ -97,23 +106,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)
@@ -146,38 +138,38 @@ module.exports = class MetamaskController {
}
initializeProvider (opts) {
- const idStore = this.idStore
+ const keyringController = this.keyringController
var providerOpts = {
rpcUrl: this.configManager.getCurrentRpcAddress(),
// account mgmt
getAccounts: (cb) => {
- var selectedAddress = idStore.getSelectedAddress()
- 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) => {
- idStore.signTransaction(...args)
+ keyringController.signTransaction(...args)
this.sendUpdate()
},
// msg signing
approveMessage: this.newUnsignedMessage.bind(this),
signMessage: (...args) => {
- idStore.signMessage(...args)
+ keyringController.signMessage(...args)
this.sendUpdate()
},
}
var provider = MetaMaskProvider(providerOpts)
var web3 = new Web3(provider)
- idStore.web3 = web3
- idStore.getNetwork()
+ this.web3 = web3
+ keyringController.web3 = web3
provider.on('block', this.processBlock.bind(this))
- provider.on('error', idStore.getNetwork.bind(idStore))
+ provider.on('error', this.getNetwork.bind(this))
return provider
}
@@ -185,7 +177,7 @@ module.exports = class MetamaskController {
initPublicConfigStore () {
// get init state
var initPublicState = extend(
- idStoreToPublic(this.idStore.getState()),
+ keyringControllerToPublic(this.keyringController.getState()),
configToPublic(this.configManager.getConfig())
)
@@ -195,21 +187,27 @@ module.exports = class MetamaskController {
this.configManager.subscribe(function (state) {
storeSetFromObj(publicConfigStore, configToPublic(state))
})
- this.idStore.on('update', function (state) {
- storeSetFromObj(publicConfigStore, idStoreToPublic(state))
+ this.keyringController.on('update', () => {
+ const state = this.keyringController.getState()
+ storeSetFromObj(publicConfigStore, keyringControllerToPublic(state))
+ this.sendUpdate()
})
- // idStore substate
- function idStoreToPublic (state) {
+ this.keyringController.on('newAccount', (account) => {
+ autoFaucet(account)
+ })
+
+ // keyringController substate
+ function keyringControllerToPublic (state) {
return {
- selectedAddress: state.selectedAddress,
+ selectedAccount: state.selectedAccount,
}
}
// config substate
function configToPublic (state) {
return {
provider: state.provider,
- selectedAddress: state.selectedAccount,
+ selectedAccount: state.selectedAccount,
}
}
// dump obj into store
@@ -223,10 +221,10 @@ module.exports = class MetamaskController {
}
newUnsignedTransaction (txParams, onTxDoneCb) {
- const idStore = this.idStore
- let err = this.enforceTxValidations(txParams)
+ const keyringController = this.keyringController
+ const err = this.enforceTxValidations(txParams)
if (err) return onTxDoneCb(err)
- idStore.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => {
+ keyringController.addUnconfirmedTransaction(txParams, onTxDoneCb, (err, txData) => {
if (err) return onTxDoneCb(err)
this.sendUpdate()
this.opts.showUnconfirmedTx(txParams, txData, onTxDoneCb)
@@ -241,9 +239,9 @@ module.exports = class MetamaskController {
}
newUnsignedMessage (msgParams, cb) {
- var state = this.idStore.getState()
+ var state = this.keyringController.getState()
if (!state.isUnlocked) {
- this.idStore.addUnconfirmedMessage(msgParams, cb)
+ this.keyringController.addUnconfirmedMessage(msgParams, cb)
this.opts.unlockAccountMessage()
} else {
this.addUnconfirmedMessage(msgParams, cb)
@@ -252,8 +250,8 @@ module.exports = class MetamaskController {
}
addUnconfirmedMessage (msgParams, cb) {
- const idStore = this.idStore
- const msgId = idStore.addUnconfirmedMessage(msgParams, cb)
+ const keyringController = this.keyringController
+ const msgId = keyringController.addUnconfirmedMessage(msgParams, cb)
this.opts.showUnconfirmedMessage(msgParams, msgId)
}
@@ -272,8 +270,8 @@ module.exports = class MetamaskController {
verifyNetwork () {
// Check network when restoring connectivity:
- if (this.idStore._currentState.network === 'loading') {
- this.idStore.getNetwork()
+ if (this.state.network === 'loading') {
+ this.getNetwork()
}
}
@@ -298,14 +296,13 @@ module.exports = class MetamaskController {
} catch (err) {
console.error('Error in checking TOS change.')
}
-
}
// disclaimer
agreeToDisclaimer (cb) {
try {
- this.configManager.setConfirmed(true)
+ this.configManager.setConfirmedDisclaimer(true)
cb()
} catch (err) {
cb(err)
@@ -314,9 +311,9 @@ module.exports = class MetamaskController {
resetDisclaimer () {
try {
- this.configManager.setConfirmed(false)
- } catch (err) {
- console.error(err)
+ this.configManager.setConfirmedDisclaimer(false)
+ } catch (e) {
+ console.error(e)
}
}
@@ -345,26 +342,17 @@ module.exports = class MetamaskController {
}, 300000)
}
- agreeToEthWarning (cb) {
- try {
- this.configManager.setShouldntShowWarning()
- cb()
- } catch (err) {
- cb(err)
- }
- }
-
// called from popup
setRpcTarget (rpcTarget) {
this.configManager.setRpcTarget(rpcTarget)
extension.runtime.reload()
- this.idStore.getNetwork()
+ this.getNetwork()
}
setProviderType (type) {
this.configManager.setProviderType(type)
extension.runtime.reload()
- this.idStore.getNetwork()
+ this.getNetwork()
}
useEtherscanProvider () {
@@ -375,7 +363,7 @@ module.exports = class MetamaskController {
buyEth (address, amount) {
if (!amount) amount = '5'
- var network = this.idStore._currentState.network
+ 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 === '3') {
@@ -391,6 +379,25 @@ module.exports = class MetamaskController {
this.configManager.createShapeShiftTx(depositAddress, depositType)
}
+ getNetwork (err) {
+ if (err) {
+ this.state.network = 'loading'
+ this.sendUpdate()
+ }
+
+ this.web3.version.getNetwork((err, network) => {
+ if (err) {
+ this.state.network = 'loading'
+ return this.sendUpdate()
+ }
+ if (global.METAMASK_DEBUG) {
+ console.log('web3.getNetwork returned ' + network)
+ }
+ this.state.network = network
+ this.sendUpdate()
+ })
+ }
+
setGasMultiplier (gasMultiplier, cb) {
try {
this.configManager.setGasMultiplier(gasMultiplier)
@@ -399,4 +406,8 @@ module.exports = class MetamaskController {
cb(err)
}
}
+
+ getStateNetwork () {
+ return this.state.network
+ }
}
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/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.json b/development/states/accounts.json
index 9068be0bd..02c11cd98 100644
--- a/development/states/accounts.json
+++ b/development/states/accounts.json
@@ -2,7 +2,6 @@
"metamask": {
"isInitialized": true,
"isUnlocked": true,
- "isEthConfirmed": true,
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {
"0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80": {
@@ -90,9 +89,9 @@
}
},
"transactions": [],
- "selectedAddress": "0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80",
+ "selectedAccount": "0x0abdd95cafcabec9b3e99dcd09fc4b441037cb80",
"network": "2",
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
@@ -116,4 +115,4 @@
"scrollToBottom": true
},
"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 5ac8e9e58..79c2d667a 100644
--- a/development/states/custom-rpc.json
+++ b/development/states/custom-rpc.json
@@ -157,11 +157,10 @@
"estimatedGas": "0x5208"
}
],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "166",
"seedWords": null,
- "isConfirmed": true,
- "isEthConfirmed": 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/terms.json b/development/states/first-time.json
index 3a4914841..d6d95fe06 100644
--- a/development/states/terms.json
+++ b/development/states/first-time.json
@@ -2,18 +2,22 @@
"metamask": {
"isInitialized": false,
"isUnlocked": false,
- "currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {},
"unconfTxs": {},
+ "currentFiat": "USD",
+ "conversionRate": 11.47635827,
+ "conversionDate": 1477606503,
+ "network": null,
"accounts": {},
"transactions": [],
- "network": "2",
- "seedWords": null,
- "isConfirmed": false,
- "isEthConfirmed": false,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
+ "shapeShiftTxList": [],
+ "keyringTypes": [
+ "Simple Key Pair"
+ ],
"provider": {
"type": "testnet"
}
@@ -21,15 +25,15 @@
"appState": {
"menuOpen": false,
"currentView": {
- "name": "EthStoreWarning"
+ "name": "accounts",
+ "detailView": null
},
"accountDetail": {
"subview": "transactions"
},
- "currentDomain": "127.0.0.1:9966",
"transForward": true,
"isLoading": false,
"warning": null
},
"identities": {}
-} \ No newline at end of file
+}
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 d21a062c1..d1eab125a 100644
--- a/development/states/locked.json
+++ b/development/states/locked.json
@@ -2,7 +2,6 @@
"metamask": {
"isInitialized": true,
"isUnlocked": false,
- "isEthConfirmed": true,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {},
@@ -12,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/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/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 33f79b4c8..bc233a0ad 100644
--- a/development/states/pending-signature.json
+++ b/development/states/pending-signature.json
@@ -2,7 +2,6 @@
"metamask": {
"isInitialized": true,
"isUnlocked": true,
- "isEthConfirmed": true,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {
@@ -352,10 +351,10 @@
"hash": "0xb6e6ff57e7b5f6bd7f2e6dc44c39f4e858a227c9509586634ca547179345a13e"
}
],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1471904489432",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {
"1472076978535283": {
"id": 1472076978535283,
@@ -403,4 +402,4 @@
"warning": null
},
"identities": {}
-} \ No newline at end of file
+}
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 e1f157ddf..bde15d861 100644
--- a/development/states/restore-vault.json
+++ b/development/states/restore-vault.json
@@ -2,7 +2,6 @@
"metamask": {
"isInitialized": false,
"isUnlocked": false,
- "isEthConfirmed": false,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {},
@@ -13,7 +12,7 @@
"accounts": {},
"transactions": [],
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
@@ -36,4 +35,4 @@
"warning": null
},
"identities": {}
-} \ No newline at end of file
+}
diff --git a/development/states/send.json b/development/states/send.json
index afc1e6397..3e1aa88ba 100644
--- a/development/states/send.json
+++ b/development/states/send.json
@@ -2,7 +2,6 @@
"metamask": {
"isInitialized": true,
"isUnlocked": true,
- "isEthConfirmed": false,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {
@@ -49,7 +48,7 @@
"transactions": [],
"network": "2",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
@@ -73,4 +72,4 @@
"detailView": {}
},
"identities": {}
-} \ No newline at end of file
+}
diff --git a/development/states/shapeshift.json b/development/states/shapeshift.json
index a656fb00f..7004e83be 100644
--- a/development/states/shapeshift.json
+++ b/development/states/shapeshift.json
@@ -2,7 +2,6 @@
"metamask": {
"isInitialized": true,
"isUnlocked": true,
- "isEthConfirmed": true,
"currentDomain": "example.com",
"rpcTarget": "https://rawtestrpc.metamask.io/",
"identities": {
@@ -47,10 +46,10 @@
}
},
"transactions": [],
- "selectedAddress": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
+ "selectedAccount": "0xfdea65c8e26263f6d9a1b5de9555d2931a33b825",
"network": "1",
"seedWords": null,
- "isConfirmed": true,
+ "isDisclaimerConfirmed": true,
"unconfMsgs": {},
"messages": [],
"shapeShiftTxList": [],
@@ -345,4 +344,4 @@
"isSubLoading": false
},
"identities": {}
-} \ No newline at end of file
+}
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/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/docs/multi_vault_planning.md b/docs/multi_vault_planning.md
new file mode 100644
index 000000000..fdde2bc50
--- /dev/null
+++ b/docs/multi_vault_planning.md
@@ -0,0 +1,188 @@
+https://hackmd.io/JwIwDMDGKQZgtAFgKZjEgbARhPAhgKxZbwAcA7LAWOQCaKEgFA==?edit
+
+Subscribablez(initState)
+ .subscribe()
+ .emitUpdate(newState)
+ //.getState()
+
+
+var initState = fromDisk()
+ReduxStore(reducer, initState)
+.reduce(action) -> .emitUpdate()
+
+ReduxStore.subscribe(toDisk)
+
+
+### KeyChainManager / idStore 2.0 (maybe just in MetaMaskController)
+ keychains: []
+ getAllAccounts(cb)
+ getAllKeychainViewStates(cb) -> returns [ KeyChainViewState]
+
+#### Old idStore external methods, for feature parity:
+
+- init(configManager)
+- setStore(ethStore)
+- getState()
+- getSelectedAddres()
+- setSelectedAddress()
+- createNewVault()
+- recoverFromSeed()
+- submitPassword()
+- approveTransaction()
+- cancelTransaction()
+- addUnconfirmedMessage(msgParams, cb)
+- signMessage()
+- cancelMessage()
+- setLocked()
+- clearSeedWordCache()
+- exportAccount()
+- revealAccount()
+- saveAccountLabel()
+- tryPassword()
+- recoverSeed()
+- getNetwork()
+
+##### Of those methods
+
+Where they should end up:
+
+##### MetaMaskController
+
+- getNetwork()
+
+##### KeyChainManager
+
+- init(configManager)
+- setStore(ethStore)
+- getState() // Deprecate for unidirectional flow
+- on('update', cb)
+- createNewVault(password)
+- getSelectedAddres()
+- setSelectedAddress()
+- submitPassword()
+- tryPassword()
+- approveTransaction()
+- cancelTransaction()
+- signMessage()
+- cancelMessage()
+- setLocked()
+- exportAccount()
+
+##### Bip44 KeyChain
+
+- getState() // Deprecate for unidirectional flow
+- on('update', cb)
+
+If we adopt a ReactStore style unidirectional action dispatching data flow, these methods will be unified under a `dispatch` method, and rather than having a cb will emit an update to the UI:
+
+- createNewKeyChain(entropy)
+- recoverFromSeed()
+- approveTransaction()
+- signMessage()
+- clearSeedWordCache()
+- exportAccount()
+- revealAccount()
+- saveAccountLabel()
+- recoverSeed()
+
+Additional methods, new to this:
+- serialize()
+ - Returns pojo with optional `secret` key whose contents will be encrypted with the users' password and salt when written to disk.
+ - The isolation of secrets is to preserve performance when decrypting user data.
+- deserialize(pojo)
+
+### KeyChain (ReduxStore?)
+ // attributes
+ @name
+
+ signTx(txParams, cb)
+ signMsg(msg, cb)
+
+ getAddressList(cb)
+
+ getViewState(cb) -> returns KeyChainViewState
+
+ serialize(cb) -> obj
+ deserialize(obj)
+
+ dispatch({ type: <str>, value: <pojo> })
+
+
+### KeyChainViewState
+ // The serialized, renderable keychain data
+ accountList: [],
+ typeName: 'uPort',
+ iconAddress: 'uport.gif',
+ internal: {} // Subclass-defined metadata
+
+### KeyChainReactComponent
+ // takes a KeyChainViewState
+
+ // Subclasses of this:
+ - KeyChainListItemComponent
+ - KeyChainInitComponent - Maybe part of the List Item
+ - KeyChainAccountHeaderComponent
+ - KeyChainConfirmationComponent
+ // Account list item, tx confirmation extra data (like a QR code),
+ // Maybe an options screen, init screen,
+
+ how to send actions?
+ emitAction(keychains.<id>.didInit)
+
+
+gimmeRemoteKeychain((err, remoteKeychain)=>
+
+)
+
+
+
+
+
+KeyChainReactComponent({
+ keychain
+})
+
+Keychain:
+ methods:{},
+ cachedAccountList: [],
+ name: '',
+
+
+CoinbaseKeychain
+ getAccountList
+
+
+CoinbaseKeychainComponent
+ isLoading = true
+ keychain.getAccountList(()=>{
+ isLoading=false
+ accountList=accounts
+ })
+
+
+
+
+
+KeyChainViewState {
+ attributes: {
+ //mandatory:
+ accountList: [],
+ typeName: 'uPort',
+ iconAddress: 'uport.gif',
+
+ internal: {
+ // keychain-specific metadata
+ proxyAddresses: {
+ 0xReal: '0xProxy'
+ }
+ },
+ },
+ methods: {
+ // arbitrary, internal
+ }
+}
+
+## A note on the security of arbitrary action dispatchers
+
+Since keychains will be dispatching actions that are then passed through the background process to be routed, we should not trust or require them to include their own keychain ID as a prefix to their action, but we should tack it on ourselves, so that no action dispatched by a KeyChainComponent ever reaches any KeyChain other than its own.
+
diff --git a/mock-dev.js b/mock-dev.js
index 99b846e51..84f2d234a 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)
@@ -107,7 +107,7 @@ function getOldStyleData () {
return result
}
-actions._setAccountManager(controller.getApi())
+actions._setBackgroundConnection(controller.getApi())
actions.update = function(stateName) {
selectedView = stateName
updateQueryParams(stateName)
diff --git a/package.json b/package.json
index 2b3b821db..46d17a94c 100644
--- a/package.json
+++ b/package.json
@@ -4,19 +4,20 @@
"public": false,
"private": true,
"scripts": {
- "start": "gulp dev",
+ "start": "npm run dev",
"lint": "gulp lint",
- "dev": "gulp dev",
+ "buildCiUnits": "node test/integration/index.js",
+ "dev": "gulp dev --debug",
"dist": "gulp dist --disableLiveReload",
"test": "npm run fastTest && npm run ci && npm run lint",
- "fastTest": "mocha --require test/helper.js --compilers js:babel-register --recursive \"test/unit/**/*.js\"",
+ "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\"",
"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": "npm run genStates && browserify ./mock-dev.js -o ./development/bundle.js",
"testem": "npm run buildMock && testem",
- "ci": "npm run buildMock && testem ci -P 2",
+ "ci": "npm run buildMock && npm run buildCiUnits && testem ci -P 2",
"announce": "node development/announcer.js",
"generateNotice": "node development/notice-generator.js"
},
@@ -35,6 +36,7 @@
},
"dependencies": {
"async": "^1.5.2",
+ "bip39": "^2.2.0",
"browserify-derequire": "^0.9.4",
"clone": "^1.0.2",
"copy-to-clipboard": "^2.0.0",
@@ -48,6 +50,7 @@
"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",
@@ -57,7 +60,7 @@
"iframe": "^1.0.0",
"iframe-stream": "^1.0.2",
"inject-css": "^0.1.1",
- "jazzicon": "1.1.5",
+ "jazzicon": "^1.2.0",
"menu-droppo": "^1.1.0",
"metamask-logo": "^2.1.2",
"mississippi": "^1.2.0",
@@ -67,6 +70,7 @@
"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",
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 6de40b046..8a54cb829 100644
--- a/test/integration/index.html
+++ b/test/integration/index.html
@@ -12,10 +12,10 @@
<script src="https://code.jquery.com/qunit/qunit-2.0.0.js"></script>
<script src="./jquery-3.1.0.min.js"></script>
<script src="helpers.js"></script>
- <script src="tests.js"></script>
+ <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/index.js b/test/integration/index.js
new file mode 100644
index 000000000..ff6d1baf8
--- /dev/null
+++ b/test/integration/index.js
@@ -0,0 +1,21 @@
+var fs = require('fs')
+var path = require('path')
+var browserify = require('browserify');
+var tests = fs.readdirSync(path.join(__dirname, 'lib'))
+var bundlePath = path.join(__dirname, 'bundle.js')
+
+var b = browserify();
+
+// Remove old bundle
+try {
+ fs.unlinkSync(bundlePath)
+} catch (e) {}
+
+var writeStream = fs.createWriteStream(bundlePath)
+
+tests.forEach(function(fileName) {
+ b.add(path.join(__dirname, 'lib', fileName))
+})
+
+b.bundle().pipe(writeStream);
+
diff --git a/test/integration/lib/encryptor-test.js b/test/integration/lib/encryptor-test.js
new file mode 100644
index 000000000..897d22740
--- /dev/null
+++ b/test/integration/lib/encryptor-test.js
@@ -0,0 +1,71 @@
+var encryptor = require('../../../app/scripts/lib/encryptor')
+
+QUnit.module('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
new file mode 100644
index 000000000..12c573db1
--- /dev/null
+++ b/test/integration/lib/first-time.js
@@ -0,0 +1,90 @@
+const PASSWORD = 'password123'
+
+QUnit.module('first time usage')
+
+QUnit.test('agree to terms', function (assert) {
+ var done = assert.async()
+ let app
+
+ wait().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 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(1500)
+ }).then(function() {
+
+ var detail = app.find('.account-detail-section')[0]
+ assert.ok(detail, 'Account detail section loaded again.')
+
+ done()
+ })
+})
diff --git a/test/integration/lib/keyring-controller-test.js b/test/integration/lib/keyring-controller-test.js
new file mode 100644
index 000000000..ae5ecc578
--- /dev/null
+++ b/test/integration/lib/keyring-controller-test.js
@@ -0,0 +1,62 @@
+var KeyringController = require('../../../app/scripts/keyring-controller')
+var ConfigManager = require('../../../app/scripts/lib/config-manager')
+
+var oldStyleVault = require('../mocks/oldVault.json')
+
+var STORAGE_KEY = 'metamask-config'
+var PASSWORD = '12345678'
+var FIRST_ADDRESS = '0x4dd5d356c5A016A220bCD69e82e5AF680a430d00'.toLowerCase()
+
+
+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.keyringController = new KeyringController({
+ configManager: this.configManager,
+ getNetwork: () => { return '2' },
+ })
+
+ this.ethStore = {
+ addAccount: () => {},
+ removeAccount: () => {},
+ }
+
+ this.keyringController.setStore(this.ethStore)
+ }
+})
+
+QUnit.test('keyringController:isInitialized', function (assert) {
+ assert.ok(this.keyringController.getState().isInitialized)
+})
+
+QUnit.test('keyringController:submitPassword', function (assert) {
+ var done = assert.async()
+
+ this.keyringController.submitPassword(PASSWORD)
+ .then((state) => {
+ assert.ok(state.identities[FIRST_ADDRESS])
+ done()
+ })
+})
+
+QUnit.test('keyringController:setLocked', function (assert) {
+ var done = assert.async()
+ var self = this
+
+ this.keyringController.setLocked()
+ .then(function() {
+ assert.notOk(self.keyringController.password, 'password should be deallocated')
+ assert.deepEqual(self.keyringController.keyrings, [], 'keyrings should be deallocated')
+ done()
+ })
+ .catch((reason) => {
+ assert.ifError(reason)
+ done()
+ })
+})
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/integration/tests.js b/test/integration/tests.js
deleted file mode 100644
index 92111b05b..000000000
--- a/test/integration/tests.js
+++ /dev/null
@@ -1,24 +0,0 @@
-QUnit.test('agree to terms', function (assert) {
- var done = assert.async()
-
- // 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() {
- 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, 2, 'two buttons: create and restore')
-
- done()
- })
-
- // Wait for view to transition:
-})
diff --git a/test/lib/mock-config-manager.js b/test/lib/mock-config-manager.js
index fe841f455..ccd518c68 100644
--- a/test/lib/mock-config-manager.js
+++ b/test/lib/mock-config-manager.js
@@ -1,5 +1,5 @@
var ConfigManager = require('../../app/scripts/lib/config-manager')
-const STORAGE_KEY = 'metamask-persistance-key'
+const STORAGE_KEY = 'metamask-config'
const extend = require('xtend')
module.exports = function() {
diff --git a/test/lib/mock-encryptor.js b/test/lib/mock-encryptor.js
new file mode 100644
index 000000000..09bbf7ad5
--- /dev/null
+++ b/test/lib/mock-encryptor.js
@@ -0,0 +1,32 @@
+var mockHex = '0xabcdef0123456789'
+var mockKey = new Buffer(32)
+let cacheVal
+
+module.exports = {
+
+ encrypt(password, dataObj) {
+ cacheVal = dataObj
+ return Promise.resolve(mockHex)
+ },
+
+ decrypt(password, text) {
+ return Promise.resolve(cacheVal || {})
+ },
+
+ encryptWithKey(key, dataObj) {
+ return this.encrypt(key, dataObj)
+ },
+
+ decryptWithKey(key, text) {
+ return this.decrypt(key, text)
+ },
+
+ keyFromPassword(password) {
+ return Promise.resolve(mockKey)
+ },
+
+ generateSalt() {
+ return 'WHADDASALT!'
+ },
+
+}
diff --git a/test/lib/mock-simple-keychain.js b/test/lib/mock-simple-keychain.js
new file mode 100644
index 000000000..615b3e537
--- /dev/null
+++ b/test/lib/mock-simple-keychain.js
@@ -0,0 +1,38 @@
+var fakeWallet = {
+ privKey: '0x123456788890abcdef',
+ address: '0xfedcba0987654321',
+}
+const type = 'Simple Key Pair'
+
+module.exports = class MockSimpleKeychain {
+
+ static type() { return type }
+
+ constructor(opts) {
+ this.type = type
+ this.opts = opts || {}
+ this.wallets = []
+ }
+
+ serialize() {
+ return [ fakeWallet.privKey ]
+ }
+
+ deserialize(data) {
+ if (!Array.isArray(data)) {
+ throw new Error('Simple keychain deserialize requires a privKey array.')
+ }
+ this.wallets = [ fakeWallet ]
+ }
+
+ addAccounts(n = 1) {
+ for(var i = 0; i < n; i++) {
+ this.wallets.push(fakeWallet)
+ }
+ }
+
+ getAccounts() {
+ return this.wallets.map(w => w.address)
+ }
+
+}
diff --git a/test/unit/actions/restore_vault_test.js b/test/unit/actions/restore_vault_test.js
deleted file mode 100644
index 609f5429e..000000000
--- a/test/unit/actions/restore_vault_test.js
+++ /dev/null
@@ -1,60 +0,0 @@
-var jsdom = require('mocha-jsdom')
-var assert = require('assert')
-var freeze = require('deep-freeze-strict')
-var path = require('path')
-var sinon = require('sinon')
-
-var actions = require(path.join(__dirname, '..', '..', '..', 'ui', 'app', 'actions.js'))
-var reducers = require(path.join(__dirname, '..', '..', '..', 'ui', 'app', 'reducers.js'))
-
-describe('#recoverFromSeed(password, seed)', function() {
-
- beforeEach(function() {
- // sinon allows stubbing methods that are easily verified
- this.sinon = sinon.sandbox.create()
- })
-
- afterEach(function() {
- // sinon requires cleanup otherwise it will overwrite context
- this.sinon.restore()
- })
-
- // stub out account manager
- actions._setAccountManager({
- recoverFromSeed(pw, seed, cb) {
- cb(null, {
- identities: {
- foo: 'bar'
- }
- })
- },
- })
-
- it('sets metamask.isUnlocked to true', function() {
- var initialState = {
- metamask: {
- isUnlocked: false,
- isInitialized: false,
- }
- }
- freeze(initialState)
-
- const restorePhrase = 'invite heavy among daring outdoor dice jelly coil stable note seat vicious'
- const password = 'foo'
- const dispatchFunc = actions.recoverFromSeed(password, restorePhrase)
-
- var dispatchStub = this.sinon.stub()
- dispatchStub.withArgs({ TYPE: actions.unlockMetamask() }).onCall(0)
- dispatchStub.withArgs({ TYPE: actions.showAccountsPage() }).onCall(1)
-
- var action
- var resultingState = initialState
- dispatchFunc((newAction) => {
- action = newAction
- resultingState = reducers(resultingState, action)
- })
-
- assert.equal(resultingState.metamask.isUnlocked, true, 'was unlocked')
- assert.equal(resultingState.metamask.isInitialized, true, 'was initialized')
- });
-});
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/actions/tx_test.js b/test/unit/actions/tx_test.js
index c08a8aa26..1f06b1120 100644
--- a/test/unit/actions/tx_test.js
+++ b/test/unit/actions/tx_test.js
@@ -46,7 +46,7 @@ describe('tx confirmation screen', function() {
describe('cancelTx', function() {
before(function(done) {
- actions._setAccountManager({
+ actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb('An error!') },
cancelTransaction(txId) { /* noop */ },
clearSeedWordCache(cb) { cb() },
@@ -75,7 +75,7 @@ describe('tx confirmation screen', function() {
before(function(done) {
alert = () => {/* noop */}
- actions._setAccountManager({
+ actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb({message: 'An error!'}) },
})
@@ -96,7 +96,7 @@ describe('tx confirmation screen', function() {
describe('when there is success', function() {
it('should complete tx and go home', function() {
- actions._setAccountManager({
+ actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb() },
})
@@ -135,7 +135,7 @@ describe('tx confirmation screen', function() {
}
freeze(initialState)
- actions._setAccountManager({
+ actions._setBackgroundConnection({
approveTransaction(txId, cb) { cb() },
})
diff --git a/test/unit/config-manager-test.js b/test/unit/config-manager-test.js
index 26aa35a74..477188b67 100644
--- a/test/unit/config-manager-test.js
+++ b/test/unit/config-manager-test.js
@@ -100,31 +100,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 +153,7 @@ describe('config-manager', function() {
rpcTarget: 'foobar'
},
}
- configManager.setConfirmed(true)
+ configManager.setConfirmedDisclaimer(true)
configManager.setConfig(testConfig)
var testWallet = {
@@ -164,7 +164,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 +173,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)
})
})
diff --git a/test/unit/idStore-migration-test.js b/test/unit/idStore-migration-test.js
new file mode 100644
index 000000000..ac8e23d22
--- /dev/null
+++ b/test/unit/idStore-migration-test.js
@@ -0,0 +1,160 @@
+const async = require('async')
+const assert = require('assert')
+const ethUtil = require('ethereumjs-util')
+const BN = ethUtil.BN
+const ConfigManager = require('../../app/scripts/lib/config-manager')
+const delegateCallCode = require('../lib/example-code.json').delegateCallCode
+
+// The old way:
+const IdentityStore = require('../../app/scripts/lib/idStore')
+const STORAGE_KEY = 'metamask-config'
+const extend = require('xtend')
+
+// The new ways:
+var KeyringController = require('../../app/scripts/keyring-controller')
+const mockEncryptor = require('../lib/mock-encryptor')
+const MockSimpleKeychain = require('../lib/mock-simple-keychain')
+const sinon = require('sinon')
+
+const mockVault = {
+ seed: 'picnic injury awful upper eagle junk alert toss flower renew silly vague',
+ account: '0x5d8de92c205279c10e5669f797b853ccef4f739a',
+}
+
+describe('IdentityStore to KeyringController migration', function() {
+
+ // The stars of the show:
+ let idStore, keyringController, seedWords, configManager
+
+ let password = 'password123'
+ let entropy = 'entripppppyy duuude'
+ let accounts = []
+ let newAccounts = []
+ let originalKeystore
+
+ // This is a lot of setup, I know!
+ // We have to create an old style vault, populate it,
+ // and THEN create a new one, before we can run tests on it.
+ beforeEach(function(done) {
+ this.sinon = sinon.sandbox.create()
+ window.localStorage = {} // Hacking localStorage support into JSDom
+ configManager = new ConfigManager({
+ loadData,
+ setData: (d) => { window.localStorage = d }
+ })
+
+
+ idStore = new IdentityStore({
+ configManager: configManager,
+ ethStore: {
+ addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
+ del(acct) { delete accounts[acct] },
+ },
+ })
+
+ idStore._createVault(password, mockVault.seed, (err) => {
+ assert.ifError(err, 'createNewVault threw error')
+ originalKeystore = idStore._idmgmt.keyStore
+
+ idStore.setLocked((err) => {
+ assert.ifError(err, 'createNewVault threw error')
+ keyringController = new KeyringController({
+ configManager,
+ ethStore: {
+ addAccount(acct) { newAccounts.push(ethUtil.addHexPrefix(acct)) },
+ del(acct) { delete newAccounts[acct] },
+ },
+ })
+
+ // Stub out the browser crypto for a mock encryptor.
+ // Browser crypto is tested in the integration test suite.
+ keyringController.encryptor = mockEncryptor
+ done()
+ })
+ })
+ })
+
+ describe('entering a password', function() {
+ it('should identify an old wallet as an initialized keyring', function() {
+ 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')
+ done()
+ })
+ })
+ */
+
+ })
+})
+
+function loadData () {
+ var oldData = getOldStyleData()
+ var newData
+ try {
+ newData = JSON.parse(window.localStorage[STORAGE_KEY])
+ } catch (e) {}
+
+ var data = extend({
+ meta: {
+ version: 0,
+ },
+ data: {
+ config: {
+ provider: {
+ type: 'testnet',
+ },
+ },
+ },
+ }, oldData || null, newData || null)
+ return data
+}
+
+function setData (data) {
+ window.localStorage[STORAGE_KEY] = JSON.stringify(data)
+}
+
+function getOldStyleData () {
+ var config, wallet, seedWords
+
+ var result = {
+ meta: { version: 0 },
+ data: {},
+ }
+
+ try {
+ config = JSON.parse(window.localStorage['config'])
+ result.data.config = config
+ } catch (e) {}
+ try {
+ wallet = JSON.parse(window.localStorage['lightwallet'])
+ result.data.wallet = wallet
+ } catch (e) {}
+ try {
+ seedWords = window.localStorage['seedWords']
+ result.data.seedWords = seedWords
+ } catch (e) {}
+
+ return result
+}
diff --git a/test/unit/idStore-test.js b/test/unit/idStore-test.js
index bf8270540..3ca89cd38 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
diff --git a/test/unit/keyring-controller-test.js b/test/unit/keyring-controller-test.js
new file mode 100644
index 000000000..69a57ef52
--- /dev/null
+++ b/test/unit/keyring-controller-test.js
@@ -0,0 +1,200 @@
+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')
+const sinon = require('sinon')
+
+describe('KeyringController', function() {
+
+ let keyringController, state
+ let password = 'password123'
+ let seedWords = 'puzzle seed penalty soldier say clay field arctic metal hen cage runway'
+ let addresses = ['eF35cA8EbB9669A35c31b5F6f249A9941a812AC1'.toLowerCase()]
+ let accounts = []
+ let originalKeystore
+
+ beforeEach(function(done) {
+ this.sinon = sinon.sandbox.create()
+ window.localStorage = {} // Hacking localStorage support into JSDom
+
+ keyringController = new KeyringController({
+ configManager: configManagerGen(),
+ ethStore: {
+ addAccount(acct) { accounts.push(ethUtil.addHexPrefix(acct)) },
+ },
+ })
+
+ // Stub out the browser crypto for a mock encryptor.
+ // Browser crypto is tested in the integration test suite.
+ keyringController.encryptor = mockEncryptor
+
+ keyringController.createNewVaultAndKeychain(password)
+ .then(function (newState) {
+ state = newState
+ done()
+ })
+ })
+
+ afterEach(function() {
+ // Cleanup mocks
+ this.sinon.restore()
+ })
+
+ describe('#createNewVaultAndKeychain', function () {
+ this.timeout(10000)
+
+ it('should set a vault on the configManager', function(done) {
+ keyringController.configManager.setVault(null)
+ assert(!keyringController.configManager.getVault(), 'no previous vault')
+ 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(done) {
+ const mockSerialized = {
+ type: 'HD Key Tree',
+ data: {
+ mnemonic: seedWords,
+ numberOfAccounts: 1,
+ }
+ }
+ const mock = this.sinon.mock(keyringController)
+
+ mock.expects('getBalanceAndNickname')
+ .exactly(1)
+
+ 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()
+ })
+ })
+ })
+
+ describe('#migrateOldVaultIfAny', function() {
+ it('should return and init a new vault', function(done) {
+ keyringController.migrateOldVaultIfAny(password)
+ .then(() => {
+ assert(keyringController.configManager.getVault(), 'now has a vault')
+ assert(keyringController.password, 'has a password set')
+ done()
+ })
+ .catch((reason) => {
+ assert.ifError(reason)
+ done()
+ })
+ })
+ })
+
+ describe('#createNickname', function() {
+ it('should add the address to the identities hash', function() {
+ const fakeAddress = '0x12345678'
+ keyringController.createNickname(fakeAddress)
+ const identities = keyringController.identities
+ const identity = identities[fakeAddress]
+ assert.equal(identity.address, fakeAddress)
+
+ const nick = keyringController.configManager.nicknameForWallet(fakeAddress)
+ assert.equal(typeof nick, 'string')
+ })
+ })
+
+ describe('#saveAccountLabel', function() {
+ it ('sets the nickname', function(done) {
+ const account = addresses[0]
+ var nick = 'Test nickname'
+ 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)
+ it('retrieves the persisted nickname', function(done) {
+ const account = addresses[0]
+ var nick = 'Test nickname'
+ keyringController.configManager.setNicknameForWallet(account, nick)
+ keyringController.createNewVaultAndRestore(password, seedWords)
+ .then((state) => {
+
+ const identity = keyringController.identities['0x' + account]
+ assert.equal(identity.name, nick)
+
+ 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 Promise.resolve([1,2,3]) } },
+ { getAccounts() { return Promise.resolve([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
new file mode 100644
index 000000000..dfc0ec908
--- /dev/null
+++ b/test/unit/keyrings/hd-test.js
@@ -0,0 +1,127 @@
+const assert = require('assert')
+const extend = require('xtend')
+const HdKeyring = require('../../../app/scripts/keyrings/hd')
+
+// Sample account:
+const privKeyHex = 'b8a9c05beeedb25df85f8d641538cbffedf67216048de9c678ee26260eb91952'
+
+const sampleMnemonic = 'finish oppose decorate face calm tragic certain desk hour urge dinosaur mango'
+const firstAcct = '1c96099350f13d558464ec79b9be4445aa0ef579'
+const secondAcct = '1b00aed43a693f3a957f9feb5cc08afa031e37a0'
+
+describe('hd-keyring', function() {
+
+ let keyring
+ beforeEach(function() {
+ keyring = new HdKeyring()
+ })
+
+ describe('constructor', function(done) {
+ keyring = new HdKeyring({
+ mnemonic: sampleMnemonic,
+ numberOfAccounts: 2,
+ })
+
+ const accounts = keyring.getAccounts()
+ .then((accounts) => {
+ assert.equal(accounts[0], firstAcct)
+ assert.equal(accounts[1], secondAcct)
+ done()
+ })
+ })
+
+ describe('Keyring.type', function() {
+ it('is a class property that returns the type string.', function() {
+ const type = HdKeyring.type
+ assert.equal(typeof type, 'string')
+ })
+ })
+
+ describe('#type', function() {
+ it('returns the correct value', function() {
+ const type = keyring.type
+ const correct = HdKeyring.type
+ assert.equal(type, correct)
+ })
+ })
+
+ describe('#serialize empty wallets.', function() {
+ it('serializes a new mnemonic', function() {
+ 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(done) {
+ keyring.deserialize({
+ mnemonic: sampleMnemonic,
+ 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()
+ })
+ })
+ })
+
+ describe('#addAccounts', function() {
+ describe('with no arguments', function() {
+ it('creates a single wallet', function(done) {
+ keyring.addAccounts()
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1)
+ done()
+ })
+ })
+ })
+
+ describe('with a numeric argument', function() {
+ it('creates that number of wallets', function(done) {
+ keyring.addAccounts(3)
+ .then(() => {
+ assert.equal(keyring.wallets.length, 3)
+ done()
+ })
+ })
+ })
+ })
+
+ describe('#getAccounts', function() {
+ it('calls getAddress on each wallet', function(done) {
+
+ // Push a mock wallet
+ const desiredOutput = 'foo'
+ keyring.wallets.push({
+ getAddress() {
+ return {
+ toString() {
+ return desiredOutput
+ }
+ }
+ }
+ })
+
+ const output = keyring.getAccounts()
+ .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
new file mode 100644
index 000000000..979abdb69
--- /dev/null
+++ b/test/unit/keyrings/simple-test.js
@@ -0,0 +1,94 @@
+const assert = require('assert')
+const extend = require('xtend')
+const SimpleKeyring = require('../../../app/scripts/keyrings/simple')
+const TYPE_STR = 'Simple Key Pair'
+
+// Sample account:
+const privKeyHex = 'b8a9c05beeedb25df85f8d641538cbffedf67216048de9c678ee26260eb91952'
+
+describe('simple-keyring', function() {
+
+ let keyring
+ beforeEach(function() {
+ keyring = new SimpleKeyring()
+ })
+
+ describe('Keyring.type', function() {
+ it('is a class property that returns the type string.', function() {
+ const type = SimpleKeyring.type
+ assert.equal(type, TYPE_STR)
+ })
+ })
+
+ describe('#type', function() {
+ it('returns the correct value', function() {
+ const type = keyring.type
+ assert.equal(type, TYPE_STR)
+ })
+ })
+
+ describe('#serialize empty wallets.', function() {
+ 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])
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1, 'has one wallet')
+ const serialized = keyring.serialize()
+ assert.equal(serialized[0], privKeyHex)
+ })
+ })
+ })
+
+ describe('#addAccounts', function() {
+ describe('with no arguments', function() {
+ it('creates a single wallet', function() {
+ keyring.addAccounts()
+ .then(() => {
+ assert.equal(keyring.wallets.length, 1)
+ })
+ })
+ })
+
+ describe('with a numeric argument', function() {
+ it('creates that number of wallets', function() {
+ keyring.addAccounts(3)
+ .then(() => {
+ assert.equal(keyring.wallets.length, 3)
+ })
+ })
+ })
+ })
+
+ describe('#getAccounts', function() {
+ it('calls getAddress on each wallet', function(done) {
+
+ // Push a mock wallet
+ const desiredOutput = 'foo'
+ keyring.wallets.push({
+ getAddress() {
+ return {
+ toString() {
+ return desiredOutput
+ }
+ }
+ }
+ })
+
+ keyring.getAccounts()
+ .then((output) => {
+ assert.equal(output[0], desiredOutput)
+ assert.equal(output.length, 1)
+ done()
+ })
+ })
+ })
+})
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/testem.yml b/testem.yml
index 7923a2929..2cf40f7f4 100644
--- a/testem.yml
+++ b/testem.yml
@@ -6,4 +6,5 @@ launch_in_ci:
- Firefox
framework:
- qunit
+before_tests: "npm run buildCiUnits"
test_page: "test/integration/index.html"
diff --git a/ui-dev.js b/ui-dev.js
index bfc84d415..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)
@@ -41,7 +41,7 @@ function updateQueryParams(newView) {
}
const actions = {
- _setAccountManager(){},
+ _setBackgroundConnection(){},
update: function(stateName) {
selectedView = stateName
updateQueryParams(stateName)
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index 01c7e8781..c41ba61fd 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -30,7 +30,6 @@ function mapStateToProps (state) {
network: state.metamask.network,
unconfTxs: valuesFor(state.metamask.unconfTxs),
unconfMsgs: valuesFor(state.metamask.unconfMsgs),
- isEthWarningConfirmed: state.metamask.isEthConfirmed,
shapeShiftTxList: state.metamask.shapeShiftTxList,
}
}
diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js
index 4e0d69ed7..ef7b749e4 100644
--- a/ui/app/accounts/account-list-item.js
+++ b/ui/app/accounts/account-list-item.js
@@ -16,7 +16,7 @@ function AccountListItem () {
AccountListItem.prototype.render = function () {
const identity = this.props.identity
- var isSelected = this.props.selectedAddress === identity.address
+ var isSelected = this.props.selectedAccount === identity.address
var account = this.props.accounts[identity.address]
const selectedClass = isSelected ? '.selected' : ''
diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js
index 7551c498e..fcb3a7b0f 100644
--- a/ui/app/accounts/index.js
+++ b/ui/app/accounts/index.js
@@ -19,7 +19,7 @@ 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,
}
@@ -34,11 +34,7 @@ AccountsScreen.prototype.render = function () {
var state = this.props
var identityList = valuesFor(state.identities)
var unconfTxList = valuesFor(state.unconfTxs)
- var actions = {
- onSelect: this.onSelect.bind(this),
- onShowDetail: this.onShowDetail.bind(this),
- goHome: this.goHome.bind(this),
- }
+
return (
h('.accounts-section.flex-grow', [
@@ -46,7 +42,7 @@ AccountsScreen.prototype.render = function () {
// subtitle and nav
h('.section-title.flex-center', [
h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: actions.goHome,
+ onClick: this.goHome.bind(this),
}),
h('h2.page-subtitle', 'Select Account'),
]),
@@ -76,7 +72,7 @@ AccountsScreen.prototype.render = function () {
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,
@@ -87,7 +83,7 @@ AccountsScreen.prototype.render = function () {
h('div.footer.hover-white.pointer', {
key: 'reveal-account-bar',
onClick: () => {
- this.onRevealAccount()
+ this.addNewAccount()
},
style: {
display: 'flex',
@@ -137,8 +133,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) {
@@ -146,8 +142,8 @@ AccountsScreen.prototype.onShowDetail = function (address, event) {
this.props.dispatch(actions.showAccountDetail(address))
}
-AccountsScreen.prototype.onRevealAccount = function () {
- this.props.dispatch(actions.revealAccount())
+AccountsScreen.prototype.addNewAccount = function () {
+ this.props.dispatch(actions.addNewAccount(0))
}
AccountsScreen.prototype.goHome = function () {
diff --git a/ui/app/actions.js b/ui/app/actions.js
index 07df5ada2..58600dd34 100644
--- a/ui/app/actions.js
+++ b/ui/app/actions.js
@@ -1,9 +1,15 @@
var actions = {
+ _setBackgroundConnection: _setBackgroundConnection,
+
GO_HOME: 'GO_HOME',
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,
@@ -23,17 +29,16 @@ var actions = {
SHOW_INIT_MENU: 'SHOW_INIT_MENU',
SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED',
SHOW_INFO_PAGE: 'SHOW_INFO_PAGE',
- RECOVER_FROM_SEED: 'RECOVER_FROM_SEED',
- CLEAR_SEED_WORD_CACHE: 'CLEAR_SEED_WORD_CACHE',
- clearSeedWordCache: clearSeedWordCache,
- recoverFromSeed: recoverFromSeed,
unlockMetamask: unlockMetamask,
unlockFailed: unlockFailed,
showCreateVault: showCreateVault,
showRestoreVault: showRestoreVault,
showInitializeMenu: showInitializeMenu,
- createNewVault: createNewVault,
+ createNewVaultAndKeychain: createNewVaultAndKeychain,
+ createNewVaultAndRestore: createNewVaultAndRestore,
createNewVaultInProgress: createNewVaultInProgress,
+ addNewKeyring,
+ addNewAccount,
showNewVaultSeed: showNewVaultSeed,
showInfoPage: showInfoPage,
// seed recovery actions
@@ -59,8 +64,6 @@ var actions = {
SHOW_ACCOUNTS_PAGE: 'SHOW_ACCOUNTS_PAGE',
SHOW_CONF_TX_PAGE: 'SHOW_CONF_TX_PAGE',
SHOW_CONF_MSG_PAGE: 'SHOW_CONF_MSG_PAGE',
- REVEAL_ACCOUNT: 'REVEAL_ACCOUNT',
- revealAccount: revealAccount,
SET_CURRENT_FIAT: 'SET_CURRENT_FIAT',
setCurrentFiat: setCurrentFiat,
// account detail screen
@@ -74,16 +77,12 @@ var actions = {
showPrivateKey: showPrivateKey,
SAVE_ACCOUNT_LABEL: 'SAVE_ACCOUNT_LABEL',
saveAccountLabel: saveAccountLabel,
- AGREE_TO_ETH_WARNING: 'AGREE_TO_ETH_WARNING',
- agreeToEthWarning: agreeToEthWarning,
- SHOW_ETH_WARNING: 'SHOW_ETH_WARNING',
- showEthWarning: showEthWarning,
// tx conf screen
COMPLETED_TX: 'COMPLETED_TX',
TRANSACTION_ERROR: 'TRANSACTION_ERROR',
NEXT_TX: 'NEXT_TX',
PREVIOUS_TX: 'PREV_TX',
- setSelectedAddress: setSelectedAddress,
+ setSelectedAccount: setSelectedAccount,
signMsg: signMsg,
cancelMsg: cancelMsg,
sendTx: sendTx,
@@ -96,12 +95,12 @@ var actions = {
viewPendingTx: viewPendingTx,
VIEW_PENDING_TX: 'VIEW_PENDING_TX',
// app messages
+ confirmSeedWords: confirmSeedWords,
showAccountDetail: showAccountDetail,
BACK_TO_ACCOUNT_DETAIL: 'BACK_TO_ACCOUNT_DETAIL',
backToAccountDetail: backToAccountDetail,
showAccountsPage: showAccountsPage,
showConfTxPage: showConfTxPage,
- confirmSeedWords: confirmSeedWords,
// config screen
SHOW_CONFIG_PAGE: 'SHOW_CONFIG_PAGE',
SET_RPC_TARGET: 'SET_RPC_TARGET',
@@ -111,8 +110,6 @@ var actions = {
showConfigPage: showConfigPage,
setRpcTarget: setRpcTarget,
setProviderType: setProviderType,
- // hacky - need a way to get a reference to account manager
- _setAccountManager: _setAccountManager,
// loading overlay
SHOW_LOADING: 'SHOW_LOADING_INDICATION',
HIDE_LOADING: 'HIDE_LOADING_INDICATION',
@@ -149,13 +146,18 @@ var actions = {
RECOVERY_IN_PROGRESS: 'RECOVERY_IN_PROGRESS',
BACK_TO_UNLOCK_VIEW: 'BACK_TO_UNLOCK_VIEW',
backToUnlockView: backToUnlockView,
+ // SHOWING KEYCHAIN
+ SHOW_NEW_KEYCHAIN: 'SHOW_NEW_KEYCHAIN',
+ showNewKeychain: showNewKeychain,
+
+
}
module.exports = actions
-var _accountManager = null
-function _setAccountManager (accountManager) {
- _accountManager = accountManager
+var background = null
+function _setBackgroundConnection (backgroundConnection) {
+ background = backgroundConnection
}
function goHome () {
@@ -170,25 +172,63 @@ function tryUnlockMetamask (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
dispatch(actions.unlockInProgress())
- _accountManager.submitPassword(password, (err, selectedAccount) => {
+ background.submitPassword(password, (err, newState) => {
dispatch(actions.hideLoadingIndication())
if (err) {
- dispatch(actions.unlockFailed())
+ dispatch(actions.unlockFailed(err.message))
} else {
- dispatch(actions.unlockMetamask(selectedAccount))
+ dispatch(actions.transitionForward())
+ dispatch(actions.updateMetamaskState(newState))
}
})
}
}
-function createNewVault (password, entropy) {
+function transitionForward() {
+ return {
+ type: this.TRANSITION_FORWARD,
+ }
+}
+
+function transitionBackward() {
+ return {
+ type: this.TRANSITION_BACKWARD,
+ }
+}
+
+function confirmSeedWords () {
return (dispatch) => {
- dispatch(actions.createNewVaultInProgress())
- _accountManager.createNewVault(password, entropy, (err, result) => {
+ dispatch(actions.showLoadingIndication())
+ background.clearSeedWordCache((err, account) => {
+ dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
}
- dispatch(actions.showNewVaultSeed(result))
+
+ console.log('Seed word cache cleared. ' + account)
+ dispatch(actions.showAccountDetail(account))
+ })
+ }
+}
+
+function createNewVaultAndRestore (password, seed) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ background.createNewVaultAndRestore(password, seed, (err) => {
+ dispatch(actions.hideLoadingIndication())
+ if (err) return dispatch(actions.displayWarning(err.message))
+ dispatch(actions.showAccountsPage())
+ })
+ }
+}
+
+function createNewVaultAndKeychain (password) {
+ return (dispatch) => {
+ background.createNewVaultAndKeychain(password, (err, newState) => {
+ if (err) {
+ return dispatch(actions.showWarning(err.message))
+ }
+ dispatch(actions.updateMetamaskState(newState))
})
}
}
@@ -202,27 +242,37 @@ function revealSeedConfirmation () {
function requestRevealSeed (password) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- _accountManager.tryPassword(password, (err, seed) => {
- dispatch(actions.hideLoadingIndication())
+ background.submitPassword(password, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
- _accountManager.recoverSeed((err, seed) => {
+ background.placeSeedWords((err) => {
if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.showNewVaultSeed(seed))
+ dispatch(actions.hideLoadingIndication())
})
})
}
}
-function recoverFromSeed (password, seed) {
+
+function addNewKeyring (type, opts) {
return (dispatch) => {
- // dispatch(actions.createNewVaultInProgress())
dispatch(actions.showLoadingIndication())
- _accountManager.recoverFromSeed(password, seed, (err, metamaskState) => {
- dispatch(actions.hideLoadingIndication())
- if (err) return dispatch(actions.displayWarning(err.message))
+ background.addNewKeyring(type, opts, (err) => {
+ dispatch(this.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.showWarning(err))
+ }
+ })
+ }
+}
- var account = Object.keys(metamaskState.identities)[0]
- dispatch(actions.unlockMetamask(account))
+function addNewAccount (ringNumber = 0) {
+ return (dispatch) => {
+ dispatch(actions.showLoadingIndication())
+ background.addNewAccount(ringNumber, (err) => {
+ dispatch(this.hideLoadingIndication())
+ if (err) {
+ return dispatch(actions.showWarning(err))
+ }
})
}
}
@@ -233,29 +283,16 @@ function showInfoPage () {
}
}
-function setSelectedAddress (address) {
+function setSelectedAccount (address) {
return (dispatch) => {
- _accountManager.setSelectedAddress(address)
- }
-}
-
-function revealAccount () {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- _accountManager.revealAccount((err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch({
- type: actions.REVEAL_ACCOUNT,
- })
- })
+ background.setSelectedAccount(address)
}
}
function setCurrentFiat (fiat) {
return (dispatch) => {
dispatch(this.showLoadingIndication())
- _accountManager.setCurrentFiat(fiat, (data, err) => {
+ background.setCurrentFiat(fiat, (data, err) => {
dispatch(this.hideLoadingIndication())
dispatch({
type: this.SET_CURRENT_FIAT,
@@ -273,7 +310,7 @@ function signMsg (msgData) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- _accountManager.signMessage(msgData, (err) => {
+ background.signMessage(msgData, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) return dispatch(actions.displayWarning(err.message))
@@ -284,7 +321,7 @@ function signMsg (msgData) {
function signTx (txData) {
return (dispatch) => {
- _accountManager.setGasMultiplier(txData.gasMultiplier, (err) => {
+ background.setGasMultiplier(txData.gasMultiplier, (err) => {
if (err) return dispatch(actions.displayWarning(err.message))
web3.eth.sendTransaction(txData, (err, data) => {
dispatch(actions.hideLoadingIndication())
@@ -299,7 +336,7 @@ function signTx (txData) {
function sendTx (txData) {
return (dispatch) => {
- _accountManager.approveTransaction(txData.id, (err) => {
+ background.approveTransaction(txData.id, (err) => {
if (err) {
alert(err.message)
dispatch(actions.txError(err))
@@ -325,12 +362,12 @@ function txError (err) {
}
function cancelMsg (msgData) {
- _accountManager.cancelMessage(msgData.id)
+ background.cancelMessage(msgData.id)
return actions.completedTx(msgData.id)
}
function cancelTx (txData) {
- _accountManager.cancelTransaction(txData.id)
+ background.cancelTransaction(txData.id)
return actions.completedTx(txData.id)
}
@@ -359,7 +396,7 @@ function showInitializeMenu () {
function agreeToDisclaimer () {
return (dispatch) => {
dispatch(this.showLoadingIndication())
- _accountManager.agreeToDisclaimer((err) => {
+ background.agreeToDisclaimer((err) => {
if (err) {
return dispatch(actions.displayWarning(err.message))
}
@@ -391,6 +428,12 @@ function backToUnlockView () {
}
}
+function showNewKeychain () {
+ return {
+ type: actions.SHOW_NEW_KEYCHAIN,
+ }
+}
+
//
// unlock screen
//
@@ -401,9 +444,10 @@ function unlockInProgress () {
}
}
-function unlockFailed () {
+function unlockFailed (message) {
return {
type: actions.UNLOCK_FAILED,
+ value: message,
}
}
@@ -423,15 +467,12 @@ function updateMetamaskState (newState) {
function lockMetamask () {
return (dispatch) => {
- _accountManager.setLocked((err) => {
+ background.setLocked((err, newState) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
}
-
- dispatch({
- type: actions.LOCK_METAMASK,
- })
+ dispatch(actions.updateMetamaskState(newState))
})
}
}
@@ -439,7 +480,7 @@ function lockMetamask () {
function showAccountDetail (address) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- _accountManager.setSelectedAddress(address, (err, address) => {
+ background.setSelectedAccount(address, (err, address) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
@@ -459,27 +500,6 @@ function backToAccountDetail (address) {
value: address,
}
}
-function clearSeedWordCache (account) {
- return {
- type: actions.CLEAR_SEED_WORD_CACHE,
- value: account,
- }
-}
-
-function confirmSeedWords () {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- _accountManager.clearSeedWordCache((err, account) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
-
- console.log('Seed word cache cleared. ' + account)
- dispatch(actions.showAccountDetail(account))
- })
- }
-}
function showAccountsPage () {
return {
@@ -533,7 +553,7 @@ function goBackToInitView () {
function markNoticeRead (notice) {
return (dispatch) => {
dispatch(this.showLoadingIndication())
- _accountManager.markNoticeRead(notice, (err, notice) => {
+ background.markNoticeRead(notice, (err, notice) => {
dispatch(this.hideLoadingIndication())
if (err) {
return dispatch(actions.showWarning(err))
@@ -568,7 +588,7 @@ function clearNotices () {
//
function setRpcTarget (newRpc) {
- _accountManager.setRpcTarget(newRpc)
+ background.setRpcTarget(newRpc)
return {
type: actions.SET_RPC_TARGET,
value: newRpc,
@@ -576,7 +596,7 @@ function setRpcTarget (newRpc) {
}
function setProviderType (type) {
- _accountManager.setProviderType(type)
+ background.setProviderType(type)
return {
type: actions.SET_PROVIDER_TYPE,
value: type,
@@ -584,7 +604,7 @@ function setProviderType (type) {
}
function useEtherscanProvider () {
- _accountManager.useEtherscanProvider()
+ background.useEtherscanProvider()
return {
type: actions.USE_ETHERSCAN_PROVIDER,
}
@@ -639,7 +659,7 @@ function exportAccount (address) {
return function (dispatch) {
dispatch(self.showLoadingIndication())
- _accountManager.exportAccount(address, function (err, result) {
+ background.exportAccount(address, function (err, result) {
dispatch(self.hideLoadingIndication())
if (err) {
@@ -662,7 +682,7 @@ function showPrivateKey (key) {
function saveAccountLabel (account, label) {
return (dispatch) => {
dispatch(actions.showLoadingIndication())
- _accountManager.saveAccountLabel(account, label, (err) => {
+ background.saveAccountLabel(account, label, (err) => {
dispatch(actions.hideLoadingIndication())
if (err) {
return dispatch(actions.displayWarning(err.message))
@@ -681,28 +701,9 @@ function showSendPage () {
}
}
-function agreeToEthWarning () {
- return (dispatch) => {
- _accountManager.agreeToEthWarning((err) => {
- if (err) {
- return dispatch(actions.showEthWarning(err.message))
- }
- dispatch({
- type: actions.AGREE_TO_ETH_WARNING,
- })
- })
- }
-}
-
-function showEthWarning () {
- return {
- type: actions.SHOW_ETH_WARNING,
- }
-}
-
function buyEth (address, amount) {
return (dispatch) => {
- _accountManager.buyEth(address, amount)
+ background.buyEth(address, amount)
dispatch({
type: actions.BUY_ETH,
})
@@ -780,7 +781,7 @@ function coinShiftRquest (data, marketData) {
if (response.error) return dispatch(actions.displayWarning(response.error))
var message = `
Deposit your ${response.depositType} to the address bellow:`
- _accountManager.createShapeShiftTx(response.deposit, response.depositType)
+ background.createShapeShiftTx(response.deposit, response.depositType)
dispatch(actions.showQrView(response.deposit, [message].concat(marketData)))
})
}
diff --git a/ui/app/app.js b/ui/app/app.js
index 422b3739c..2fa6415dd 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -7,9 +7,7 @@ const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
// init
const DisclaimerScreen = require('./first-time/disclaimer')
const InitializeMenuScreen = require('./first-time/init-menu')
-const CreateVaultScreen = require('./first-time/create-vault')
-const CreateVaultCompleteScreen = require('./first-time/create-vault-complete')
-const RestoreVaultScreen = require('./first-time/restore-vault')
+const NewKeyChainScreen = require('./new-keychain')
// unlock
const UnlockScreen = require('./unlock')
// accounts
@@ -21,7 +19,6 @@ const ConfirmTxScreen = require('./conf-tx')
const NoticeScreen = require('./notice')
// other views
const ConfigScreen = require('./config')
-const RevealSeedConfirmation = require('./recover-seed/confirmation')
const InfoScreen = require('./info')
const LoadingIndicator = require('./components/loading')
const SandwichExpando = require('sandwich-expando')
@@ -29,9 +26,12 @@ const MenuDroppo = require('menu-droppo')
const DropMenuItem = require('./components/drop-menu-item')
const NetworkIndicator = require('./components/network')
const Tooltip = require('./components/tooltip')
-const EthStoreWarning = require('./eth-store-warning')
const BuyView = require('./components/buy-button-subview')
const QrView = require('./components/qr-code')
+const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
+const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
+const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
+
module.exports = connect(mapStateToProps)(App)
inherits(App, Component)
@@ -41,8 +41,7 @@ function mapStateToProps (state) {
return {
// state from plugin
isLoading: state.appState.isLoading,
- isConfirmed: state.metamask.isConfirmed,
- isEthConfirmed: state.metamask.isEthConfirmed,
+ isDisclaimerConfirmed: state.metamask.isDisclaimerConfirmed,
noActiveNotices: state.metamask.noActiveNotices,
isInitialized: state.metamask.isInitialized,
isUnlocked: state.metamask.isUnlocked,
@@ -94,7 +93,6 @@ App.prototype.render = function () {
transitionLeaveTimeout: 300,
}, [
this.renderPrimary(),
- this.renderBackToInitButton(),
]),
]),
])
@@ -102,7 +100,6 @@ App.prototype.render = function () {
}
App.prototype.renderAppBar = function () {
-
if (window.METAMASK_UI_TYPE === 'notification') {
return null
}
@@ -254,7 +251,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'),
+ }),
+
])
}
@@ -305,6 +310,7 @@ App.prototype.renderDropdown = function () {
}),
])
}
+
App.prototype.renderBackButton = function (style, justArrow = false) {
var props = this.props
return (
@@ -322,85 +328,17 @@ App.prototype.renderBackButton = function (style, justArrow = false) {
}, 'BACK'),
])
)
-
-}
-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
- } else if (props.isInitialized) {
- var style
- switch (props.currentView.name) {
- case 'createVault':
- style = {
- position: 'absolute',
- top: '41px',
- left: '80px',
- fontSize: '21px',
- fontFamily: 'Montserrat Bold',
- color: 'rgb(174, 174, 174)',
- }
- return this.renderBackButton(style, true)
- case 'restoreVault':
- style = {
- position: 'absolute',
- top: '41px',
- left: '70px',
- fontSize: '21px',
- fontFamily: 'Montserrat Bold',
- color: 'rgb(174, 174, 174)',
- }
- return this.renderBackButton(style, true)
- default:
- style = {
- position: 'absolute',
- bottom: '10px',
- left: '15px',
- fontSize: '21px',
- fontFamily: 'Montserrat Light',
- color: '#7F8082',
- width: '71.969px',
- alignItems: 'flex-end',
- }
- return this.renderBackButton(style)
- }
- }
- }
- return button
}
App.prototype.renderPrimary = function () {
var props = this.props
- if (!props.isConfirmed) {
+ if (!props.isDisclaimerConfirmed) {
return h(DisclaimerScreen, {key: 'disclaimerScreen'})
}
if (props.seedWords) {
- return h(CreateVaultCompleteScreen, {key: 'createVaultComplete'})
+ return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
}
// show initialize screen
@@ -408,24 +346,24 @@ App.prototype.renderPrimary = function () {
// show current view
switch (props.currentView.name) {
- case 'createVault':
- return h(CreateVaultScreen, {key: 'createVault'})
-
case 'restoreVault':
- return h(RestoreVaultScreen, {key: 'restoreVault'})
-
- case 'createVaultComplete':
- return h(CreateVaultCompleteScreen, {key: 'createVaultComplete'})
+ return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
default:
return h(InitializeMenuScreen, {key: 'menuScreenInit'})
-
}
}
// show unlock screen
if (!props.isUnlocked) {
- return h(UnlockScreen, {key: 'locked'})
+ switch (props.currentView.name) {
+
+ case 'restoreVault':
+ return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
+
+ default:
+ return h(UnlockScreen, {key: 'locked'})
+ }
}
if (!props.noActiveNotices) {
@@ -434,8 +372,6 @@ App.prototype.renderPrimary = function () {
// show current view
switch (props.currentView.name) {
- case 'EthStoreWarning':
- return h(EthStoreWarning, {key: 'ethWarning'})
case 'accounts':
return h(AccountsScreen, {key: 'accounts'})
@@ -446,6 +382,9 @@ App.prototype.renderPrimary = function () {
case 'sendTransaction':
return h(SendTransactionScreen, {key: 'send-transaction'})
+ case 'newKeychain':
+ return h(NewKeyChainScreen, {key: 'new-keychain'})
+
case 'confTx':
return h(ConfirmTxScreen, {key: 'confirm-tx'})
@@ -458,10 +397,9 @@ App.prototype.renderPrimary = function () {
case 'info':
return h(InfoScreen, {key: 'info'})
- case 'createVault':
- return h(CreateVaultScreen, {key: 'createVault'})
case 'buyEth':
return h(BuyView, {key: 'buyEthView'})
+
case 'qr':
return h('div', {
style: {
@@ -506,23 +444,14 @@ 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 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'),
- })
+ return null
default:
return h(DropMenuItem, {
diff --git a/ui/app/components/coinbase-form.js b/ui/app/components/coinbase-form.js
index 3c5708bf8..693eb2ea8 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)
}
@@ -124,7 +124,6 @@ CoinbaseForm.prototype.toCoinbase = function () {
}
CoinbaseForm.prototype.renderLoading = function () {
-
return h('img', {
style: {
width: '27px',
@@ -134,9 +133,8 @@ CoinbaseForm.prototype.renderLoading = function () {
})
}
-function isValidAmountforCoinBase(amount) {
+function isValidAmountforCoinBase (amount) {
amount = parseFloat(amount)
-
if (amount) {
if (amount <= 5 && amount > 0) {
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 ac0aecadd..9f002234e 100644
--- a/ui/app/components/drop-menu-item.js
+++ b/ui/app/components/drop-menu-item.js
@@ -32,9 +32,9 @@ 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) {
diff --git a/ui/app/components/identicon.js b/ui/app/components/identicon.js
index 4b2bf899e..6d4871d02 100644
--- a/ui/app/components/identicon.js
+++ b/ui/app/components/identicon.js
@@ -16,8 +16,8 @@ function IdenticonComponent () {
}
IdenticonComponent.prototype.render = function () {
- var state = this.props
- var diameter = state.diameter || this.defaultDiameter
+ var props = this.props
+ var diameter = props.diameter || this.defaultDiameter
return (
h('div', {
key: 'identicon-' + this.props.address,
@@ -33,15 +33,31 @@ IdenticonComponent.prototype.render = function () {
}
IdenticonComponent.prototype.componentDidMount = function () {
- var state = this.props
- var address = state.address
+ var props = this.props
+ var address = props.address
if (!address) return
var container = findDOMNode(this)
- var diameter = state.diameter || this.defaultDiameter
- var imageify = state.imageify === undefined ? true : state.imageify
- var img = iconFactory.iconForAddress(address, diameter, imageify)
+ var diameter = props.diameter || this.defaultDiameter
+ var img = iconFactory.iconForAddress(address, diameter, false)
container.appendChild(img)
}
+IdenticonComponent.prototype.componentDidUpdate = function () {
+ var props = this.props
+ var address = props.address
+
+ if (!address) return
+
+ var container = findDOMNode(this)
+
+ var children = container.children
+ for (var i = 0; i < children.length; i++) {
+ container.removeChild(children[i])
+ }
+
+ var diameter = props.diameter || this.defaultDiameter
+ var img = iconFactory.iconForAddress(address, diameter, false)
+ container.appendChild(img)
+}
diff --git a/ui/app/components/network.js b/ui/app/components/network.js
index 1f61ef73f..43dc747b3 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,7 +31,6 @@ Network.prototype.render = function () {
},
src: 'images/loading.svg',
})
-
} else if (providerName === 'mainnet') {
hoverText = 'Main Ethereum Network'
iconName = 'ethereum-network'
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..89472b221 100644
--- a/ui/app/components/pending-tx-details.js
+++ b/ui/app/components/pending-tx-details.js
@@ -24,7 +24,7 @@ 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'
@@ -154,8 +154,6 @@ PTXP.render = function () {
]),
]), // End of Table
- this.warnIfNeeded(),
-
])
)
}
@@ -201,29 +199,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/shapeshift-form.js b/ui/app/components/shapeshift-form.js
index 1da549288..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 () {
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.js b/ui/app/components/transaction-list-item.js
index 491e90c7c..d1306549e 100644
--- a/ui/app/components/transaction-list-item.js
+++ b/ui/app/components/transaction-list-item.js
@@ -63,7 +63,7 @@ TransactionListItem.prototype.render = function () {
style: {
fontSize: '27px',
},
- }) : h( '.pop-hover', {
+ }) : h('.pop-hover', {
onClick: (event) => {
event.stopPropagation()
if (!isTx || isPending) return
diff --git a/ui/app/conf-tx.js b/ui/app/conf-tx.js
index 8d23adfe5..0b1dcac45 100644
--- a/ui/app/conf-tx.js
+++ b/ui/app/conf-tx.js
@@ -18,7 +18,7 @@ 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,
@@ -90,12 +90,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),
// 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),
@@ -120,7 +120,7 @@ ConfirmTxScreen.prototype.checkBalnceAgainstTx = function (txData) {
var state = this.props
var txParams = txData.txParams || {}
- var address = txParams.from || state.selectedAddress
+ var address = txParams.from || state.selectedAccount
var account = state.accounts[address]
var balance = account ? account.balance : '0x0'
diff --git a/ui/app/config.js b/ui/app/config.js
index 8824c6bec..3730baf6b 100644
--- a/ui/app/config.js
+++ b/ui/app/config.js
@@ -3,7 +3,7 @@ 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
module.exports = connect(mapStateToProps)(ConfigScreen)
function mapStateToProps (state) {
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/eth-store-warning.js b/ui/app/eth-store-warning.js
deleted file mode 100644
index fe3c7ce5d..000000000
--- a/ui/app/eth-store-warning.js
+++ /dev/null
@@ -1,89 +0,0 @@
-const connect = require('react-redux').connect
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const actions = require('./actions')
-
-module.exports = connect(mapStateToProps)(EthStoreWarning)
-
-inherits(EthStoreWarning, Component)
-function EthStoreWarning () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- selectedAccount: state.metamask.selectedAccount,
- }
-}
-
-EthStoreWarning.prototype.render = function () {
-
- return (
-
- h('.flex-column', {
- key: 'ethWarning',
- style: {
- paddingTop: '25px',
- marginRight: '30px',
- marginLeft: '30px',
- alignItems: 'center',
- },
- }, [
- h('.warning', {
- style: {
- margin: '10px 10px 10px 10px',
- },
- },
- `MetaMask is currently in beta; use
- caution in storing large
- amounts of ether.
- `),
-
- h('i.fa.fa-exclamation-triangle.fa-4', {
- style: {
- fontSize: '152px',
- color: '#AEAEAE',
- textAlign: 'center',
- },
- }),
-
- h('.flex-row', {
- style: {
- marginTop: '25px',
- marginBottom: '10px',
- },
- }, [
- h('input', {
- type: 'checkbox',
- onChange: this.toggleShowWarning.bind(this),
- }),
- h('.warning', {
- style: {
- fontSize: '11px',
- },
-
- }, 'Don\'t show me this message again'),
- ]),
- h('.flex-row', {
- style: {
- width: '100%',
- justifyContent: 'space-around',
- },
- }, [
- h('button', {
- onClick: this.toAccounts.bind(this),
- },
- 'Continue to MetaMask'),
- ]),
- ])
- )
-}
-
-EthStoreWarning.prototype.toggleShowWarning = function () {
- this.props.dispatch(actions.agreeToEthWarning())
-}
-
-EthStoreWarning.prototype.toAccounts = function () {
- this.props.dispatch(actions.showAccountDetail(this.props.account))
-}
diff --git a/ui/app/first-time/create-vault.js b/ui/app/first-time/create-vault.js
deleted file mode 100644
index 33ae62179..000000000
--- a/ui/app/first-time/create-vault.js
+++ /dev/null
@@ -1,129 +0,0 @@
-const inherits = require('util').inherits
-
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../actions')
-
-module.exports = connect(mapStateToProps)(CreateVaultScreen)
-
-inherits(CreateVaultScreen, Component)
-function CreateVaultScreen () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-CreateVaultScreen.prototype.render = function () {
- var state = this.props
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Create Vault',
- ]),
-
- // password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: 'New Password (min 8 chars)',
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- // confirm password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box-confirm',
- placeholder: 'Confirm Password',
- onKeyPress: this.createVaultOnEnter.bind(this),
- style: {
- width: 260,
- marginTop: 16,
- },
- }),
-
- h('.flex-row.flex-space-between', {
- style: {
- marginTop: 30,
- width: '50%',
- },
- }, [
-
- // cancel
- h('button.primary', {
- onClick: this.showInitializeMenu.bind(this),
- }, 'CANCEL'),
-
- // submit
- h('button.primary', {
- onClick: this.createNewVault.bind(this),
- }, 'OK'),
-
- ]),
-
- (!state.inProgress && state.warning) && (
- h('span.in-progress-notification', state.warning)
- ),
-
- state.inProgress && (
- h('span.in-progress-notification', 'Generating Seed...')
- ),
- ])
- )
-}
-
-CreateVaultScreen.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
-
-CreateVaultScreen.prototype.showInitializeMenu = function () {
- this.props.dispatch(actions.showInitializeMenu())
-}
-
-// create vault
-
-CreateVaultScreen.prototype.createVaultOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewVault()
- }
-}
-
-CreateVaultScreen.prototype.createNewVault = function () {
- var passwordBox = document.getElementById('password-box')
- var password = passwordBox.value
- var passwordConfirmBox = document.getElementById('password-box-confirm')
- var passwordConfirm = passwordConfirmBox.value
- // var entropy = document.getElementById('entropy-text-entry').value
-
- if (password.length < 8) {
- this.warning = 'password not long enough'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
- if (password !== passwordConfirm) {
- this.warning = 'passwords don\'t match'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
-
- this.props.dispatch(actions.createNewVault(password, ''/* entropy*/))
-}
diff --git a/ui/app/first-time/init-menu.js b/ui/app/first-time/init-menu.js
index 94a9d3df6..c41aecc48 100644
--- a/ui/app/first-time/init-menu.js
+++ b/ui/app/first-time/init-menu.js
@@ -5,6 +5,8 @@ const connect = require('react-redux').connect
const h = require('react-hyperscript')
const Mascot = require('../components/mascot')
const actions = require('../actions')
+const Tooltip = require('../components/tooltip')
+const getCaretCoordinates = require('textarea-caret')
module.exports = connect(mapStateToProps)(InitializeMenuScreen)
@@ -18,6 +20,8 @@ function mapStateToProps (state) {
return {
// state from plugin
currentView: state.appState.currentView,
+ warning: state.appState.warning,
+ forgottenPassword: state.metamask.isInitialized,
}
}
@@ -27,7 +31,7 @@ InitializeMenuScreen.prototype.render = function () {
switch (state.currentView.name) {
default:
- return this.renderMenu()
+ return this.renderMenu(state)
}
}
@@ -36,7 +40,7 @@ InitializeMenuScreen.prototype.render = function () {
// document.getElementById('password-box').focus()
// }
-InitializeMenuScreen.prototype.renderMenu = function () {
+InitializeMenuScreen.prototype.renderMenu = function (state) {
return (
h('.initialize-screen.flex-column.flex-center.flex-grow', [
@@ -47,49 +51,146 @@ InitializeMenuScreen.prototype.renderMenu = function () {
h('h1', {
style: {
- fontSize: '1.4em',
+ fontSize: '1.3em',
textTransform: 'uppercase',
color: '#7F8082',
- marginBottom: 20,
+ marginBottom: 10,
},
}, 'MetaMask'),
- h('button.primary', {
- onClick: this.showCreateVault.bind(this),
+
+ h('div', [
+ h('h3', {
+ style: {
+ fontSize: '0.8em',
+ color: '#7F8082',
+ display: 'inline',
+ },
+ }, 'Encrypt your new DEN'),
+
+ h(Tooltip, {
+ title: 'Your DEN is your password-encrypted storage within MetaMask.',
+ }, [
+ h('i.fa.fa-question-circle.pointer', {
+ style: {
+ fontSize: '18px',
+ position: 'relative',
+ color: 'rgb(247, 134, 28)',
+ top: '2px',
+ marginLeft: '4px',
+ },
+ }),
+ ]),
+ ]),
+
+ h('span.in-progress-notification', state.warning),
+
+ // password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box',
+ placeholder: 'New Password (min 8 chars)',
+ onInput: this.inputChanged.bind(this),
style: {
- margin: 12,
+ width: 260,
+ marginTop: 12,
+ },
+ }),
+
+ // confirm password
+ h('input.large-input.letter-spacey', {
+ type: 'password',
+ id: 'password-box-confirm',
+ placeholder: 'Confirm Password',
+ onKeyPress: this.createVaultOnEnter.bind(this),
+ onInput: this.inputChanged.bind(this),
+ style: {
+ width: 260,
+ marginTop: 16,
},
- }, 'Create New Vault'),
+ }),
- h('.flex-row.flex-center.flex-grow', [
- h('hr'),
- h('div', 'OR'),
- h('hr'),
- ]),
h('button.primary', {
- onClick: this.showRestoreVault.bind(this),
+ onClick: this.createNewVaultAndKeychain.bind(this),
style: {
margin: 12,
},
- }, 'Restore Existing Vault'),
+ }, 'Create'),
+
+ state.forgottenPassword ? h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.backToUnlockView.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, 'Return to Login'),
+ ]) : null,
+
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: this.showRestoreVault.bind(this),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, 'Import Existing DEN'),
+ ]),
+
])
)
}
-// InitializeMenuScreen.prototype.splitWor = function() {
-// this.props.dispatch(actions.showInitializeMenu())
-// }
-
-InitializeMenuScreen.prototype.showInitializeMenu = function () {
- this.props.dispatch(actions.showInitializeMenu())
+InitializeMenuScreen.prototype.createVaultOnEnter = function (event) {
+ if (event.key === 'Enter') {
+ event.preventDefault()
+ this.createNewVaultAndKeychain()
+ }
}
-InitializeMenuScreen.prototype.showCreateVault = function () {
- this.props.dispatch(actions.showCreateVault())
+InitializeMenuScreen.prototype.componentDidMount = function () {
+ document.getElementById('password-box').focus()
}
InitializeMenuScreen.prototype.showRestoreVault = function () {
this.props.dispatch(actions.showRestoreVault())
}
+InitializeMenuScreen.prototype.backToUnlockView = function () {
+ this.props.dispatch(actions.backToUnlockView())
+}
+
+InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
+ var passwordBox = document.getElementById('password-box')
+ var password = passwordBox.value
+ var passwordConfirmBox = document.getElementById('password-box-confirm')
+ var passwordConfirm = passwordConfirmBox.value
+ // var entropy = document.getElementById('entropy-text-entry').value
+
+ if (password.length < 8) {
+ this.warning = 'password not long enough'
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+ if (password !== passwordConfirm) {
+ this.warning = 'passwords don\'t match'
+ this.props.dispatch(actions.displayWarning(this.warning))
+ return
+ }
+
+ this.props.dispatch(actions.createNewVaultAndKeychain(password))
+}
+
+InitializeMenuScreen.prototype.inputChanged = function (event) {
+ // tell mascot to look at page action
+ var element = event.target
+ var boundingRect = element.getBoundingClientRect()
+ var coordinates = getCaretCoordinates(element, element.selectionEnd)
+ this.animationEventEmitter.emit('point', {
+ x: boundingRect.left + coordinates.left - element.scrollLeft,
+ y: boundingRect.top + coordinates.top - element.scrollTop,
+ })
+}
diff --git a/ui/app/first-time/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js
index 2b5413955..7272ebdbd 100644
--- a/ui/app/first-time/create-vault-complete.js
+++ b/ui/app/keychains/hd/create-vault-complete.js
@@ -2,7 +2,7 @@ const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
-const actions = require('../actions')
+const actions = require('../../actions')
module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen)
@@ -71,4 +71,3 @@ CreateVaultCompleteScreen.prototype.render = function () {
CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
this.props.dispatch(actions.confirmSeedWords())
}
-
diff --git a/ui/app/recover-seed/confirmation.js b/ui/app/keychains/hd/recover-seed/confirmation.js
index 55b18025f..56ac461ea 100644
--- a/ui/app/recover-seed/confirmation.js
+++ b/ui/app/keychains/hd/recover-seed/confirmation.js
@@ -3,12 +3,12 @@ const inherits = require('util').inherits
const Component = require('react').Component
const connect = require('react-redux').connect
const h = require('react-hyperscript')
-const actions = require('../actions')
+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
@@ -68,7 +68,7 @@ RevealSeedConfirmatoin.prototype.render = function () {
style: {
marginTop: '12px',
},
- }, 'Enter the phrase "I understand" to proceed.'),
+ }, `Enter the phrase "${this.confirmationPhrase}" to proceed.`),
// confirm confirmation
h('input.large-input.letter-spacey', {
@@ -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/first-time/restore-vault.js b/ui/app/keychains/hd/restore-vault.js
index 4c1f21008..3fa25a2eb 100644
--- a/ui/app/first-time/restore-vault.js
+++ b/ui/app/keychains/hd/restore-vault.js
@@ -1,8 +1,8 @@
const inherits = require('util').inherits
-const PersistentForm = require('../../lib/persistent-form')
+const PersistentForm = require('../../../lib/persistent-form')
const connect = require('react-redux').connect
const h = require('react-hyperscript')
-const actions = require('../actions')
+const actions = require('../../actions')
module.exports = connect(mapStateToProps)(RestoreVaultScreen)
@@ -66,7 +66,7 @@ RestoreVaultScreen.prototype.render = function () {
type: 'password',
id: 'password-box-confirm',
placeholder: 'Confirm Password',
- onKeyPress: this.onMaybeCreate.bind(this),
+ onKeyPress: this.createOnEnter.bind(this),
dataset: {
persistentFormId: 'password-confirmation',
},
@@ -96,7 +96,7 @@ RestoreVaultScreen.prototype.render = function () {
// submit
h('button.primary', {
- onClick: this.restoreVault.bind(this),
+ onClick: this.createNewVaultAndRestore.bind(this),
}, 'OK'),
]),
@@ -110,13 +110,13 @@ RestoreVaultScreen.prototype.showInitializeMenu = function () {
this.props.dispatch(actions.showInitializeMenu())
}
-RestoreVaultScreen.prototype.onMaybeCreate = function (event) {
+RestoreVaultScreen.prototype.createOnEnter = function (event) {
if (event.key === 'Enter') {
- this.restoreVault()
+ this.createNewVaultAndRestore()
}
}
-RestoreVaultScreen.prototype.restoreVault = function () {
+RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
// check password
var passwordBox = document.getElementById('password-box')
var password = passwordBox.value
@@ -144,5 +144,5 @@ RestoreVaultScreen.prototype.restoreVault = function () {
// submit
this.warning = null
this.props.dispatch(actions.displayWarning(this.warning))
- this.props.dispatch(actions.recoverFromSeed(password, seed))
+ this.props.dispatch(actions.createNewVaultAndRestore(password, seed))
}
diff --git a/ui/app/new-keychain.js b/ui/app/new-keychain.js
new file mode 100644
index 000000000..cc9633166
--- /dev/null
+++ b/ui/app/new-keychain.js
@@ -0,0 +1,29 @@
+const inherits = require('util').inherits
+const Component = require('react').Component
+const h = require('react-hyperscript')
+const connect = require('react-redux').connect
+
+module.exports = connect(mapStateToProps)(NewKeychain)
+
+function mapStateToProps (state) {
+ return {}
+}
+
+inherits(NewKeychain, Component)
+function NewKeychain () {
+ Component.call(this)
+}
+
+NewKeychain.prototype.render = function () {
+ // const props = this.props
+
+ return (
+ h('div', {
+ style: {
+ background: 'blue',
+ },
+ }, [
+ h('h1', `Here's a list!!!!`),
+ ])
+ )
+}
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 5c5c0acce..719d8c8b9 100644
--- a/ui/app/reducers/app.js
+++ b/ui/app/reducers/app.js
@@ -29,13 +29,10 @@ function reduceApp (state, action) {
name: 'createVaultComplete',
seedWords,
}
- var ethStoreWarning = {
- name: 'EthStoreWarning',
- }
var appState = extend({
menuOpen: false,
- currentView: seedWords ? seedConfView : !state.metamask.isEthConfirmed ? ethStoreWarning : defaultView,
+ currentView: seedWords ? seedConfView : defaultView,
accountDetail: {
subview: 'transactions',
},
@@ -46,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, {
@@ -119,6 +128,15 @@ function reduceApp (state, action) {
warning: null,
})
+ case actions.SHOW_NEW_KEYCHAIN:
+ return extend(appState, {
+ currentView: {
+ name: 'newKeychain',
+ context: appState.currentView.context,
+ },
+ transForward: true,
+ })
+
// unlock
case actions.UNLOCK_METAMASK:
@@ -227,6 +245,7 @@ function reduceApp (state, action) {
isLoading: false,
warning: null,
scrollToBottom: false,
+ forgottenPassword: false,
})
case actions.SHOW_NOTICE:
@@ -278,7 +297,6 @@ function reduceApp (state, action) {
warning: null,
})
} else {
-
notification.closePopup()
return extend(appState, {
@@ -286,7 +304,7 @@ function reduceApp (state, action) {
warning: null,
currentView: {
name: 'accountDetail',
- context: state.metamask.selectedAddress,
+ context: state.metamask.selectedAccount,
},
accountDetail: {
subview: 'transactions',
@@ -335,7 +353,7 @@ function reduceApp (state, action) {
case actions.UNLOCK_FAILED:
return extend(appState, {
- warning: 'Incorrect password. Try again.',
+ warning: action.value || 'Incorrect password. Try again.',
})
case actions.SHOW_LOADING:
@@ -546,4 +564,3 @@ function indexForPending (state, txId) {
})
return idx
}
-
diff --git a/ui/app/reducers/metamask.js b/ui/app/reducers/metamask.js
index 9a1c5814d..8679ab062 100644
--- a/ui/app/reducers/metamask.js
+++ b/ui/app/reducers/metamask.js
@@ -10,7 +10,6 @@ function reduceMetamask (state, action) {
var metamaskState = extend({
isInitialized: false,
isUnlocked: false,
- isEthConfirmed: false,
rpcTarget: 'https://rawtestrpc.metamask.io/',
identities: {},
unconfTxs: {},
@@ -44,12 +43,7 @@ function reduceMetamask (state, action) {
case actions.AGREE_TO_DISCLAIMER:
return extend(metamaskState, {
- isConfirmed: true,
- })
-
- case actions.AGREE_TO_ETH_WARNING:
- return extend(metamaskState, {
- isEthConfirmed: !metamaskState.isEthConfirmed,
+ isDisclaimerConfirmed: true,
})
case actions.UNLOCK_METAMASK:
@@ -117,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 b82e46d02..17416766d 100644
--- a/ui/app/unlock.js
+++ b/ui/app/unlock.js
@@ -55,6 +55,8 @@ UnlockScreen.prototype.render = function () {
h('.error', {
style: {
display: warning ? 'block' : 'none',
+ padding: '0 20px',
+ textAlign: 'center',
},
}, warning),
@@ -65,6 +67,17 @@ UnlockScreen.prototype.render = function () {
},
}, 'Unlock'),
]),
+
+ h('.flex-row.flex-center.flex-grow', [
+ h('p.pointer', {
+ onClick: () => this.props.dispatch(actions.goBackToInitView()),
+ style: {
+ fontSize: '0.8em',
+ color: 'rgb(247, 134, 28)',
+ textDecoration: 'underline',
+ },
+ }, 'I forgot my password.'),
+ ]),
])
)
}
@@ -103,7 +116,3 @@ UnlockScreen.prototype.inputChanged = function (event) {
y: boundingRect.top + coordinates.top - element.scrollTop,
})
}
-
-UnlockScreen.prototype.emitAnim = function (name, a, b, c) {
- this.animationEventEmitter.emit(name, a, b, c)
-}
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/index.js b/ui/index.js
index a6905b639..dedfd8c8c 100644
--- a/ui/index.js
+++ b/ui/index.js
@@ -8,7 +8,7 @@ module.exports = launchApp
function launchApp (opts) {
var accountManager = opts.accountManager
- actions._setAccountManager(accountManager)
+ actions._setBackgroundConnection(accountManager)
// check if we are unlocked first
accountManager.getState(function (err, metamaskState) {
diff --git a/ui/lib/account-link.js b/ui/lib/account-link.js
index ff52d9c54..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
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/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
+}