From 61739df350249d68787b78f79798d6b25f8f9fc2 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Thu, 20 Jun 2024 23:28:20 +0300 Subject: [PATCH 1/3] fix(extension): [lw-10782] add proper mappers for missed conway era certs in activities transformers --- apps/browser-extension-wallet/src/utils/tx-inspection.ts | 6 +++++- .../features/activity/components/ActivityDetail.tsx | 9 ++++++--- .../ui/components/ActivityDetail/ActivityTypeIcon.tsx | 2 ++ packages/core/src/ui/components/ActivityDetail/types.ts | 2 ++ packages/translation/src/lib/translations/core/en.json | 2 ++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index 0cee507b97..47d0391a0b 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -1,3 +1,4 @@ +/* eslint-disable complexity */ /* eslint-disable consistent-return */ import { createTxInspector, @@ -53,8 +54,11 @@ const governanceCertificateInspection = ( // Assumes single certificate only, should update switch (true) { + case signedCertificateTypenames.includes(CertificateType.Registration): + return ConwayEraCertificatesTypes.Registration; + case signedCertificateTypenames.includes(CertificateType.Unregistration): + return ConwayEraCertificatesTypes.Unregistration; case signedCertificateTypenames.includes(CertificateType.RegisterDelegateRepresentative): - // TODO: can we map to Cip30TxType instead? return ConwayEraCertificatesTypes.RegisterDelegateRepresentative; case signedCertificateTypenames.includes(CertificateType.UnregisterDelegateRepresentative): return ConwayEraCertificatesTypes.UnregisterDelegateRepresentative; diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx index 488c9cd1d5..bb1c3fbf66 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/components/ActivityDetail.tsx @@ -3,8 +3,9 @@ import uniq from 'lodash/uniq'; import flatMap from 'lodash/flatMap'; import { Skeleton } from 'antd'; import { Wallet } from '@lace/cardano'; -import type { ActivityType } from '@lace/core'; import { + ActivityType, + ConwayEraCertificatesTypes, ActivityStatus, AssetActivityListProps, DelegationActivityType, @@ -83,8 +84,10 @@ interface ActivityDetailProps { } const getTypeLabel = (type: ActivityType): TranslationKey => { - if (type === DelegationActivityType.delegationRegistration) return 'core.activityDetails.registration'; - if (type === DelegationActivityType.delegationDeregistration) return 'core.activityDetails.deregistration'; + if (type === DelegationActivityType.delegationRegistration || type === ConwayEraCertificatesTypes.Registration) + return 'core.activityDetails.registration'; + if (type === DelegationActivityType.delegationDeregistration || type === ConwayEraCertificatesTypes.Unregistration) + return 'core.activityDetails.deregistration'; if (type === TransactionActivityType.incoming) return 'core.activityDetails.received'; if (type === TransactionActivityType.outgoing) return 'core.activityDetails.sent'; return `core.activityDetails.${type}`; diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index 125252f91d..daec6d4632 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -60,6 +60,8 @@ const activityTypeIcon: Record Date: Mon, 24 Jun 2024 23:47:01 +0300 Subject: [PATCH 2/3] fix(extension): [lw-10782] fix fiat amount for pending tx, differentiate between conway and non --- .../src/hooks/useWalletActivities.ts | 1 + .../src/utils/tx-inspection.ts | 18 ++++++++++++------ .../activity/helpers/common-tx-transformer.ts | 16 ++++++++++------ .../ActivityDetail/ActivityTypeIcon.tsx | 10 +++++++--- 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/apps/browser-extension-wallet/src/hooks/useWalletActivities.ts b/apps/browser-extension-wallet/src/hooks/useWalletActivities.ts index 20d50ef016..23f164a889 100644 --- a/apps/browser-extension-wallet/src/hooks/useWalletActivities.ts +++ b/apps/browser-extension-wallet/src/hooks/useWalletActivities.ts @@ -22,6 +22,7 @@ export const useWalletActivities = ({ const fetchWalletActivities = useCallback(async () => { fiatCurrency && + cardanoFiatPrice && getWalletActivities({ fiatCurrency, cardanoFiatPrice, diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index 47d0391a0b..9d638ebdd3 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -9,6 +9,7 @@ import { sentInspector, totalAddressOutputsValueInspector } from '@cardano-sdk/core'; +import { certificateInspectorFactory } from '@src/features/dapp/components/confirm-transaction/utils'; import { Wallet } from '@lace/cardano'; import { ActivityType, @@ -54,10 +55,6 @@ const governanceCertificateInspection = ( // Assumes single certificate only, should update switch (true) { - case signedCertificateTypenames.includes(CertificateType.Registration): - return ConwayEraCertificatesTypes.Registration; - case signedCertificateTypenames.includes(CertificateType.Unregistration): - return ConwayEraCertificatesTypes.Unregistration; case signedCertificateTypenames.includes(CertificateType.RegisterDelegateRepresentative): return ConwayEraCertificatesTypes.RegisterDelegateRepresentative; case signedCertificateTypenames.includes(CertificateType.UnregisterDelegateRepresentative): @@ -112,7 +109,7 @@ const getWalletAccounts = (walletAddresses: Wallet.KeyManagement.GroupedAddress[ { paymentAddresses: [], rewardAccounts: [] } ); -const txIncludesConwayCertificates = (certificates?: Wallet.Cardano.Certificate[]) => +export const txIncludesConwayCertificates = (certificates?: Wallet.Cardano.Certificate[]): boolean => certificates?.length > 0 ? certificates.some((certificate) => Object.values(ConwayEraCertificatesTypes).includes( @@ -162,11 +159,16 @@ export const inspectTxType = async ({ delegation: delegationInspector, stakeKeyRegistration: stakeKeyRegistrationInspector, stakeKeyDeregistration: stakeKeyDeregistrationInspector, + conwayEraStakeKeyRegistration: certificateInspectorFactory(CertificateType.Registration), + conwayEraStakeKeyDeregistration: certificateInspectorFactory(CertificateType.Unregistration), selfTransaction: selfTxInspector(paymentAddresses) })(tx); if (txIncludesConwayCertificates(tx.body.certificates)) { - return governanceCertificateInspection(tx.body.certificates); + const inspection = governanceCertificateInspection(tx.body.certificates); + if (inspection) { + return inspection; + } } const withRewardsWithdrawal = isTxWithRewardsWithdrawal( @@ -183,6 +185,10 @@ export const inspectTxType = async ({ return DelegationActivityType.delegationRegistration; case inspectionProperties.stakeKeyDeregistration.length > 0: return DelegationActivityType.delegationDeregistration; + case !!inspectionProperties.conwayEraStakeKeyRegistration: + return ConwayEraCertificatesTypes.Registration; + case !!inspectionProperties.conwayEraStakeKeyDeregistration: + return ConwayEraCertificatesTypes.Unregistration; // Voting procedures take priority over proposals // TODO: use proper inspector when available on sdk side (LW-9569) case tx.body.votingProcedures?.length > 0: diff --git a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts index e1903bfea8..bf2517fa9a 100644 --- a/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts +++ b/apps/browser-extension-wallet/src/views/browser-view/features/activity/helpers/common-tx-transformer.ts @@ -4,11 +4,11 @@ import BigNumber from 'bignumber.js'; import { Wallet } from '@lace/cardano'; import { CurrencyInfo, TxDirections } from '@types'; -import { inspectTxValues, inspectTxType } from '@src/utils/tx-inspection'; +import { inspectTxValues, inspectTxType, txIncludesConwayCertificates } from '@src/utils/tx-inspection'; import { formatDate, formatTime } from '@src/utils/format-date'; import { getTransactionTotalAmount } from '@src/utils/get-transaction-total-amount'; import type { TransformedActivity, TransformedTransactionActivity } from './types'; -import { ActivityStatus, DelegationActivityType } from '@lace/core'; +import { ActivityStatus, ConwayEraCertificatesTypes, DelegationActivityType } from '@lace/core'; import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; import { hasPhase2ValidationFailed } from '@src/utils/phase2-validation'; @@ -43,7 +43,7 @@ export const getFormattedFiatAmount = ({ return fiatAmount ? `${fiatAmount} ${fiatCurrency.code}` : '-'; }; -const splitDelegationTx = (tx: TransformedActivity): TransformedTransactionActivity[] => { +const splitDelegationTx = (tx: TransformedActivity, hasConwayEraCerts: boolean): TransformedTransactionActivity[] => { if (tx.deposit) { return [ { @@ -54,7 +54,9 @@ const splitDelegationTx = (tx: TransformedActivity): TransformedTransactionActiv }, { ...tx, - type: DelegationActivityType.delegationRegistration, + type: hasConwayEraCerts + ? ConwayEraCertificatesTypes.Registration + : DelegationActivityType.delegationRegistration, // Let registration show just the deposit, // and the other transaction show fee to avoid duplicity fee: '0' @@ -70,7 +72,9 @@ const splitDelegationTx = (tx: TransformedActivity): TransformedTransactionActiv }, { ...tx, - type: DelegationActivityType.delegationDeregistration, + type: hasConwayEraCerts + ? ConwayEraCertificatesTypes.Unregistration + : DelegationActivityType.delegationDeregistration, // Let de-registration show just the returned deposit, // and the other transaction show fee to avoid duplicity fee: '0' @@ -239,7 +243,7 @@ export const txTransformer = async ({ }); if (type === DelegationActivityType.delegation) { - return splitDelegationTx(baseTransformedActivity); + return splitDelegationTx(baseTransformedActivity, txIncludesConwayCertificates(tx.body.certificates)); } return [ diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx index daec6d4632..fa02b22ef1 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx +++ b/packages/core/src/ui/components/ActivityDetail/ActivityTypeIcon.tsx @@ -75,10 +75,14 @@ export const ActivityTypeIcon = ({ type }: ActivityTypeIconProps): React.ReactEl const icon = (type && activityTypeIcon[type]) || RefreshOutlinedIcon; const iconStyle = { fontSize: txIconSize() }; + const isDelegationActivity = + type === ConwayEraCertificatesTypes.Unregistration || type === ConwayEraCertificatesTypes.Registration; + const isGovernanceTx = - Object.values(ConwayEraCertificatesTypes).includes(type as unknown as ConwayEraCertificatesTypes) || - type in ConwayEraGovernanceActions || - type in Cip1694GovernanceActivityType; + !isDelegationActivity && + (Object.values(ConwayEraCertificatesTypes).includes(type as unknown as ConwayEraCertificatesTypes) || + type in ConwayEraGovernanceActions || + type in Cip1694GovernanceActivityType); return ( Date: Tue, 25 Jun 2024 14:09:15 +0300 Subject: [PATCH 3/3] fix(extension): [lw-10789] fix delegation tx summary --- .../stores/slices/activity-detail-slice.ts | 17 +++++++++---- .../stores/slices/wallet-activities-slice.ts | 24 +++++++++++++++---- .../components/Activity/AssetActivityItem.tsx | 22 +++++++++++++---- .../hasPendingDelegationTransaction.ts | 9 +++++-- 4 files changed, 57 insertions(+), 15 deletions(-) diff --git a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts index c42a1b3d80..0bf9aa0f39 100644 --- a/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/activity-detail-slice.ts @@ -16,7 +16,12 @@ import { inspectTxValues } from '@src/utils/tx-inspection'; import { firstValueFrom } from 'rxjs'; import { getAssetsInformation } from '@src/utils/get-assets-information'; import { MAX_POOLS_COUNT } from '@lace/staking'; -import { ActivityStatus, DelegationActivityType, TransactionActivityType } from '@lace/core'; +import { + ActivityStatus, + ConwayEraCertificatesTypes, + DelegationActivityType, + TransactionActivityType +} from '@lace/core'; import type { ActivityType } from '@lace/core'; import { formatDate, formatTime } from '@src/utils/format-date'; import { createHistoricalOwnInputResolver, HistoricalOwnInputResolverArgs } from '@src/utils/own-input-resolver'; @@ -68,10 +73,12 @@ const shouldIncludeFee = ( return !( type === DelegationActivityType.delegationRegistration || + type === ConwayEraCertificatesTypes.Registration || // Existence of any (new) delegationInfo means that this "de-registration" // activity is accompanied by a "delegation" activity, which carries the fees. // However, fees should be shown if de-registration activity is standalone. - (type === DelegationActivityType.delegationDeregistration && !!delegationInfo?.length) + ((type === DelegationActivityType.delegationDeregistration || type === ConwayEraCertificatesTypes.Unregistration) && + !!delegationInfo?.length) ); }; @@ -213,14 +220,16 @@ const buildGetActivityDetail = const deposit = // since one tx can be split into two (delegation, registration) actions, // ensure only the registration tx carries the deposit - implicitCoin.deposit && type === DelegationActivityType.delegationRegistration + implicitCoin.deposit && + (type === DelegationActivityType.delegationRegistration || type === ConwayEraCertificatesTypes.Registration) ? Wallet.util.lovelacesToAdaString(implicitCoin.deposit.toString()) : undefined; const depositReclaimValue = Wallet.util.calculateDepositReclaim(implicitCoin); const depositReclaim = // since one tx can be split into two (delegation, de-registration) actions, // ensure only the de-registration tx carries the reclaimed deposit - depositReclaimValue && type === DelegationActivityType.delegationDeregistration + depositReclaimValue && + (type === DelegationActivityType.delegationDeregistration || type === ConwayEraCertificatesTypes.Unregistration) ? Wallet.util.lovelacesToAdaString(depositReclaimValue.toString()) : undefined; const feeInAda = Wallet.util.lovelacesToAdaString(tx.body.fee.toString()); diff --git a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts index 2aeaa34f67..48fa1ba303 100644 --- a/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts +++ b/apps/browser-extension-wallet/src/stores/slices/wallet-activities-slice.ts @@ -21,6 +21,7 @@ import { ActivityStatus, AssetActivityItemProps, AssetActivityListProps, + ConwayEraCertificatesTypes, DelegationActivityType, TransactionActivityType } from '@lace/core'; @@ -69,21 +70,34 @@ type MappedActivityListProps = Omit & { }; export type FetchWalletActivitiesReturn = MappedActivityListProps[]; +type extendedDelegationActivityType = + | DelegationActivityType + | ConwayEraCertificatesTypes.Registration + | ConwayEraCertificatesTypes.Unregistration; + type DelegationActivityItemProps = Omit & { - type: DelegationActivityType; + type: extendedDelegationActivityType; }; const isDelegationActivity = (activity: ExtendedActivityProps): activity is DelegationActivityItemProps => - activity.type in DelegationActivityType; + activity.type in DelegationActivityType || + activity.type === ConwayEraCertificatesTypes.Registration || + activity.type === ConwayEraCertificatesTypes.Unregistration; const getDelegationAmount = (activity: DelegationActivityItemProps) => { const fee = new BigNumber(Number.parseFloat(activity.fee)); - if (activity.type === DelegationActivityType.delegationRegistration) { + if ( + activity.type === DelegationActivityType.delegationRegistration || + activity.type === ConwayEraCertificatesTypes.Registration + ) { return fee.plus(activity.deposit); } - if (activity.type === DelegationActivityType.delegationDeregistration) { + if ( + activity.type === DelegationActivityType.delegationDeregistration || + activity.type === ConwayEraCertificatesTypes.Unregistration + ) { return new BigNumber(activity.depositReclaim).minus(fee); } @@ -363,7 +377,7 @@ const mapWalletActivities = memoize( { cardanoFiatPrice, fiatCurrency, assetId }, { cardanoCoin, assetDetails } ) => - `${transactions.history.length}_${transactions.outgoing.inFlight.length}_${assetInfo.size}_${ + `${transactions.history.length}_${transactions.outgoing.inFlight.map(({ id }) => id).join('')}_${assetInfo.size}_${ rewardsHistory.all.length }_${cardanoFiatPrice}_${fiatCurrency.code}_${assetId || ''}_${cardanoCoin?.id}_${assetDetails?.id}_${ addresses[0]?.address diff --git a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx index af3c7cc360..d278ff572f 100644 --- a/packages/core/src/ui/components/Activity/AssetActivityItem.tsx +++ b/packages/core/src/ui/components/Activity/AssetActivityItem.tsx @@ -1,3 +1,4 @@ +/* eslint-disable complexity */ /* eslint-disable unicorn/consistent-function-scoping */ /* eslint-disable react/no-multi-comp */ import React, { useMemo, useRef, useEffect, useCallback } from 'react'; @@ -10,7 +11,7 @@ import { ReactComponent as PendingIcon } from '../../assets/icons/pending.compon import { ReactComponent as ErrorIcon } from '../../assets/icons/error.component.svg'; import pluralize from 'pluralize'; import { txIconSize } from '@src/ui/utils/icon-size'; -import { DelegationActivityType, TransactionActivityType } from '../ActivityDetail/types'; +import { DelegationActivityType, TransactionActivityType, ConwayEraCertificatesTypes } from '../ActivityDetail/types'; import type { ActivityType } from '../ActivityDetail/types'; import styles from './AssetActivityItem.module.scss'; import { ActivityTypeIcon } from '../ActivityDetail/ActivityTypeIcon'; @@ -93,6 +94,7 @@ const ActivityStatusIcon = ({ status, type }: ActivityStatusIconProps) => { const negativeBalanceStyling: Set> = new Set([ TransactionActivityType.outgoing, DelegationActivityType.delegationRegistration, + ConwayEraCertificatesTypes.Registration, TransactionActivityType.self, DelegationActivityType.delegation ]); @@ -115,7 +117,13 @@ export const AssetActivityItem = ({ const getText = useCallback( (items: number): { text: string; suffix: string } => { - if (type in DelegationActivityType || type === TransactionActivityType.self) return { text: amount, suffix: '' }; + if ( + type in DelegationActivityType || + type === ConwayEraCertificatesTypes.Registration || + type === ConwayEraCertificatesTypes.Unregistration || + type === TransactionActivityType.self + ) + return { text: amount, suffix: '' }; const assetsIdsText = assets ?.slice(0, items) @@ -161,7 +169,9 @@ export const AssetActivityItem = ({ const assetsText = useMemo(() => getText(assetsToShow), [getText, assetsToShow]); const assetAmountContent = - type in DelegationActivityType ? ( + type in DelegationActivityType || + type === ConwayEraCertificatesTypes.Registration || + type === ConwayEraCertificatesTypes.Unregistration ? (

{DELEGATION_ASSET_NUMBER} {t('core.assetActivityItem.entry.token')}

@@ -192,7 +202,11 @@ export const AssetActivityItem = ({
- {isPendingTx && type !== TransactionActivityType.self && !(type in DelegationActivityType) + {isPendingTx && + type !== TransactionActivityType.self && + !(type in DelegationActivityType) && + type !== ConwayEraCertificatesTypes.Registration && + type !== ConwayEraCertificatesTypes.Unregistration ? t('core.assetActivityItem.entry.name.sending') : t(`core.assetActivityItem.entry.name.${type}` as unknown as CoreTranslationKey)}
diff --git a/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts b/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts index 540e3cca6c..4a0d274691 100644 --- a/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts +++ b/packages/staking/src/features/overview/helpers/hasPendingDelegationTransaction.ts @@ -1,7 +1,12 @@ -import { ActivityStatus, AssetActivityListProps, DelegationActivityType } from '@lace/core'; +import { ActivityStatus, AssetActivityListProps, ConwayEraCertificatesTypes, DelegationActivityType } from '@lace/core'; import flatMap from 'lodash/flatMap'; export const hasPendingDelegationTransaction = (walletActivities: AssetActivityListProps[]) => flatMap(walletActivities, ({ items }) => items).some( - ({ type, status }) => type && type in DelegationActivityType && status === ActivityStatus.PENDING + ({ type, status }) => + type && + (type in DelegationActivityType || + type === ConwayEraCertificatesTypes.Registration || + type === ConwayEraCertificatesTypes.Unregistration) && + status === ActivityStatus.PENDING );