Merge pull request #356 from poanetwork/vb-rsk-dpath-update
Custom derivation paths and access to funds in accounts derived from ETH dPath
This commit is contained in:
commit
7662c11542
|
@ -2,9 +2,11 @@
|
||||||
|
|
||||||
## Current Master
|
## Current Master
|
||||||
|
|
||||||
|
- [#356](https://github.com/poanetwork/nifty-wallet/pull/356) - (Backwards-compatibility feature) Custom derivation paths and access to funds in accounts derived from ETH dPath
|
||||||
- [#379](https://github.com/poanetwork/nifty-wallet/pull/379) - (Feature) Ability to set custom nonce of tx
|
- [#379](https://github.com/poanetwork/nifty-wallet/pull/379) - (Feature) Ability to set custom nonce of tx
|
||||||
- [#377](https://github.com/poanetwork/nifty-wallet/pull/377) - (Fix) Sign message screen: do not decode message if it is not hex encoded
|
- [#377](https://github.com/poanetwork/nifty-wallet/pull/377) - (Fix) Sign message screen: do not decode message if it is not hex encoded
|
||||||
- [#364](https://github.com/poanetwork/nifty-wallet/pull/364) - (Fix) notifications order in batch requests
|
- [#364](https://github.com/poanetwork/nifty-wallet/pull/364) - (Fix) notifications order in batch requests
|
||||||
|
- [#364](https://github.com/poanetwork/nifty-wallet/pull/364) - Fix notifications order in batch requests
|
||||||
|
|
||||||
## 5.0.3 Fri May 01 2020
|
## 5.0.3 Fri May 01 2020
|
||||||
|
|
||||||
|
@ -14,6 +16,7 @@
|
||||||
- [#368](https://github.com/poanetwork/nifty-wallet/pull/368) - (Fix) Ability to import Keystore file if it is not secured by password
|
- [#368](https://github.com/poanetwork/nifty-wallet/pull/368) - (Fix) Ability to import Keystore file if it is not secured by password
|
||||||
- [#366](https://github.com/poanetwork/nifty-wallet/pull/366) - (Fix) Increase max token symbol length up to 12
|
- [#366](https://github.com/poanetwork/nifty-wallet/pull/366) - (Fix) Increase max token symbol length up to 12
|
||||||
- [#363](https://github.com/poanetwork/nifty-wallet/pull/363) - (Fix) token decimals display in pending tx screen
|
- [#363](https://github.com/poanetwork/nifty-wallet/pull/363) - (Fix) token decimals display in pending tx screen
|
||||||
|
- [#356](https://github.com/poanetwork/nifty-wallet/pull/356) - (Backwards-compatibility feature) Custom derivation paths and access to funds in accounts derived from ETH dPath
|
||||||
|
|
||||||
## 5.0.2 Thu Apr 16 2020
|
## 5.0.2 Thu Apr 16 2020
|
||||||
|
|
||||||
|
|
|
@ -12,10 +12,10 @@ import createJsonRpcClient from './createJsonRpcClient'
|
||||||
import createLocalhostClient from './createLocalhostClient'
|
import createLocalhostClient from './createLocalhostClient'
|
||||||
const createPocketClient = require('./createPocketClient')
|
const createPocketClient = require('./createPocketClient')
|
||||||
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
|
const { createSwappableProxy, createEventEmitterProxy } = require('swappable-obj-proxy')
|
||||||
const ethNetProps = require('eth-net-props')
|
import ethNetProps from 'eth-net-props'
|
||||||
import parse from 'url-parse'
|
import parse from 'url-parse'
|
||||||
const networks = { networkList: {} }
|
const networks = { networkList: {} }
|
||||||
const { isKnownProvider, getDPath } = require('../../../../old-ui/app/util')
|
const { isKnownProvider } = require('../../../../old-ui/app/util')
|
||||||
|
|
||||||
const {
|
const {
|
||||||
ROPSTEN,
|
ROPSTEN,
|
||||||
|
@ -205,8 +205,6 @@ module.exports = class NetworkController extends EventEmitter {
|
||||||
const previousNetworkID = this.getNetworkState()
|
const previousNetworkID = this.getNetworkState()
|
||||||
this.setNetworkState('loading')
|
this.setNetworkState('loading')
|
||||||
this._configureProvider(opts)
|
this._configureProvider(opts)
|
||||||
const dPath = getDPath(opts.type)
|
|
||||||
this.store.updateState({ dPath })
|
|
||||||
this.emit('networkDidChange', opts.type, previousNetworkID)
|
this.emit('networkDidChange', opts.type, previousNetworkID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
const KeyringController = require('eth-keychain-controller')
|
import KeyringController from 'eth-keychain-controller'
|
||||||
const log = require('loglevel')
|
import log from 'loglevel'
|
||||||
const { getDPath } = require('../../../old-ui/app/util')
|
const { getDPath } = require('../../../old-ui/app/util')
|
||||||
|
|
||||||
const seedPhraseVerifier = {
|
const seedPhraseVerifier = {
|
||||||
|
@ -17,14 +17,14 @@ const seedPhraseVerifier = {
|
||||||
* @returns {Promise<void>} Promises undefined
|
* @returns {Promise<void>} Promises undefined
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
verifyAccounts (createdAccounts, seedWords, network) {
|
verifyAccounts (createdAccounts, seedWords, network, isCreatedWithCorrectDPath) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
if (!createdAccounts || createdAccounts.length < 1) {
|
if (!createdAccounts || createdAccounts.length < 1) {
|
||||||
return reject(new Error('No created accounts defined.'))
|
return reject(new Error('No created accounts defined.'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const dPath = getDPath(network)
|
const dPath = getDPath(network, isCreatedWithCorrectDPath)
|
||||||
const keyringController = new KeyringController({})
|
const keyringController = new KeyringController({})
|
||||||
const Keyring = keyringController.getKeyringClassForType('HD Key Tree')
|
const Keyring = keyringController.getKeyringClassForType('HD Key Tree')
|
||||||
const opts = {
|
const opts = {
|
||||||
|
@ -56,4 +56,4 @@ const seedPhraseVerifier = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = seedPhraseVerifier
|
export default seedPhraseVerifier
|
||||||
|
|
|
@ -52,7 +52,7 @@ const version = require('../manifest.json').version
|
||||||
import ethUtil, { BN } from 'ethereumjs-util'
|
import ethUtil, { BN } from 'ethereumjs-util'
|
||||||
const GWEI_BN = new BN('1000000000')
|
const GWEI_BN = new BN('1000000000')
|
||||||
import percentile from 'percentile'
|
import percentile from 'percentile'
|
||||||
const seedPhraseVerifier = require('./lib/seed-phrase-verifier')
|
import seedPhraseVerifier from './lib/seed-phrase-verifier'
|
||||||
import log from 'loglevel'
|
import log from 'loglevel'
|
||||||
const TrezorKeyring = require('eth-trezor-keyring')
|
const TrezorKeyring = require('eth-trezor-keyring')
|
||||||
const LedgerBridgeKeyring = require('eth-ledger-bridge-keyring')
|
const LedgerBridgeKeyring = require('eth-ledger-bridge-keyring')
|
||||||
|
@ -169,26 +169,32 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
})
|
})
|
||||||
|
|
||||||
// ensure accountTracker updates balances after network change
|
// ensure accountTracker updates balances after network change
|
||||||
this.networkController.on('networkDidChange', (newType, previousNetworkIDStr) => {
|
this.networkController.on('networkDidChange', (newNetworkType, previousNetworkIDStr) => {
|
||||||
const dPath = getDPath(newType)
|
this.keyringController.isCreatedWithCorrectDPath()
|
||||||
this.deriveKeyringFromNewDPath(dPath)
|
.then(isCreatedWithCorrectDPath => {
|
||||||
.then(accounts => {
|
const dPath = getDPath(newNetworkType, isCreatedWithCorrectDPath)
|
||||||
this.accountTracker._updateAccounts()
|
this.deriveKeyringFromNewDPath(dPath)
|
||||||
this.detectTokensController.restartTokenDetection()
|
.then(_accounts => {
|
||||||
|
this.accountTracker._updateAccounts()
|
||||||
|
this.detectTokensController.restartTokenDetection()
|
||||||
|
|
||||||
const previousNetworkID = parseInt(previousNetworkIDStr, 10)
|
const previousNetworkID = parseInt(previousNetworkIDStr, 10)
|
||||||
const nextNetwork = getNetworkID({network: newType})
|
const nextNetwork = getNetworkID({network: newNetworkType})
|
||||||
const nextNetworkID = parseInt(nextNetwork && nextNetwork.netId, 10)
|
const nextNetworkID = parseInt(nextNetwork && nextNetwork.netId, 10)
|
||||||
if (nextNetworkID !== previousNetworkID) {
|
if (nextNetworkID !== previousNetworkID) {
|
||||||
const isPreviousETC = previousNetworkID === CLASSIC_CODE
|
const isPreviousETC = previousNetworkID === CLASSIC_CODE
|
||||||
const isPreviousRSK = ifRSK(previousNetworkID)
|
const isPreviousRSK = ifRSK(previousNetworkID)
|
||||||
const isNextETC = nextNetworkID === CLASSIC_CODE
|
const isNextETC = nextNetworkID === CLASSIC_CODE
|
||||||
const isNextRSK = ifRSK(nextNetworkID)
|
const isNextRSK = ifRSK(nextNetworkID)
|
||||||
if (isPreviousETC || isPreviousRSK || isNextETC || isNextRSK) {
|
if (isPreviousETC || isPreviousRSK || isNextETC || isNextRSK) {
|
||||||
this.forgetDevice(LEDGER, false)
|
this.forgetDevice(LEDGER, false)
|
||||||
this.forgetDevice(TREZOR, false)
|
this.forgetDevice(TREZOR, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
.catch(e => {
|
||||||
|
console.log(e)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
console.log(e)
|
console.log(e)
|
||||||
|
@ -493,6 +499,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
|
addNewKeyring: nodeify(keyringController.addNewKeyring, keyringController),
|
||||||
addNewMultisig: nodeify(keyringController.addNewMultisig, keyringController),
|
addNewMultisig: nodeify(keyringController.addNewMultisig, keyringController),
|
||||||
exportAccount: nodeify(keyringController.exportAccount, keyringController),
|
exportAccount: nodeify(keyringController.exportAccount, keyringController),
|
||||||
|
isCreatedWithCorrectDPath: nodeify(keyringController.isCreatedWithCorrectDPath, keyringController),
|
||||||
|
|
||||||
// txController
|
// txController
|
||||||
cancelTransaction: nodeify(txController.cancelTransaction, txController),
|
cancelTransaction: nodeify(txController.cancelTransaction, txController),
|
||||||
|
@ -582,7 +589,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
* @param {} password
|
* @param {} password
|
||||||
* @param {} seed
|
* @param {} seed
|
||||||
*/
|
*/
|
||||||
async createNewVaultAndRestore (password, seed) {
|
async createNewVaultAndRestore (password, seed, dPath) {
|
||||||
const releaseLock = await this.createVaultMutex.acquire()
|
const releaseLock = await this.createVaultMutex.acquire()
|
||||||
try {
|
try {
|
||||||
let accounts, lastBalance
|
let accounts, lastBalance
|
||||||
|
@ -592,9 +599,8 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
// clear known identities
|
// clear known identities
|
||||||
this.preferencesController.setAddresses([])
|
this.preferencesController.setAddresses([])
|
||||||
// create new vault
|
// create new vault
|
||||||
const network = this.networkController.getProviderConfig().type
|
const networkType = this.networkController.getProviderConfig().type
|
||||||
const dPath = getDPath(network)
|
const isCreatedWithCorrectDPath = true
|
||||||
this.store.updateState({dPath})
|
|
||||||
const vault = await keyringController.createNewVaultAndRestore(password, seed, dPath)
|
const vault = await keyringController.createNewVaultAndRestore(password, seed, dPath)
|
||||||
|
|
||||||
const ethQuery = new EthQuery(this.provider)
|
const ethQuery = new EthQuery(this.provider)
|
||||||
|
@ -606,7 +612,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
throw new Error('MetamaskController - No HD Key Tree found')
|
throw new Error('MetamaskController - No HD Key Tree found')
|
||||||
}
|
}
|
||||||
|
|
||||||
setDPath(primaryKeyring, network)
|
setDPath(primaryKeyring, networkType, isCreatedWithCorrectDPath)
|
||||||
|
|
||||||
// seek out the first zero balance
|
// seek out the first zero balance
|
||||||
while (lastBalance !== '0x0') {
|
while (lastBalance !== '0x0') {
|
||||||
|
@ -911,13 +917,14 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
* @returns {} keyState
|
* @returns {} keyState
|
||||||
*/
|
*/
|
||||||
async addNewAccount () {
|
async addNewAccount () {
|
||||||
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
|
const keyringController = this.keyringController
|
||||||
|
const primaryKeyring = keyringController.getKeyringsByType('HD Key Tree')[0]
|
||||||
if (!primaryKeyring) {
|
if (!primaryKeyring) {
|
||||||
throw new Error('MetamaskController - No HD Key Tree found')
|
throw new Error('MetamaskController - No HD Key Tree found')
|
||||||
}
|
}
|
||||||
const network = this.networkController.getProviderConfig().type
|
const networkType = this.networkController.getProviderConfig().type
|
||||||
setDPath(primaryKeyring, network)
|
const isCreatedWithCorrectDPath = await keyringController.isCreatedWithCorrectDPath()
|
||||||
const keyringController = this.keyringController
|
setDPath(primaryKeyring, networkType, isCreatedWithCorrectDPath)
|
||||||
const oldAccounts = await keyringController.getAccounts()
|
const oldAccounts = await keyringController.getAccounts()
|
||||||
const keyState = await keyringController.addNewAccount(primaryKeyring)
|
const keyState = await keyringController.addNewAccount(primaryKeyring)
|
||||||
const newAccounts = await keyringController.getAccounts()
|
const newAccounts = await keyringController.getAccounts()
|
||||||
|
@ -965,12 +972,14 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
* @returns {Promise<string>} Seed phrase to be confirmed by the user.
|
* @returns {Promise<string>} Seed phrase to be confirmed by the user.
|
||||||
*/
|
*/
|
||||||
async verifySeedPhrase () {
|
async verifySeedPhrase () {
|
||||||
const primaryKeyring = this.keyringController.getKeyringsByType('HD Key Tree')[0]
|
const keyringController = this.keyringController
|
||||||
|
const isCreatedWithCorrectDPath = await keyringController.isCreatedWithCorrectDPath()
|
||||||
|
const primaryKeyring = keyringController.getKeyringsByType('HD Key Tree')[0]
|
||||||
if (!primaryKeyring) {
|
if (!primaryKeyring) {
|
||||||
throw new Error('MetamaskController - No HD Key Tree found')
|
throw new Error('MetamaskController - No HD Key Tree found')
|
||||||
}
|
}
|
||||||
const network = this.networkController.getProviderConfig().type
|
const networkType = this.networkController.getProviderConfig().type
|
||||||
setDPath(primaryKeyring, network)
|
setDPath(primaryKeyring, networkType, isCreatedWithCorrectDPath)
|
||||||
|
|
||||||
const serialized = await primaryKeyring.serialize()
|
const serialized = await primaryKeyring.serialize()
|
||||||
const seedWords = serialized.mnemonic
|
const seedWords = serialized.mnemonic
|
||||||
|
@ -981,7 +990,7 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await seedPhraseVerifier.verifyAccounts(accounts, seedWords, network)
|
await seedPhraseVerifier.verifyAccounts(accounts, seedWords, networkType, isCreatedWithCorrectDPath)
|
||||||
return seedWords
|
return seedWords
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error(err.message)
|
log.error(err.message)
|
||||||
|
@ -1086,8 +1095,6 @@ module.exports = class MetamaskController extends EventEmitter {
|
||||||
const privateKey = await accountImporter.importAccount(strategy, args)
|
const privateKey = await accountImporter.importAccount(strategy, args)
|
||||||
keyring = await this.keyringController.addNewKeyring('Simple Key Pair', [ privateKey ])
|
keyring = await this.keyringController.addNewKeyring('Simple Key Pair', [ privateKey ])
|
||||||
}
|
}
|
||||||
const network = this.networkController.getProviderConfig().type
|
|
||||||
setDPath(keyring, network)
|
|
||||||
const accounts = await keyring.getAccounts()
|
const accounts = await keyring.getAccounts()
|
||||||
// update accounts in preferences controller
|
// update accounts in preferences controller
|
||||||
const allAccounts = await this.keyringController.getAccounts()
|
const allAccounts = await this.keyringController.getAccounts()
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -4,7 +4,7 @@ const Component = require('react').Component
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
const connect = require('react-redux').connect
|
const connect = require('react-redux').connect
|
||||||
const actions = require('../../ui/app/actions')
|
const actions = require('../../ui/app/actions')
|
||||||
const { getCurrentKeyring, ifContractAcc, valuesFor, toChecksumAddress } = require('./util')
|
const { getCurrentKeyring, ifContractAcc, valuesFor, toChecksumAddress, ifLooseAcc, ifRSK, ifETC } = require('./util')
|
||||||
const Identicon = require('./components/identicon')
|
const Identicon = require('./components/identicon')
|
||||||
const EthBalance = require('./components/eth-balance')
|
const EthBalance = require('./components/eth-balance')
|
||||||
const TransactionList = require('./components/transaction-list')
|
const TransactionList = require('./components/transaction-list')
|
||||||
|
@ -14,10 +14,10 @@ const TabBar = require('./components/tab-bar')
|
||||||
const TokenList = require('./components/token-list')
|
const TokenList = require('./components/token-list')
|
||||||
const AccountDropdowns = require('./components/account-dropdowns/account-dropdowns.component').AccountDropdowns
|
const AccountDropdowns = require('./components/account-dropdowns/account-dropdowns.component').AccountDropdowns
|
||||||
const CopyButton = require('./components/copy/copy-button')
|
const CopyButton = require('./components/copy/copy-button')
|
||||||
const ToastComponent = require('./components/toast')
|
import * as Toast from './components/toast'
|
||||||
import { getMetaMaskAccounts } from '../../ui/app/selectors'
|
import { getMetaMaskAccounts } from '../../ui/app/selectors'
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(AccountDetailScreen)
|
module.exports = connect(mapStateToProps, mapDispatchToProps)(AccountDetailScreen)
|
||||||
|
|
||||||
function mapStateToProps (state) {
|
function mapStateToProps (state) {
|
||||||
const accounts = getMetaMaskAccounts(state)
|
const accounts = getMetaMaskAccounts(state)
|
||||||
|
@ -42,11 +42,66 @@ function mapStateToProps (state) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapDispatchToProps (dispatch) {
|
||||||
|
return {
|
||||||
|
actions: {
|
||||||
|
showSendPage: () => dispatch(actions.showSendPage()),
|
||||||
|
showSendContractPage: ({ methodSelected, methodABI, inputValues }) => dispatch(actions.showSendContractPage({methodSelected, methodABI, inputValues})),
|
||||||
|
buyEthView: (selected) => dispatch(actions.buyEthView(selected)),
|
||||||
|
viewPendingTx: (txId) => dispatch(actions.viewPendingTx(txId)),
|
||||||
|
setAccountLabel: (account, label) => dispatch(actions.setAccountLabel(account, label)),
|
||||||
|
showRemoveTokenPage: (token) => dispatch(actions.showRemoveTokenPage(token)),
|
||||||
|
showAddSuggestedTokenPage: () => dispatch(actions.showAddSuggestedTokenPage()),
|
||||||
|
showAddTokenPage: () => dispatch(actions.showAddTokenPage()),
|
||||||
|
setCurrentAccountTab: (key) => dispatch(actions.setCurrentAccountTab(key)),
|
||||||
|
displayToast: (msg) => dispatch(actions.displayToast(msg)),
|
||||||
|
isCreatedWithCorrectDPath: () => dispatch(actions.isCreatedWithCorrectDPath()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inherits(AccountDetailScreen, Component)
|
inherits(AccountDetailScreen, Component)
|
||||||
function AccountDetailScreen () {
|
function AccountDetailScreen () {
|
||||||
Component.call(this)
|
Component.call(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AccountDetailScreen.prototype.componentDidMount = function () {
|
||||||
|
const props = this.props
|
||||||
|
const { address, network, keyrings, identities } = props
|
||||||
|
props.actions.isCreatedWithCorrectDPath()
|
||||||
|
.then(isCreatedWithCorrectDPath => {
|
||||||
|
if (!isCreatedWithCorrectDPath) {
|
||||||
|
const currentKeyring = getCurrentKeyring(address, network, keyrings, identities)
|
||||||
|
if (!ifLooseAcc(currentKeyring) && !ifContractAcc(currentKeyring) && (ifRSK(network) || ifETC(network))) {
|
||||||
|
props.actions.displayToast(Toast.ERROR_ON_INCORRECT_DPATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
AccountDetailScreen.prototype.componentWillUpdate = function (nextProps) {
|
||||||
|
const {
|
||||||
|
network: oldNet,
|
||||||
|
} = this.props
|
||||||
|
const {
|
||||||
|
network: newNet,
|
||||||
|
} = nextProps
|
||||||
|
|
||||||
|
if (oldNet !== newNet) {
|
||||||
|
const props = this.props
|
||||||
|
const { address, keyrings, identities } = props
|
||||||
|
props.actions.isCreatedWithCorrectDPath()
|
||||||
|
.then(isCreatedWithCorrectDPath => {
|
||||||
|
if (!isCreatedWithCorrectDPath) {
|
||||||
|
const currentKeyring = getCurrentKeyring(address, newNet, keyrings, identities)
|
||||||
|
if (!ifLooseAcc(currentKeyring) && !ifContractAcc(currentKeyring) && (ifRSK(newNet) || ifETC(newNet))) {
|
||||||
|
props.actions.displayToast(Toast.ERROR_ON_INCORRECT_DPATH)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AccountDetailScreen.prototype.render = function () {
|
AccountDetailScreen.prototype.render = function () {
|
||||||
const props = this.props
|
const props = this.props
|
||||||
const { network, conversionRate, currentCurrency } = props
|
const { network, conversionRate, currentCurrency } = props
|
||||||
|
@ -56,7 +111,7 @@ AccountDetailScreen.prototype.render = function () {
|
||||||
const account = props.accounts[selected]
|
const account = props.accounts[selected]
|
||||||
|
|
||||||
if (Object.keys(props.suggestedTokens).length > 0) {
|
if (Object.keys(props.suggestedTokens).length > 0) {
|
||||||
this.props.dispatch(actions.showAddSuggestedTokenPage())
|
this.props.actions.showAddSuggestedTokenPage()
|
||||||
}
|
}
|
||||||
|
|
||||||
const currentKeyring = getCurrentKeyring(props.address, network, props.keyrings, props.identities)
|
const currentKeyring = getCurrentKeyring(props.address, network, props.keyrings, props.identities)
|
||||||
|
@ -65,8 +120,9 @@ AccountDetailScreen.prototype.render = function () {
|
||||||
|
|
||||||
h('.account-detail-section.full-flex-height', [
|
h('.account-detail-section.full-flex-height', [
|
||||||
|
|
||||||
h(ToastComponent, {
|
h(Toast.ToastComponent, {
|
||||||
isSuccess: false,
|
type: Toast.TOAST_TYPE_ERROR,
|
||||||
|
hideManually: true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
// identicon, label, balance, etc
|
// identicon, label, balance, etc
|
||||||
|
@ -108,7 +164,7 @@ AccountDetailScreen.prototype.render = function () {
|
||||||
isEditingLabel: false,
|
isEditingLabel: false,
|
||||||
},
|
},
|
||||||
saveText: (text) => {
|
saveText: (text) => {
|
||||||
props.dispatch(actions.setAccountLabel(selected, text))
|
props.actions.setAccountLabel(selected, text)
|
||||||
},
|
},
|
||||||
}, [
|
}, [
|
||||||
|
|
||||||
|
@ -223,16 +279,16 @@ AccountDetailScreen.prototype.render = function () {
|
||||||
h('.flex-grow'),
|
h('.flex-grow'),
|
||||||
|
|
||||||
!ifContractAcc(currentKeyring) ? h('button', {
|
!ifContractAcc(currentKeyring) ? h('button', {
|
||||||
onClick: () => props.dispatch(actions.buyEthView(selected)),
|
onClick: () => props.actions.buyEthView(selected),
|
||||||
style: { marginRight: '10px' },
|
style: { marginRight: '10px' },
|
||||||
}, 'Buy') : null,
|
}, 'Buy') : null,
|
||||||
|
|
||||||
h('button', {
|
h('button', {
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
if (ifContractAcc(currentKeyring)) {
|
if (ifContractAcc(currentKeyring)) {
|
||||||
return props.dispatch(actions.showSendContractPage({}))
|
return props.actions.showSendContractPage({})
|
||||||
} else {
|
} else {
|
||||||
return props.dispatch(actions.showSendPage())
|
return props.actions.showSendPage()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, ifContractAcc(currentKeyring) ? 'Execute methods' : 'Send'),
|
}, ifContractAcc(currentKeyring) ? 'Execute methods' : 'Send'),
|
||||||
|
@ -278,7 +334,7 @@ AccountDetailScreen.prototype.tabSections = function () {
|
||||||
],
|
],
|
||||||
defaultTab: currentAccountTab || 'history',
|
defaultTab: currentAccountTab || 'history',
|
||||||
tabSelected: (key) => {
|
tabSelected: (key) => {
|
||||||
this.props.dispatch(actions.setCurrentAccountTab(key))
|
this.props.actions.setCurrentAccountTab(key)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -297,8 +353,8 @@ AccountDetailScreen.prototype.tabSwitchView = function () {
|
||||||
userAddress: address,
|
userAddress: address,
|
||||||
network,
|
network,
|
||||||
tokens,
|
tokens,
|
||||||
addToken: () => this.props.dispatch(actions.showAddTokenPage()),
|
addToken: () => this.props.actions.showAddTokenPage(),
|
||||||
removeToken: (token) => this.props.dispatch(actions.showRemoveTokenPage(token)),
|
removeToken: (token) => this.props.actions.showRemoveTokenPage(token),
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
return this.transactionList()
|
return this.transactionList()
|
||||||
|
@ -317,7 +373,7 @@ AccountDetailScreen.prototype.transactionList = function () {
|
||||||
address,
|
address,
|
||||||
shapeShiftTxList,
|
shapeShiftTxList,
|
||||||
viewPendingTx: (txId) => {
|
viewPendingTx: (txId) => {
|
||||||
this.props.dispatch(actions.viewPendingTx(txId))
|
this.props.actions.viewPendingTx(txId)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@ import actions from '../../../../ui/app/actions'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { DropdownMenuItem } from '../dropdown'
|
import { DropdownMenuItem } from '../dropdown'
|
||||||
import Identicon from '../identicon'
|
import Identicon from '../identicon'
|
||||||
import { ifLooseAcc, ifContractAcc, ifHardwareAcc } from '../../util'
|
import { ifLooseAcc, ifContractAcc, ifHardwareAcc, ifRSK, ifETC } from '../../util'
|
||||||
import { getHdPaths, isLedger } from '../connect-hardware/util'
|
import { getHdPaths, isLedger } from '../connect-hardware/util'
|
||||||
import { LEDGER } from '../connect-hardware/enum'
|
import { LEDGER } from '../connect-hardware/enum'
|
||||||
import { importTypes, labels } from '../../accounts/import/enums'
|
import { importTypes, labels } from '../../accounts/import/enums'
|
||||||
|
import { ERROR_ON_INCORRECT_DPATH } from '../toast'
|
||||||
|
|
||||||
class AccountsDropdownItemView extends Component {
|
class AccountsDropdownItemView extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
|
@ -100,7 +101,7 @@ class AccountsDropdownItemView extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ifProxyAcc (address, setProxy) {
|
ifProxyAcc (address, _setProxy) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.props.actions.getContract(address)
|
this.props.actions.getContract(address)
|
||||||
.then(contractProps => {
|
.then(contractProps => {
|
||||||
|
@ -138,6 +139,15 @@ class AccountsDropdownItemView extends Component {
|
||||||
} else {
|
} else {
|
||||||
this.preventToast()
|
this.preventToast()
|
||||||
}
|
}
|
||||||
|
} else if (!ifLooseAcc(keyring) && !ifContractAcc(keyring) && (ifRSK(this.props.network) || ifETC(this.props.network))) {
|
||||||
|
this.props.actions.isCreatedWithCorrectDPath()
|
||||||
|
.then(isCreatedWithCorrectDPath => {
|
||||||
|
if (isCreatedWithCorrectDPath) {
|
||||||
|
this.preventToast()
|
||||||
|
} else {
|
||||||
|
this.props.actions.displayToast(ERROR_ON_INCORRECT_DPATH)
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
this.preventToast()
|
this.preventToast()
|
||||||
}
|
}
|
||||||
|
@ -152,6 +162,13 @@ class AccountsDropdownItemView extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mapStateToProps (state) {
|
||||||
|
const result = {
|
||||||
|
network: state.metamask.network,
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch) => {
|
const mapDispatchToProps = (dispatch) => {
|
||||||
return {
|
return {
|
||||||
|
@ -163,10 +180,11 @@ const mapDispatchToProps = (dispatch) => {
|
||||||
return dispatch(actions.connectHardwareAndUnlockAddress(deviceName, hdPath, address))
|
return dispatch(actions.connectHardwareAndUnlockAddress(deviceName, hdPath, address))
|
||||||
},
|
},
|
||||||
displayToast: (msg) => dispatch(actions.displayToast(msg)),
|
displayToast: (msg) => dispatch(actions.displayToast(msg)),
|
||||||
|
isCreatedWithCorrectDPath: () => dispatch(actions.isCreatedWithCorrectDPath()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
AccountsDropdownItemView: connect(null, mapDispatchToProps)(AccountsDropdownItemView),
|
AccountsDropdownItemView: connect(mapStateToProps, mapDispatchToProps)(AccountsDropdownItemView),
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ const { tokenInfoGetter, calcTokenAmount } = require('../../../ui/app/token-util
|
||||||
import BigNumber from 'bignumber.js'
|
import BigNumber from 'bignumber.js'
|
||||||
import ethNetProps from 'eth-net-props'
|
import ethNetProps from 'eth-net-props'
|
||||||
import { getMetaMaskAccounts } from '../../../ui/app/selectors'
|
import { getMetaMaskAccounts } from '../../../ui/app/selectors'
|
||||||
import ToastComponent from './toast'
|
import * as Toast from './toast'
|
||||||
|
|
||||||
const MIN_GAS_PRICE_BN = new BN('0')
|
const MIN_GAS_PRICE_BN = new BN('0')
|
||||||
const MIN_GAS_LIMIT_BN = new BN('21000')
|
const MIN_GAS_LIMIT_BN = new BN('21000')
|
||||||
|
@ -158,14 +158,15 @@ class PendingTx extends Component {
|
||||||
fontSize: '14px',
|
fontSize: '14px',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const isError = txMeta.simulationFails || !isValidAddress || insufficientBalance || (dangerousGasLimit && !gasLimitSpecified)
|
const isError = txMeta.simulationFails || !isValidAddress || insufficientBalance || (dangerousGasLimit && !gasLimitSpecified)
|
||||||
return (
|
return (
|
||||||
|
|
||||||
h('div', {
|
h('div', {
|
||||||
key: txMeta.id,
|
key: txMeta.id,
|
||||||
}, [
|
}, [
|
||||||
h(ToastComponent, {
|
h(Toast.ToastComponent, {
|
||||||
isSuccess: false,
|
type: Toast.TOAST_TYPE_ERROR,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
h('form#pending-tx-form', {
|
h('form#pending-tx-form', {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import PersistentForm from '../../../lib/persistent-form'
|
||||||
import SendProfile from './send-profile'
|
import SendProfile from './send-profile'
|
||||||
import SendHeader from './send-header'
|
import SendHeader from './send-header'
|
||||||
import ErrorComponent from '../error'
|
import ErrorComponent from '../error'
|
||||||
import ToastComponent from '../toast'
|
import * as Toast from '../toast'
|
||||||
import Select from 'react-select'
|
import Select from 'react-select'
|
||||||
import actions from '../../../../ui/app/actions'
|
import actions from '../../../../ui/app/actions'
|
||||||
import abi from 'web3-eth-abi'
|
import abi from 'web3-eth-abi'
|
||||||
|
@ -154,7 +154,7 @@ class SendTransactionScreen extends PersistentForm {
|
||||||
<SendProfile />
|
<SendProfile />
|
||||||
<SendHeader title="Execute Method" />
|
<SendHeader title="Execute Method" />
|
||||||
<ErrorComponent error={error} />
|
<ErrorComponent error={error} />
|
||||||
<ToastComponent isSuccess={true} />
|
<Toast.ToastComponent type={Toast.TOAST_TYPE_SUCCESS} />
|
||||||
<div style={{ padding: '0 30px' }}>
|
<div style={{ padding: '0 30px' }}>
|
||||||
<Select
|
<Select
|
||||||
clearable={false}
|
clearable={false}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import SendProfile from './send-profile'
|
||||||
import SendHeader from './send-header'
|
import SendHeader from './send-header'
|
||||||
import ErrorComponent from '../error'
|
import ErrorComponent from '../error'
|
||||||
import { getMetaMaskAccounts } from '../../../../ui/app/selectors'
|
import { getMetaMaskAccounts } from '../../../../ui/app/selectors'
|
||||||
import ToastComponent from '../toast'
|
import * as Toast from '../toast'
|
||||||
|
|
||||||
const optionalDataLabelStyle = {
|
const optionalDataLabelStyle = {
|
||||||
background: '#ffffff',
|
background: '#ffffff',
|
||||||
|
@ -42,7 +42,7 @@ class SendTransactionScreen extends PersistentForm {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="send-screen flex-column flex-grow">
|
<div className="send-screen flex-column flex-grow">
|
||||||
<ToastComponent isSuccess={false} />
|
<Toast.ToastComponent type={Toast.TOAST_TYPE_ERROR} />
|
||||||
<SendProfile/>
|
<SendProfile/>
|
||||||
|
|
||||||
<SendHeader
|
<SendHeader
|
||||||
|
|
|
@ -4,12 +4,18 @@ import { connect } from 'react-redux'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import actions from '../../../ui/app/actions'
|
import actions from '../../../ui/app/actions'
|
||||||
|
|
||||||
|
const TOAST_TYPE_SUCCESS = 'success'
|
||||||
|
const TOAST_TYPE_ERROR = 'error'
|
||||||
|
|
||||||
|
const ERROR_ON_INCORRECT_DPATH = 'The account is derived from ETH derivation path despite you connected to another chain. If you are ready to switch to correct derivation path, just restore from the same seed phrase.'
|
||||||
|
|
||||||
class ToastComponent extends Component {
|
class ToastComponent extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
msg: PropTypes.string,
|
msg: PropTypes.string,
|
||||||
toastMsg: PropTypes.string,
|
toastMsg: PropTypes.string,
|
||||||
isSuccess: PropTypes.bool,
|
type: PropTypes.string,
|
||||||
hideToast: PropTypes.func,
|
hideToast: PropTypes.func,
|
||||||
|
hideManually: PropTypes.bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
|
@ -19,10 +25,12 @@ class ToastComponent extends Component {
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
if ((!prevProps.msg && this.props.msg) || (!prevProps.toastMsg && this.props.toastMsg)) {
|
if ((!prevProps.msg && this.props.msg) || (!prevProps.toastMsg && this.props.toastMsg)) {
|
||||||
this.timerID = setTimeout(() => {
|
if (!this.props.hideManually) {
|
||||||
this.props.hideToast()
|
this.timerID = setTimeout(() => {
|
||||||
clearTimeout(this.timerID)
|
this.props.hideToast()
|
||||||
}, 4000)
|
clearTimeout(this.timerID)
|
||||||
|
}, 4000)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,15 +39,23 @@ class ToastComponent extends Component {
|
||||||
clearTimeout(this.timerID)
|
clearTimeout(this.timerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getClass (type) {
|
||||||
|
switch (type) {
|
||||||
|
case TOAST_TYPE_SUCCESS:
|
||||||
|
return 'green'
|
||||||
|
case TOAST_TYPE_ERROR:
|
||||||
|
return 'red'
|
||||||
|
default:
|
||||||
|
return 'green'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let toastMsg = this.props.msg || this.props.toastMsg
|
let toastMsg = this.props.msg || this.props.toastMsg
|
||||||
toastMsg = (toastMsg && toastMsg.message) || toastMsg
|
toastMsg = (toastMsg && toastMsg.message) || toastMsg
|
||||||
return toastMsg ? (
|
return toastMsg ? (
|
||||||
<div
|
<div
|
||||||
className={classnames('toast', {
|
className={classnames('toast', this._getClass(this.props.type))}
|
||||||
'green': this.props.isSuccess,
|
|
||||||
'red': !this.props.isSuccess,
|
|
||||||
})}
|
|
||||||
onClick={(e) => this.props.hideToast()}
|
onClick={(e) => this.props.hideToast()}
|
||||||
>{toastMsg}</div>
|
>{toastMsg}</div>
|
||||||
) : null
|
) : null
|
||||||
|
@ -58,4 +74,9 @@ function mapDispatchToProps (dispatch) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps, mapDispatchToProps)(ToastComponent)
|
module.exports = {
|
||||||
|
ToastComponent: connect(mapStateToProps, mapDispatchToProps)(ToastComponent),
|
||||||
|
TOAST_TYPE_SUCCESS,
|
||||||
|
TOAST_TYPE_ERROR,
|
||||||
|
ERROR_ON_INCORRECT_DPATH,
|
||||||
|
}
|
||||||
|
|
|
@ -293,7 +293,7 @@ app sections
|
||||||
color: #ffffff !important;
|
color: #ffffff !important;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 10px;
|
padding: 20px;
|
||||||
width: 357px;
|
width: 357px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
|
@ -4,6 +4,7 @@ const Component = require('react').Component
|
||||||
const connect = require('react-redux').connect
|
const connect = require('react-redux').connect
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
const actions = require('../../../../../ui/app/actions')
|
const actions = require('../../../../../ui/app/actions')
|
||||||
|
const { getDPath } = require('../../../util')
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
|
module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
|
||||||
|
|
||||||
|
@ -16,6 +17,7 @@ function mapStateToProps (state) {
|
||||||
return {
|
return {
|
||||||
warning: state.appState.warning,
|
warning: state.appState.warning,
|
||||||
dPath: state.metamask.dPath,
|
dPath: state.metamask.dPath,
|
||||||
|
provider: state.metamask.provider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +117,9 @@ RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RevealSeedConfirmation.prototype.revealSeedWords = function () {
|
RevealSeedConfirmation.prototype.revealSeedWords = async function () {
|
||||||
const password = document.getElementById('password-box').value
|
const password = document.getElementById('password-box').value
|
||||||
this.props.dispatch(actions.requestRevealSeed(password, this.props.dPath))
|
const isCreatedWithCorrectDPath = this.props.dispatch(actions.isCreatedWithCorrectDPath())
|
||||||
|
const dPath = getDPath(this.props.provider.type, isCreatedWithCorrectDPath)
|
||||||
|
this.props.dispatch(actions.requestRevealSeed(password, dPath))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ const PersistentForm = require('../../../lib/persistent-form')
|
||||||
const connect = require('react-redux').connect
|
const connect = require('react-redux').connect
|
||||||
const h = require('react-hyperscript')
|
const h = require('react-hyperscript')
|
||||||
const actions = require('../../../../ui/app/actions')
|
const actions = require('../../../../ui/app/actions')
|
||||||
|
const { getDPath } = require('../../util')
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(RestoreVaultScreen)
|
module.exports = connect(mapStateToProps)(RestoreVaultScreen)
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ function mapStateToProps (state) {
|
||||||
return {
|
return {
|
||||||
warning: state.appState.warning,
|
warning: state.appState.warning,
|
||||||
forgottenPassword: state.appState.forgottenPassword,
|
forgottenPassword: state.appState.forgottenPassword,
|
||||||
|
provider: state.metamask.provider,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,5 +187,7 @@ RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
|
||||||
// submit
|
// submit
|
||||||
this.warning = null
|
this.warning = null
|
||||||
this.props.dispatch(actions.displayWarning(this.warning))
|
this.props.dispatch(actions.displayWarning(this.warning))
|
||||||
this.props.dispatch(actions.createNewVaultAndRestore(password, seed))
|
const isCreatedWithCorrectDPath = true
|
||||||
|
const dPath = getDPath(this.props.provider.type, isCreatedWithCorrectDPath)
|
||||||
|
this.props.dispatch(actions.createNewVaultAndRestore(password, seed, dPath))
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,11 +111,13 @@ UnlockScreen.prototype.onKeyPress = function (event) {
|
||||||
UnlockScreen.prototype.submitPassword = async function (event) {
|
UnlockScreen.prototype.submitPassword = async function (event) {
|
||||||
const element = event.target
|
const element = event.target
|
||||||
const password = element.value
|
const password = element.value
|
||||||
|
const props = this.props
|
||||||
// reset input
|
// reset input
|
||||||
element.value = ''
|
element.value = ''
|
||||||
try {
|
try {
|
||||||
const dPath = getDPath(this.props.provider.type) || this.props.dPath
|
const isCreatedWithCorrectDPath = await props.dispatch(actions.isCreatedWithCorrectDPath())
|
||||||
await this.props.dispatch(actions.tryUnlockMetamask(password, dPath))
|
const dPath = getDPath(props.provider.type, isCreatedWithCorrectDPath) || props.dPath
|
||||||
|
await props.dispatch(actions.tryUnlockMetamask(password, dPath))
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log.error(e)
|
log.error(e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ const {
|
||||||
RSK,
|
RSK,
|
||||||
RSK_TESTNET,
|
RSK_TESTNET,
|
||||||
RSK_TICK,
|
RSK_TICK,
|
||||||
// customDPaths,
|
customDPaths,
|
||||||
} = require('../../app/scripts/controllers/network/enums')
|
} = require('../../app/scripts/controllers/network/enums')
|
||||||
|
|
||||||
const valueTable = {
|
const valueTable = {
|
||||||
|
@ -88,6 +88,7 @@ module.exports = {
|
||||||
ifHardwareAcc,
|
ifHardwareAcc,
|
||||||
getAllKeyRingsAccounts,
|
getAllKeyRingsAccounts,
|
||||||
ifRSK,
|
ifRSK,
|
||||||
|
ifETC,
|
||||||
ifRSKByProviderType,
|
ifRSKByProviderType,
|
||||||
ifPOA,
|
ifPOA,
|
||||||
toChecksumAddress,
|
toChecksumAddress,
|
||||||
|
@ -432,6 +433,12 @@ function ifRSK (network) {
|
||||||
return numericNet === RSK_CODE || numericNet === RSK_TESTNET_CODE
|
return numericNet === RSK_CODE || numericNet === RSK_TESTNET_CODE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ifETC (network) {
|
||||||
|
if (!network) return false
|
||||||
|
const numericNet = isNaN(network) ? network : parseInt(network)
|
||||||
|
return numericNet === CLASSIC_CODE
|
||||||
|
}
|
||||||
|
|
||||||
function ifRSKByProviderType (type) {
|
function ifRSKByProviderType (type) {
|
||||||
if (!type) return false
|
if (!type) return false
|
||||||
return type === RSK || type === RSK_TESTNET
|
return type === RSK || type === RSK_TESTNET
|
||||||
|
@ -557,14 +564,16 @@ function getNetworkID ({ network }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDPath (network) {
|
function getDPath (networkType, isCreatedWithCorrectDPath) {
|
||||||
// todo: return when the robust solution will be ready
|
if (isCreatedWithCorrectDPath) {
|
||||||
return `m/44'/60'/0'/0`
|
return customDPaths[networkType] || `m/44'/60'/0'/0`
|
||||||
// return customDPaths[network] || `m/44'/60'/0'/0`
|
} else {
|
||||||
|
return `m/44'/60'/0'/0`
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDPath (keyring, network) {
|
function setDPath (keyring, networkType, isCreatedWithCorrectDPath) {
|
||||||
const dPath = getDPath(network)
|
const dPath = getDPath(networkType, isCreatedWithCorrectDPath)
|
||||||
if (dPath && keyring.setHdPath) {
|
if (dPath && keyring.setHdPath) {
|
||||||
keyring.setHdPath(dPath)
|
keyring.setHdPath(dPath)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const Func = require('./func').Functions
|
const Func = require('./func').Functions
|
||||||
const account1 = '0x2E428ABd9313D256d64D1f69fe3929C3BE18fD1f'
|
const account1 = '0x2E428ABd9313D256d64D1f69fe3929C3BE18fD1f'
|
||||||
// todo:
|
const account1RSK = '0x7a9bc05F7441d862d1B83CB724861a9872FF43fe'
|
||||||
// const account1RSK = '0x7a9bc05F7441d862d1B83CB724861a9872FF43fe'
|
|
||||||
const account1RSK = '0x2E428aBd9313D256d64D1f69fe3929c3Be18Fd1F'
|
|
||||||
const account2 = '0xd7b7AFeCa35e32594e29504771aC847E2a803742'
|
const account2 = '0xd7b7AFeCa35e32594e29504771aC847E2a803742'
|
||||||
const testsFolder = './test-cases'
|
const testsFolder = './test-cases'
|
||||||
const setup = require(`${testsFolder}/setup.spec`)
|
const setup = require(`${testsFolder}/setup.spec`)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const assert = require('assert')
|
import assert from 'assert'
|
||||||
const clone = require('clone')
|
import clone from 'clone'
|
||||||
const KeyringController = require('eth-keychain-controller')
|
import KeyringController from 'eth-keychain-controller'
|
||||||
|
import seedPhraseVerifier from '../../../app/scripts/lib/seed-phrase-verifier'
|
||||||
const firstTimeState = require('../../../app/scripts/first-time-state')
|
const firstTimeState = require('../../../app/scripts/first-time-state')
|
||||||
const seedPhraseVerifier = require('../../../app/scripts/lib/seed-phrase-verifier')
|
|
||||||
const mockEncryptor = require('../../lib/mock-encryptor')
|
const mockEncryptor = require('../../lib/mock-encryptor')
|
||||||
|
|
||||||
describe('SeedPhraseVerifier', function () {
|
describe('SeedPhraseVerifier', function () {
|
||||||
|
|
|
@ -235,7 +235,7 @@ describe('Actions', () => {
|
||||||
|
|
||||||
createNewVaultAndRestoreSpy = sinon.stub(background, 'createNewVaultAndRestore')
|
createNewVaultAndRestoreSpy = sinon.stub(background, 'createNewVaultAndRestore')
|
||||||
|
|
||||||
createNewVaultAndRestoreSpy.callsFake((password, seed, callback) => {
|
createNewVaultAndRestoreSpy.callsFake((password, seed, dPath, callback) => {
|
||||||
callback(new Error('error'))
|
callback(new Error('error'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -370,6 +370,7 @@ const actions = {
|
||||||
getRequestAccountTabIds,
|
getRequestAccountTabIds,
|
||||||
setOpenMetamaskTabsIDs,
|
setOpenMetamaskTabsIDs,
|
||||||
getOpenMetamaskTabsIds,
|
getOpenMetamaskTabsIds,
|
||||||
|
isCreatedWithCorrectDPath,
|
||||||
closeCurrentNotificationWindow,
|
closeCurrentNotificationWindow,
|
||||||
closeNotificationWindow,
|
closeNotificationWindow,
|
||||||
}
|
}
|
||||||
|
@ -406,7 +407,12 @@ function tryUnlockMetamask (password, dPath) {
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
dispatch(actions.unlockSucceeded())
|
dispatch(actions.unlockSucceeded())
|
||||||
return forceUpdateMetamaskState(dispatch)
|
return updateMetamaskStateFromBackground()
|
||||||
|
.then(newState => {
|
||||||
|
newState = Object.assign(newState, {dPath: dPath})
|
||||||
|
dispatch(actions.updateMetamaskState(newState))
|
||||||
|
forceUpdateMetamaskState(dispatch)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
log.error(err)
|
log.error(err)
|
||||||
|
@ -436,6 +442,21 @@ function tryUnlockMetamask (password, dPath) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isCreatedWithCorrectDPath () {
|
||||||
|
return dispatch => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
background.isCreatedWithCorrectDPath((err, isCreatedWithCorrectDPath) => {
|
||||||
|
if (err) {
|
||||||
|
dispatch(actions.displayWarning(err.message))
|
||||||
|
return reject(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(isCreatedWithCorrectDPath)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function transitionForward () {
|
function transitionForward () {
|
||||||
return {
|
return {
|
||||||
type: this.TRANSITION_FORWARD,
|
type: this.TRANSITION_FORWARD,
|
||||||
|
@ -468,7 +489,7 @@ function confirmSeedWords () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createNewVaultAndRestore (password, seed) {
|
function createNewVaultAndRestore (password, seed, dPath) {
|
||||||
return (dispatch) => {
|
return (dispatch) => {
|
||||||
dispatch(actions.showLoadingIndication())
|
dispatch(actions.showLoadingIndication())
|
||||||
log.debug(`background.createNewVaultAndRestore`)
|
log.debug(`background.createNewVaultAndRestore`)
|
||||||
|
@ -479,7 +500,7 @@ function createNewVaultAndRestore (password, seed) {
|
||||||
return reject(err)
|
return reject(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
background.createNewVaultAndRestore(password, seed, (err) => {
|
background.createNewVaultAndRestore(password, seed, dPath, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return reject(err)
|
return reject(err)
|
||||||
}
|
}
|
||||||
|
@ -491,6 +512,11 @@ function createNewVaultAndRestore (password, seed) {
|
||||||
.then(() => dispatch(actions.unMarkPasswordForgotten()))
|
.then(() => dispatch(actions.unMarkPasswordForgotten()))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
dispatch(actions.showAccountsPage())
|
dispatch(actions.showAccountsPage())
|
||||||
|
updateMetamaskStateFromBackground()
|
||||||
|
.then(newState => {
|
||||||
|
newState = Object.assign(newState, {dPath: dPath})
|
||||||
|
dispatch(actions.updateMetamaskState(newState))
|
||||||
|
})
|
||||||
dispatch(actions.hideLoadingIndication())
|
dispatch(actions.hideLoadingIndication())
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
const extend = require('xtend')
|
import extend from 'xtend'
|
||||||
|
import log from 'loglevel'
|
||||||
const actions = require('../actions')
|
const actions = require('../actions')
|
||||||
const txHelper = require('../../lib/tx-helper')
|
const txHelper = require('../../lib/tx-helper')
|
||||||
const { customHdPaths } = require('../../../old-ui/app/components/connect-hardware/util.js')
|
const { customHdPaths } = require('../../../old-ui/app/components/connect-hardware/util.js')
|
||||||
const log = require('loglevel')
|
|
||||||
|
|
||||||
module.exports = reduceApp
|
module.exports = reduceApp
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue