Skip to content

Commit

Permalink
chore(suite): cj session actions refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
dahaca committed Nov 23, 2022
1 parent 1b24b43 commit 14027f9
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 48 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { notificationsActions } from '@suite-common/toast-notifications';
import { accountsActions } from '@suite-common/wallet-core';
import { Account } from '@wallet-types';

const ACCOUNT = {
const ACCOUNT: Partial<Account> = {
accountType: 'coinjoin',
backendType: 'coinjoin',
symbol: 'btc',
deviceState: 'device-state',
key: '12345',
};

export const createCoinjoinAccount = [
Expand Down Expand Up @@ -166,17 +168,16 @@ export const startCoinjoinSession = [
export const stopCoinjoinSession = [
{
description: 'client not found',
params: {
...ACCOUNT,
symbol: 'ltc', // only btc is supported in tests
},
account: ACCOUNT,
param: '000',
result: {
actions: [],
},
},
{
description: 'success',
params: ACCOUNT,
account: ACCOUNT,
param: '12345',
result: {
actions: ['@coinjoin/account-unregister'],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { configureStore } from '@suite/support/tests/configureStore';

import { accountsReducer } from '@wallet-reducers';
import { coinjoinReducer } from '@wallet-reducers/coinjoinReducer';
import { Account } from '@wallet-types';
import * as coinjoinAccountActions from '../coinjoinAccountActions';
import * as fixtures from '../__fixtures__/coinjoinAccountActions';

Expand Down Expand Up @@ -121,9 +122,15 @@ describe('coinjoinAccountActions', () => {
fixtures.stopCoinjoinSession.forEach(f => {
it(`stopCoinjoinSession: ${f.description}`, async () => {
const initialState = getInitialState();
const store = initStore(initialState);

await store.dispatch(coinjoinAccountActions.stopCoinjoinSession(f.params as any));
const store = initStore({
...initialState,
wallet: {
...initialState.wallet,
accounts: [...initialState.wallet.accounts, f.account as Account],
},
});

await store.dispatch(coinjoinAccountActions.stopCoinjoinSession(f.param));

const actions = store.getActions();
expect(actions.map(a => a.type)).toEqual(f.result.actions);
Expand Down
76 changes: 53 additions & 23 deletions packages/suite/src/actions/wallet/coinjoinAccountActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@ import { getRegisterAccountParams, getMaxRounds } from '@wallet-utils/coinjoinUt
import { Dispatch, GetState } from '@suite-types';
import { Network, NetworkSymbol } from '@suite-common/wallet-config';
import { Account, CoinjoinAccount, CoinjoinSessionParameters } from '@suite-common/wallet-types';
import { accountsActions, transactionsActions } from '@suite-common/wallet-core';
import {
accountsActions,
selectAccountByKey,
transactionsActions,
} from '@suite-common/wallet-core';
import {
isAccountOutdated,
getAccountTransactions,
Expand Down Expand Up @@ -451,16 +455,23 @@ export const startCoinjoinSession =
};

// called from coinjoin account UI or exceptions like device disconnection, forget wallet/account etc.
export const pauseCoinjoinSession = (account: Account) => (dispatch: Dispatch) => {
// get @trezor/coinjoin client if available
const client = getCoinjoinClient(account.symbol);
export const pauseCoinjoinSession =
(accountKey: string) => (dispatch: Dispatch, getState: GetState) => {
const account = selectAccountByKey(getState(), accountKey);

// unregister account in @trezor/coinjoin
client?.unregisterAccount(account.key);
if (!account) {
return;
}

// dispatch data to reducer
dispatch(coinjoinSessionPause(account.key));
};
// get @trezor/coinjoin client if available
const client = getCoinjoinClient(account.symbol);

// unregister account in @trezor/coinjoin
client?.unregisterAccount(accountKey);

// dispatch data to reducer
dispatch(coinjoinSessionPause(accountKey));
};

export const pauseCoinjoinSessionByDeviceId =
(deviceID: string) => (dispatch: Dispatch, getState: GetState) => {
Expand Down Expand Up @@ -496,10 +507,15 @@ export const pauseCoinjoinSessionByDeviceId =
// use same parameters as in startCoinjoinSession but recalculate maxRounds value
// if Trezor is already preauthorized it will not ask for confirmation
export const restoreCoinjoinSession =
(account: Account) => async (dispatch: Dispatch, getState: GetState) => {
(accountKey: string) => async (dispatch: Dispatch, getState: GetState) => {
// TODO: check if device is connected, passphrase is authorized...
const { device } = getState().suite;
const { coinjoin } = getState().wallet;
const account = selectAccountByKey(getState(), accountKey);

if (!account) {
return;
}

// get @trezor/coinjoin client if available
const client = getCoinjoinClient(account.symbol);
Expand Down Expand Up @@ -556,35 +572,47 @@ export const restoreCoinjoinSession =
};

// called from coinjoin account UI or exceptions like device disconnection, forget wallet/account etc.
export const stopCoinjoinSession = (account: Account) => (dispatch: Dispatch) => {
// get @trezor/coinjoin client if available
const client = getCoinjoinClient(account.symbol);
if (!client) {
return;
}
export const stopCoinjoinSession =
(accountKey: string) => (dispatch: Dispatch, getState: GetState) => {
const account = selectAccountByKey(getState(), accountKey);

if (!account) {
return;
}

// unregister account in @trezor/coinjoin
client.unregisterAccount(account.key);
// get @trezor/coinjoin client if available
const client = getCoinjoinClient(account.symbol);
if (!client) {
return;
}

// dispatch data to reducer
dispatch(coinjoinAccountUnregister(account.key));
};
// unregister account in @trezor/coinjoin
client.unregisterAccount(account.key);

// dispatch data to reducer
dispatch(coinjoinAccountUnregister(account.key));
};

export const forgetCoinjoinAccounts =
(accounts: Account[]) => (dispatch: Dispatch, getState: GetState) => {
const { coinjoin } = getState().wallet;

// find all accounts to unregister
const coinjoinNetworks = coinjoin.accounts.reduce<NetworkSymbol[]>((res, cjAccount) => {
const account = accounts.find(a => a.key === cjAccount.key);

if (account) {
if (cjAccount.session) {
dispatch(stopCoinjoinSession(account));
dispatch(stopCoinjoinSession(cjAccount.key));
}

dispatch(coinjoinAccountRemove(cjAccount.key));

if (!res.includes(cjAccount.symbol)) {
return res.concat(cjAccount.symbol);
}
}

return res;
}, []);

Expand All @@ -602,17 +630,19 @@ export const restoreCoinjoin = () => (dispatch: Dispatch, getState: GetState) =>
// find all networks to restore
const coinjoinNetworks = coinjoin.accounts.reduce<NetworkSymbol[]>((res, cjAccount) => {
const account = accounts.find(a => a.key === cjAccount.key);

if (account) {
// currently it is not possible to full restore session while using passphrase.
// related to @trezor/connect and inner-outer state
if (cjAccount.session) {
dispatch(pauseCoinjoinSession(account));
dispatch(pauseCoinjoinSession(cjAccount.key));
}

if (!res.includes(account.symbol)) {
return res.concat(account.symbol);
}
}

return res;
}, []);

Expand Down
18 changes: 10 additions & 8 deletions packages/suite/src/components/suite/modals/CancelCoinjoin.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react';
import styled from 'styled-components';
import { Button } from '@trezor/components';
import { SelectedAccountLoaded } from '@suite-common/wallet-types';
import { useActions } from '@suite-hooks/useActions';
import * as coinjoinAccountActions from '@wallet-actions/coinjoinAccountActions';
import { useSelector } from '@suite-hooks/useSelector';
import { Modal, Translation } from '..';
import { selectSelectedAccount } from '@wallet-reducers/selectedAccountReducer';
import { useDispatch } from 'react-redux';
import { stopCoinjoinSession } from '@wallet-actions/coinjoinAccountActions';

const StyledModal = styled(Modal)`
width: 430px;
Expand All @@ -29,11 +29,13 @@ interface CancelCoinjoinProps {
}

export const CancelCoinjoin = ({ onClose }: CancelCoinjoinProps) => {
const { account } = useSelector(state => state.wallet.selectedAccount) as SelectedAccountLoaded;
const account = useSelector(selectSelectedAccount);

const { stopCoinjoinSession } = useActions({
stopCoinjoinSession: coinjoinAccountActions.stopCoinjoinSession,
});
const dispatch = useDispatch();

if (!account) {
return null;
}

return (
<StyledModal
Expand All @@ -48,7 +50,7 @@ export const CancelCoinjoin = ({ onClose }: CancelCoinjoinProps) => {
<StyledButton
variant="danger"
onClick={() => {
stopCoinjoinSession(account);
dispatch(stopCoinjoinSession(account.key));
onClose();
}}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
import { CoinjoinSession } from '@suite-common/wallet-types';
import { Translation } from '@suite-components/Translation';
import { CountdownTimer } from '@suite-components';
import { selectAccountByKey } from '@suite-common/wallet-core';
import { COINJOIN_PHASE_MESSAGES } from '@suite-constants/coinjoin';
import {
calculateSessionProgress,
Expand All @@ -25,7 +24,6 @@ import {
restoreCoinjoinSession,
stopCoinjoinSession,
} from '@wallet-actions/coinjoinAccountActions';
import { useSelector } from '@suite-hooks/useSelector';

const Container = styled.div`
position: relative;
Expand Down Expand Up @@ -138,7 +136,6 @@ interface CoinjoinStatusProps {
}

export const CoinjoinStatus = ({ session, accountKey }: CoinjoinStatusProps) => {
const account = useSelector(state => selectAccountByKey(state, accountKey));
const [isLoading, setIsLoading] = useState(false);
const [isWheelHovered, setIsWheelHovered] = useState(false);

Expand All @@ -154,12 +151,12 @@ export const CoinjoinStatus = ({ session, accountKey }: CoinjoinStatusProps) =>
const togglePause = useCallback(async () => {
if (isPaused) {
setIsLoading(true);
await dispatch(restoreCoinjoinSession(account!));
await dispatch(restoreCoinjoinSession(accountKey));
setIsLoading(false);
} else {
dispatch(pauseCoinjoinSession(account!));
dispatch(pauseCoinjoinSession(accountKey));
}
}, [isPaused, dispatch, account]);
}, [isPaused, dispatch, accountKey]);

const menuItems = useMemo<Array<GroupedMenuItems>>(
() => [
Expand Down Expand Up @@ -211,14 +208,14 @@ export const CoinjoinStatus = ({ session, accountKey }: CoinjoinStatusProps) =>
),
callback: () => {
menuRef.current?.close();
dispatch(stopCoinjoinSession(account!));
dispatch(stopCoinjoinSession(accountKey));
},
'data-test': `@coinjoin/cancel`,
},
],
},
],
[isPaused, togglePause, isLoading, dispatch, account],
[isPaused, togglePause, isLoading, dispatch, accountKey],
);

const iconConfig = {
Expand Down

0 comments on commit 14027f9

Please sign in to comment.