A Metamask fork with Infura removed and default networks editable
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ciphermask/ui/app/reducers/app.js

603 lines
15 KiB

const extend = require('xtend')
const actions = require('../actions')
const txHelper = require('../../lib/tx-helper')
const notification = require('../../../app/scripts/lib/notifications')
module.exports = reduceApp
9 years ago
function reduceApp (state, action) {
log.debug('App Reducer got ' + action.type)
// clone and defaults
const selectedAddress = state.metamask.selectedAddress
const pendingTxs = hasPendingTxs(state)
let name = 'accounts'
if (selectedAddress) {
name = 'accountDetail'
}
if (pendingTxs) {
name = 'confTx'
}
var defaultView = {
name,
detailView: null,
context: selectedAddress,
}
// confirm seed words
var seedWords = state.metamask.seedWords
var seedConfView = {
name: 'createVaultComplete',
seedWords,
}
var appState = extend({
menuOpen: false,
currentView: seedWords ? seedConfView : defaultView,
accountDetail: {
subview: 'transactions',
},
transForward: true, // Used to render transition direction
isLoading: false, // Used to display loading indicator
warning: null, // Used to display error text
}, state.appState)
switch (action.type) {
// transition methods
case actions.TRANSITION_FORWARD:
return extend(appState, {
transForward: true,
})
case actions.TRANSITION_BACKWARD:
return extend(appState, {
transForward: false,
})
// intialize
9 years ago
case actions.SHOW_CREATE_VAULT:
return extend(appState, {
currentView: {
name: 'createVault',
},
transForward: true,
warning: null,
})
9 years ago
case actions.SHOW_RESTORE_VAULT:
return extend(appState, {
currentView: {
name: 'restoreVault',
},
transForward: true,
forgottenPassword: true,
9 years ago
})
case actions.FORGOT_PASSWORD:
return extend(appState, {
currentView: {
name: 'restoreVault',
},
transForward: false,
forgottenPassword: true,
9 years ago
})
9 years ago
case actions.SHOW_INIT_MENU:
return extend(appState, {
currentView: defaultView,
transForward: false,
})
9 years ago
case actions.SHOW_CONFIG_PAGE:
return extend(appState, {
currentView: {
name: 'config',
context: appState.currentView.context,
},
transForward: action.value,
})
case actions.SHOW_IMPORT_PAGE:
return extend(appState, {
currentView: {
name: 'import-menu',
},
transForward: true,
})
9 years ago
case actions.SHOW_INFO_PAGE:
return extend(appState, {
currentView: {
name: 'info',
context: appState.currentView.context,
},
transForward: true,
})
9 years ago
case actions.CREATE_NEW_VAULT_IN_PROGRESS:
return extend(appState, {
currentView: {
name: 'createVault',
inProgress: true,
},
transForward: true,
isLoading: true,
})
9 years ago
case actions.SHOW_NEW_VAULT_SEED:
return extend(appState, {
currentView: {
name: 'createVaultComplete',
seedWords: action.value,
},
transForward: true,
isLoading: false,
})
case actions.NEW_ACCOUNT_SCREEN:
return extend(appState, {
currentView: {
name: 'new-account',
context: appState.currentView.context,
},
transForward: true,
})
9 years ago
case actions.SHOW_SEND_PAGE:
return extend(appState, {
currentView: {
name: 'sendTransaction',
context: appState.currentView.context,
},
transForward: true,
warning: null,
})
case actions.SHOW_NEW_KEYCHAIN:
return extend(appState, {
currentView: {
name: 'newKeychain',
8 years ago
context: appState.currentView.context,
},
transForward: true,
})
9 years ago
// unlock
9 years ago
case actions.UNLOCK_METAMASK:
return extend(appState, {
forgottenPassword: appState.forgottenPassword ? !appState.forgottenPassword : null,
9 years ago
detailView: {},
transForward: true,
isLoading: false,
warning: null,
})
case actions.LOCK_METAMASK:
return extend(appState, {
currentView: defaultView,
transForward: false,
9 years ago
warning: null,
})
case actions.BACK_TO_INIT_MENU:
return extend(appState, {
warning: null,
transForward: false,
forgottenPassword: true,
currentView: {
name: 'InitMenu',
},
})
case actions.BACK_TO_UNLOCK_VIEW:
return extend(appState, {
warning: null,
transForward: true,
forgottenPassword: false,
currentView: {
name: 'UnlockScreen',
},
})
9 years ago
// reveal seed words
case actions.REVEAL_SEED_CONFIRMATION:
return extend(appState, {
currentView: {
9 years ago
name: 'reveal-seed-conf',
},
9 years ago
transForward: true,
warning: null,
})
9 years ago
// accounts
case actions.SET_SELECTED_ACCOUNT:
return extend(appState, {
9 years ago
activeAddress: action.value,
})
case actions.GO_HOME:
return extend(appState, {
currentView: extend(appState.currentView, {
name: 'accountDetail',
}),
accountDetail: {
subview: 'transactions',
accountExport: 'none',
privateKey: '',
},
transForward: false,
warning: null,
9 years ago
})
case actions.SHOW_ACCOUNT_DETAIL:
return extend(appState, {
forgottenPassword: appState.forgottenPassword ? !appState.forgottenPassword : null,
currentView: {
name: 'accountDetail',
9 years ago
context: action.value,
},
accountDetail: {
subview: 'transactions',
9 years ago
accountExport: 'none',
privateKey: '',
},
9 years ago
transForward: false,
})
9 years ago
case actions.BACK_TO_ACCOUNT_DETAIL:
return extend(appState, {
currentView: {
name: 'accountDetail',
context: action.value,
},
accountDetail: {
subview: 'transactions',
accountExport: 'none',
privateKey: '',
},
transForward: false,
})
case actions.SHOW_ACCOUNTS_PAGE:
return extend(appState, {
currentView: {
name: seedWords ? 'createVaultComplete' : 'accounts',
seedWords,
},
transForward: true,
isLoading: false,
warning: null,
9 years ago
scrollToBottom: false,
forgottenPassword: false,
9 years ago
})
case actions.SHOW_NOTICE:
return extend(appState, {
transForward: true,
isLoading: false,
})
9 years ago
case actions.REVEAL_ACCOUNT:
return extend(appState, {
scrollToBottom: true,
})
case actions.SHOW_CONF_TX_PAGE:
return extend(appState, {
currentView: {
name: pendingTxs ? 'confTx' : 'account-detail',
9 years ago
context: 0,
},
transForward: action.transForward,
warning: null,
isLoading: false,
9 years ago
})
case actions.SHOW_CONF_MSG_PAGE:
return extend(appState, {
currentView: {
name: pendingTxs ? 'confTx' : 'account-detail',
9 years ago
context: 0,
},
transForward: true,
warning: null,
isLoading: false,
9 years ago
})
case actions.COMPLETED_TX:
log.debug('reducing COMPLETED_TX')
var { unapprovedTxs, unapprovedMsgs,
unapprovedPersonalMsgs, network } = state.metamask
9 years ago
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
.filter(tx => tx !== tx.id)
log.debug(`actions - COMPLETED_TX with ${unconfTxList.length} txs`)
9 years ago
if (unconfTxList && unconfTxList.length > 0) {
log.debug('reducer detected txs - rendering confTx view')
9 years ago
return extend(appState, {
transForward: false,
currentView: {
name: 'confTx',
context: 0,
},
warning: null,
})
} else {
log.debug('attempting to close popup')
notification.closePopup()
8 years ago
9 years ago
return extend(appState, {
transForward: false,
warning: null,
currentView: {
name: 'accountDetail',
context: state.metamask.selectedAddress,
9 years ago
},
accountDetail: {
subview: 'transactions',
},
})
}
9 years ago
case actions.NEXT_TX:
return extend(appState, {
transForward: true,
currentView: {
name: 'confTx',
context: ++appState.currentView.context,
warning: null,
},
})
case actions.VIEW_PENDING_TX:
const context = indexForPending(state, action.value)
return extend(appState, {
transForward: true,
currentView: {
name: 'confTx',
context,
warning: null,
},
})
case actions.PREVIOUS_TX:
return extend(appState, {
transForward: false,
currentView: {
name: 'confTx',
context: --appState.currentView.context,
warning: null,
},
})
case actions.TRANSACTION_ERROR:
return extend(appState, {
currentView: {
name: 'confTx',
errorMessage: 'There was a problem submitting this transaction.',
},
})
case actions.UNLOCK_FAILED:
return extend(appState, {
warning: action.value || 'Incorrect password. Try again.',
9 years ago
})
case actions.SHOW_LOADING:
return extend(appState, {
isLoading: true,
loadingMessage: action.value,
9 years ago
})
case actions.HIDE_LOADING:
return extend(appState, {
isLoading: false,
})
8 years ago
case actions.SHOW_SUB_LOADING_INDICATION:
return extend(appState, {
isSubLoading: true,
})
case actions.HIDE_SUB_LOADING_INDICATION:
return extend(appState, {
isSubLoading: false,
})
9 years ago
case actions.CLEAR_SEED_WORD_CACHE:
return extend(appState, {
transForward: true,
currentView: {},
isLoading: false,
accountDetail: {
subview: 'transactions',
accountExport: 'none',
privateKey: '',
},
})
case actions.DISPLAY_WARNING:
return extend(appState, {
warning: action.value,
})
case actions.HIDE_WARNING:
return extend(appState, {
warning: undefined,
})
case actions.REQUEST_ACCOUNT_EXPORT:
return extend(appState, {
transForward: true,
currentView: {
name: 'accountDetail',
context: appState.currentView.context,
},
accountDetail: {
subview: 'export',
accountExport: 'requested',
},
})
case actions.EXPORT_ACCOUNT:
return extend(appState, {
accountDetail: {
subview: 'export',
accountExport: 'completed',
},
})
case actions.SHOW_PRIVATE_KEY:
return extend(appState, {
accountDetail: {
subview: 'export',
accountExport: 'completed',
privateKey: action.value,
},
})
case actions.BUY_ETH_VIEW:
return extend(appState, {
transForward: true,
currentView: {
name: 'buyEth',
context: appState.currentView.name,
},
buyView: {
8 years ago
subview: 'buyForm',
amount: '15.00',
buyAddress: action.value,
8 years ago
formView: {
coinbase: true,
shapeshift: false,
},
},
})
case actions.UPDATE_BUY_ADDRESS:
return extend(appState, {
buyView: {
8 years ago
subview: 'buyForm',
formView: {
coinbase: appState.buyView.formView.coinbase,
shapeshift: appState.buyView.formView.shapeshift,
8 years ago
},
buyAddress: action.value,
amount: appState.buyView.amount,
8 years ago
},
})
case actions.UPDATE_COINBASE_AMOUNT:
return extend(appState, {
buyView: {
8 years ago
subview: 'buyForm',
formView: {
coinbase: true,
shapeshift: false,
},
buyAddress: appState.buyView.buyAddress,
8 years ago
amount: action.value,
},
})
case actions.COINBASE_SUBVIEW:
return extend(appState, {
buyView: {
8 years ago
subview: 'buyForm',
formView: {
coinbase: true,
shapeshift: false,
},
buyAddress: appState.buyView.buyAddress,
amount: appState.buyView.amount,
8 years ago
},
})
case actions.SHAPESHIFT_SUBVIEW:
return extend(appState, {
buyView: {
8 years ago
subview: 'buyForm',
formView: {
coinbase: false,
shapeshift: true,
marketinfo: action.value.marketinfo,
coinOptions: action.value.coinOptions,
},
buyAddress: appState.buyView.buyAddress,
amount: appState.buyView.amount,
8 years ago
},
})
case actions.PAIR_UPDATE:
return extend(appState, {
buyView: {
8 years ago
subview: 'buyForm',
formView: {
coinbase: false,
shapeshift: true,
marketinfo: action.value.marketinfo,
coinOptions: appState.buyView.formView.coinOptions,
8 years ago
},
buyAddress: appState.buyView.buyAddress,
amount: appState.buyView.amount,
8 years ago
warning: null,
},
})
case actions.SHOW_QR:
8 years ago
return extend(appState, {
qrRequested: true,
transForward: true,
Qr: {
message: action.value.message,
data: action.value.data,
},
})
case actions.SHOW_QR_VIEW:
return extend(appState, {
currentView: {
name: 'qr',
context: appState.currentView.context,
},
transForward: true,
Qr: {
message: action.value.message,
data: action.value.data,
},
})
default:
9 years ago
return appState
}
}
function hasPendingTxs (state) {
var { unapprovedTxs, unapprovedMsgs,
unapprovedPersonalMsgs, network } = state.metamask
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
var has = unconfTxList.length > 0
log.debug('checking if state has pending txs, concluded ' + has)
return unconfTxList.length > 0
}
9 years ago
function indexForPending (state, txId) {
var unapprovedTxs = state.metamask.unapprovedTxs
var unapprovedMsgs = state.metamask.unapprovedMsgs
var network = state.metamask.network
var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, network)
let idx
unconfTxList.forEach((tx, i) => {
if (tx.id === txId) {
idx = i
}
})
return idx
}