Merge branch 'develop' of github.com:MetaMask/metamask-extension into network-remove-provider-engine
commit
9d77b0a196
@ -0,0 +1,14 @@ |
||||
# MetaMask Philosophy |
||||
|
||||
## Mission |
||||
|
||||
Making it safe and easy for the most people to use the decentralized web to the greatest degree that is empowering to them. |
||||
|
||||
## Vision |
||||
|
||||
To realize the highest goals achievable for the human race with the twin powers of peer to peer networks and cryptography. To empower users to hold and use their own keys on these new networks as securely and intelligibly as possible, enabling a new world of peer to peer agreements and economies, in hopes that we may collectively overcome the many great problems that we face together, through the power of strong cooperation. |
||||
|
||||
## Strategy |
||||
|
||||
We provide software for users to manage accounts, for sites to easily propose actions to users, and for users to coherently review actions before approving them. We build on this rapidly evolving set of protocols with the goal of empowering the most people to the greatest degree, and aspire to continuously evolve our offering to pursue that goal. |
||||
|
After Width: | Height: | Size: 1.0 KiB |
@ -0,0 +1,17 @@ |
||||
const MessageManager = require('./lib/message-manager') |
||||
const PersonalMessageManager = require('./lib/personal-message-manager') |
||||
const TypedMessageManager = require('./lib/typed-message-manager') |
||||
|
||||
class UserActionController { |
||||
|
||||
constructor (opts = {}) { |
||||
|
||||
this.messageManager = new MessageManager() |
||||
this.personalMessageManager = new PersonalMessageManager() |
||||
this.typedMessageManager = new TypedMessageManager() |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
module.exports = UserActionController |
@ -0,0 +1,24 @@ |
||||
/** |
||||
* Returns error without stack trace for better UI display |
||||
* @param {Error} err - error |
||||
* @returns {Error} Error with clean stack trace. |
||||
*/ |
||||
function cleanErrorStack(err){ |
||||
var name = err.name |
||||
name = (name === undefined) ? 'Error' : String(name) |
||||
|
||||
var msg = err.message |
||||
msg = (msg === undefined) ? '' : String(msg) |
||||
|
||||
if (name === '') { |
||||
err.stack = err.message |
||||
} else if (msg === '') { |
||||
err.stack = err.name |
||||
} else { |
||||
err.stack = err.name + ': ' + err.message |
||||
} |
||||
|
||||
return err |
||||
} |
||||
|
||||
module.exports = cleanErrorStack |
@ -0,0 +1,71 @@ |
||||
class DiagnosticsReporter { |
||||
|
||||
constructor ({ firstTimeInfo, version }) { |
||||
this.firstTimeInfo = firstTimeInfo |
||||
this.version = version |
||||
} |
||||
|
||||
async reportOrphans(orphans) { |
||||
try { |
||||
return await this.submit({ |
||||
accounts: Object.keys(orphans), |
||||
metadata: { |
||||
type: 'orphans', |
||||
}, |
||||
}) |
||||
} catch (err) { |
||||
console.error('DiagnosticsReporter - "reportOrphans" encountered an error:') |
||||
console.error(err) |
||||
} |
||||
} |
||||
|
||||
async reportMultipleKeyrings(rawKeyrings) { |
||||
try { |
||||
const keyrings = await Promise.all(rawKeyrings.map(async (keyring, index) => { |
||||
return { |
||||
index, |
||||
type: keyring.type, |
||||
accounts: await keyring.getAccounts(), |
||||
} |
||||
})) |
||||
return await this.submit({ |
||||
accounts: [], |
||||
metadata: { |
||||
type: 'keyrings', |
||||
keyrings, |
||||
}, |
||||
}) |
||||
} catch (err) { |
||||
console.error('DiagnosticsReporter - "reportMultipleKeyrings" encountered an error:') |
||||
console.error(err) |
||||
} |
||||
} |
||||
|
||||
async submit (message) { |
||||
try { |
||||
// add metadata
|
||||
message.metadata.version = this.version |
||||
message.metadata.firstTimeInfo = this.firstTimeInfo |
||||
return await postData(message) |
||||
} catch (err) { |
||||
console.error('DiagnosticsReporter - "submit" encountered an error:') |
||||
throw err |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
function postData(data) { |
||||
const uri = 'https://diagnostics.metamask.io/v1/orphanedAccounts' |
||||
return fetch(uri, { |
||||
body: JSON.stringify(data), // must match 'Content-Type' header
|
||||
credentials: 'same-origin', // include, same-origin, *omit
|
||||
headers: { |
||||
'content-type': 'application/json', |
||||
}, |
||||
method: 'POST', // *GET, POST, PUT, DELETE, etc.
|
||||
mode: 'cors', // no-cors, cors, *same-origin
|
||||
}) |
||||
} |
||||
|
||||
module.exports = DiagnosticsReporter |
@ -1,5 +1,9 @@ |
||||
@import './export-text-container/index'; |
||||
|
||||
@import './selected-account/index'; |
||||
|
||||
@import './info-box/index'; |
||||
|
||||
@import './pages/index'; |
||||
|
||||
@import './modals/index'; |
||||
|
@ -0,0 +1,54 @@ |
||||
import React, { Component } from 'react' |
||||
import PropTypes from 'prop-types' |
||||
import Button from '../../button' |
||||
|
||||
class ConfirmResetAccount extends Component { |
||||
static propTypes = { |
||||
hideModal: PropTypes.func.isRequired, |
||||
resetAccount: PropTypes.func.isRequired, |
||||
} |
||||
|
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
} |
||||
|
||||
handleReset () { |
||||
this.props.resetAccount() |
||||
.then(() => this.props.hideModal()) |
||||
} |
||||
|
||||
render () { |
||||
const { t } = this.context |
||||
|
||||
return ( |
||||
<div className="modal-container"> |
||||
<div className="modal-container__content"> |
||||
<div className="modal-container__title"> |
||||
{ `${t('resetAccount')}?` } |
||||
</div> |
||||
<div className="modal-container__description"> |
||||
{ t('resetAccountDescription') } |
||||
</div> |
||||
</div> |
||||
<div className="modal-container__footer"> |
||||
<Button |
||||
type="default" |
||||
className="modal-container__footer-button" |
||||
onClick={() => this.props.hideModal()} |
||||
> |
||||
{ t('nevermind') } |
||||
</Button> |
||||
<Button |
||||
type="secondary" |
||||
className="modal-container__footer-button" |
||||
onClick={() => this.handleReset()} |
||||
> |
||||
{ t('reset') } |
||||
</Button> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
|
||||
export default ConfirmResetAccount |
@ -0,0 +1,13 @@ |
||||
import { connect } from 'react-redux' |
||||
import ConfirmResetAccount from './confirm-reset-account.component' |
||||
|
||||
const { hideModal, resetAccount } = require('../../../actions') |
||||
|
||||
const mapDispatchToProps = dispatch => { |
||||
return { |
||||
hideModal: () => dispatch(hideModal()), |
||||
resetAccount: () => dispatch(resetAccount()), |
||||
} |
||||
} |
||||
|
||||
export default connect(null, mapDispatchToProps)(ConfirmResetAccount) |
@ -0,0 +1,2 @@ |
||||
import ConfirmResetAccount from './confirm-reset-account.container' |
||||
module.exports = ConfirmResetAccount |
@ -0,0 +1,52 @@ |
||||
.modal-container { |
||||
width: 100%; |
||||
height: 100%; |
||||
background-color: #fff; |
||||
display: flex; |
||||
flex-flow: column; |
||||
border-radius: 8px; |
||||
|
||||
&__title { |
||||
font-size: 1.5rem; |
||||
font-weight: 500; |
||||
padding: 16px 0; |
||||
text-align: center; |
||||
} |
||||
|
||||
&__description { |
||||
text-align: center; |
||||
font-size: .875rem; |
||||
} |
||||
|
||||
&__content { |
||||
overflow-y: auto; |
||||
flex: 1; |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: center; |
||||
padding: 32px; |
||||
|
||||
@media screen and (max-width: 575px) { |
||||
justify-content: center; |
||||
padding: 28px 20px; |
||||
} |
||||
} |
||||
|
||||
&__footer { |
||||
display: flex; |
||||
flex-flow: row; |
||||
justify-content: center; |
||||
border-top: 1px solid #d2d8dd; |
||||
padding: 16px; |
||||
flex: 0 0 auto; |
||||
|
||||
&-button { |
||||
min-width: 0; |
||||
margin-right: 16px; |
||||
|
||||
&:last-of-type { |
||||
margin-right: 0; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,46 +0,0 @@ |
||||
const { Component } = require('react') |
||||
const PropTypes = require('prop-types') |
||||
const h = require('react-hyperscript') |
||||
const connect = require('react-redux').connect |
||||
const actions = require('../../../actions') |
||||
const NotifcationModal = require('../notification-modal') |
||||
|
||||
class ConfirmResetAccount extends Component { |
||||
render () { |
||||
const { resetAccount } = this.props |
||||
|
||||
return h(NotifcationModal, { |
||||
header: 'Are you sure you want to reset account?', |
||||
message: h('div', [ |
||||
|
||||
h('span', `Resetting is for developer use only. This button wipes the current account's transaction history,
|
||||
which is used to calculate the current account nonce. `),
|
||||
|
||||
h('a.notification-modal__link', { |
||||
href: 'http://metamask.helpscoutdocs.com/article/36-resetting-an-account', |
||||
target: '_blank', |
||||
onClick (event) { global.platform.openWindow({ url: event.target.href }) }, |
||||
}, 'Read more.'), |
||||
|
||||
]), |
||||
showCancelButton: true, |
||||
showConfirmButton: true, |
||||
onConfirm: resetAccount, |
||||
|
||||
}) |
||||
} |
||||
} |
||||
|
||||
ConfirmResetAccount.propTypes = { |
||||
resetAccount: PropTypes.func, |
||||
} |
||||
|
||||
const mapDispatchToProps = dispatch => { |
||||
return { |
||||
resetAccount: () => { |
||||
dispatch(actions.resetAccount()) |
||||
}, |
||||
} |
||||
} |
||||
|
||||
module.exports = connect(null, mapDispatchToProps)(ConfirmResetAccount) |
@ -0,0 +1,2 @@ |
||||
import Notification from './notification.container' |
||||
module.exports = Notification |
@ -0,0 +1,30 @@ |
||||
import React from 'react' |
||||
import PropTypes from 'prop-types' |
||||
import Button from '../../button' |
||||
|
||||
const Notification = (props, context) => { |
||||
return ( |
||||
<div className="modal-container"> |
||||
{ props.children } |
||||
<div className="modal-container__footer"> |
||||
<Button |
||||
type="primary" |
||||
onClick={() => props.onHide()} |
||||
> |
||||
{ context.t('ok') } |
||||
</Button> |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
Notification.propTypes = { |
||||
onHide: PropTypes.func.isRequired, |
||||
children: PropTypes.element, |
||||
} |
||||
|
||||
Notification.contextTypes = { |
||||
t: PropTypes.func, |
||||
} |
||||
|
||||
export default Notification |
@ -0,0 +1,38 @@ |
||||
import { connect } from 'react-redux' |
||||
import Notification from './notification.component' |
||||
|
||||
const { hideModal } = require('../../../actions') |
||||
|
||||
const mapStateToProps = state => { |
||||
const { appState: { modal: { modalState: { props } } } } = state |
||||
const { onHide } = props |
||||
return { |
||||
onHide, |
||||
} |
||||
} |
||||
|
||||
const mapDispatchToProps = dispatch => { |
||||
return { |
||||
hideModal: () => dispatch(hideModal()), |
||||
} |
||||
} |
||||
|
||||
const mergeProps = (stateProps, dispatchProps, ownProps) => { |
||||
const { onHide, ...otherStateProps } = stateProps |
||||
const { hideModal, ...otherDispatchProps } = dispatchProps |
||||
|
||||
return { |
||||
...otherStateProps, |
||||
...otherDispatchProps, |
||||
...ownProps, |
||||
onHide: () => { |
||||
hideModal() |
||||
|
||||
if (onHide && typeof onHide === 'function') { |
||||
onHide() |
||||
} |
||||
}, |
||||
} |
||||
} |
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(Notification) |
@ -0,0 +1,2 @@ |
||||
import TransactionConfirmed from './transaction-confirmed.component' |
||||
module.exports = TransactionConfirmed |
@ -0,0 +1,24 @@ |
||||
import React from 'react' |
||||
import PropTypes from 'prop-types' |
||||
|
||||
const TransactionConfirmed = (props, context) => { |
||||
const { t } = context |
||||
|
||||
return ( |
||||
<div className="modal-container__content"> |
||||
<img src="images/check-icon.svg" /> |
||||
<div className="modal-container__title"> |
||||
{ `${t('confirmed')}!` } |
||||
</div> |
||||
<div className="modal-container__description"> |
||||
{ t('initialTransactionConfirmed') } |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
TransactionConfirmed.contextTypes = { |
||||
t: PropTypes.func, |
||||
} |
||||
|
||||
export default TransactionConfirmed |
@ -0,0 +1,2 @@ |
||||
import WelcomeBeta from './welcome-beta.component' |
||||
module.exports = WelcomeBeta |
@ -0,0 +1,23 @@ |
||||
import React from 'react' |
||||
import PropTypes from 'prop-types' |
||||
|
||||
const TransactionConfirmed = (props, context) => { |
||||
const { t } = context |
||||
|
||||
return ( |
||||
<div className="modal-container__content"> |
||||
<div className="modal-container__title"> |
||||
{ `${t('uiWelcome')}` } |
||||
</div> |
||||
<div className="modal-container__description"> |
||||
{ t('uiWelcomeMessage') } |
||||
</div> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
TransactionConfirmed.contextTypes = { |
||||
t: PropTypes.func, |
||||
} |
||||
|
||||
export default TransactionConfirmed |
@ -0,0 +1,2 @@ |
||||
import SelectedAccount from './selected-account.container' |
||||
module.exports = SelectedAccount |
@ -0,0 +1,38 @@ |
||||
.selected-account { |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
align-items: center; |
||||
flex: 1; |
||||
|
||||
&__name { |
||||
max-width: 200px; |
||||
text-overflow: ellipsis; |
||||
overflow: hidden; |
||||
white-space: nowrap; |
||||
text-align: center; |
||||
} |
||||
|
||||
&__address { |
||||
font-size: .75rem; |
||||
color: $silver-chalice; |
||||
} |
||||
|
||||
&__clickable { |
||||
display: flex; |
||||
flex-direction: column; |
||||
align-items: center; |
||||
justify-content: center; |
||||
padding: 5px 15px; |
||||
border-radius: 10px; |
||||
cursor: pointer; |
||||
|
||||
&:hover { |
||||
background-color: #e8e6e8; |
||||
} |
||||
|
||||
&:active { |
||||
background-color: #d9d7da; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,60 @@ |
||||
import React, { Component } from 'react' |
||||
import PropTypes from 'prop-types' |
||||
import copyToClipboard from 'copy-to-clipboard' |
||||
|
||||
const Tooltip = require('../tooltip-v2.js') |
||||
|
||||
const addressStripper = (address = '') => { |
||||
if (address.length < 4) { |
||||
return address |
||||
} |
||||
|
||||
return `${address.slice(0, 4)}...${address.slice(-4)}` |
||||
} |
||||
|
||||
class SelectedAccount extends Component { |
||||
state = { |
||||
copied: false, |
||||
} |
||||
|
||||
static contextTypes = { |
||||
t: PropTypes.func, |
||||
} |
||||
|
||||
static propTypes = { |
||||
selectedAddress: PropTypes.string, |
||||
selectedIdentity: PropTypes.object, |
||||
} |
||||
|
||||
render () { |
||||
const { t } = this.context |
||||
const { selectedAddress, selectedIdentity } = this.props |
||||
|
||||
return ( |
||||
<div className="selected-account"> |
||||
<Tooltip |
||||
position="bottom" |
||||
title={this.state.copied ? t('copiedExclamation') : t('copyToClipboard')} |
||||
> |
||||
<div |
||||
className="selected-account__clickable" |
||||
onClick={() => { |
||||
this.setState({ copied: true }) |
||||
setTimeout(() => this.setState({ copied: false }), 3000) |
||||
copyToClipboard(selectedAddress) |
||||
}} |
||||
> |
||||
<div className="selected-account__name"> |
||||
{ selectedIdentity.name } |
||||
</div> |
||||
<div className="selected-account__address"> |
||||
{ addressStripper(selectedAddress) } |
||||
</div> |
||||
</div> |
||||
</Tooltip> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
|
||||
export default SelectedAccount |
@ -0,0 +1,13 @@ |
||||
import { connect } from 'react-redux' |
||||
import SelectedAccount from './selected-account.component' |
||||
|
||||
const selectors = require('../../selectors') |
||||
|
||||
const mapStateToProps = state => { |
||||
return { |
||||
selectedAddress: selectors.getSelectedAddress(state), |
||||
selectedIdentity: selectors.getSelectedIdentity(state), |
||||
} |
||||
} |
||||
|
||||
export default connect(mapStateToProps)(SelectedAccount) |
Loading…
Reference in new issue