From f24a5bf590683e1e04b68fd93a387fbb7924570a Mon Sep 17 00:00:00 2001 From: Javier Bueno Date: Sun, 27 Oct 2024 04:16:10 +0100 Subject: [PATCH] feature(wallet-mobile): new tx review success and error screens --- .../ConfirmTxWithHwModal.tsx | 2 +- .../LedgerTransportSwitch.tsx | 12 +- .../common/ConfirmHWConnectionModal.tsx | 2 +- .../useCases/ConfirmPin/ConfirmPin.tsx | 14 +- .../features/ReviewTx/ReviewTxNavigator.tsx | 6 + .../ReviewTx/common/ReviewTxProvider.tsx | 65 +-- .../ReviewTx/common/hooks/useNavigateTo.tsx | 13 + .../ReviewTx/common/hooks/useOnConfirm.tsx | 8 +- .../ReviewTx/common/hooks/useSignTx.tsx | 69 ++++ .../ReviewTx/common/hooks/useStrings.tsx | 30 ++ .../ReviewTx/illustrations/FailedTxIcon.tsx | 46 +++ .../illustrations/SuccessfulTxIcon.tsx | 79 ++++ .../ReviewTxScreen/ReviewTxScreen.tsx | 13 +- .../ShowFailedTxScreen/FailedTxScreen.tsx | 75 ++++ .../SubmittedTxScreen.tsx | 76 ++++ .../src/features/Send/common/navigation.ts | 2 - .../ConfirmTx/FailedTx/FailedTxImage.tsx | 62 --- .../FailedTx/FailedTxScreen.stories.tsx | 8 - .../ConfirmTx/FailedTx/FailedTxScreen.tsx | 62 --- .../SubmittedTx/SubmittedTxImage.tsx | 78 ---- .../SubmittedTx/SubmittedTxScreen.stories.tsx | 8 - .../SubmittedTx/SubmittedTxScreen.tsx | 65 --- .../ConfirmTx/Summary/BalanceAfter.tsx | 43 -- .../ConfirmTx/Summary/CurrentBalance.tsx | 43 -- .../Send/useCases/ConfirmTx/Summary/Fees.tsx | 29 -- .../ConfirmTx/Summary/PrimaryTotal.tsx | 46 --- .../ConfirmTx/Summary/ReceiverInfo.tsx | 67 ---- .../ConfirmTx/Summary/SecondaryTotals.tsx | 58 --- .../ListAmountsToSendScreen.tsx | 8 +- .../Settings/SettingsScreenNavigator.tsx | 19 - .../ConfirmTx/FailedTx/FailedTxImage.tsx | 62 --- .../FailedTx/FailedTxScreen.stories.tsx | 8 - .../ConfirmTx/FailedTx/FailedTxScreen.tsx | 60 --- .../SubmittedTx/SubmittedTxImage.tsx | 78 ---- .../SubmittedTx/SubmittedTxScreen.stories.tsx | 8 - .../SubmittedTx/SubmittedTxScreen.tsx | 62 --- .../ManageCollateralScreen.tsx | 13 +- .../ManageCollateral/navigation.ts | 14 - .../Governance/GovernanceNavigator.tsx | 6 - .../Staking/Governance/common/helpers.tsx | 76 +--- .../Staking/Governance/common/navigation.ts | 10 +- .../FailedTx/FailedTxScreen.stories.tsx | 9 - .../useCases/FailedTx/FailedTxScreen.tsx | 75 ---- .../Governance/useCases/Home/HomeScreen.tsx | 7 +- .../SuccessTx/SuccessTxScreen.stories.tsx | 9 - .../useCases/SuccessTx/SuccessTxScreen.tsx | 106 ----- .../ConfirmRawTx/ConfirmRawTxWithHW.tsx | 2 +- .../src/features/Swap/common/navigation.ts | 2 - .../ShowFailedTxScreen/FailedTxImage.tsx | 62 --- .../ShowFailedTxScreen.stories.tsx | 8 - .../ShowFailedTxScreen/ShowFailedTxScreen.tsx | 61 --- .../ShowSubmittedTxScreen.stories.tsx | 20 - .../ShowSubmittedTxScreen.tsx | 96 ----- .../SubmittedTxImage.tsx | 78 ---- .../Swap/useCases/ReviewSwap/ReviewSwap.tsx | 21 +- .../src/features/Swap/useCases/index.ts | 2 - .../Transactions/TxHistoryNavigator.tsx | 33 +- .../src/kernel/i18n/locales/en-US.json | 8 +- apps/wallet-mobile/src/kernel/navigation.tsx | 27 +- .../src/legacy/Dashboard/Dashboard.tsx | 2 +- .../legacy/Dashboard/DashboardNavigator.tsx | 3 - .../legacy/Staking/FailedTx/FailedTxImage.tsx | 47 --- .../FailedTx/FailedTxScreen.stories.tsx | 8 - .../Staking/FailedTx/FailedTxScreen.tsx | 121 ------ .../PoolTransition/usePoolTransition.tsx | 41 +- .../Staking/StakingCenter/StakingCenter.tsx | 25 +- .../messages/src/AppNavigator.json | 32 +- .../ReviewTx/common/hooks/useStrings.json | 378 +++++++++++------- .../ListAmountsToSendScreen.json | 8 +- .../Settings/SettingsScreenNavigator.json | 160 ++++---- .../Transactions/TxHistoryNavigator.json | 184 ++++----- .../src/legacy/Dashboard/Dashboard.json | 4 +- .../legacy/Dashboard/DashboardNavigator.json | 8 +- .../PoolTransition/usePoolTransition.json | 104 ++--- .../Staking/StakingCenter/StakingCenter.json | 16 +- 75 files changed, 979 insertions(+), 2293 deletions(-) rename apps/wallet-mobile/src/{features/Swap/useCases/ConfirmTxScreen => components/LedgerTransportSwitch}/LedgerTransportSwitch.tsx (82%) create mode 100644 apps/wallet-mobile/src/features/ReviewTx/common/hooks/useNavigateTo.tsx create mode 100644 apps/wallet-mobile/src/features/ReviewTx/common/hooks/useSignTx.tsx create mode 100644 apps/wallet-mobile/src/features/ReviewTx/illustrations/FailedTxIcon.tsx create mode 100644 apps/wallet-mobile/src/features/ReviewTx/illustrations/SuccessfulTxIcon.tsx create mode 100644 apps/wallet-mobile/src/features/ReviewTx/useCases/ShowFailedTxScreen/FailedTxScreen.tsx create mode 100644 apps/wallet-mobile/src/features/ReviewTx/useCases/ShowSubmittedTxScreen/SubmittedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/FailedTx/FailedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/FailedTx/FailedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/FailedTx/FailedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/SubmittedTx/SubmittedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/SubmittedTx/SubmittedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/SubmittedTx/SubmittedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/BalanceAfter.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/CurrentBalance.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/Fees.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/PrimaryTotal.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/ReceiverInfo.tsx delete mode 100644 apps/wallet-mobile/src/features/Send/useCases/ConfirmTx/Summary/SecondaryTotals.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/ConfirmTx/FailedTx/FailedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/ConfirmTx/FailedTx/FailedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/ConfirmTx/FailedTx/FailedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/ConfirmTx/SubmittedTx/SubmittedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/ConfirmTx/SubmittedTx/SubmittedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/ConfirmTx/SubmittedTx/SubmittedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Settings/useCases/changeWalletSettings/ManageCollateral/navigation.ts delete mode 100644 apps/wallet-mobile/src/features/Staking/Governance/useCases/FailedTx/FailedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Staking/Governance/useCases/FailedTx/FailedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Staking/Governance/useCases/SuccessTx/SuccessTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Staking/Governance/useCases/SuccessTx/SuccessTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowFailedTxScreen/FailedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowFailedTxScreen/ShowFailedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowFailedTxScreen/ShowFailedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/ShowSubmittedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/ShowSubmittedTxScreen.tsx delete mode 100644 apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/ShowSubmittedTxScreen/SubmittedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/legacy/Staking/FailedTx/FailedTxImage.tsx delete mode 100644 apps/wallet-mobile/src/legacy/Staking/FailedTx/FailedTxScreen.stories.tsx delete mode 100644 apps/wallet-mobile/src/legacy/Staking/FailedTx/FailedTxScreen.tsx diff --git a/apps/wallet-mobile/src/components/ConfirmTxWithHwModal/ConfirmTxWithHwModal.tsx b/apps/wallet-mobile/src/components/ConfirmTxWithHwModal/ConfirmTxWithHwModal.tsx index 7846df0cd9..4c00a066fa 100644 --- a/apps/wallet-mobile/src/components/ConfirmTxWithHwModal/ConfirmTxWithHwModal.tsx +++ b/apps/wallet-mobile/src/components/ConfirmTxWithHwModal/ConfirmTxWithHwModal.tsx @@ -4,7 +4,6 @@ import React, {useState} from 'react' import {ErrorBoundary} from 'react-error-boundary' import {ActivityIndicator, ScrollView, StyleSheet, View} from 'react-native' -import {LedgerTransportSwitch} from '../../features/Swap/useCases/ConfirmTxScreen/LedgerTransportSwitch' import {useSelectedWallet} from '../../features/WalletManager/common/hooks/useSelectedWallet' import {useWalletManager} from '../../features/WalletManager/context/WalletManagerProvider' import {LedgerConnect} from '../../legacy/HW' @@ -12,6 +11,7 @@ import {useSignTxWithHW, useSubmitTx} from '../../yoroi-wallets/hooks' import {withBLE, withUSB} from '../../yoroi-wallets/hw/hwWallet' import {YoroiSignedTx, YoroiUnsignedTx} from '../../yoroi-wallets/types/yoroi' import {delay} from '../../yoroi-wallets/utils/timeUtils' +import {LedgerTransportSwitch} from '../LedgerTransportSwitch/LedgerTransportSwitch' import {ModalError} from '../ModalError/ModalError' import {Text} from '../Text' import {useStrings} from './strings' diff --git a/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/LedgerTransportSwitch.tsx b/apps/wallet-mobile/src/components/LedgerTransportSwitch/LedgerTransportSwitch.tsx similarity index 82% rename from apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/LedgerTransportSwitch.tsx rename to apps/wallet-mobile/src/components/LedgerTransportSwitch/LedgerTransportSwitch.tsx index bd06825b7f..9ba7b95e38 100644 --- a/apps/wallet-mobile/src/features/Swap/useCases/ConfirmTxScreen/LedgerTransportSwitch.tsx +++ b/apps/wallet-mobile/src/components/LedgerTransportSwitch/LedgerTransportSwitch.tsx @@ -2,12 +2,12 @@ import {useTheme} from '@yoroi/theme' import React from 'react' import {Alert, ScrollView, StyleSheet, View} from 'react-native' -import {Button, ButtonType} from '../../../../components/Button/Button' -import {Spacer} from '../../../../components/Spacer/Spacer' -import {Text} from '../../../../components/Text' -import {useIsUsbSupported} from '../../../../legacy/HW' -import {HARDWARE_WALLETS, useLedgerPermissions} from '../../../../yoroi-wallets/hw/hw' -import {useStrings} from '../../common/strings' +import {useStrings} from '../../features/Swap/common/strings' +import {useIsUsbSupported} from '../../legacy/HW' +import {HARDWARE_WALLETS, useLedgerPermissions} from '../../yoroi-wallets/hw/hw' +import {Button, ButtonType} from '../Button/Button' +import {Spacer} from '../Spacer/Spacer' +import {Text} from '../Text' type Props = { onSelectUSB: () => void diff --git a/apps/wallet-mobile/src/features/Discover/common/ConfirmHWConnectionModal.tsx b/apps/wallet-mobile/src/features/Discover/common/ConfirmHWConnectionModal.tsx index 2da7d51285..7558ab1255 100644 --- a/apps/wallet-mobile/src/features/Discover/common/ConfirmHWConnectionModal.tsx +++ b/apps/wallet-mobile/src/features/Discover/common/ConfirmHWConnectionModal.tsx @@ -3,11 +3,11 @@ import {HW} from '@yoroi/types' import React, {useCallback, useState} from 'react' import {ActivityIndicator, ScrollView, StyleSheet, View} from 'react-native' +import {LedgerTransportSwitch} from '../../../components/LedgerTransportSwitch/LedgerTransportSwitch' import {useModal} from '../../../components/Modal/ModalContext' import {Text} from '../../../components/Text' import {LedgerConnect} from '../../../legacy/HW' import {withBLE, withUSB} from '../../../yoroi-wallets/hw/hwWallet' -import {LedgerTransportSwitch} from '../../Swap/useCases/ConfirmTxScreen/LedgerTransportSwitch' import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' import {useWalletManager} from '../../WalletManager/context/WalletManagerProvider' import {useStrings} from './useStrings' diff --git a/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmPin/ConfirmPin.tsx b/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmPin/ConfirmPin.tsx index 90c3fda793..f69850c9a5 100644 --- a/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmPin/ConfirmPin.tsx +++ b/apps/wallet-mobile/src/features/RegisterCatalyst/useCases/ConfirmPin/ConfirmPin.tsx @@ -26,7 +26,7 @@ export const ConfirmPin = () => { const navigateTo = useNavigateTo() const [currentActivePin, setCurrentActivePin] = React.useState(1) const {wallet, meta} = useSelectedWallet() - const {onCIP36SupportChangeChanged, unsignedTxChanged, onSuccessChanged} = useReviewTx() + const {unsignedTxChanged} = useReviewTx() const {navigateToTxReview} = useWalletNavigation() const {generateVotingKeys, isLoading} = useGenerateVotingKeys({ @@ -40,13 +40,13 @@ export const ConfirmPin = () => { }) unsignedTxChanged(votingRegTx.votingRegTx) - onCIP36SupportChangeChanged(async (supportsCIP36: boolean) => { - votingRegTx = await wallet.createVotingRegTx({catalystKeyHex, supportsCIP36, addressMode: meta.addressMode}) - unsignedTxChanged(votingRegTx.votingRegTx) + navigateToTxReview({ + onCIP36SupportChange: async (supportsCIP36: boolean) => { + votingRegTx = await wallet.createVotingRegTx({catalystKeyHex, supportsCIP36, addressMode: meta.addressMode}) + unsignedTxChanged(votingRegTx.votingRegTx) + }, + onSuccess: navigateTo.qrCode, }) - onSuccessChanged(navigateTo.qrCode) - - navigateToTxReview() }, }) diff --git a/apps/wallet-mobile/src/features/ReviewTx/ReviewTxNavigator.tsx b/apps/wallet-mobile/src/features/ReviewTx/ReviewTxNavigator.tsx index 4f28322aff..1ae41aecb4 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/ReviewTxNavigator.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/ReviewTxNavigator.tsx @@ -6,6 +6,8 @@ import {Boundary} from '../../components/Boundary/Boundary' import {defaultStackNavigationOptions, ReviewTxRoutes} from '../../kernel/navigation' import {useStrings} from './common/hooks/useStrings' import {ReviewTxScreen} from './useCases/ReviewTxScreen/ReviewTxScreen' +import {FailedTxScreen} from './useCases/ShowFailedTxScreen/FailedTxScreen' +import {SubmittedTxScreen} from './useCases/ShowSubmittedTxScreen/SubmittedTxScreen' export const Stack = createStackNavigator() @@ -26,6 +28,10 @@ export const ReviewTxNavigator = () => { )} + + + + ) } diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx index c882fef6e7..9e6c7ab203 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx @@ -2,7 +2,7 @@ import {castDraft, produce} from 'immer' import _ from 'lodash' import React from 'react' -import {YoroiSignedTx, YoroiUnsignedTx} from '../../../yoroi-wallets/types/yoroi' +import {YoroiUnsignedTx} from '../../../yoroi-wallets/types/yoroi' export const useReviewTx = () => React.useContext(ReviewTxContext) @@ -27,13 +27,6 @@ export const ReviewTxProvider = ({ customReceiverTitleChanged: (customReceiverTitle: ReviewTxState['customReceiverTitle']) => dispatch({type: ReviewTxActionType.CustomReceiverTitleChanged, customReceiverTitle}), detailsChanged: (details: ReviewTxState['details']) => dispatch({type: ReviewTxActionType.DetailsChanged, details}), - onSuccessChanged: (onSuccess: ReviewTxState['onSuccess']) => - dispatch({type: ReviewTxActionType.OnSuccessChanged, onSuccess}), - onErrorChanged: (onError: ReviewTxState['onError']) => dispatch({type: ReviewTxActionType.OnErrorChanged, onError}), - onNotSupportedCIP1694Changed: (onNotSupportedCIP1694: ReviewTxState['onNotSupportedCIP1694']) => - dispatch({type: ReviewTxActionType.OnNotSupportedCIP1694Changed, onNotSupportedCIP1694}), - onCIP36SupportChangeChanged: (onCIP36SupportChange: ReviewTxState['onCIP36SupportChange']) => - dispatch({type: ReviewTxActionType.OnCIP36SupportChangeChanged, onCIP36SupportChange}), reset: () => dispatch({type: ReviewTxActionType.Reset}), }).current @@ -71,32 +64,12 @@ const reviewTxReducer = (state: ReviewTxState, action: ReviewTxAction) => { draft.details = action.details break - case ReviewTxActionType.OnSuccessChanged: - draft.onSuccess = action.onSuccess - break - - case ReviewTxActionType.OnErrorChanged: - draft.onError = action.onError - break - - case ReviewTxActionType.OnNotSupportedCIP1694Changed: - draft.onNotSupportedCIP1694 = action.onNotSupportedCIP1694 - break - - case ReviewTxActionType.OnCIP36SupportChangeChanged: - draft.onCIP36SupportChange = action.onCIP36SupportChange - break - case ReviewTxActionType.Reset: draft.unsignedTx = castDraft(defaultState.unsignedTx) draft.cbor = defaultState.cbor draft.operations = defaultState.operations draft.customReceiverTitle = defaultState.customReceiverTitle draft.details = defaultState.details - draft.onSuccess = defaultState.onSuccess - draft.onError = defaultState.onError - draft.onNotSupportedCIP1694 = defaultState.onNotSupportedCIP1694 - draft.onCIP36SupportChange = defaultState.onCIP36SupportChange break default: @@ -126,22 +99,6 @@ type ReviewTxAction = type: ReviewTxActionType.DetailsChanged details: ReviewTxState['details'] } - | { - type: ReviewTxActionType.OnSuccessChanged - onSuccess: ReviewTxState['onSuccess'] - } - | { - type: ReviewTxActionType.OnErrorChanged - onError: ReviewTxState['onError'] - } - | { - type: ReviewTxActionType.OnNotSupportedCIP1694Changed - onNotSupportedCIP1694: ReviewTxState['onNotSupportedCIP1694'] - } - | { - type: ReviewTxActionType.OnCIP36SupportChangeChanged - onCIP36SupportChange: ReviewTxState['onCIP36SupportChange'] - } | { type: ReviewTxActionType.Reset } @@ -152,10 +109,6 @@ export type ReviewTxState = { operations: Array | null customReceiverTitle: React.ReactNode | null details: {title: string; component: React.ReactNode} | null - onSuccess: ((signedTx: YoroiSignedTx) => void) | null - onError: (() => void) | null - onNotSupportedCIP1694: (() => void) | null - onCIP36SupportChange: ((isCIP36Supported: boolean) => void) | null } type ReviewTxActions = { @@ -164,10 +117,6 @@ type ReviewTxActions = { operationsChanged: (operations: ReviewTxState['operations']) => void customReceiverTitleChanged: (customReceiverTitle: ReviewTxState['customReceiverTitle']) => void detailsChanged: (details: ReviewTxState['details']) => void - onSuccessChanged: (onSuccess: ReviewTxState['onSuccess']) => void - onErrorChanged: (onError: ReviewTxState['onError']) => void - onNotSupportedCIP1694Changed: (onNotSupportedCIP1694: ReviewTxState['onNotSupportedCIP1694']) => void - onCIP36SupportChangeChanged: (onCIP36SupportChange: ReviewTxState['onCIP36SupportChange']) => void reset: () => void } @@ -177,10 +126,6 @@ const defaultState: ReviewTxState = Object.freeze({ operations: null, customReceiverTitle: null, details: null, - onSuccess: null, - onError: null, - onNotSupportedCIP1694: null, - onCIP36SupportChange: null, }) function missingInit() { @@ -194,10 +139,6 @@ const initialReviewTxContext: ReviewTxContext = { operationsChanged: missingInit, customReceiverTitleChanged: missingInit, detailsChanged: missingInit, - onSuccessChanged: missingInit, - onErrorChanged: missingInit, - onNotSupportedCIP1694Changed: missingInit, - onCIP36SupportChangeChanged: missingInit, reset: missingInit, } @@ -207,10 +148,6 @@ enum ReviewTxActionType { OperationsChanged = 'operationsChanged', CustomReceiverTitleChanged = 'customReceiverTitleChanged', DetailsChanged = 'detailsChanged', - OnSuccessChanged = 'onSuccessChanged', - OnErrorChanged = 'onErrorChanged', - OnNotSupportedCIP1694Changed = 'onNotSupportedCIP1694Changed', - OnCIP36SupportChangeChanged = 'onCIP36SupportChangeChanged', Reset = 'reset', } diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useNavigateTo.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useNavigateTo.tsx new file mode 100644 index 0000000000..f5a15da331 --- /dev/null +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useNavigateTo.tsx @@ -0,0 +1,13 @@ +import {NavigationProp, useNavigation} from '@react-navigation/native' +import * as React from 'react' + +import {ReviewTxRoutes} from '../../../../kernel/navigation' + +export const useNavigateTo = () => { + const navigation = useNavigation>() + + return React.useRef({ + showSubmittedTxScreen: () => navigation.navigate('review-tx-submitted-tx'), + showFailedTxScreen: () => navigation.navigate('review-tx-failed-tx'), + } as const).current +} diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx index 129affceba..35e6a4bf9c 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx @@ -6,7 +6,7 @@ import {ConfirmTxWithSpendingPasswordModal} from '../../../../components/Confirm import {useModal} from '../../../../components/Modal/ModalContext' import {YoroiSignedTx, YoroiUnsignedTx} from '../../../../yoroi-wallets/types/yoroi' import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet' -import {useReviewTx} from '../ReviewTxProvider' +import {useNavigateTo} from './useNavigateTo' import {useStrings} from './useStrings' // TODO: make it compatible with CBOR signing @@ -29,15 +29,15 @@ export const useOnConfirm = ({ const {meta} = useSelectedWallet() const {openModal, closeModal} = useModal() const strings = useStrings() - const {reset} = useReviewTx() + const navigateTo = useNavigateTo() const handleOnSuccess = (signedTx: YoroiSignedTx) => { onSuccess?.(signedTx) - reset() + navigateTo.showSubmittedTxScreen() } const handleOnError = () => { onError?.() - reset() + navigateTo.showFailedTxScreen() } const onConfirm = () => { diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useSignTx.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useSignTx.tsx new file mode 100644 index 0000000000..87f0a7c15b --- /dev/null +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useSignTx.tsx @@ -0,0 +1,69 @@ +import {TransactionWitnessSet} from '@emurgo/cross-csl-core' +import {WalletMeta} from '@yoroi/types/lib/typescript/wallet/meta' +import * as React from 'react' + +import {useModal} from '../../../../components/Modal/ModalContext' +import {cip30ExtensionMaker} from '../../../../yoroi-wallets/cardano/cip30/cip30' +import {YoroiWallet} from '../../../../yoroi-wallets/cardano/types' +import {wrappedCsl} from '../../../../yoroi-wallets/cardano/wrappedCsl' +import {useStrings} from '../../../Discover/common/useStrings' +import {ConfirmRawTxWithOs} from '../../../Swap/common/ConfirmRawTx/ConfirmRawTxWithOs' +import {ConfirmRawTxWithPassword} from '../../../Swap/common/ConfirmRawTx/ConfirmRawTxWithPassword' +import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet' + +export const useSignTx = () => { + const {openModal, closeModal} = useModal() + const {meta, wallet} = useSelectedWallet() + const strings = useStrings() + const modalHeight = 350 + + return React.useCallback( + (cbor: string) => { + const handleOnConfirm = async (rootKey: string) => { + console.log('signTx-123') + const witnesses = await signTx(Buffer.from(cbor).toString('hex'), rootKey, wallet, meta) + + if (!witnesses) throw new Error('kdkdkdk') + await submitTx(cbor, witnesses, wallet) + closeModal() + return + } + + if (meta.isHW) { + throw new Error('Not implemented yet') + } + + if (meta.isEasyConfirmationEnabled) { + openModal(strings.confirmTx, , modalHeight) + return + } + + openModal(strings.confirmTx, , modalHeight) + }, + [meta, openModal, strings.confirmTx, wallet, closeModal], + ) +} + +export const signTx = async (cbor: string, rootKey: string, wallet: YoroiWallet, meta: WalletMeta) => { + const cip30 = cip30ExtensionMaker(wallet, meta) + try { + return cip30.signTx(rootKey, cbor, false) + } catch { + console.log('smksksksksk') + } +} + +export const submitTx = async (cbor: string, witnesses: TransactionWitnessSet, wallet: YoroiWallet) => { + const {csl, release} = wrappedCsl() + + try { + const tx = await csl.Transaction.fromHex(cbor) + const txBody = await tx.body() + const signedTx = await csl.Transaction.new(txBody, witnesses, undefined) + const signedTxBytes = await signedTx.toBytes() + + await wallet.submitTransaction(Buffer.from(signedTxBytes).toString('base64')) + } finally { + release() + } +} diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx index 59311a3c62..81fa9da683 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx @@ -43,6 +43,12 @@ export const useStrings = () => { deregisterStakingKey: intl.formatMessage(messages.deregisterStakingKey), rewardsWithdrawalLabel: intl.formatMessage(messages.rewardsWithdrawalLabel), rewardsWithdrawalText: intl.formatMessage(messages.rewardsWithdrawalText), + submittedTxTitle: intl.formatMessage(messages.submittedTxTitle), + submittedTxText: intl.formatMessage(messages.submittedTxText), + submittedTxButton: intl.formatMessage(messages.submittedTxButton), + failedTxTitle: intl.formatMessage(messages.failedTxTitle), + failedTxText: intl.formatMessage(messages.failedTxText), + failedTxButton: intl.formatMessage(messages.failedTxButton), } } @@ -191,4 +197,28 @@ const messages = defineMessages({ id: 'txReview.operations.delegateStake', defaultMessage: '!!!Stake entire wallet balance to', }, + submittedTxTitle: { + id: 'txReview.submittedTxTitle', + defaultMessage: '!!!Transaction submitted', + }, + submittedTxText: { + id: 'txReview.submittedTxText', + defaultMessage: '!!!Check this transaction in the list of wallet transactions', + }, + submittedTxButton: { + id: 'txReview.submittedTxButton', + defaultMessage: '!!!Go to transactions', + }, + failedTxTitle: { + id: 'txReview.failedTxTitle', + defaultMessage: '!!!Transaction failed', + }, + failedTxText: { + id: 'txReview.failedTxText', + defaultMessage: '!!!Your transaction has not been processed properly due to technical issues', + }, + failedTxButton: { + id: 'txReview.failedTxButton', + defaultMessage: '!!!Go to transactions', + }, }) diff --git a/apps/wallet-mobile/src/features/ReviewTx/illustrations/FailedTxIcon.tsx b/apps/wallet-mobile/src/features/ReviewTx/illustrations/FailedTxIcon.tsx new file mode 100644 index 0000000000..48f7cf371c --- /dev/null +++ b/apps/wallet-mobile/src/features/ReviewTx/illustrations/FailedTxIcon.tsx @@ -0,0 +1,46 @@ +import * as React from 'react' +import Svg, {Defs, G, LinearGradient, Path, Stop} from 'react-native-svg' + +export const FailedTxIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/wallet-mobile/src/features/ReviewTx/illustrations/SuccessfulTxIcon.tsx b/apps/wallet-mobile/src/features/ReviewTx/illustrations/SuccessfulTxIcon.tsx new file mode 100644 index 0000000000..9729385194 --- /dev/null +++ b/apps/wallet-mobile/src/features/ReviewTx/illustrations/SuccessfulTxIcon.tsx @@ -0,0 +1,79 @@ +import * as React from 'react' +import Svg, {Defs, LinearGradient, Path, Stop} from 'react-native-svg' + +export const SuccessfulTxIcon = () => { + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ) +} diff --git a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx index 1b3344465d..1ab3d4d038 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx @@ -15,6 +15,7 @@ import { import {Button} from '../../../../components/Button/Button' import {SafeArea} from '../../../../components/SafeArea' import {ScrollView} from '../../../../components/ScrollView/ScrollView' +import {ReviewTxRoutes, useUnsafeParams} from '../../../../kernel/navigation' import {isEmptyString} from '../../../../kernel/utils' import {formatMetadata} from '../../common/hooks/useFormattedMetadata' import {useFormattedTx} from '../../common/hooks/useFormattedTx' @@ -31,17 +32,17 @@ const MaterialTab = createMaterialTopTabNavigator() export const ReviewTxScreen = () => { const {styles} = useStyles() const strings = useStrings() - const {unsignedTx, operations, details, onSuccess, onError, onNotSupportedCIP1694, onCIP36SupportChange} = - useReviewTx() + const {unsignedTx, operations, details} = useReviewTx() + const params = useUnsafeParams() if (unsignedTx === null) throw new Error('ReviewTxScreen: missing unsignedTx') const {onConfirm} = useOnConfirm({ unsignedTx, - onSuccess, - onError, - onNotSupportedCIP1694, - onCIP36SupportChange, + onSuccess: params?.onSuccess, + onError: params?.onError, + onNotSupportedCIP1694: params?.onNotSupportedCIP1694, + onCIP36SupportChange: params?.onCIP36SupportChange, }) // TODO: apply cbor diff --git a/apps/wallet-mobile/src/features/ReviewTx/useCases/ShowFailedTxScreen/FailedTxScreen.tsx b/apps/wallet-mobile/src/features/ReviewTx/useCases/ShowFailedTxScreen/FailedTxScreen.tsx new file mode 100644 index 0000000000..38fc137ff9 --- /dev/null +++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ShowFailedTxScreen/FailedTxScreen.tsx @@ -0,0 +1,75 @@ +import {useTheme} from '@yoroi/theme' +import React from 'react' +import {StyleSheet, Text, View} from 'react-native' + +import {Button} from '../../../../components/Button/Button' +import {SafeArea} from '../../../../components/SafeArea' +import {Space} from '../../../../components/Space/Space' +import {Spacer} from '../../../../components/Spacer/Spacer' +import {useBlockGoBack, useWalletNavigation} from '../../../../kernel/navigation' +import {useStrings} from '../../common/hooks/useStrings' +import {FailedTxIcon} from '../../illustrations/FailedTxIcon' + +export const FailedTxScreen = () => { + useBlockGoBack() + const strings = useStrings() + const {styles} = useStyles() + const {resetToTxHistory} = useWalletNavigation() + + return ( + + + + + + + + {strings.failedTxTitle} + + {strings.failedTxText} + + + + +