diff --git a/app/background/wallet/client.js b/app/background/wallet/client.js
index eb09e749e..056f9e679 100644
--- a/app/background/wallet/client.js
+++ b/app/background/wallet/client.js
@@ -42,4 +42,5 @@ export const clientStub = ipcRendererInjector => makeClient(ipcRendererInjector,
'zap',
'importName',
'rpcGetWalletInfo',
+ 'listWallets'
]);
diff --git a/app/background/wallet/service.js b/app/background/wallet/service.js
index 6d0562ba3..ee95a10f3 100644
--- a/app/background/wallet/service.js
+++ b/app/background/wallet/service.js
@@ -29,7 +29,6 @@ const Covenant = require('hsd/lib/primitives/covenant');
// const walletHeightKey = 'wallet:lastSyncHeight';
-const WALLET_ID = 'allison';
const randomAddrs = {
[NETWORKS.TESTNET]: 'ts1qfcljt5ylsa9rcyvppvl8k8gjnpeh079drfrmzq',
[NETWORKS.REGTEST]: 'rs1qh57neh8npuxeyxfsl35373vshs0d40cvxx57aj',
@@ -46,6 +45,11 @@ class WalletService {
this.nodeService = nodeService;
}
+ setWallet = (name) => {
+ this.didSelectWallet = false;
+ this.name = name;
+ };
+
reset = async () => {
await this._ensureClient();
@@ -68,7 +72,7 @@ class WalletService {
this.network,
this.apiKey,
);
-
+ this.setName(null);
return true;
} catch (e) {
console.error(e);
@@ -83,18 +87,18 @@ class WalletService {
getWalletInfo = async () => {
await this._ensureClient();
- return this.client.getInfo(WALLET_ID);
+ return this.client.getInfo(this.name);
};
getAccountInfo = async () => {
await this._ensureClient();
- return this.client.getAccount(WALLET_ID, 'default');
+ return this.client.getAccount(this.name, 'default');
};
getCoin = async (hash, index) => {
await this._ensureClient();
- return this.client.getCoin(WALLET_ID, hash, index);
+ return this.client.getCoin(this.name, hash, index);
};
getNames = async () => {
@@ -102,14 +106,12 @@ class WalletService {
return this.client.execute('getnames');
};
- createNewWallet = async (passphraseOrXPub, isLedger) => {
+ createNewWallet = async (name, passphraseOrXPub, isLedger) => {
await this._ensureClient();
-
- await this.reset();
- this.didSelectWallet = false;
+ this.setWallet(name);
if (isLedger) {
- return this.client.createWallet(WALLET_ID, {
+ return this.client.createWallet(name, {
watchOnly: true,
accountKey: passphraseOrXPub,
});
@@ -122,7 +124,7 @@ class WalletService {
watchOnly: false,
mnemonic: mnemonic.getPhrase(),
};
- return this.client.createWallet(WALLET_ID, options);
+ return this.client.createWallet(name, options);
};
checkRescanStatus = async () => {
@@ -189,10 +191,9 @@ class WalletService {
});
};
- importSeed = async (passphrase, mnemonic) => {
+ importSeed = async (name, passphrase, mnemonic) => {
await this._ensureClient();
-
- await this.reset();
+ this.setWallet(name);
this.didSelectWallet = false;
const options = {
passphrase,
@@ -200,14 +201,14 @@ class WalletService {
// menmonics with trailing whitespace
mnemonic: mnemonic.trim(),
};
- const res = await this.client.createWallet(WALLET_ID, options);
+ const res = await this.client.createWallet(this.name, options);
this.rescan(0);
return res;
};
generateReceivingAddress = async () => {
await this._ensureClient();
- return this.client.createAddress(WALLET_ID, 'default');
+ return this.client.createAddress(this.name, 'default');
};
getAuctionInfo = async (name) => {
@@ -216,12 +217,12 @@ class WalletService {
getTransactionHistory = async () => {
await this._ensureClient();
- return this.client.getHistory(WALLET_ID, 'default');
+ return this.client.getHistory(this.name, 'default');
};
getPendingTransactions = async () => {
await this._ensureClient();
- return this.client.getPending(WALLET_ID, 'default');
+ return this.client.getPending(this.name, 'default');
};
getBids = async () => {
@@ -230,12 +231,12 @@ class WalletService {
getMasterHDKey = () => this._ledgerDisabled(
'cannot get HD key for watch-only wallet',
- () => this.client.getMaster(WALLET_ID),
+ () => this.client.getMaster(this.name),
);
setPassphrase = (newPass) => this._ledgerDisabled(
'cannot set passphrase for watch-only wallet',
- () => this.client.setPassphrase(WALLET_ID, newPass),
+ () => this.client.setPassphrase(this.name, newPass),
);
revealSeed = (passphrase) => this._ledgerDisabled(
@@ -268,7 +269,7 @@ class WalletService {
estimateTxFee = async (to, amount, feeRate, subtractFee = false) => {
await this._ensureClient();
const feeRateBaseUnits = Number(toBaseUnits(feeRate));
- const createdTx = await this.client.createTX(WALLET_ID, {
+ const createdTx = await this.client.createTX(this.name, {
rate: feeRateBaseUnits,
outputs: [{
value: Number(toBaseUnits(amount)),
@@ -356,7 +357,7 @@ class WalletService {
send = (to, amount, fee) => this._ledgerProxy(
() => this._executeRPC('createsendtoaddress', [to, Number(amount), '', '', false, 'default']),
- () => this.client.send(WALLET_ID, {
+ () => this.client.send(this.name, {
rate: Number(toBaseUnits(fee)),
outputs: [{
value: Number(toBaseUnits(amount)),
@@ -367,19 +368,22 @@ class WalletService {
lock = () => this._ledgerProxy(
() => null,
- () => this.client.lock(WALLET_ID),
+ () => this.client.lock(this.name),
);
- unlock = (passphrase) => this._ledgerProxy(
- () => null,
- () => this.client.unlock(WALLET_ID, passphrase),
- );
+ unlock = (name, passphrase) => {
+ this.setWallet(name);
+ return this._ledgerProxy(
+ () => null,
+ () => this.client.unlock(this.name, passphrase),
+ );
+ };
isLocked = () => this._ledgerProxy(
() => false,
async () => {
try {
- const info = await this.client.getInfo(WALLET_ID);
+ const info = await this.client.getInfo(this.name);
return info === null || info.master.until === 0;
} catch (e) {
console.error(e);
@@ -390,7 +394,7 @@ class WalletService {
getNonce = async (options) => {
await this._ensureClient();
- return this.client.getNonce(WALLET_ID, options.name, options);
+ return this.client.getNonce(this.name, options.name, options);
};
importNonce = async (options) => {
@@ -399,7 +403,7 @@ class WalletService {
zap = async () => {
await this._ensureClient();
- return this.client.zap(WALLET_ID, 'default', 1);
+ return this.client.zap(this.name, 'default', 1);
};
importName = (name, start) => {
@@ -525,6 +529,8 @@ class WalletService {
throw new Error('Transaction never appeared in the mempool.');
};
+ listWallets = () => this.client.getWallets();
+
_onNodeStart = async (networkName, network, apiKey) => {
const conn = await getConnection();
@@ -606,7 +612,7 @@ class WalletService {
return this.pendingSelection;
}
- this.pendingSelection = this.client.execute('selectwallet', [WALLET_ID]);
+ this.pendingSelection = this.client.execute('selectwallet', [this.name]);
await this.pendingSelection;
this.pendingSelection = null;
this.didSelectWallet = true;
@@ -685,6 +691,7 @@ const methods = {
zap: service.zap,
importName: service.importName,
rpcGetWalletInfo: service.rpcGetWalletInfo,
+ listWallets: service.listWallets,
};
export async function start(server) {
diff --git a/app/ducks/node.js b/app/ducks/node.js
index 06b9587c2..94f9cf0aa 100644
--- a/app/ducks/node.js
+++ b/app/ducks/node.js
@@ -1,7 +1,7 @@
import { clientStub } from '../background/node/client';
import { clientStub as connClientStub } from '../background/connections/client';
import { getNetwork, setNetwork, getInitializationState } from '../db/system';
-import { fetchWallet, fetchTransactions } from './walletActions';
+import { fetchWallet, fetchTransactions, listWallets } from './walletActions';
import { getWatching } from './watching';
import * as logger from '../utils/logClient';
import { onNewBlock } from './backgroundMonitor';
@@ -109,6 +109,7 @@ export const start = (network) => async (dispatch, getState) => {
},
});
await dispatch(setNodeInfo());
+ await dispatch(listWallets());
await dispatch(fetchWallet());
if (await getInitializationState(network)) {
setTimeout(async () => {
diff --git a/app/ducks/walletActions.js b/app/ducks/walletActions.js
index 6aed135f5..cc381c9af 100644
--- a/app/ducks/walletActions.js
+++ b/app/ducks/walletActions.js
@@ -16,7 +16,9 @@ import {
STOP_SYNC_WALLET,
SYNC_WALLET_PROGRESS,
UNLOCK_WALLET,
- SET_API_KEY, SET_FETCHING,
+ SET_API_KEY,
+ SET_FETCHING,
+ SET_WALLETS,
} from './walletReducer';
import { NEW_BLOCK_STATUS } from './nodeReducer';
@@ -43,9 +45,9 @@ export const setWallet = opts => {
};
};
-export const completeInitialization = (passphrase) => async (dispatch, getState) => {
+export const completeInitialization = (name, passphrase) => async (dispatch, getState) => {
const network = getState().node.network;
- await walletClient.unlock(passphrase);
+ await walletClient.unlock(name, passphrase);
await setInitializationState(network, true);
await dispatch(fetchWallet());
dispatch({
@@ -94,8 +96,8 @@ export const revealSeed = (passphrase) => async () => {
return walletClient.revealSeed(passphrase);
};
-export const unlockWallet = passphrase => async (dispatch) => {
- await walletClient.unlock(passphrase);
+export const unlockWallet = (name, passphrase) => async (dispatch) => {
+ await walletClient.unlock(name, passphrase);
dispatch({
type: UNLOCK_WALLET,
});
@@ -108,7 +110,7 @@ export const lockWallet = () => async (dispatch) => {
});
};
-export const removeWallet = () => async (dispatch, getState) => {
+export const reset = () => async (dispatch, getState) => {
const network = getState().node.network;
await walletClient.reset();
await setInitializationState(network, false);
@@ -265,6 +267,15 @@ export const watchActivity = () => dispatch => {
}
};
+export const listWallets = () => async (dispatch) => {
+ const wallets = await walletClient.listWallets();
+
+ dispatch({
+ type: SET_WALLETS,
+ payload: wallets,
+ });
+};
+
async function parseInputsOutputs(net, tx) {
// Look for covenants. A TX with multiple covenant types is not supported
let covAction = null;
@@ -353,7 +364,7 @@ async function parseInputsOutputs(net, tx) {
type: 'UNKNOWN',
meta: {},
fee: tx.fee,
- value: 0
+ value: 0,
};
}
diff --git a/app/ducks/walletReducer.js b/app/ducks/walletReducer.js
index a6abe0895..7db19513b 100644
--- a/app/ducks/walletReducer.js
+++ b/app/ducks/walletReducer.js
@@ -16,6 +16,7 @@ export const SYNC_WALLET_PROGRESS = 'app/wallet/syncWalletProgress';
export const GET_PASSPHRASE = 'app/wallet/getPassphrase';
export const SET_API_KEY = 'app/wallet/setApiKey';
export const SET_FETCHING = 'app/wallet/setFetching';
+export const SET_WALLETS = 'app/wallet/setWallets';
export function getInitialState() {
return {
@@ -37,6 +38,7 @@ export function getInitialState() {
walletSync: false,
walletSyncProgress: 0,
getPassphrase: {get: false},
+ wallets: [],
};
}
@@ -66,17 +68,17 @@ export default function walletReducer(state = getInitialState(), {type, payload}
case LOCK_WALLET:
return {
...state,
- isLocked: true
+ isLocked: true,
};
case UNLOCK_WALLET:
return {
...state,
- isLocked: false
+ isLocked: false,
};
case SET_TRANSACTIONS:
return {
...state,
- transactions: payload
+ transactions: payload,
};
case INCREMENT_IDLE:
return {
@@ -113,6 +115,11 @@ export default function walletReducer(state = getInitialState(), {type, payload}
...state,
isFetching: payload,
};
+ case SET_WALLETS:
+ return {
+ ...state,
+ wallets: payload,
+ };
default:
return state;
}
diff --git a/app/pages/AcountLogin/index.js b/app/pages/AcountLogin/index.js
index f96c580b4..7f25bc5fe 100644
--- a/app/pages/AcountLogin/index.js
+++ b/app/pages/AcountLogin/index.js
@@ -5,52 +5,73 @@ import c from 'classnames';
import * as walletActions from '../../ducks/walletActions';
import './login.scss';
import Submittable from '../../components/Submittable';
-import { Link } from 'react-router-dom';
+import { Link, Redirect } from 'react-router-dom';
+import Dropdown from '../../components/Dropdown';
+import { withRouter } from 'react-router';
@connect(
- () => ({}),
+ (state) => ({
+ wallets: state.wallet.wallets,
+ }),
dispatch => ({
- unlockWallet: passphrase => dispatch(walletActions.unlockWallet(passphrase))
- })
+ unlockWallet: (name, passphrase) => dispatch(walletActions.unlockWallet(name, passphrase)),
+ fetchWallet: () => dispatch(walletActions.fetchWallet()),
+ }),
)
+@withRouter
export default class AccountLogin extends Component {
static propTypes = {
- unlockWallet: PropTypes.func.isRequired
+ unlockWallet: PropTypes.func.isRequired,
};
static defaultProps = {
- className: ''
+ className: '',
};
state = {
passphrase: '',
- showError: false
+ showError: false,
+ chosenWallet: 0,
};
async handleLogin(passphrase) {
try {
- await this.props.unlockWallet(passphrase);
+ await this.props.unlockWallet(
+ this.props.wallets[this.state.chosenWallet],
+ passphrase,
+ );
+ await this.props.fetchWallet();
+ this.props.history.push('/account');
} catch (error) {
- return this.setState({ showError: true });
+ return this.setState({showError: true});
}
}
render() {
- const { passphrase, showError } = this.state;
+ const {passphrase, showError} = this.state;
+
+ if (!this.props.wallets.length) {
+ return ;
+ }
return (
Log in to your wallet
this.handleLogin(passphrase)}>
+ ({label: w}))}
+ currentIndex={this.state.chosenWallet}
+ onChange={(i) => this.setState({chosenWallet: i})}
+ />
- this.setState({ passphrase: e.target.value, showError: false })
+ this.setState({passphrase: e.target.value, showError: false})
}
value={passphrase}
autoFocus
@@ -73,6 +94,12 @@ export default class AccountLogin extends Component {
>
Restore with your seed phrase
+
+ Create new wallet
+
);
}
diff --git a/app/pages/App/index.js b/app/pages/App/index.js
index 41364f557..c63f6554c 100644
--- a/app/pages/App/index.js
+++ b/app/pages/App/index.js
@@ -22,18 +22,24 @@ import YourBids from '../YourBids';
import Watching from '../Watching';
import SearchTLD from '../SearchTLD';
import * as walletActions from '../../ducks/walletActions';
+import { listWallets } from '../../ducks/walletActions';
import './app.scss';
import AccountLogin from '../AcountLogin';
import PassphraseModal from '../AcountLogin/PassphraseModal';
import * as node from '../../ducks/node';
import { onNewBlock } from '../../ducks/backgroundMonitor';
-import Notification from '../../components/Notification';
-import SplashScreen from "../../components/SplashScreen";
-import WalletSync from "../../components/WalletSync";
+import SplashScreen from '../../components/SplashScreen';
import NetworkPicker from '../NetworkPicker';
import IdleModal from '../../components/IdleModal';
-import { LedgerModal } from '../../components/LedgerModal';
+@connect(
+ (state) => ({
+ wallets: state.wallet.wallets,
+ }),
+ (dispatch) => ({
+ listWallets: () => dispatch(listWallets()),
+ }),
+)
class App extends Component {
static propTypes = {
error: PropTypes.string.isRequired,
@@ -46,20 +52,22 @@ class App extends Component {
};
state = {
- isLoading: true
+ isLoading: true,
+ isListingWallets: true
};
async componentDidMount() {
this.setState({isLoading: true});
await this.props.startNode();
this.props.watchActivity();
- setTimeout(() => this.setState({isLoading: false}), 1000)
+ await this.props.listWallets();
+ setTimeout(() => this.setState({isLoading: false}), 1000);
}
render() {
// TODO: Confirm that error shows properly
if (this.props.error) {
- return
+ return ;
}
if (this.state.isLoading || this.props.isChangingNetworks) {
@@ -77,52 +85,106 @@ class App extends Component {
}
renderContent() {
- const { isLocked, initialized } = this.props;
-
- if (isLocked || !initialized) {
- return (
-
- , true, true)}
- />
-
-
-
-
-
- {this.renderDefault()}
-
- );
- }
-
return (
-
-
-
- {this.renderRoutes()}
-
+
+ , true, true)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
uninitializedWrapper(Component, isMainMenu = false, autoHeight = false) {
- const { history, isRunning } = this.props;
+ const {history, isRunning} = this.props;
if (isMainMenu) {
return () => (
-
+
- { isRunning && }
+ {isRunning && }
-
- )
+ );
}
return () => (
@@ -135,58 +197,12 @@ class App extends Component {
-
- )
- }
-
- renderRoutes() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- {this.renderDefault()}
-
);
}
@@ -214,22 +230,19 @@ class App extends Component {
);
}
+}
- renderDefault = () => {
- let {isLocked, initialized} = this.props;
-
-
- if (!initialized) {
- return ;
- }
+const ProtectedRoute = (props) => {
+ if (!props.wallets.length) {
+ return ;
+ }
- if (isLocked) {
- return ;
- }
+ if (props.isLocked) {
+ return ;
+ }
- return ;
- };
-}
+ return ;
+};
export default withRouter(
connect(
@@ -244,6 +257,6 @@ export default withRouter(
watchActivity: () => dispatch(walletActions.watchActivity()),
startNode: () => dispatch(node.startApp()),
onNewBlock: () => dispatch(onNewBlock()),
- })
- )(App)
+ }),
+ )(App),
);
diff --git a/app/pages/Onboarding/ConfirmSeed/index.js b/app/pages/Onboarding/ConfirmSeed/index.js
index 6c2d8c99e..71b5138f4 100644
--- a/app/pages/Onboarding/ConfirmSeed/index.js
+++ b/app/pages/Onboarding/ConfirmSeed/index.js
@@ -62,11 +62,6 @@ export default class ConfirmSeed extends Component {
placeholder="Enter your seed phrase"
onKeyDown={this.handleKeyDown}
onChange={e => this.setState({ words: e.target.value })}
- onPaste={e => {
- e.preventDefault();
- this.setState({ pasteAttempted: true });
- setTimeout(() => this.setState({ pasteAttempted: false }), 1000);
- }}
value={this.state.words}
autoFocus
/>
diff --git a/app/pages/Onboarding/CreateNewAccount/index.js b/app/pages/Onboarding/CreateNewAccount/index.js
index 78c268ce1..1cab8c511 100644
--- a/app/pages/Onboarding/CreateNewAccount/index.js
+++ b/app/pages/Onboarding/CreateNewAccount/index.js
@@ -7,6 +7,7 @@ import CreatePassword from '../CreatePassword/index';
import BackUpSeedWarning from '../BackUpSeedWarning/index';
import CopySeed from '../../CopySeed/index';
import ConfirmSeed from '../ConfirmSeed/index';
+import SetName from '../SetName/index';
import * as walletActions from '../../../ducks/walletActions';
import '../ImportSeedEnterMnemonic/importenter.scss';
import '../ImportSeedWarning/importwarning.scss';
@@ -22,6 +23,7 @@ const BACK_UP_SEED_WARNING = 2;
const COPY_SEEDPHRASE = 3;
const CONFIRM_SEEDPHRASE = 4;
const OPT_IN_ANALYTICS = 5;
+const SET_NAME = 6;
class CreateNewAccount extends Component {
static propTypes = {
@@ -30,9 +32,9 @@ class CreateNewAccount extends Component {
};
state = {
- currentStep: CREATE_PASSWORD,
+ currentStep: SET_NAME,
seedphrase: '',
- pasphrase: '',
+ passphrase: '',
isLoading: false,
};
@@ -42,7 +44,7 @@ class CreateNewAccount extends Component {
return (
{
this.setState({
currentStep: CREATE_PASSWORD,
@@ -51,12 +53,26 @@ class CreateNewAccount extends Component {
onBack={() => this.props.history.push('/funding-options')}
/>
);
- case CREATE_PASSWORD:
+ case SET_NAME:
return (
- this.props.history.push('/funding-options')}
+ onNext={(name) => {
+ this.setState({currentStep: CREATE_PASSWORD, name});
+ }}
+ onCancel={() => this.props.history.push('/funding-options')}
+ />
+ );
+ case CREATE_PASSWORD:
+ return (
+ this.setState({
+ currentStep: SET_NAME
+ })}
onNext={async (passphrase) => {
const optInState = await analytics.getOptIn();
let currentStep = BACK_UP_SEED_WARNING;
@@ -72,8 +88,8 @@ class CreateNewAccount extends Component {
case OPT_IN_ANALYTICS:
return (
this.setState({currentStep: CREATE_PASSWORD})}
onNext={async (optInState) => {
await analytics.setOptIn(optInState);
@@ -85,12 +101,12 @@ class CreateNewAccount extends Component {
case BACK_UP_SEED_WARNING:
return (
this.setState({currentStep: CREATE_PASSWORD})}
onNext={async () => {
this.setState({isLoading: true});
- await walletClient.createNewWallet();
+ await walletClient.createNewWallet(this.state.name);
const masterHDKey = await walletClient.getMasterHDKey();
await walletClient.setPassphrase(this.state.passphrase);
this.setState({currentStep: COPY_SEEDPHRASE, seedphrase: masterHDKey.mnemonic.phrase, isLoading: false});
@@ -102,8 +118,8 @@ class CreateNewAccount extends Component {
case COPY_SEEDPHRASE:
return (
this.setState({currentStep: BACK_UP_SEED_WARNING})}
onNext={() => this.setState({currentStep: CONFIRM_SEEDPHRASE})}
@@ -113,13 +129,13 @@ class CreateNewAccount extends Component {
case CONFIRM_SEEDPHRASE:
return (
this.setState({currentStep: COPY_SEEDPHRASE})}
onNext={async () => {
- await this.props.completeInitialization(this.state.passphrase);
- this.props.history.push('/');
+ await this.props.completeInitialization(this.state.name, this.state.passphrase);
+ this.props.history.push('/account');
}}
onCancel={() => this.props.history.push('/funding-options')}
/>
@@ -136,7 +152,7 @@ export default withRouter(
network: state.node.network,
}),
dispatch => ({
- completeInitialization: (passphrase) => dispatch(walletActions.completeInitialization(passphrase)),
+ completeInitialization: (name, passphrase) => dispatch(walletActions.completeInitialization(name, passphrase)),
}),
)(CreateNewAccount),
);
diff --git a/app/pages/Onboarding/FundAccessOptions/index.js b/app/pages/Onboarding/FundAccessOptions/index.js
index a1cf70ba2..da3fca55a 100644
--- a/app/pages/Onboarding/FundAccessOptions/index.js
+++ b/app/pages/Onboarding/FundAccessOptions/index.js
@@ -1,9 +1,7 @@
import React, { Component } from 'react';
-import { withRouter } from 'react-router-dom';
+import { withRouter, Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
-// import classNames from 'classnames';
-// import * as auctions.js from '../../../ducks/extension';
import './access.scss';
class FundAccessOptions extends Component {
@@ -41,8 +39,17 @@ class FundAccessOptions extends Component {
className="funding-options__footer__secondary-btn"
onClick={() => this.props.history.push('/existing-options')}
>
- I already have a wallet
+ Import a wallet
+
+ {!!this.props.wallets.length && (
+
+ Return to login
+
+ )}
);
@@ -51,7 +58,9 @@ class FundAccessOptions extends Component {
export default withRouter(
connect(
- state => ({}),
+ state => ({
+ wallets: state.wallet.wallets
+ }),
dispatch => ({})
)(FundAccessOptions)
);
diff --git a/app/pages/Onboarding/ImportSeedFlow/index.js b/app/pages/Onboarding/ImportSeedFlow/index.js
index ffe26b3d9..4089f9186 100644
--- a/app/pages/Onboarding/ImportSeedFlow/index.js
+++ b/app/pages/Onboarding/ImportSeedFlow/index.js
@@ -13,6 +13,7 @@ import * as logger from '../../../utils/logClient';
import OptInAnalytics from '../OptInAnalytics';
import { clientStub as aClientStub } from '../../../background/analytics/client';
import { showError } from '../../../ducks/notifications';
+import SetName from '../SetName';
const analytics = aClientStub(() => require('electron').ipcRenderer);
@@ -21,6 +22,7 @@ const WARNING_STEP = 'WARNING';
const CREATE_PASSWORD = 'CREATE_PASSWORD';
const ENTRY_STEP = 'ENTRY';
const OPT_IN_ANALYTICS = 'ANALYTICS';
+const SET_NAME = 'SET_NAME';
class ImportSeedFlow extends Component {
static propTypes = {
@@ -38,6 +40,7 @@ class ImportSeedFlow extends Component {
state = {
currentStep: WARNING_STEP,
+ name: '',
passphrase: '',
mnemonic: '',
isLoading: false,
@@ -57,10 +60,24 @@ class ImportSeedFlow extends Component {
case WARNING_STEP:
return (
this.props.history.push('/existing-options')}
- onNext={() => this.goTo(CREATE_PASSWORD)}
+ onNext={() => this.goTo(SET_NAME)}
+ onCancel={() => this.props.history.push('/funding-options')}
+ />
+ );
+ case SET_NAME:
+ return (
+ this.setState({
+ currentStep: WARNING_STEP,
+ })}
+ onNext={(name) => {
+ this.setState({currentStep: CREATE_PASSWORD, name});
+ }}
onCancel={() => this.props.history.push('/funding-options')}
/>
);
@@ -120,10 +137,11 @@ class ImportSeedFlow extends Component {
finishFlow = async mnemonic => {
this.setState({isLoading: true});
try {
- await walletClient.importSeed(this.state.passphrase, mnemonic);
- await this.props.completeInitialization(this.state.passphrase);
+ await walletClient.importSeed(this.state.name, this.state.passphrase, mnemonic);
+ await this.props.completeInitialization(this.state.name, this.state.passphrase);
await this.props.fetchWallet();
await this.props.fetchTransactions();
+ this.props.history.push('/account');
} catch (e) {
this.props.showError(e.message);
logger.error(`Error received from ImportSeedFlow - finishFlow]\n\n${e.message}\n${e.stack}\n`);
@@ -139,7 +157,7 @@ export default withRouter(
network: state.node.network,
}),
dispatch => ({
- completeInitialization: (passphrase) => dispatch(walletActions.completeInitialization(passphrase)),
+ completeInitialization: (name, passphrase) => dispatch(walletActions.completeInitialization(name, passphrase)),
waitForWalletSync: () => dispatch(walletActions.waitForWalletSync()),
startWalletSync: () => dispatch(walletActions.startWalletSync()),
showError: (message) => dispatch(showError(message)),
diff --git a/app/pages/Onboarding/SetName/create.scss b/app/pages/Onboarding/SetName/create.scss
new file mode 100644
index 000000000..fe54e56e3
--- /dev/null
+++ b/app/pages/Onboarding/SetName/create.scss
@@ -0,0 +1,97 @@
+@import '../../../variables';
+
+.create-password {
+ @extend %col-nowrap;
+ height: 100%;
+
+ &__header {
+ @extend %row-nowrap;
+ align-items: center;
+ justify-content: center;
+ padding: 1.125rem 1.625rem 0.5rem;
+ }
+
+ &__header_text {
+ @extend %header_text;
+ margin-bottom: 1.125rem;
+ }
+
+ &__body-text {
+ @extend %h4;
+ color: $manatee-gray;
+ margin-bottom: 1.375rem;
+ }
+
+ &__cancel {
+ @extend %link;
+ flex: 1 0 auto;
+ text-align: right;
+ font-size: 0.8rem;
+ }
+
+ &__status-bar {
+ padding: 0 1.625rem;
+ }
+
+ &__content {
+ @extend %col-nowrap;
+ padding: 1.25rem 1.875rem;
+ flex: 1 1 auto;
+ // height: 0;
+ }
+
+ &__input {
+ @extend %box-input;
+ width: 100%;
+ box-sizing: border-box;
+ margin-bottom: 12px;
+
+ input {
+ width: 100%;
+ }
+
+ &--error {
+ box-shadow: 0 0 0 1.25px rgba($orange-red, 0.5);
+ }
+ }
+
+ &__error {
+ color: $orange-red;
+ font-size: 0.75rem;
+ margin: -6px 0.375rem 12px 0.375rem;
+
+ &:empty {
+ margin: 0;
+ }
+ }
+
+ &__footer {
+ padding: 1.25rem 1.875rem 1.875rem 1.875rem;
+
+ &__removed-padding-top {
+ padding-top: 0;
+ }
+ }
+}
+
+.create_back {
+ margin-right: 7px;
+ position: relative;
+ bottom: 1px;
+}
+
+.create_status_bar {
+ margin: 0.8rem 0 1rem;
+}
+
+.clickable {
+ cursor: pointer;
+}
+
+.login_password_input {
+ @extend %box-input;
+ width: 90%;
+ margin: 10px 0rem;
+ border: 1px solid #e2e2e2;
+ border-radius: 8px;
+}
diff --git a/app/pages/Onboarding/SetName/index.js b/app/pages/Onboarding/SetName/index.js
new file mode 100644
index 000000000..e3161a45f
--- /dev/null
+++ b/app/pages/Onboarding/SetName/index.js
@@ -0,0 +1,84 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { connect } from 'react-redux';
+import c from 'classnames';
+import './create.scss';
+import Submittable from '../../../components/Submittable';
+import WizardHeader from '../../../components/WizardHeader';
+
+@connect()
+export default class CreatePassword extends Component {
+ static propTypes = {
+ currentStep: PropTypes.number.isRequired,
+ totalSteps: PropTypes.number.isRequired,
+ onBack: PropTypes.func.isRequired,
+ onNext: PropTypes.func.isRequired,
+ onCancel: PropTypes.func.isRequired,
+ };
+
+ constructor(props) {
+ super(props);
+ this.state = {
+ name: '',
+ };
+ }
+
+ onSubmit = () => {
+ this.props.onNext(this.state.name);
+ };
+
+ isValidName = () => {
+ return this.state.name.match(/^[a-z0-9]+$/);
+ };
+
+ onChange = name => e => {
+ this.setState({
+ [name]: e.target.value,
+ });
+ };
+
+ render() {
+ const {currentStep, totalSteps, onBack} = this.props;
+
+ return (
+
+
+
+
+
+ Name this wallet
+
+
+ The name can only contain alphanumeric lowercase characters.
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/app/pages/Settings/index.js b/app/pages/Settings/index.js
index db2191d75..981f39a96 100644
--- a/app/pages/Settings/index.js
+++ b/app/pages/Settings/index.js
@@ -40,7 +40,7 @@ const analytics = aClientStub(() => require('electron').ipcRenderer);
}),
dispatch => ({
lockWallet: () => dispatch(walletActions.lockWallet()),
- removeWallet: () => dispatch(walletActions.removeWallet()),
+ reset: () => dispatch(walletActions.reset()),
stopNode: () => dispatch(nodeActions.stop()),
startNode: () => dispatch(nodeActions.start()),
setCustomRPCStatus: isConnected => dispatch(setCustomRPCStatus(isConnected)),
@@ -55,7 +55,7 @@ export default class Settings extends Component {
isRunning: PropTypes.bool.isRequired,
isChangingNodeStatus: PropTypes.bool.isRequired,
lockWallet: PropTypes.func.isRequired,
- removeWallet: PropTypes.func.isRequired,
+ reset: PropTypes.func.isRequired,
stopNode: PropTypes.func.isRequired,
startNode: PropTypes.func.isRequired,
setCustomRPCStatus: PropTypes.func.isRequired,
@@ -207,10 +207,10 @@ export default class Settings extends Component {
() => history.push('/settings/wallet/reveal-seed'),
)}
{this.renderSection(
- 'Remove wallet',
- 'This will remove all data from Bob. Proceed with caution.',
- 'Remove Wallet ',
- () => history.push('/settings/wallet/new-wallet'),
+ 'Create new wallet',
+ 'This will allow you to create a new wallet',
+ 'Create New',
+ () => history.push('/funding-options'),
)}
>
);
@@ -314,15 +314,6 @@ export default class Settings extends Component {
{ this.renderContent() }
- (
- this.props.removeWallet()}
- nextRoute="/"
- />
- )}
- />