MyCrypto is an open-source, client-side tool for generating ether wallets, handling ERC-20 tokens, and interacting with the blockchain more easily. https://mycrypto.com
Go to file
William O'Beirne baea6aaf5f Use babel minifier instead of uglify (#273) 2017-10-08 18:31:26 -07:00
common Wallet Decrypt - Ledger (#238) 2017-10-05 16:29:14 -07:00
jest_config Migrate to Typescript (#224) 2017-09-24 19:06:28 -07:00
spec Migrate to Typescript (#224) 2017-09-24 19:06:28 -07:00
static Manifest and Favicons (#69) 2017-07-22 15:55:59 -05:00
webpack_config Use babel minifier instead of uglify (#273) 2017-10-08 18:31:26 -07:00
.editorconfig update .editorconfig 2017-07-04 15:16:08 +04:00
.flowconfig Flow style include fix (#75) 2017-07-27 11:50:29 -05:00
.gitignore Refresh on Network Change (#261) 2017-10-03 21:37:06 -07:00
.nvmrc Enforce node / npm versions, add package-lock.json (#57) 2017-07-18 19:41:17 -05:00
.travis.yml Travis TypeScript Compiler Checking (#263) 2017-10-04 10:51:37 -07:00
Dockerfile Enforce node / npm versions, add package-lock.json (#57) 2017-07-18 19:41:17 -05:00
LICENSE Initial commit 2016-12-04 02:35:28 +01:00
README.md Shoutout to browserstack in the readme. (#221) 2017-09-24 19:55:23 -07:00
docker-compose.yml Docker (#40) 2017-07-10 22:03:08 -05:00
package-lock.json Use babel minifier instead of uglify (#273) 2017-10-08 18:31:26 -07:00
package.json Use babel minifier instead of uglify (#273) 2017-10-08 18:31:26 -07:00
tsconfig.json Wallet Decrypt - Ledger (#238) 2017-10-05 16:29:14 -07:00
tslint.json Migrate to Typescript (#224) 2017-09-24 19:06:28 -07:00

README.md

MyEtherWallet V4+ (ALPHA - VISIT V3 for the production site)

Run:

npm run dev # run app in dev mode

Build:

npm run build # build app

It generates app in dist folder.

Test:

npm run test # run tests with Jest

Dev (HTTPS):

  1. Create your own SSL Certificate (Heroku has a nice guide here)
  2. Move the .key and .crt files into webpack_config/server.*
  3. Run the following command:
npm run dev:https

Derivation Check:

The derivation checker utility assumes that you have:
  1. Docker installed/available
  2. dternyak/eth-priv-to-addr pulled from DockerHub
Docker setup instructions:
  1. Install docker (on macOS, I suggest Docker for Mac)
  2. docker pull dternyak/eth-priv-to-addr
Run Derivation Checker
npm run derivation-checker

Folder structure:

│
├── common - Your App
│   ├── actions - application actions
│   ├── api - Services and XHR utils(also custom form validation, see InputComponent from components/common)
│   ├── components - components according to "Redux philosophy"
│   ├── config - frontend config depending on REACT_WEBPACK_ENV
│   ├── containers - containers according to "Redux philosophy"
│   ├── reducers - application reducers
│   ├── routing - application routing
│   ├── index.jsx - entry
│   ├── index.html
├── static
├── webpack_config - Webpack configuration
├── jest_config - Jest configuration

Docker setup

You should already have docker and docker-compose setup for your platform as a pre-req.

docker-compose up

Style Guides and Philosophies

The following are guides for developers to follow for writing compliant code.

Redux and Actions

Each reducer has one file in reducers/[namespace].js that contains the reducer and initial state, one file in actions/[namespace].js that contains the action creators and their return types, and optionally one file in sagas/[namespace].js that handles action side effects using redux-saga.

The files should be laid out as follows:

Reducer

  • State should be explicitly defined and exported
  • Initial state should match state flow typing, define every key
  • Reducer function should handle all cases for actions. If state does not change as a result of an action (Because it merely kicks off side-effects in saga) then define the case above default, and have it fall through.
// @flow
import type { NamespaceAction } from "actions/namespace";

export type State = { /* Flowtype definition for state object */ };
export const INITIAL_STATE: State = { /* Initial state shape */ };

export function namespace(
	state: State = INITIAL_STATE,
	action: NamespaceAction
): State {
	switch (action.type) {
		case 'NAMESPACE_NAME_OF_ACTION':
			return {
				...state,
				// Alterations to state
			};

		case 'NAMESPACE_NAME_OF_SAGA_ACTION':
		default:
			// Ensures every action was handled in reducer
			// Unhandled actions should just fall into default
			(action: empty);
			return state;
	}
}

Actions

  • Define each action object type beside the action creator
  • Export a union of all of the action types for use by the reducer
/*** Name of action ***/
export type NameOfActionAction = {
	type: 'NAMESPACE_NAME_OF_ACTION',
	/* Rest of the action object shape */
};

export function nameOfAction(): NameOfActionAction {
	return {
		type: 'NAMESPACE_NAME_OF_ACTION',
		/* Rest of the action object */
	};
};

/*** Action Union ***/
export type NamespaceAction =
	| ActionOneAction
	| ActionTwoAction
	| ActionThreeAction;

Action Constants

Action constants are not used thanks to flow type checking. To avoid typos, we use (action: empty) in the default case which assures every case is accounted for. If you need to use another reducer's action, import that action type into your reducer, and create a new action union of your actions, and the other action types used.

Styling

Legacy styles are housed under common/assets/styles and written with LESS. However, going forward, each styled component should create a a .scss file of the same name in the same folder, and import it like so:

import React from "react";

import "./MyComponent.scss";

export default class MyComponent extends React.component {
	render() {
		return (
			<div className="MyComponent">
				<div className="MyComponent-child">Hello!</div>
			</div>
		);
	}
}

These style modules adhere to SuitCSS naming convention:

.MyComponent {
	/* Styles */

	&-child {
		/* Styles */

		&.is-hidden {
			display: none;
		}
	}
}

All elements inside of a component should extend its parent class namespace, or create a new namespace (Potentially breaking that out into its own component.)

Variables and mixins can be imported from the files in common/styles:

@import "sass/colors";

code {
	color: $code-color;
}

Converting Styles

When working on a module that has styling in Less, try to do the following:

  • Screenshot the component in question
  • Create a new SCSS file in the same directory
  • Remove styling from LESS file, convert it to the SCSS file (Mostly s/@/$)
  • Convert class names to SuitCSS naming convention
  • Convert any utility classes from etherewallet-utilities.less into mixins
  • Convert as many element selectors to class name selectors as possible
  • Convert as many <br/> tags or &nbsp;s to margins
  • Ensure that there has been little to no deviation from screenshot

Thanks & Support

Cross browser testing and debugging provided by the very lovely team at BrowserStack.