From 28bbd8fe82b036c952c83f33d89f57e2adf79519 Mon Sep 17 00:00:00 2001 From: Javier Bueno Date: Thu, 24 Oct 2024 13:38:58 +0200 Subject: [PATCH] feature(wallet-mobile): new tx review for withdraw staking rewards --- .../.storybook/storybook.requires.js | 1 - .../ReviewTx/common/ReviewTxProvider.tsx | 35 +- .../ReviewTx/common/hooks/useFormattedTx.tsx | 9 +- .../ReviewTx/common/hooks/useOnConfirm.tsx | 23 +- .../ReviewTx/common/hooks/useStrings.tsx | 15 + .../features/ReviewTx/common/operations.tsx | 109 ++++-- .../src/features/ReviewTx/common/types.ts | 63 +++- .../ReviewTxScreen/Overview/OverviewTab.tsx | 15 +- .../ReviewTxScreen/ReviewTxScreen.tsx | 2 +- .../Staking/Governance/common/helpers.tsx | 35 +- .../Governance/useCases/Home/HomeScreen.tsx | 3 - .../src/kernel/i18n/locales/en-US.json | 3 + .../WithdrawStakingRewards.tsx | 28 +- .../PoolTransition/usePoolTransition.tsx | 5 +- .../Staking/StakingCenter/StakingCenter.tsx | 11 +- .../src/yoroi-wallets/hooks/index.ts | 19 ++ .../ReviewTx/common/hooks/useStrings.json | 309 ++++++++++-------- .../ListAmountsToSendScreen.json | 4 +- .../WithdrawStakingRewards.json | 72 ++-- .../PoolTransition/usePoolTransition.json | 104 +++--- .../Staking/StakingCenter/StakingCenter.json | 16 +- 21 files changed, 530 insertions(+), 351 deletions(-) diff --git a/apps/wallet-mobile/.storybook/storybook.requires.js b/apps/wallet-mobile/.storybook/storybook.requires.js index 6ec961a8f2..efdffe4715 100644 --- a/apps/wallet-mobile/.storybook/storybook.requires.js +++ b/apps/wallet-mobile/.storybook/storybook.requires.js @@ -283,7 +283,6 @@ const getStories = () => { "./src/legacy/HW/LedgerConnect/DeviceItem/DeviceItem.stories.tsx": require("../src/legacy/HW/LedgerConnect/DeviceItem/DeviceItem.stories.tsx"), "./src/legacy/HW/LedgerConnect/LedgerConnect.stories.tsx": require("../src/legacy/HW/LedgerConnect/LedgerConnect.stories.tsx"), "./src/legacy/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.stories.tsx": require("../src/legacy/HW/LedgerTransportSwitchModal/LedgerTransportSwitchModal.stories.tsx"), - "./src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.stories.tsx": require("../src/legacy/Staking/DelegationConfirmation/DelegationConfirmation.stories.tsx"), "./src/legacy/Staking/FailedTx/FailedTxScreen.stories.tsx": require("../src/legacy/Staking/FailedTx/FailedTxScreen.stories.tsx"), "./src/legacy/Staking/PoolDetails/PoolDetailScreen.stories.tsx": require("../src/legacy/Staking/PoolDetails/PoolDetailScreen.stories.tsx"), "./src/legacy/Staking/PoolTransition/PoolTransitionModal.stories.tsx": require("../src/legacy/Staking/PoolTransition/PoolTransitionModal.stories.tsx"), diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx index 44274bd96c..c882fef6e7 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/ReviewTxProvider.tsx @@ -31,9 +31,10 @@ export const ReviewTxProvider = ({ dispatch({type: ReviewTxActionType.OnSuccessChanged, onSuccess}), onErrorChanged: (onError: ReviewTxState['onError']) => dispatch({type: ReviewTxActionType.OnErrorChanged, onError}), onNotSupportedCIP1694Changed: (onNotSupportedCIP1694: ReviewTxState['onNotSupportedCIP1694']) => - dispatch({type: ReviewTxActionType.onNotSupportedCIP1694Changed, onNotSupportedCIP1694}), + dispatch({type: ReviewTxActionType.OnNotSupportedCIP1694Changed, onNotSupportedCIP1694}), onCIP36SupportChangeChanged: (onCIP36SupportChange: ReviewTxState['onCIP36SupportChange']) => - dispatch({type: ReviewTxActionType.onCIP36SupportChangeChanged, onCIP36SupportChange}), + dispatch({type: ReviewTxActionType.OnCIP36SupportChangeChanged, onCIP36SupportChange}), + reset: () => dispatch({type: ReviewTxActionType.Reset}), }).current const context = React.useMemo( @@ -78,14 +79,26 @@ const reviewTxReducer = (state: ReviewTxState, action: ReviewTxAction) => { draft.onError = action.onError break - case ReviewTxActionType.onNotSupportedCIP1694Changed: + case ReviewTxActionType.OnNotSupportedCIP1694Changed: draft.onNotSupportedCIP1694 = action.onNotSupportedCIP1694 break - case ReviewTxActionType.onCIP36SupportChangeChanged: + 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: throw new Error('[ReviewTxContext] invalid action') } @@ -122,13 +135,16 @@ type ReviewTxAction = onError: ReviewTxState['onError'] } | { - type: ReviewTxActionType.onNotSupportedCIP1694Changed + type: ReviewTxActionType.OnNotSupportedCIP1694Changed onNotSupportedCIP1694: ReviewTxState['onNotSupportedCIP1694'] } | { - type: ReviewTxActionType.onCIP36SupportChangeChanged + type: ReviewTxActionType.OnCIP36SupportChangeChanged onCIP36SupportChange: ReviewTxState['onCIP36SupportChange'] } + | { + type: ReviewTxActionType.Reset + } export type ReviewTxState = { unsignedTx: YoroiUnsignedTx | null @@ -152,6 +168,7 @@ type ReviewTxActions = { onErrorChanged: (onError: ReviewTxState['onError']) => void onNotSupportedCIP1694Changed: (onNotSupportedCIP1694: ReviewTxState['onNotSupportedCIP1694']) => void onCIP36SupportChangeChanged: (onCIP36SupportChange: ReviewTxState['onCIP36SupportChange']) => void + reset: () => void } const defaultState: ReviewTxState = Object.freeze({ @@ -181,6 +198,7 @@ const initialReviewTxContext: ReviewTxContext = { onErrorChanged: missingInit, onNotSupportedCIP1694Changed: missingInit, onCIP36SupportChangeChanged: missingInit, + reset: missingInit, } enum ReviewTxActionType { @@ -191,8 +209,9 @@ enum ReviewTxActionType { DetailsChanged = 'detailsChanged', OnSuccessChanged = 'onSuccessChanged', OnErrorChanged = 'onErrorChanged', - onNotSupportedCIP1694Changed = 'onNotSupportedCIP1694Changed', - onCIP36SupportChangeChanged = 'onCIP36SupportChangeChanged', + OnNotSupportedCIP1694Changed = 'onNotSupportedCIP1694Changed', + OnCIP36SupportChangeChanged = 'onCIP36SupportChangeChanged', + Reset = 'reset', } type ReviewTxContext = ReviewTxState & ReviewTxActions diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx index e01bdae3ea..419c218b1c 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx @@ -14,6 +14,8 @@ import {asQuantity} from '../../../../yoroi-wallets/utils/utils' import {usePortfolioTokenInfos} from '../../../Portfolio/common/hooks/usePortfolioTokenInfos' import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet' import { + Certificates, + FormattedCertificates, FormattedFee, FormattedInputs, FormattedOutputs, @@ -50,12 +52,13 @@ export const useFormattedTx = (data: TransactionBody): FormattedTx => { const formattedInputs = useFormattedInputs(wallet, inputs, portfolioTokenInfos) const formattedOutputs = useFormattedOutputs(wallet, outputs, portfolioTokenInfos) const formattedFee = formatFee(wallet, data) + const formattedCertificates = formatCertificates(data.certs as Certificates) return { inputs: formattedInputs, outputs: formattedOutputs, fee: formattedFee, - certificates: data.certs ?? null, + certificates: formattedCertificates, } } @@ -220,6 +223,10 @@ export const formatFee = (wallet: YoroiWallet, data: TransactionBody): Formatted } } +const formatCertificates = (certificates: Certificates) => { + return certificates.flatMap(Object.entries) as FormattedCertificates +} + const deriveAddress = async (address: string, chainId: number) => { try { return await deriveRewardAddressFromAddress(address, chainId) 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 b00d30458b..129affceba 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useOnConfirm.tsx @@ -6,6 +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 {useStrings} from './useStrings' // TODO: make it compatible with CBOR signing @@ -28,6 +29,16 @@ export const useOnConfirm = ({ const {meta} = useSelectedWallet() const {openModal, closeModal} = useModal() const strings = useStrings() + const {reset} = useReviewTx() + + const handleOnSuccess = (signedTx: YoroiSignedTx) => { + onSuccess?.(signedTx) + reset() + } + const handleOnError = () => { + onError?.() + reset() + } const onConfirm = () => { if (meta.isHW) { @@ -36,7 +47,7 @@ export const useOnConfirm = ({ onSuccess?.(signedTx)} + onSuccess={handleOnSuccess} onNotSupportedCIP1694={() => { if (onNotSupportedCIP1694) { closeModal() @@ -55,8 +66,8 @@ export const useOnConfirm = ({ strings.signTransaction, onSuccess?.(signedTx)} - onError={onError ?? undefined} + onSuccess={handleOnSuccess} + onError={handleOnError} />, ) return @@ -65,11 +76,7 @@ export const useOnConfirm = ({ if (!meta.isHW && meta.isEasyConfirmationEnabled) { openModal( strings.signTransaction, - onSuccess?.(signedTx)} - onError={onError ?? undefined} - />, + , ) return } 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 3858509fab..59311a3c62 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useStrings.tsx @@ -40,6 +40,9 @@ export const useStrings = () => { selectNoConfidence: intl.formatMessage(messages.selectNoConfidence), delegateVotingToDRep: intl.formatMessage(messages.delegateVotingToDRep), delegateStake: intl.formatMessage(messages.delegateStake), + deregisterStakingKey: intl.formatMessage(messages.deregisterStakingKey), + rewardsWithdrawalLabel: intl.formatMessage(messages.rewardsWithdrawalLabel), + rewardsWithdrawalText: intl.formatMessage(messages.rewardsWithdrawalText), } } @@ -160,6 +163,18 @@ const messages = defineMessages({ id: 'txReview.operations.registerStakingKey', defaultMessage: '!!!Register staking key deposit', }, + deregisterStakingKey: { + id: 'txReview.operations.deregisterStakingKey', + defaultMessage: '!!!Deregister staking key', + }, + rewardsWithdrawalLabel: { + id: 'txReview.operations.rewardsWithdrawal.label', + defaultMessage: '!!!Staking', + }, + rewardsWithdrawalText: { + id: 'txReview.operations.rewardsWithdrawal.text', + defaultMessage: '!!!Rewards withdrawal', + }, selectAbstain: { id: 'txReview.operations.selectAbstain', defaultMessage: '!!!Select abstain', diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx index 37e67650b2..6af35e8f63 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx @@ -1,5 +1,3 @@ -import {PoolInfoApi} from '@emurgo/yoroi-lib' -import {useBech32DRepID} from '@yoroi/staking' import {useTheme} from '@yoroi/theme' import * as React from 'react' import {Linking, StyleSheet, Text, View} from 'react-native' @@ -7,14 +5,16 @@ import {TouchableOpacity} from 'react-native-gesture-handler' import {useQuery} from 'react-query' import {Space} from '../../../components/Space/Space' -import {getPoolBech32Id} from '../../../yoroi-wallets/cardano/delegationUtils' +import {wrappedCsl} from '../../../yoroi-wallets/cardano/wrappedCsl' +import {usePoolInfo} from '../../../yoroi-wallets/hooks' import {formatTokenWithText} from '../../../yoroi-wallets/utils/format' import {asQuantity} from '../../../yoroi-wallets/utils/utils' import {useSelectedNetwork} from '../../WalletManager/common/hooks/useSelectedNetwork' import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' import {useStrings} from './hooks/useStrings' +import {Certificate, CertificateTypes, FormattedCertificates} from './types' -export const RegisterStakingKeyOperation = () => { +export const StakeRegistrationOperation = () => { const {styles} = useStyles() const strings = useStrings() const {wallet} = useSelectedWallet() @@ -31,7 +31,32 @@ export const RegisterStakingKeyOperation = () => { ) } -export const DelegateStakeOperation = ({poolId}: {poolId: string}) => { + +export const StakeDeregistrationOperation = () => { + const {styles} = useStyles() + const strings = useStrings() + + return ( + + {strings.deregisterStakingKey} + + ) +} + +export const StakeRewardsWithdrawalOperation = () => { + const {styles} = useStyles() + const strings = useStrings() + + return ( + + {strings.rewardsWithdrawalLabel} + + {strings.rewardsWithdrawalText} + + ) +} + +export const StakeDelegateOperation = ({poolId}: {poolId: string}) => { const {styles} = useStyles() const strings = useStrings() const poolInfo = usePoolInfo({poolId}) @@ -55,23 +80,6 @@ export const DelegateStakeOperation = ({poolId}: {poolId: string}) => { ) } -export const usePoolInfo = ({poolId}: {poolId: string}) => { - const {networkManager} = useSelectedNetwork() - const poolInfoApi = React.useMemo( - () => new PoolInfoApi(networkManager.legacyApiBaseUrl), - [networkManager.legacyApiBaseUrl], - ) - const poolInfo = useQuery({ - queryKey: ['usePoolInfoStakeOperation', poolId], - queryFn: async () => { - const poolBech32Id = await getPoolBech32Id(poolId) - return poolInfoApi.getSingleExplorerPoolInfo(poolBech32Id) - }, - }) - - return poolInfo?.data ?? null -} - export const AbstainOperation = () => { const {styles} = useStyles() const strings = useStrings() @@ -94,11 +102,11 @@ export const NoConfidenceOperation = () => { ) } -export const DelegateVotingToDrepOperation = ({drepID}: {drepID: string}) => { +export const VoteDelegationOperation = ({drepID}: {drepID: string}) => { const {styles} = useStyles() const strings = useStrings() - const {data: bech32DrepId} = useBech32DRepID(drepID) + const bech32DrepId = useDrepBech32Id(drepID) return ( @@ -111,6 +119,59 @@ export const DelegateVotingToDrepOperation = ({drepID}: {drepID: string}) => { ) } +export const useOperations = (certificates: FormattedCertificates | null) => { + if (certificates === null) return [] + + return certificates.reduce((acc, [certificateKind, CertificateData], index) => { + switch (certificateKind) { + case CertificateTypes.StakeRegistration: + return [...acc, ] + + case CertificateTypes.StakeDeregistration: + return [...acc, ] + + case CertificateTypes.StakeDelegation: { + const poolKeyHash = (CertificateData as Certificate[CertificateTypes.StakeDelegation]).pool_keyhash ?? null + if (poolKeyHash == null) return acc + return [...acc, ] + } + + case CertificateTypes.VoteDelegation: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const drep: any = (CertificateData as Certificate[CertificateTypes.VoteDelegation]).drep + + if (drep === 'AlwaysAbstain') return [...acc, ] + if (drep === 'AlwaysNoConfidence') return [...acc, ] + + const drepId = drep.KeyHash ?? drep.ScriptHash ?? '' + return [...acc, ] + } + + default: + return acc + } + }, []) +} + +export const getDrepBech32Id = async (poolId: string) => { + const {csl, release} = wrappedCsl() + try { + const keyHash = await csl.Ed25519KeyHash.fromHex(poolId) + return keyHash.toBech32('drep') + } finally { + release() + } +} + +export const useDrepBech32Id = (poolId: string) => { + const query = useQuery({ + queryKey: ['drepBech32', poolId], + queryFn: () => getDrepBech32Id(poolId), + }) + + return query?.data ?? null +} + const useStyles = () => { const {color, atoms} = useTheme() diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/types.ts b/apps/wallet-mobile/src/features/ReviewTx/common/types.ts index f06f1d2530..95d7a4ce05 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/types.ts +++ b/apps/wallet-mobile/src/features/ReviewTx/common/types.ts @@ -1,8 +1,24 @@ import { - CertificatesJSON, + CommitteeColdResignJSON, + CommitteeHotAuthJSON, + DRepDeregistrationJSON, + DRepRegistrationJSON, + DRepUpdateJSON, + GenesisKeyDelegationJSON, + MoveInstantaneousRewardsCertJSON, + PoolRegistrationJSON, + PoolRetirementJSON, + StakeAndVoteDelegationJSON, + StakeDelegationJSON, + StakeDeregistrationJSON, + StakeRegistrationAndDelegationJSON, + StakeRegistrationJSON, + StakeVoteRegistrationAndDelegationJSON, TransactionBodyJSON, TransactionInputsJSON, TransactionOutputsJSON, + VoteDelegationJSON, + VoteRegistrationAndDelegationJSON, } from '@emurgo/cardano-serialization-lib-nodejs' import {CredKind} from '@emurgo/cross-csl-core' import {Balance, Portfolio} from '@yoroi/types' @@ -57,7 +73,7 @@ export type FormattedTx = { inputs: FormattedInputs outputs: FormattedOutputs fee: FormattedFee - certificates: Certificates + certificates: FormattedCertificates | null } export type FormattedMetadata = { @@ -65,4 +81,45 @@ export type FormattedMetadata = { metadata: {msg: Array} | null } -export type Certificates = CertificatesJSON | null +export type Certificates = Array +export type FormattedCertificates = Array<[CertificateTypes, Certificate[CertificateTypes]]> + +export type Certificate = { + StakeRegistration: StakeRegistrationJSON + StakeDeregistration: StakeDeregistrationJSON + StakeDelegation: StakeDelegationJSON + PoolRegistration: PoolRegistrationJSON + PoolRetirement: PoolRetirementJSON + GenesisKeyDelegation: GenesisKeyDelegationJSON + MoveInstantaneousRewardsCert: MoveInstantaneousRewardsCertJSON + CommitteeHotAuth: CommitteeHotAuthJSON + CommitteeColdResign: CommitteeColdResignJSON + DRepDeregistration: DRepDeregistrationJSON + DRepRegistration: DRepRegistrationJSON + DRepUpdate: DRepUpdateJSON + StakeAndVoteDelegation: StakeAndVoteDelegationJSON + StakeRegistrationAndDelegation: StakeRegistrationAndDelegationJSON + StakeVoteRegistrationAndDelegation: StakeVoteRegistrationAndDelegationJSON + VoteDelegation: VoteDelegationJSON + VoteRegistrationAndDelegation: VoteRegistrationAndDelegationJSON +} + +export enum CertificateTypes { + StakeRegistration = 'StakeRegistration', + StakeDeregistration = 'StakeDeregistration', + StakeDelegation = 'StakeDelegation', + PoolRegistration = 'PoolRegistration', + PoolRetirement = 'PoolRetirement', + GenesisKeyDelegation = 'GenesisKeyDelegation', + MoveInstantaneousRewardsCert = 'MoveInstantaneousRewardsCert', + CommitteeHotAuth = 'CommitteeHotAuth', + CommitteeColdResign = 'CommitteeColdResign', + DRepDeregistration = 'DRepDeregistration', + DRepRegistration = 'DRepRegistration', + DRepUpdate = 'DRepUpdate', + StakeAndVoteDelegation = 'StakeAndVoteDelegation', + StakeRegistrationAndDelegation = 'StakeRegistrationAndDelegation', + StakeVoteRegistrationAndDelegation = 'StakeVoteRegistrationAndDelegation', + VoteDelegation = 'VoteDelegation', + VoteRegistrationAndDelegation = 'VoteRegistrationAndDelegation', +} diff --git a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx index cd04aeeb68..640a2783eb 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/Overview/OverviewTab.tsx @@ -17,17 +17,18 @@ import {useWalletManager} from '../../../../WalletManager/context/WalletManagerP import {Accordion} from '../../../common/Accordion' import {CopiableText} from '../../../common/CopiableText' import {useStrings} from '../../../common/hooks/useStrings' +import {useOperations} from '../../../common/operations' import {ReviewTxState, useReviewTx} from '../../../common/ReviewTxProvider' import {TokenItem} from '../../../common/TokenItem' import {FormattedOutputs, FormattedTx} from '../../../common/types' export const OverviewTab = ({ tx, - operations, + extraOperations, details, }: { tx: FormattedTx - operations: ReviewTxState['operations'] + extraOperations: ReviewTxState['operations'] details: ReviewTxState['details'] }) => { const {styles} = useStyles() @@ -45,7 +46,7 @@ export const OverviewTab = ({ - +
@@ -212,8 +213,10 @@ const ReceiverSection = ({notOwnedOutputs}: {notOwnedOutputs: FormattedOutputs}) ) } -const OperationsSection = ({operations}: {operations: ReviewTxState['operations']}) => { - if (operations === null || (Array.isArray(operations) && operations.length === 0)) return null +const OperationsSection = ({tx, extraOperations}: {tx: FormattedTx; extraOperations: ReviewTxState['operations']}) => { + const operations = useOperations(tx.certificates) + + if (extraOperations === null && tx.certificates === null) return null return ( @@ -222,7 +225,7 @@ const OperationsSection = ({operations}: {operations: ReviewTxState['operations' - {operations.map((operation, index) => { + {[...operations, ...(extraOperations ?? [])].map((operation, index) => { if (index === 0) return operation 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 48f54294af..1b3344465d 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/useCases/ReviewTxScreen/ReviewTxScreen.tsx @@ -64,7 +64,7 @@ export const ReviewTxScreen = () => { {() => ( /* TODO: make scrollview general to use button border */ - + )} diff --git a/apps/wallet-mobile/src/features/Staking/Governance/common/helpers.tsx b/apps/wallet-mobile/src/features/Staking/Governance/common/helpers.tsx index b8ec96328e..500b7e42c5 100644 --- a/apps/wallet-mobile/src/features/Staking/Governance/common/helpers.tsx +++ b/apps/wallet-mobile/src/features/Staking/Governance/common/helpers.tsx @@ -3,8 +3,6 @@ import { type StakingKeyState, governanceApiMaker, governanceManagerMaker, - GovernanceProvider, - useGovernance, useStakingKeyState, useUpdateLatestGovernanceAction, } from '@yoroi/staking' @@ -16,12 +14,6 @@ import {YoroiWallet} from '../../../../yoroi-wallets/cardano/types' import {useStakingKey} from '../../../../yoroi-wallets/hooks' import {YoroiUnsignedTx} from '../../../../yoroi-wallets/types/yoroi' import {CardanoMobile} from '../../../../yoroi-wallets/wallets' -import { - AbstainOperation, - DelegateVotingToDrepOperation, - NoConfidenceOperation, - RegisterStakingKeyOperation, -} from '../../../ReviewTx/common/operations' import {useReviewTx} from '../../../ReviewTx/common/ReviewTxProvider' import {useBestBlock} from '../../../WalletManager/common/hooks/useBestBlock' import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet' @@ -78,34 +70,21 @@ export const useGovernanceManagerMaker = () => { } export const useGovernanceActions = () => { - const {manager} = useGovernance() const {wallet} = useSelectedWallet() const navigateTo = useNavigateTo() - const {unsignedTxChanged, onSuccessChanged, onErrorChanged, operationsChanged, onNotSupportedCIP1694Changed} = - useReviewTx() + const {unsignedTxChanged, onSuccessChanged, onErrorChanged, onNotSupportedCIP1694Changed} = useReviewTx() const {updateLatestGovernanceAction} = useUpdateLatestGovernanceAction(wallet.id) const {navigateToTxReview} = useWalletNavigation() const handleDelegateAction = ({ drepID, unsignedTx, - hasStakeCert = false, navigateToStakingOnSuccess = false, }: { drepID: string unsignedTx: YoroiUnsignedTx - hasStakeCert?: boolean navigateToStakingOnSuccess?: boolean }) => { - let operations = [ - - - , - ] - - if (hasStakeCert) operations = [, ...operations] - - operationsChanged(operations) onSuccessChanged((signedTx) => { updateLatestGovernanceAction({kind: 'delegate-to-drep', drepID, txID: signedTx.signedTx.id}) navigateTo.txSuccess({navigateToStaking: navigateToStakingOnSuccess ?? false, kind: 'delegate'}) @@ -121,17 +100,11 @@ export const useGovernanceActions = () => { const handleAbstainAction = ({ unsignedTx, - hasStakeCert = false, navigateToStakingOnSuccess = false, }: { unsignedTx: YoroiUnsignedTx - hasStakeCert?: boolean navigateToStakingOnSuccess?: boolean }) => { - let operations = [] - if (hasStakeCert) operations = [, ...operations] - - operationsChanged(operations) onSuccessChanged((signedTx) => { updateLatestGovernanceAction({kind: 'vote', vote: 'abstain', txID: signedTx.signedTx.id}) navigateTo.txSuccess({navigateToStaking: navigateToStakingOnSuccess ?? false, kind: 'abstain'}) @@ -147,17 +120,11 @@ export const useGovernanceActions = () => { const handleNoConfidenceAction = ({ unsignedTx, - hasStakeCert = false, navigateToStakingOnSuccess = false, }: { unsignedTx: YoroiUnsignedTx - hasStakeCert?: boolean navigateToStakingOnSuccess?: boolean }) => { - let operations = [] - if (hasStakeCert) operations = [, ...operations] - - operationsChanged(operations) onSuccessChanged((signedTx) => { updateLatestGovernanceAction({kind: 'vote', vote: 'no-confidence', txID: signedTx.signedTx.id}) navigateTo.txSuccess({ diff --git a/apps/wallet-mobile/src/features/Staking/Governance/useCases/Home/HomeScreen.tsx b/apps/wallet-mobile/src/features/Staking/Governance/useCases/Home/HomeScreen.tsx index 9f43088d3e..19f03a4fcf 100644 --- a/apps/wallet-mobile/src/features/Staking/Governance/useCases/Home/HomeScreen.tsx +++ b/apps/wallet-mobile/src/features/Staking/Governance/useCases/Home/HomeScreen.tsx @@ -255,7 +255,6 @@ const NeverParticipatedInGovernanceVariant = () => { unsignedTx, drepID, navigateToStakingOnSuccess: params?.navigateToStakingOnSuccess, - hasStakeCert: stakeCert !== null, }) }, }, @@ -281,7 +280,6 @@ const NeverParticipatedInGovernanceVariant = () => { governanceActions.handleAbstainAction({ unsignedTx, navigateToStakingOnSuccess: params?.navigateToStakingOnSuccess, - hasStakeCert: stakeCert !== null, }) }, }, @@ -306,7 +304,6 @@ const NeverParticipatedInGovernanceVariant = () => { governanceActions.handleNoConfidenceAction({ unsignedTx, navigateToStakingOnSuccess: params?.navigateToStakingOnSuccess, - hasStakeCert: stakeCert !== null, }) }, }, diff --git a/apps/wallet-mobile/src/kernel/i18n/locales/en-US.json b/apps/wallet-mobile/src/kernel/i18n/locales/en-US.json index caeffe72a9..56f0b8cc98 100644 --- a/apps/wallet-mobile/src/kernel/i18n/locales/en-US.json +++ b/apps/wallet-mobile/src/kernel/i18n/locales/en-US.json @@ -1248,6 +1248,9 @@ "txReview.tokenDetails.overViewTab.details.label": "Details on", "txReview.tokenDetails.title": "Asset Details", "txReview.operations.registerStakingKey": "Register staking key deposit", + "txReview.operations.deregisterStakingKey": "Deregister staking key", + "txReview.operations.rewardsWithdrawal.label": "Staking", + "txReview.operations.rewardsWithdrawal.text": "Rewards withdrawal", "txReview.operations.selectAbstain": "Select abstain", "txReview.operations.selectNoConfidence": "Select no confidence", "txReview.operations.delegateVotingToDRep": "Delegate voting to", diff --git a/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx b/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx index c85860ddd7..18e000913d 100644 --- a/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx +++ b/apps/wallet-mobile/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx @@ -11,42 +11,32 @@ import {PleaseWaitView} from '../../../components/PleaseWaitModal' import {ScrollView, useScrollView} from '../../../components/ScrollView/ScrollView' import {Space} from '../../../components/Space/Space' import {Warning} from '../../../components/Warning/Warning' +import {StakeRewardsWithdrawalOperation} from '../../../features/ReviewTx/common/operations' +import {useReviewTx} from '../../../features/ReviewTx/common/ReviewTxProvider' import {useSelectedWallet} from '../../../features/WalletManager/common/hooks/useSelectedWallet' import globalMessages, {confirmationMessages, ledgerMessages, txLabels} from '../../../kernel/i18n/global-messages' import {useWalletNavigation} from '../../../kernel/navigation' import {YoroiWallet} from '../../../yoroi-wallets/cardano/types' import {useWithdrawalTx} from '../../../yoroi-wallets/hooks' import {YoroiUnsignedTx} from '../../../yoroi-wallets/types/yoroi' -import {delay} from '../../../yoroi-wallets/utils/timeUtils' import {Quantities} from '../../../yoroi-wallets/utils/utils' import {useStakingInfo} from '../StakePoolInfos' -import {ConfirmTx} from './ConfirmTx/ConfirmTx' type Props = { wallet: YoroiWallet } export const WithdrawStakingRewards = ({wallet}: Props) => { const strings = useWithdrawStakingRewardsStrings() - const {closeModal, openModal} = useModal() - const {resetToTxHistory} = useWalletNavigation() + const {closeModal} = useModal() + const {navigateToTxReview} = useWalletNavigation() + const {unsignedTxChanged, operationsChanged} = useReviewTx() - const handleOnConfirm = async (withdrawalTx: YoroiUnsignedTx) => { + const handleOnConfirm = (withdrawalTx: YoroiUnsignedTx) => { closeModal() - await delay(1000) - - openModal( - strings.confirmTx, - - resetToTxHistory()} - onCancel={() => closeModal()} - /> - , - 450, - ) + unsignedTxChanged(withdrawalTx) + operationsChanged([]) + navigateToTxReview() } return ( diff --git a/apps/wallet-mobile/src/legacy/Staking/PoolTransition/usePoolTransition.tsx b/apps/wallet-mobile/src/legacy/Staking/PoolTransition/usePoolTransition.tsx index d6bd535031..e4dd55e330 100644 --- a/apps/wallet-mobile/src/legacy/Staking/PoolTransition/usePoolTransition.tsx +++ b/apps/wallet-mobile/src/legacy/Staking/PoolTransition/usePoolTransition.tsx @@ -7,7 +7,6 @@ import * as React from 'react' import {defineMessages, useIntl} from 'react-intl' import {useQuery} from 'react-query' -import {DelegateStakeOperation} from '../../../features/ReviewTx/common/operations' import {useReviewTx} from '../../../features/ReviewTx/common/ReviewTxProvider' import {useSelectedNetwork} from '../../../features/WalletManager/common/hooks/useSelectedNetwork' import {useSelectedWallet} from '../../../features/WalletManager/common/hooks/useSelectedWallet' @@ -41,7 +40,7 @@ export const usePoolTransition = () => { const {wallet, meta} = useSelectedWallet() const {networkManager} = useSelectedNetwork() const {navigateToTxReview, resetToTxHistory} = useWalletNavigation() - const {unsignedTxChanged, onSuccessChanged, onErrorChanged, operationsChanged} = useReviewTx() + const {unsignedTxChanged, onSuccessChanged, onErrorChanged} = useReviewTx() const {stakingInfo, isLoading} = useStakingInfo(wallet) const poolInfoApi = React.useMemo( () => new PoolInfoApi(networkManager.legacyApiBaseUrl), @@ -65,7 +64,6 @@ export const usePoolTransition = () => { const navigateToUpdate = React.useCallback(async () => { try { const yoroiUnsignedTx = await createDelegationTx(wallet, poolId, meta) - operationsChanged([]) unsignedTxChanged(yoroiUnsignedTx) onSuccessChanged(() => { resetToTxHistory() @@ -85,7 +83,6 @@ export const usePoolTransition = () => { wallet, poolId, meta, - operationsChanged, unsignedTxChanged, onSuccessChanged, onErrorChanged, diff --git a/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx b/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx index 425290317f..2986550471 100644 --- a/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx +++ b/apps/wallet-mobile/src/legacy/Staking/StakingCenter/StakingCenter.tsx @@ -9,7 +9,6 @@ import {useQueryClient} from 'react-query' import {PleaseWaitModal} from '../../../components/PleaseWaitModal' import {Spacer} from '../../../components/Spacer/Spacer' -import {DelegateStakeOperation, RegisterStakingKeyOperation} from '../../../features/ReviewTx/common/operations' import {useReviewTx} from '../../../features/ReviewTx/common/ReviewTxProvider' import {useSelectedWallet} from '../../../features/WalletManager/common/hooks/useSelectedWallet' import {useWalletManager} from '../../../features/WalletManager/context/WalletManagerProvider' @@ -20,7 +19,7 @@ import {logger} from '../../../kernel/logger/logger' import {useMetrics} from '../../../kernel/metrics/metricsManager' import {StakingCenterRouteNavigation, useWalletNavigation} from '../../../kernel/navigation' import {NotEnoughMoneyToSendError} from '../../../yoroi-wallets/cardano/types' -import {useStakingInfo, useStakingTx} from '../../Dashboard/StakePoolInfos' +import {useStakingTx} from '../../Dashboard/StakePoolInfos' import {PoolDetailScreen} from '../PoolDetails' export const StakingCenter = () => { @@ -36,9 +35,7 @@ export const StakingCenter = () => { const {track} = useMetrics() const {plate} = walletManager.checksum(wallet.publicKeyHex) const {navigateToTxReview, resetToTxHistory} = useWalletNavigation() - const {unsignedTxChanged, onSuccessChanged, onErrorChanged, operationsChanged} = useReviewTx() - const stakingInfo = useStakingInfo(wallet, {suspense: true}) - const hasStakingKeyRegistered = stakingInfo?.data?.status !== 'not-registered' + const {unsignedTxChanged, onSuccessChanged, onErrorChanged} = useReviewTx() useFocusEffect( React.useCallback(() => { @@ -57,10 +54,6 @@ export const StakingCenter = () => { onSuccess: (yoroiUnsignedTx) => { if (selectedPoolId == null) return - let operations = [] - if (!hasStakingKeyRegistered) operations = [, ...operations] - - operationsChanged(operations) unsignedTxChanged(yoroiUnsignedTx) onSuccessChanged(() => { queryClient.resetQueries([wallet.id, 'stakingInfo']) diff --git a/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts b/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts index 29dbd086a9..ce610714ec 100644 --- a/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts +++ b/apps/wallet-mobile/src/yoroi-wallets/hooks/index.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import {walletChecksum} from '@emurgo/cip4-js' import {Certificate} from '@emurgo/cross-csl-core' +import {PoolInfoApi} from '@emurgo/yoroi-lib' import AsyncStorage, {AsyncStorageStatic} from '@react-native-async-storage/async-storage' import {mountMMKVStorage, observableStorageMaker, parseBoolean, useMutationWithInvalidations} from '@yoroi/common' import {themeStorageMaker} from '@yoroi/theme' @@ -25,6 +26,7 @@ import {isDev, isNightly} from '../../kernel/env' import {logger} from '../../kernel/logger/logger' import {deriveAddressFromXPub} from '../cardano/account-manager/derive-address-from-xpub' import {getSpendingKey, getStakingKey} from '../cardano/addressInfo/addressInfo' +import {getPoolBech32Id} from '../cardano/delegationUtils' import {WalletEvent, YoroiWallet} from '../cardano/types' import {TRANSACTION_DIRECTION, TRANSACTION_STATUS, TxSubmissionStatus} from '../types/other' import {YoroiSignedTx, YoroiUnsignedTx} from '../types/yoroi' @@ -702,3 +704,20 @@ export const useThemeStorageMaker = () => { return themeStorage } + +export const usePoolInfo = ({poolId}: {poolId: string}) => { + const {networkManager} = useSelectedNetwork() + const poolInfoApi = React.useMemo( + () => new PoolInfoApi(networkManager.legacyApiBaseUrl), + [networkManager.legacyApiBaseUrl], + ) + const poolInfo = useQuery({ + queryKey: ['usePoolInfoStakeOperation', poolId], + queryFn: async () => { + const poolBech32Id = await getPoolBech32Id(poolId) + return poolInfoApi.getSingleExplorerPoolInfo(poolBech32Id) + }, + }) + + return poolInfo?.data ?? null +} diff --git a/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json b/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json index 9e1a48b052..63f5ba1400 100644 --- a/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json +++ b/apps/wallet-mobile/translations/messages/src/features/ReviewTx/common/hooks/useStrings.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Confirm", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 47, + "line": 50, "column": 11, - "index": 2325 + "index": 2562 }, "end": { - "line": 50, + "line": 53, "column": 3, - "index": 2392 + "index": 2629 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!UTxOs", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 51, + "line": 54, "column": 9, - "index": 2403 + "index": 2640 }, "end": { - "line": 54, + "line": 57, "column": 3, - "index": 2466 + "index": 2703 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!UTxOs", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 55, + "line": 58, "column": 12, - "index": 2480 + "index": 2717 }, "end": { - "line": 58, + "line": 61, "column": 3, - "index": 2552 + "index": 2789 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Overview", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 59, + "line": 62, "column": 15, - "index": 2569 + "index": 2806 }, "end": { - "line": 62, + "line": 65, "column": 3, - "index": 2647 + "index": 2884 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!Metadata", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 63, + "line": 66, "column": 15, - "index": 2664 + "index": 2901 }, "end": { - "line": 66, + "line": 69, "column": 3, - "index": 2745 + "index": 2982 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Metadata hash", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 67, + "line": 70, "column": 16, - "index": 2763 + "index": 3000 }, "end": { - "line": 70, + "line": 73, "column": 3, - "index": 2850 + "index": 3087 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Metadata", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 71, + "line": 74, "column": 21, - "index": 2873 + "index": 3110 }, "end": { - "line": 74, + "line": 77, "column": 3, - "index": 2960 + "index": 3197 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Wallet", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 75, + "line": 78, "column": 15, - "index": 2977 + "index": 3214 }, "end": { - "line": 78, + "line": 81, "column": 3, - "index": 3051 + "index": 3288 } }, { @@ -124,14 +124,14 @@ "defaultMessage": "!!!Fee", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 79, + "line": 82, "column": 12, - "index": 3065 + "index": 3302 }, "end": { - "line": 82, + "line": 85, "column": 3, - "index": 3124 + "index": 3361 } }, { @@ -139,14 +139,14 @@ "defaultMessage": "!!!Your Wallet", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 83, + "line": 86, "column": 17, - "index": 3143 + "index": 3380 }, "end": { - "line": 86, + "line": 89, "column": 3, - "index": 3229 + "index": 3466 } }, { @@ -154,14 +154,14 @@ "defaultMessage": "!!!Send", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 87, + "line": 90, "column": 13, - "index": 3244 + "index": 3481 }, "end": { - "line": 90, + "line": 93, "column": 3, - "index": 3319 + "index": 3556 } }, { @@ -169,14 +169,14 @@ "defaultMessage": "!!!To", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 91, + "line": 94, "column": 18, - "index": 3339 + "index": 3576 }, "end": { - "line": 94, + "line": 97, "column": 3, - "index": 3417 + "index": 3654 } }, { @@ -184,14 +184,14 @@ "defaultMessage": "!!!To script", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 95, + "line": 98, "column": 24, - "index": 3443 + "index": 3680 }, "end": { - "line": 98, + "line": 101, "column": 3, - "index": 3534 + "index": 3771 } }, { @@ -199,14 +199,14 @@ "defaultMessage": "!!!Inputs", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 99, + "line": 102, "column": 20, - "index": 3556 + "index": 3793 }, "end": { - "line": 102, + "line": 105, "column": 3, - "index": 3637 + "index": 3874 } }, { @@ -214,14 +214,14 @@ "defaultMessage": "!!!Outputs", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 103, + "line": 106, "column": 21, - "index": 3660 + "index": 3897 }, "end": { - "line": 106, + "line": 109, "column": 3, - "index": 3743 + "index": 3980 } }, { @@ -229,14 +229,14 @@ "defaultMessage": "!!!Your address", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 107, + "line": 110, "column": 25, - "index": 3770 + "index": 4007 }, "end": { - "line": 110, + "line": 113, "column": 3, - "index": 3862 + "index": 4099 } }, { @@ -244,14 +244,14 @@ "defaultMessage": "!!!Foreign address", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 111, + "line": 114, "column": 28, - "index": 3892 + "index": 4129 }, "end": { - "line": 114, + "line": 117, "column": 3, - "index": 3990 + "index": 4227 } }, { @@ -259,14 +259,14 @@ "defaultMessage": "!!!Overview", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 115, + "line": 118, "column": 12, - "index": 4004 + "index": 4241 }, "end": { - "line": 118, + "line": 121, "column": 3, - "index": 4095 + "index": 4332 } }, { @@ -274,14 +274,14 @@ "defaultMessage": "!!!JSON", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 119, + "line": 122, "column": 8, - "index": 4105 + "index": 4342 }, "end": { - "line": 122, + "line": 125, "column": 3, - "index": 4188 + "index": 4425 } }, { @@ -289,14 +289,14 @@ "defaultMessage": "!!!Metadata", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 123, + "line": 126, "column": 12, - "index": 4202 + "index": 4439 }, "end": { - "line": 126, + "line": 129, "column": 3, - "index": 4292 + "index": 4529 } }, { @@ -304,14 +304,14 @@ "defaultMessage": "!!!Policy ID", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 127, + "line": 130, "column": 12, - "index": 4306 + "index": 4543 }, "end": { - "line": 130, + "line": 133, "column": 3, - "index": 4395 + "index": 4632 } }, { @@ -319,14 +319,14 @@ "defaultMessage": "!!!Fingerprint", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 131, + "line": 134, "column": 15, - "index": 4412 + "index": 4649 }, "end": { - "line": 134, + "line": 137, "column": 3, - "index": 4506 + "index": 4743 } }, { @@ -334,14 +334,14 @@ "defaultMessage": "!!!Name", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 135, + "line": 138, "column": 8, - "index": 4516 + "index": 4753 }, "end": { - "line": 138, + "line": 141, "column": 3, - "index": 4608 + "index": 4845 } }, { @@ -349,14 +349,14 @@ "defaultMessage": "!!!Token Supply", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 139, + "line": 142, "column": 15, - "index": 4625 + "index": 4862 }, "end": { - "line": 142, + "line": 145, "column": 3, - "index": 4732 + "index": 4969 } }, { @@ -364,14 +364,14 @@ "defaultMessage": "!!!Symbol", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 143, + "line": 146, "column": 10, - "index": 4744 + "index": 4981 }, "end": { - "line": 146, + "line": 149, "column": 3, - "index": 4840 + "index": 5077 } }, { @@ -379,14 +379,14 @@ "defaultMessage": "!!!Description", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 147, + "line": 150, "column": 15, - "index": 4857 + "index": 5094 }, "end": { - "line": 150, + "line": 153, "column": 3, - "index": 4963 + "index": 5200 } }, { @@ -394,14 +394,14 @@ "defaultMessage": "!!!Details on", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 151, + "line": 154, "column": 11, - "index": 4976 + "index": 5213 }, "end": { - "line": 154, + "line": 157, "column": 3, - "index": 5077 + "index": 5314 } }, { @@ -409,14 +409,14 @@ "defaultMessage": "!!!Asset Details", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 155, + "line": 158, "column": 21, - "index": 5100 + "index": 5337 }, "end": { - "line": 158, + "line": 161, "column": 3, - "index": 5184 + "index": 5421 } }, { @@ -424,14 +424,59 @@ "defaultMessage": "!!!Register staking key deposit", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 159, + "line": 162, "column": 22, - "index": 5208 + "index": 5445 }, "end": { - "line": 162, + "line": 165, + "column": 3, + "index": 5555 + } + }, + { + "id": "txReview.operations.deregisterStakingKey", + "defaultMessage": "!!!Deregister staking key", + "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", + "start": { + "line": 166, + "column": 24, + "index": 5581 + }, + "end": { + "line": 169, "column": 3, - "index": 5318 + "index": 5687 + } + }, + { + "id": "txReview.operations.rewardsWithdrawal.label", + "defaultMessage": "!!!Staking", + "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", + "start": { + "line": 170, + "column": 26, + "index": 5715 + }, + "end": { + "line": 173, + "column": 3, + "index": 5809 + } + }, + { + "id": "txReview.operations.rewardsWithdrawal.text", + "defaultMessage": "!!!Rewards withdrawal", + "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", + "start": { + "line": 174, + "column": 25, + "index": 5836 + }, + "end": { + "line": 177, + "column": 3, + "index": 5940 } }, { @@ -439,14 +484,14 @@ "defaultMessage": "!!!Select abstain", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 163, + "line": 178, "column": 17, - "index": 5337 + "index": 5959 }, "end": { - "line": 166, + "line": 181, "column": 3, - "index": 5428 + "index": 6050 } }, { @@ -454,14 +499,14 @@ "defaultMessage": "!!!Select no confidence", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 167, + "line": 182, "column": 22, - "index": 5452 + "index": 6074 }, "end": { - "line": 170, + "line": 185, "column": 3, - "index": 5554 + "index": 6176 } }, { @@ -469,14 +514,14 @@ "defaultMessage": "!!!Delegate voting to", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 171, + "line": 186, "column": 24, - "index": 5580 + "index": 6202 }, "end": { - "line": 174, + "line": 189, "column": 3, - "index": 5682 + "index": 6304 } }, { @@ -484,14 +529,14 @@ "defaultMessage": "!!!Stake entire wallet balance to", "file": "src/features/ReviewTx/common/hooks/useStrings.tsx", "start": { - "line": 175, + "line": 190, "column": 17, - "index": 5701 + "index": 6323 }, "end": { - "line": 178, + "line": 193, "column": 3, - "index": 5808 + "index": 6430 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json b/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json index ce25e2fc6f..e786d91a44 100644 --- a/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json +++ b/apps/wallet-mobile/translations/messages/src/features/Send/useCases/ListAmountsToSend/ListAmountsToSendScreen.json @@ -6,12 +6,12 @@ "start": { "line": 219, "column": 12, - "index": 7280 + "index": 7301 }, "end": { "line": 222, "column": 3, - "index": 7357 + "index": 7378 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.json b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.json index d0e1d39363..e34cf33ec5 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Also deregister staking key?", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 166, + "line": 156, "column": 21, - "index": 6114 + "index": 6060 }, "end": { - "line": 169, + "line": 159, "column": 3, - "index": 6242 + "index": 6188 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!When withdrawing rewards, you also have the option to deregister the staking key.", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 170, + "line": 160, "column": 16, - "index": 6260 + "index": 6206 }, "end": { - "line": 173, + "line": 163, "column": 3, - "index": 6443 + "index": 6389 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!Keeping the staking key will allow you to withdraw the rewards, but continue delegating to the same pool.", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 174, + "line": 164, "column": 16, - "index": 6461 + "index": 6407 }, "end": { - "line": 179, + "line": 169, "column": 3, - "index": 6685 + "index": 6631 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Deregistering the staking key will give you back your deposit and undelegate the key from any pool.", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 180, + "line": 170, "column": 16, - "index": 6703 + "index": 6649 }, "end": { - "line": 184, + "line": 174, "column": 3, - "index": 6910 + "index": 6856 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!You do NOT need to deregister to delegate to a different stake pool. You can change your delegation preference at any time.", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 185, + "line": 175, "column": 12, - "index": 6924 + "index": 6870 }, "end": { - "line": 190, + "line": 180, "column": 3, - "index": 7155 + "index": 7101 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!You should NOT deregister if this staking key is used as a stake pool's reward account, as this will cause all pool operator rewards to be sent back to the reserve.", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 191, + "line": 181, "column": 12, - "index": 7169 + "index": 7115 }, "end": { - "line": 197, + "line": 187, "column": 3, - "index": 7452 + "index": 7398 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Deregistering means this key will no longer receive rewards until you re-register the staking key (usually by delegating to a pool again)", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 198, + "line": 188, "column": 12, - "index": 7466 + "index": 7412 }, "end": { - "line": 203, + "line": 193, "column": 3, - "index": 7711 + "index": 7657 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!Keep registered", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 204, + "line": 194, "column": 14, - "index": 7727 + "index": 7673 }, "end": { - "line": 207, + "line": 197, "column": 3, - "index": 7835 + "index": 7781 } }, { @@ -124,14 +124,14 @@ "defaultMessage": "!!!Deregister", "file": "src/legacy/Dashboard/WithdrawStakingRewards/WithdrawStakingRewards.tsx", "start": { - "line": 208, + "line": 198, "column": 20, - "index": 7857 + "index": 7803 }, "end": { - "line": 211, + "line": 201, "column": 3, - "index": 7966 + "index": 7912 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Staking/PoolTransition/usePoolTransition.json b/apps/wallet-mobile/translations/messages/src/legacy/Staking/PoolTransition/usePoolTransition.json index 1ec5530969..0c7ddff6bc 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Staking/PoolTransition/usePoolTransition.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Staking/PoolTransition/usePoolTransition.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Upgrade your stake pool", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 127, + "line": 124, "column": 9, - "index": 4719 + "index": 4515 }, "end": { - "line": 130, + "line": 127, "column": 3, - "index": 4817 + "index": 4613 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!The current stake pool you're using will soon close. Migrate to the new EMURGO pool to sustain reward generation.", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 131, + "line": 128, "column": 11, - "index": 4830 + "index": 4626 }, "end": { - "line": 135, + "line": 132, "column": 3, - "index": 5026 + "index": 4822 } }, { @@ -34,14 +34,14 @@ "defaultMessage": "!!!The current stake pool you're using is decommissioned and NOT generating reward anymore. Update it to continue earning", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 136, + "line": 133, "column": 16, - "index": 5044 + "index": 4840 }, "end": { - "line": 140, + "line": 137, "column": 3, - "index": 5250 + "index": 5046 } }, { @@ -49,14 +49,14 @@ "defaultMessage": "!!!Current pool", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 141, + "line": 138, "column": 15, - "index": 5267 + "index": 5063 }, "end": { - "line": 144, + "line": 141, "column": 3, - "index": 5360 + "index": 5156 } }, { @@ -64,14 +64,14 @@ "defaultMessage": "!!!New pool", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 145, + "line": 142, "column": 11, - "index": 5373 + "index": 5169 }, "end": { - "line": 148, + "line": 145, "column": 3, - "index": 5458 + "index": 5254 } }, { @@ -79,14 +79,14 @@ "defaultMessage": "!!!Estimated ROA", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 149, + "line": 146, "column": 16, - "index": 5476 + "index": 5272 }, "end": { - "line": 152, + "line": 149, "column": 3, - "index": 5571 + "index": 5367 } }, { @@ -94,14 +94,14 @@ "defaultMessage": "!!!Fee", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 153, + "line": 150, "column": 7, - "index": 5580 + "index": 5376 }, "end": { - "line": 156, + "line": 153, "column": 3, - "index": 5656 + "index": 5452 } }, { @@ -109,14 +109,14 @@ "defaultMessage": "!!!This pool continues to generate staking rewards", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 157, + "line": 154, "column": 24, - "index": 5682 + "index": 5478 }, "end": { - "line": 160, + "line": 157, "column": 3, - "index": 5819 + "index": 5615 } }, { @@ -124,14 +124,14 @@ "defaultMessage": "!!!This pool is NOT generating staking rewards anymore", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 161, + "line": 158, "column": 17, - "index": 5838 + "index": 5634 }, "end": { - "line": 164, + "line": 161, "column": 3, - "index": 5972 + "index": 5768 } }, { @@ -139,14 +139,14 @@ "defaultMessage": "!!!This pool will stop generating rewards in", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 165, + "line": 162, "column": 23, - "index": 5997 + "index": 5793 }, "end": { - "line": 168, + "line": 165, "column": 3, - "index": 6127 + "index": 5923 } }, { @@ -154,14 +154,14 @@ "defaultMessage": "!!!Skip and stop receiving rewards", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 169, + "line": 166, "column": 17, - "index": 6146 + "index": 5942 }, "end": { - "line": 172, + "line": 169, "column": 3, - "index": 6260 + "index": 6056 } }, { @@ -169,14 +169,14 @@ "defaultMessage": "!!!Update now and keep earning", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 173, + "line": 170, "column": 21, - "index": 6283 + "index": 6079 }, "end": { - "line": 176, + "line": 173, "column": 3, - "index": 6397 + "index": 6193 } }, { @@ -184,14 +184,14 @@ "defaultMessage": "!!!Update pool", "file": "src/legacy/Staking/PoolTransition/usePoolTransition.tsx", "start": { - "line": 177, + "line": 174, "column": 10, - "index": 6409 + "index": 6205 }, "end": { - "line": 180, + "line": 177, "column": 3, - "index": 6496 + "index": 6292 } } ] \ No newline at end of file diff --git a/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json b/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json index 4f55b6775b..24ceee0b8c 100644 --- a/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json +++ b/apps/wallet-mobile/translations/messages/src/legacy/Staking/StakingCenter/StakingCenter.json @@ -4,14 +4,14 @@ "defaultMessage": "!!!Invalid Pool Data", "file": "src/legacy/Staking/StakingCenter/StakingCenter.tsx", "start": { - "line": 146, + "line": 139, "column": 9, - "index": 5740 + "index": 5214 }, "end": { - "line": 149, + "line": 142, "column": 3, - "index": 5848 + "index": 5322 } }, { @@ -19,14 +19,14 @@ "defaultMessage": "!!!The data from the stake pool(s) you selected is invalid. Please try again", "file": "src/legacy/Staking/StakingCenter/StakingCenter.tsx", "start": { - "line": 150, + "line": 143, "column": 11, - "index": 5861 + "index": 5335 }, "end": { - "line": 153, + "line": 146, "column": 3, - "index": 6027 + "index": 5501 } } ] \ No newline at end of file