Skip to content

Commit

Permalink
Add the "Restore account" link in Log in page (#225)
Browse files Browse the repository at this point in the history
* onboarding welcome route

* add RESET action

* redo reset action

* add warning message in onboarding flow

* cleaning and styling

* reduce "Month" size in moment format txs view

* add case where xpub = ""

* Apply suggestions from code review

Co-authored-by: Marco Argentieri <[email protected]>
  • Loading branch information
louisinger and tiero authored Sep 24, 2021
1 parent 3cb2473 commit 627e21a
Show file tree
Hide file tree
Showing 19 changed files with 141 additions and 28 deletions.
2 changes: 1 addition & 1 deletion public/assets/images/warning.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/application/redux/actions/action-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const SET_DEEP_RESTORER_ERROR = 'SET_DEEP_RESTORER_ERROR';
export const NEW_ADDRESS_SUCCESS = 'NEW_ADDRESS_SUCCESS';
export const NEW_CHANGE_ADDRESS_SUCCESS = 'NEW_CHANGE_ADDRESS_SUCCESS';
export const SET_VERIFIED = 'SET_VERIFIED';
export const RESET_WALLET = 'RESET_WALLET';

// App
export const AUTHENTICATION_SUCCESS = 'AUTHENTICATION_SUCCESS';
Expand All @@ -18,6 +19,7 @@ export const ONBOARDING_COMPLETETED = 'ONBOARDING_COMPLETETED';
export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS';
export const CHANGE_NETWORK_SUCCESS = 'CHANGE_NETWORK_SUCCESS';
export const SET_EXPLORER = 'SET_EXPLORER';
export const RESET_APP = 'RESET_APP';

// Onboarding
export const ONBOARDING_SET_MNEMONIC_AND_PASSWORD = 'ONBOARDING_SET_MNEMONIC_AND_PASSWORD';
Expand All @@ -27,6 +29,7 @@ export const ONBOARDING_SET_IS_FROM_POPUP_FLOW = 'ONBOARDING_SET_IS_FROM_POPUP_F
// Transactions history
export const UPDATE_TXS = 'UPDATE_TXS';
export const ADD_TX = 'ADD_TX';
export const RESET_TXS = 'RESET_TXS';

// Pending transaction
export const PENDING_TX_SET_ASSET = 'PENDING_TX_SET_ASSET';
Expand All @@ -48,13 +51,18 @@ export const SET_MSG = 'SET_MSG';
export const FLUSH_MSG = 'FLUSH_MSG';
export const SELECT_HOSTNAME = 'SELECT_HOSTNAME';
export const FLUSH_SELECTED_HOSTNAME = 'FLUSH_SELECTED_HOSTNAME';
export const RESET_CONNECT = 'RESET_CONNECT';

// Taxi
export const SET_TAXI_ASSETS = 'SET_TAXI_ASSETS';
export const UPDATE_TAXI_ASSETS = 'UPDATE_TAXI_ASSETS';
export const RESET_TAXI = 'RESET_TAXI';

// Alarms
export const START_PERIODIC_UPDATE = 'START_PERIODIC_UPDATE';

// Restoration
export const START_DEEP_RESTORATION = 'START_DEEP_RESTORATION';

// Reset
export const RESET = 'RESET';
5 changes: 5 additions & 0 deletions src/application/redux/actions/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
CHANGE_NETWORK_SUCCESS,
START_PERIODIC_UPDATE,
SET_EXPLORER,
RESET,
} from './action-types';
import { AnyAction } from 'redux';
import { Network } from '../../../domain/network';
Expand Down Expand Up @@ -45,3 +46,7 @@ export function changeNetwork(network: Network): AnyAction {
export function startPeriodicUpdate(): AnyAction {
return { type: START_PERIODIC_UPDATE };
}

export function reset(): AnyAction {
return { type: RESET };
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import EndOfFlowOnboardingView, {
EndOfFlowProps,
} from '../../../presentation/onboarding/end-of-flow';
import { getExplorerURLSelector } from '../selectors/app.selector';
import { hasMnemonicSelector } from '../selectors/wallet.selector';

const mapStateToProps = (state: RootReducerState): EndOfFlowProps => {
return {
Expand All @@ -12,6 +13,7 @@ const mapStateToProps = (state: RootReducerState): EndOfFlowProps => {
isFromPopupFlow: state.onboarding.isFromPopupFlow,
network: state.app.network,
explorerURL: getExplorerURLSelector(state),
hasMnemonicRegistered: hasMnemonicSelector(state),
};
};

Expand Down
4 changes: 4 additions & 0 deletions src/application/redux/reducers/app-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ export const appInitState: IApp = {

export function appReducer(state: IApp = appInitState, { type, payload }: AnyAction): IApp {
switch (type) {
case ACTION_TYPES.RESET_APP: {
return appInitState;
}

case ACTION_TYPES.AUTHENTICATION_SUCCESS: {
return {
...state,
Expand Down
4 changes: 4 additions & 0 deletions src/application/redux/reducers/connect-data-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ export function connectDataReducer(
{ type, payload }: AnyAction
): ConnectData {
switch (type) {
case ACTION_TYPES.RESET_CONNECT: {
return connectDataInitState;
}

case ACTION_TYPES.ENABLE_WEBSITE: {
return {
...state,
Expand Down
7 changes: 6 additions & 1 deletion src/application/redux/reducers/taxi-reducer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AnyAction } from 'redux';
import { SET_TAXI_ASSETS } from '../actions/action-types';
import { RESET_TAXI, SET_TAXI_ASSETS } from '../actions/action-types';

export interface TaxiState {
taxiAssets: string[];
}
Expand All @@ -13,6 +14,10 @@ export function taxiReducer(
{ type, payload }: AnyAction
): TaxiState {
switch (type) {
case RESET_TAXI: {
return taxiInitState;
}

case SET_TAXI_ASSETS:
return { ...state, taxiAssets: payload };

Expand Down
4 changes: 4 additions & 0 deletions src/application/redux/reducers/txs-history-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export function txsHistoryReducer(
{ type, payload }: AnyAction
): TxsHistoryByNetwork {
switch (type) {
case ACTION_TYPES.RESET_TXS: {
return txsHistoryInitState;
}

case ACTION_TYPES.ADD_TX: {
let newLiquidTxsHistory = state.liquid;
let newRegtestTxsHistory = state.regtest;
Expand Down
4 changes: 4 additions & 0 deletions src/application/redux/reducers/wallet-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export function walletReducer(
{ type, payload }: AnyAction
): IWallet {
switch (type) {
case ACTION_TYPES.RESET_WALLET: {
return walletInitState;
}

case ACTION_TYPES.WALLET_SET_DATA: {
return {
...state,
Expand Down
4 changes: 4 additions & 0 deletions src/application/redux/selectors/wallet.selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ export function restorerOptsSelector(state: RootReducerState): StateRestorerOpts
export function utxosSelector(state: RootReducerState): UtxoInterface[] {
return Object.values(state.wallet.utxoMap);
}

export function hasMnemonicSelector(state: RootReducerState): boolean {
return state.wallet.encryptedMnemonic !== '' && state.wallet.encryptedMnemonic !== undefined;
}
3 changes: 3 additions & 0 deletions src/application/redux/store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
RESET,
START_DEEP_RESTORATION,
START_PERIODIC_UPDATE,
UPDATE_TAXI_ASSETS,
Expand All @@ -14,6 +15,7 @@ import {
fetchAndUpdateUtxos,
startAlarmUpdater,
deepRestorer,
resetAll,
} from '../../background/backend';
import persistStore from 'redux-persist/es/persistStore';
import { parse, stringify } from '../utils/browser-storage-converters';
Expand All @@ -30,6 +32,7 @@ const backgroundAliases = {
[UPDATE_TAXI_ASSETS]: () => fetchAndSetTaxiAssets(),
[START_PERIODIC_UPDATE]: () => startAlarmUpdater(),
[START_DEEP_RESTORATION]: () => deepRestorer(),
[RESET]: () => resetAll(),
};

const create = () => createStore(marinaReducer, applyMiddleware(alias(backgroundAliases), thunk));
Expand Down
10 changes: 10 additions & 0 deletions src/application/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import browser from 'webextension-polyfill';

/**
* Wait at least helper
* @param time
Expand All @@ -13,3 +15,11 @@ export async function waitAtLeast(time: number, promise: Promise<any>) {
const values = await promiseCombined;
return values[0];
}

export async function tabIsOpen(tabID: number): Promise<boolean> {
const tabs = await browser.tabs.query({ currentWindow: true });
for (const { id } of tabs) {
if (id && id === tabID) return true;
}
return false;
}
22 changes: 22 additions & 0 deletions src/background/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ import { AnyAction, Dispatch } from 'redux';
import { IAssets } from '../domain/assets';
import { addTx, updateTxs } from '../application/redux/actions/transaction';
import { getExplorerURLSelector } from '../application/redux/selectors/app.selector';
import {
RESET_APP,
RESET_CONNECT,
RESET_TAXI,
RESET_TXS,
RESET_WALLET,
} from '../application/redux/actions/action-types';
import { flushTx } from '../application/redux/actions/connect';

const UPDATE_ALARM = 'UPDATE_ALARM';

Expand Down Expand Up @@ -215,6 +223,7 @@ export function fetchAndSetTaxiAssets(): ThunkAction<void, RootReducerState, any
};
}

// Start the periodic updater (for utxos and txs fetching)
export function startAlarmUpdater(): ThunkAction<void, RootReducerState, any, AnyAction> {
return (dispatch) => {
dispatch(updateUtxos());
Expand All @@ -239,6 +248,7 @@ export function startAlarmUpdater(): ThunkAction<void, RootReducerState, any, An
};
}

// Using to generate addresses and use the explorer to test them
export function deepRestorer(): ThunkAction<void, RootReducerState, any, AnyAction> {
return async (dispatch, getState) => {
const state = getState();
Expand Down Expand Up @@ -283,3 +293,15 @@ function getRestoredXPub(state: RootReducerState): Promise<MasterPublicKey> {
const opts = restorerOptsSelector(state);
return masterPubKeyRestorerFromState(xPubKey)(opts);
}

// reset all the reducers except the `assets` reducer (shared data).
export function resetAll(): ThunkAction<void, RootReducerState, any, AnyAction> {
return (dispatch) => {
dispatch({ type: RESET_TAXI });
dispatch({ type: RESET_TXS });
dispatch({ type: RESET_APP });
dispatch({ type: RESET_WALLET });
dispatch({ type: RESET_CONNECT });
dispatch(flushTx());
};
}
6 changes: 2 additions & 4 deletions src/background/background-script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { enableWebsite } from '../application/redux/actions/connect';
import { setWalletData } from '../application/redux/actions/wallet';
import { marinaStore, wrapMarinaStore } from '../application/redux/store';
import { IDLE_MESSAGE_TYPE } from '../application/utils';
import { tabIsOpen } from '../application/utils/common';
import { setUpPopup } from '../application/utils/popup';
import {
isOpenPopupMessage,
Expand Down Expand Up @@ -64,10 +65,7 @@ browser.browserAction.onClicked.addListener(() => {
(async () => {
// here we prevent to open many onboarding pages fullscreen
// in case we have one active already in the current tab
const tabs = await browser.tabs.query({ currentWindow: true });
for (const { id } of tabs) {
if (id && id === welcomeTabID) return;
}
if (welcomeTabID && (await tabIsOpen(welcomeTabID))) return;

// in case the onboarding page is closed before finishing
// the wallet creation process, we let user re-open it
Expand Down
4 changes: 2 additions & 2 deletions src/presentation/components/button-transaction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const ButtonTransaction: React.FC<Props> = ({
>
<div className="flex items-center">
<TxIcon txType={tx.type} />
<span className="text-grayDark items-center mr-2 text-sm font-medium text-left">
{moment(tx.blockTimeMs).format('DD MMMM YYYY')}
<span className="text-grayDark items-center mr-2 text-xs font-medium text-left">
{moment(tx.blockTimeMs).format('DD MMM YYYY')}
</span>
</div>
<div className="flex">
Expand Down
16 changes: 16 additions & 0 deletions src/presentation/components/warningDeleteMnemonic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const WarningDeleteMnemonic: React.FC = () => (
<div className="bg-red bg-opacity-80 text-md text flex justify-between p-4 text-white align-middle border-0.5 rounded shadow-lg">
<div>
<img alt="warning" className="w-12" src="/assets/images/warning.svg" />
</div>
<div className="self-center ml-2">
<span>There is already a mnemonic on this browser. </span>
<br />
<span>Restoring a new wallet will delete that one. </span>
<br />
<span>Make sure you have a safe backup of the mnemonic words before creating a new wallet</span>
</div>
</div>
);

export default WarningDeleteMnemonic;
7 changes: 6 additions & 1 deletion src/presentation/onboarding/end-of-flow/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { useDispatch } from 'react-redux';
import { onboardingCompleted } from '../../../application/redux/actions/app';
import { onboardingCompleted, reset } from '../../../application/redux/actions/app';
import { flushOnboarding } from '../../../application/redux/actions/onboarding';
import { setWalletData } from '../../../application/redux/actions/wallet';
import { ProxyStoreDispatch } from '../../../application/redux/proxyStore';
Expand All @@ -20,6 +20,7 @@ export interface EndOfFlowProps {
isFromPopupFlow: boolean;
network: Network;
explorerURL: string;
hasMnemonicRegistered: boolean;
}

const EndOfFlowOnboardingView: React.FC<EndOfFlowProps> = ({
Expand All @@ -28,6 +29,7 @@ const EndOfFlowOnboardingView: React.FC<EndOfFlowProps> = ({
isFromPopupFlow,
network,
explorerURL,
hasMnemonicRegistered,
}) => {
const dispatch = useDispatch<ProxyStoreDispatch>();
const [isLoading, setIsLoading] = useState(true);
Expand All @@ -45,6 +47,9 @@ const EndOfFlowOnboardingView: React.FC<EndOfFlowProps> = ({
explorerURL
);

if (hasMnemonicRegistered) {
await dispatch(reset());
}
await dispatch(setWalletData(walletData));

// Startup alarms to fetch utxos & set the popup page
Expand Down
16 changes: 12 additions & 4 deletions src/presentation/onboarding/welcome/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ import React from 'react';
import Button from '../../components/button';
import { useHistory } from 'react-router-dom';
import { INITIALIZE_SELECT_ACTION_ROUTE } from '../../routes/constants';
import { useSelector } from 'react-redux';
import { hasMnemonicSelector } from '../../../application/redux/selectors/wallet.selector';
import WarningDeleteMnemonic from '../../components/warningDeleteMnemonic';

const Welcome: React.FC = () => {
const history = useHistory();
const handleClick = () => history.push(INITIALIZE_SELECT_ACTION_ROUTE);
const hasMnemonic = useSelector(hasMnemonicSelector);

return (
<div
Expand All @@ -19,10 +23,14 @@ const Welcome: React.FC = () => {
<img className="w-28 m-auto" src="assets/images/marina-logo.svg" alt="marina logo" />
<h2 className="my-5 text-4xl text-white">Welcome to Marina</h2>
</div>
<div className="self-center">
<Button className="w-52 mt-32 text-lg" onClick={handleClick}>
{'Get Started'}
</Button>

<div className="flex flex-col self-center justify-center align-middle">
{hasMnemonic && <WarningDeleteMnemonic />}
<div className="self-center">
<Button className="w-52 justify-center mt-3 text-lg" onClick={handleClick}>
{hasMnemonic ? 'I understand, go ahead!' : 'Get Started'}
</Button>
</div>
</div>
</div>
);
Expand Down
Loading

0 comments on commit 627e21a

Please sign in to comment.