Skip to content

Commit

Permalink
refactor(suite): split pushSendFormTransactionThunk into sub-thunks
Browse files Browse the repository at this point in the history
  • Loading branch information
PeKne committed May 14, 2024
1 parent ccb9c15 commit b84f20b
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 169 deletions.
20 changes: 8 additions & 12 deletions packages/suite/src/actions/wallet/moveLabelsForRbfActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { findChainedTransactions, findTransactions } from '@suite-common/wallet-
import { Dispatch, GetState } from 'src/types/suite';
import * as metadataLabelingActions from 'src/actions/suite/metadataLabelingActions';
import { AccountLabels, AccountOutputLabels } from '@suite-common/metadata-types';
import { AccountKey, WalletAccountTransaction } from '@suite-common/wallet-types';
import {
AccountKey,
RbfLabelsToBeUpdated,
WalletAccountTransaction,
} from '@suite-common/wallet-types';

type DeleteAllOutputLabelsParams = {
labels: AccountLabels['outputLabels']['labels'];
Expand Down Expand Up @@ -65,17 +69,9 @@ type FindLabelsToBeMovedOrDeletedParams = {
prevTxid: string;
};

export type LabelsToBeMovedOrDeleted = Record<
AccountKey,
{
toBeMoved: WalletAccountTransaction;
toBeDeleted: WalletAccountTransaction[];
}
>;

export const findLabelsToBeMovedOrDeleted =
({ prevTxid }: FindLabelsToBeMovedOrDeletedParams) =>
(_dispatch: Dispatch, getState: GetState): LabelsToBeMovedOrDeleted => {
(_dispatch: Dispatch, getState: GetState): RbfLabelsToBeUpdated => {
const accountTransactions = findTransactions(
prevTxid,
getState().wallet.transactions.transactions,
Expand All @@ -100,12 +96,12 @@ export const findLabelsToBeMovedOrDeleted =
};

return result;
}, {} as LabelsToBeMovedOrDeleted);
}, {} as RbfLabelsToBeUpdated);
};

type MoveLabelsForRbfParams = {
newTxid: string;
toBeMovedOrDeletedList: LabelsToBeMovedOrDeleted;
toBeMovedOrDeletedList: RbfLabelsToBeUpdated;
};

export const moveLabelsForRbfAction =
Expand Down
172 changes: 156 additions & 16 deletions packages/suite/src/actions/wallet/send/sendFormThunks.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,37 @@
import { G } from '@mobily/ts-belt';
import { isRejected } from '@reduxjs/toolkit';

import { createThunk } from '@suite-common/redux-utils';
import {
Account,
FormState,
GeneralPrecomposedTransactionFinal,
PrecomposedTransactionFinal,
PrecomposedTransactionFinalCardano,
RbfLabelsToBeUpdated,
} from '@suite-common/wallet-types';

import * as modalActions from 'src/actions/suite/modalActions';
import {
selectSelectedAccountKey,
selectIsSelectedAccountLoaded,
} from 'src/reducers/wallet/selectedAccountReducer';

import {
enhancePrecomposedTransactionThunk,
pushSendFormTransactionThunk,
replaceTransactionThunk,
selectDevice,
selectPrecomposedSendForm,
selectSendFormDrafts,
signTransactionThunk,
sendFormActions,
} from '@suite-common/wallet-core';
import { sendFormActions } from '@suite-common/wallet-core';
import { isRejected } from '@reduxjs/toolkit';
import { isCardanoTx } from '@suite-common/wallet-utils';
import { MetadataAddPayload } from '@suite-common/metadata-types';
import { Unsuccessful } from '@trezor/connect';
import { getSynchronize } from '@trezor/utils';

import {
selectSelectedAccountKey,
selectIsSelectedAccountLoaded,
} from 'src/reducers/wallet/selectedAccountReducer';
import { findLabelsToBeMovedOrDeleted } from '../moveLabelsForRbfActions';
import { selectMetadata } from 'src/reducers/suite/metadataReducer';
import * as metadataLabelingActions from 'src/actions/suite/metadataLabelingActions';
import * as modalActions from 'src/actions/suite/modalActions';

export const MODULE_PREFIX = '@send';

Expand Down Expand Up @@ -82,6 +90,110 @@ export const importSendFormRequestThunk = createThunk(
(_, { dispatch }) => dispatch(modalActions.openDeferredModal({ type: 'import-transaction' })),
);

