Skip to content

Commit

Permalink
Merge pull request #113 from echoprotocol/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
doomdabidon authored Oct 28, 2019
2 parents ec06cdb + b320aaf commit 90ab78c
Show file tree
Hide file tree
Showing 137 changed files with 6,493 additions and 9,018 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ jobs:
script:
- rm -rf node_modules
- "docker run --rm -v ${PWD}:/project -v ${PWD}/.cache/electron:/root/.cache/electron -v ${PWD}/.cache/electron-builder:/root/.cache/electron-builder electronuserland/builder:wine /bin/bash -c \"npm install && npm run package-win\""
- ls -la build/binaries
deploy:
provider: releases
api_key: $GITHUB_OAUTH_TOKEN
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,7 @@ You will find your `.exe` build file in `build/binaries` directory.
Docker (`electronuserland/builder:10`. `10` is major NodeJS version) is recommended to avoid installing system dependencies.

```bash
docker run --rm -ti \
-v ${PWD}:/project \
electronuserland/builder:10
docker run --rm -ti -v ${PWD}:/project electronuserland/builder:10
```

Type in
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
},
"description": "Echo Wallet: Cryptocurrency wallet for Echo platform",
"homepage": "https://github.com/echoprotocol/echo-wallet",
"version": "1.4.4",
"version": "1.5.0",
"license": "MIT",
"main": "build/electron/index.js",
"scripts": {
Expand Down Expand Up @@ -53,6 +53,7 @@
"query-string": "^6.1.0",
"react": "^16.5.2",
"react-copy-to-clipboard": "^5.0.1",
"react-countdown-now": "^2.1.1",
"react-dom": "^16.5.2",
"react-hot-loader": "^4.3.10",
"react-lottie": "^1.2.3",
Expand All @@ -76,9 +77,9 @@
"babel-core": "^6.26.3",
"babel-loader": "^7.1.3",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-react": "^6.24.1",
"babel-preset-es2015": "^6.24.1",
"babel-preset-es2017": "^6.24.1",
"babel-preset-react": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"babel-preset-stage-1": "^6.24.1",
"babel-preset-stage-2": "^6.24.1",
Expand All @@ -95,6 +96,7 @@
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "7.14.3",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"git-revision-webpack-plugin": "^3.0.4",
"html-webpack-plugin": "^3.0.4",
"img-loader": "^2.0.1",
"node-sass": "^4.9.3",
Expand Down
15 changes: 15 additions & 0 deletions src/actions/AmountActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@ import BN from 'bignumber.js';
import { setFormValue, setFormError, setValue } from './FormActions';
import { ECHO_ASSET_ID } from '../constants/GlobalConstants';

/**
* @method amountInput
*
* @param {String} form
* @param {String} value
* @param {Object} currency
* @param {string} name
* @returns {function(dispatch, getState): Promise<undefined>}
* */
export const amountInput = (form, value, currency, name) => (dispatch) => {
if (!value.match(/^[0-9]*[.,]?[0-9]*$/)) {
dispatch(setFormError(form, 'amount', 'Amount must contain only digits and dot'));
Expand All @@ -29,6 +38,12 @@ export const amountInput = (form, value, currency, name) => (dispatch) => {
dispatch(setFormValue(form, name, value));
};

/**
* @method setDefaultAsset
*
* @param {String} form
* @returns {function(dispatch, getState): Promise<undefined>}
*/
export const setDefaultAsset = (form) => async (dispatch, getState) => {
const currency = getState().form.getIn([form, 'currency']);

Expand Down
170 changes: 157 additions & 13 deletions src/actions/AuthActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { List } from 'immutable';
import random from 'crypto-random-string';

import { openModal, toggleLoading as toggleModalLoading, setError, closeModal } from './ModalActions';
import { addAccount, isAccountAdded, initAccount, setGlobalError } from './GlobalActions';
import { addAccount, isAccountAdded, initAccount, setGlobalError, saveWifToStorage } from './GlobalActions';

import {
setFormValue,
Expand All @@ -12,7 +12,7 @@ import {
} from './FormActions';

import { FORM_SIGN_UP, FORM_SIGN_IN } from '../constants/FormConstants';
import { MODAL_UNLOCK, MODAL_CHOOSE_ACCOUNT } from '../constants/ModalConstants';
import { MODAL_UNLOCK, MODAL_CHOOSE_ACCOUNT, MODAL_ADD_WIF, PROPOSAL_ADD_WIF } from '../constants/ModalConstants';
import { ECHO_ASSET_ID, RANDOM_SIZE, USER_STORAGE_SCHEMES } from '../constants/GlobalConstants';

import { formatError } from '../helpers/FormatHelper';
Expand All @@ -27,13 +27,24 @@ import AuthApi from '../api/AuthApi';

import Services from '../services';
import Key from '../logic-components/db/models/key';
import CryptoService from '../services/CryptoService';

/**
* @method generateWIF
* @returns {function(dispatch): Promise<undefined>}
*/
export const generateWIF = () => (dispatch) => {
const privateKey = PrivateKey.fromSeed(random({ length: RANDOM_SIZE }));

dispatch(setFormValue(FORM_SIGN_UP, 'generatedWIF', privateKey.toWif()));
};

/**
* @method createAccount
* @param {Object} param0
* @param {Boolean} isAddAccount
* @returns {function(dispatch, getState): Promise<undefined>}
*/
export const createAccount = ({
accountName, generatedWIF, confirmWIF, password,
}, isAddAccount) => async (dispatch, getState) => {
Expand Down Expand Up @@ -68,14 +79,13 @@ export const createAccount = ({
}

dispatch(toggleLoading(FORM_SIGN_UP, true));

const { publicKey } = await AuthApi.registerAccount(accountName, generatedWIF);

const userStorage = Services.getUserStorage();
const account = await echo.api.getAccountByName(accountName);
await userStorage.addKey(Key.create(publicKey, generatedWIF, account.id), { password });

dispatch(addAccount(accountName, network.name));
dispatch(addAccount(accountName, network.name, [publicKey]));

} catch (err) {
dispatch(setGlobalError(formatError(err) || 'Account creation error. Please, try again later'));
Expand All @@ -84,8 +94,27 @@ export const createAccount = ({
}

};
/**
* @method isAllWIFsAdded
* @param {Object} account
* @param {String} password
* @return {Boolean}
*/
const isAllWIFsAdded = async (account, password) => {
const userStorage = Services.getUserStorage();
const userWIFKeys = await userStorage.getAllWIFKeysForAccount(account.id, { password });
const userPublicKeys = account.active.key_auths;
const publicEchorandKey = account.echorand_key;
const isPrivateEchorandAdd = userWIFKeys.find((key) => key.publicKey === publicEchorandKey);
return ((userPublicKeys.length === userWIFKeys.length) && isPrivateEchorandAdd);
};


/**
* @method authUser
*
* @param {Object} param0
* @returns {function(dispatch, getState): Promise<Boolean>}
*/
export const authUser = ({ accountName, wif, password }) => async (dispatch, getState) => {
let accountNameError = validateAccountName(accountName);
const wifError = validateWIF(wif);
Expand Down Expand Up @@ -130,11 +159,15 @@ export const authUser = ({ accountName, wif, password }) => async (dispatch, get
await userStorage.addKey(Key.create(key.publicKey, wif, account.id), { password });

if (!isAccountAdded(accountName, networkName)) {
dispatch(addAccount(accountName, networkName));
dispatch(addAccount(accountName, networkName, [key.publicKey]));
} else {
dispatch(initAccount(accountName, networkName));
}

const hasAllWIFs = await isAllWIFsAdded(account, password);
if (!hasAllWIFs) {
dispatch(openModal(PROPOSAL_ADD_WIF));
}
return false;
} catch (err) {
dispatch(setGlobalError(formatError(err) || 'Account importing error. Please, try again later'));
Expand All @@ -151,7 +184,7 @@ export const authUser = ({ accountName, wif, password }) => async (dispatch, get
* Forming an accounts list for choose accounts in modal
*
* @param {Object}
*
* @@returns {function(dispatch): Promise<Object>}
*/
const getAccountsList = (accounts) => async (dispatch) => {

Expand Down Expand Up @@ -188,8 +221,8 @@ const getAccountsList = (accounts) => async (dispatch) => {
* Import account
*
* @param {String} accountName
* @param {String} wif
*
* @param {String} wif
* @returns {function(dispatch, getState): Promise<undefined>}
*/
export const importAccount = ({ accountName, wif, password }) =>
async (dispatch, getState) => {
Expand Down Expand Up @@ -262,7 +295,7 @@ export const importAccount = ({ accountName, wif, password }) =>
*
* @param {String} password
* @param {Array} accounts
*
* @returns {function(dispatch, getState): Promise<undefined>}
*/
export const importSelectedAccounts = (password, accounts) => async (dispatch, getState) => {
const wif = getState().form.getIn([FORM_SIGN_IN, 'wif']).value;
Expand All @@ -276,7 +309,50 @@ export const importSelectedAccounts = (password, accounts) => async (dispatch, g
dispatch(closeModal(MODAL_CHOOSE_ACCOUNT));
};

export const unlock = (password, callback = () => {}, modal = MODAL_UNLOCK) => async (dispatch) => {
/**
* @method unlock
* @param {String} password
* @param {Function} callback
* @param {String} modal
* @returns {function(dispatch, getState): Promise<undefined>}
*/
export const unlock = (password, callback = () => { }, modal = MODAL_UNLOCK) =>
async (dispatch) => {
try {
dispatch(toggleModalLoading(modal, true));

const userStorage = Services.getUserStorage();
const doesDBExist = await userStorage.doesDBExist();

if (!doesDBExist) {
dispatch(setError(modal, 'DB doesn\'t exist'));
return;
}

await userStorage.setScheme(USER_STORAGE_SCHEMES.MANUAL, password);
const correctPassword = await userStorage.isMasterPassword(password);

if (!correctPassword) {
dispatch(setError(modal, 'Invalid password'));
return;
}

dispatch(closeModal(modal));

callback(password);
} catch (err) {
dispatch(setError(modal, err));
} finally {
dispatch(toggleModalLoading(modal, false));
}

};

export const asyncUnlock = (
password,
callback = () => { },
modal = MODAL_UNLOCK,
) => async (dispatch) => {
try {
dispatch(toggleModalLoading(modal, true));

Expand All @@ -296,13 +372,81 @@ export const unlock = (password, callback = () => {}, modal = MODAL_UNLOCK) => a
return;
}

dispatch(closeModal(modal));
await callback(password);

callback(password);
dispatch(closeModal(modal));
} catch (err) {
dispatch(setError(modal, err));
} finally {
dispatch(toggleModalLoading(modal, false));
}

};

/**
*
* @param {String} publicKey
* @param {String} wif
* @param {Object} account
* @param {String} password
* @returns {function(dispatch, getState): Promise<undefined>}
*/
export const addWif = (
publicKey,
wif,
account,
password,
) => async (dispatch, getState) => {
const { id, name } = account;
const networkName = getState().global.getIn(['network', 'name']);
const userStorage = Services.getUserStorage();
if (!CryptoService.isWIF(wif)) {
throw Error('Invalid WIF');
}

const privateKey = PrivateKey.fromWif(wif);

if (publicKey !== privateKey.toPublicKey().toPublicKeyString()) {
throw Error('Wrong WIF');
}

await userStorage.addKey(Key.create(publicKey, wif, id), { password });

dispatch(saveWifToStorage(name, networkName, publicKey));
};

export const saveWifToDb = (
publicKey,
wif,
account,
password,
callback = () => { },
modal = MODAL_ADD_WIF,
) => async (dispatch, getState) => {
try {
const { id, name } = account;
const networkName = getState().global.getIn(['network', 'name']);
const userStorage = Services.getUserStorage();
if (!CryptoService.isWIF(wif)) {
dispatch(setError(modal, 'Invalid WIF'));
return;
}

const privateKey = PrivateKey.fromWif(wif);

if (publicKey !== privateKey.toPublicKey().toPublicKeyString()) {
dispatch(setError(modal, 'Wrong WIF'));
return;
}

await userStorage.addKey(Key.create(publicKey, wif, id), { password });

dispatch(saveWifToStorage(name, networkName, publicKey));
callback();
dispatch(closeModal(modal));
} catch (err) {
dispatch(setError(modal, err));
} finally {
dispatch(toggleModalLoading(modal, false));
}
};
Loading

0 comments on commit 90ab78c

Please sign in to comment.