const updateRbfLabelsThunk = createThunk(
`${MODULE_PREFIX}/updateReplacedTransactionThunk`,
(
{
labelsToBeEdited,
precomposedTx,
txid,
}: {
labelsToBeEdited: RbfLabelsToBeUpdated;
precomposedTx: PrecomposedTransactionFinal;
txid: string;
},
{ dispatch, extra },
) => {
const {
thunks: { moveLabelsForRbfAction },
} = extra;

if (labelsToBeEdited !== undefined) {
dispatch(
moveLabelsForRbfAction({
toBeMovedOrDeletedList: labelsToBeEdited,
newTxid: txid,
}),
);
}

// notification from the backend may be delayed.
// modify affected transaction(s) in the reducer until the real account update occurs.
// this will update transaction details (like time, fee etc.)
dispatch(
replaceTransactionThunk({
precomposedTx,
newTxid: txid,
}),
);
},
);

const applySendFormMetadataLabelsThunk = createThunk(
`${MODULE_PREFIX}/applyMetadataLabelsThunk`,
(
{
selectedAccount,
precomposedTx,
txid,
}: {
selectedAccount: Account;
precomposedTx: GeneralPrecomposedTransactionFinal;
txid: string;
},
{ dispatch, getState },
) => {
const metadata = selectMetadata(getState());
if (metadata.enabled) {
const precomposedForm = selectPrecomposedSendForm(getState());
let outputsPermutation: number[];
if (isCardanoTx(selectedAccount, precomposedTx)) {
// cardano preserves order of outputs
outputsPermutation = precomposedTx?.outputs.map((_o, i) => i);
} else {
outputsPermutation = precomposedTx?.outputsPermutation;
}

const synchronize = getSynchronize();

precomposedForm?.outputs
// create array of metadata objects
.map((formOutput, index) => {
const { label } = formOutput;
// final ordering of outputs differs from order in send form
// outputsPermutation contains mapping from @trezor/utxo-lib outputs to send form outputs
// mapping goes like this: Array<@trezor/utxo-lib index : send form index>
const outputIndex = outputsPermutation.findIndex(p => p === index);
const outputMetadata: Extract<MetadataAddPayload, { type: 'outputLabel' }> = {
type: 'outputLabel',
entityKey: selectedAccount.key,
txid, // txid becomes available, use it
outputIndex,
value: label,
defaultValue: '',
};

return outputMetadata;
})
// filter out empty values AFTER creating metadata objects (see outputs mapping above)
.filter(output => output.value)
// propagate metadata to reducers and persistent storage
.forEach((output, index, arr) => {
const isLast = index === arr.length - 1;

synchronize(() =>
dispatch(
metadataLabelingActions.addAccountMetadata({
...output,
skipSave: !isLast,
}),
),
);
});
}
},
);

export const signAndPushSendFormTransactionThunk = createThunk(
`${MODULE_PREFIX}/signSendFormTransactionThunk`,
async (
Expand All @@ -91,9 +203,7 @@ export const signAndPushSendFormTransactionThunk = createThunk(
selectedAccount,
}: {
formValues: FormState;
precomposedTransaction:
| PrecomposedTransactionFinal
| PrecomposedTransactionFinalCardano;
precomposedTransaction: GeneralPrecomposedTransactionFinal;
selectedAccount?: Account;
},
{ dispatch, getState },
Expand Down Expand Up @@ -130,10 +240,19 @@ export const signAndPushSendFormTransactionThunk = createThunk(
}

// Open a deferred modal and get the decision
const decision = await dispatch(
const isPushConfirmed = await dispatch(
modalActions.openDeferredModal({ type: 'review-transaction' }),
);
if (decision) {
if (isPushConfirmed) {
const isRbf = precomposedTransaction.prevTxid !== undefined;

// This has to be executed prior to pushing the transaction!
const rbfLabelsToBeEdited = isRbf
? dispatch(
findLabelsToBeMovedOrDeleted({ prevTxid: precomposedTransaction.prevTxid }),
)
: null;

// push tx to the network
const pushResponse = await dispatch(
pushSendFormTransactionThunk({
Expand All @@ -145,7 +264,28 @@ export const signAndPushSendFormTransactionThunk = createThunk(
return pushResponse.payload as Unsuccessful;
}

return pushResponse.payload;
const result = pushResponse.payload;
const { txid } = result.payload;

if (isRbf && rbfLabelsToBeEdited) {
await dispatch(
updateRbfLabelsThunk({
labelsToBeEdited: rbfLabelsToBeEdited,
precomposedTx: precomposedTransaction,
txid,
}),
);
}

dispatch(
applySendFormMetadataLabelsThunk({
selectedAccount,
precomposedTx: precomposedTransaction,
txid,
}),
);

return result;
}
},
);
Loading

0 comments on commit b84f20b

Please sign in to comment.