Skip to content

Commit daa09e3

Browse files
committed
refactor: dedicated convert musd details
# Conflicts: # ui/hooks/activity/useCachedEvmTransaction.ts # ui/pages/details/hooks/useCachedEvmTransaction.ts # ui/pages/details/templates/perps-deposit-details.tsx # ui/pages/details/templates/swap-details.tsx # ui/pages/details/templates/template-loader.tsx # ui/pages/details/transaction-details.tsx # ui/pages/details/useCachedEvmTransaction.ts
1 parent 6183003 commit daa09e3

9 files changed

Lines changed: 141 additions & 27 deletions

File tree

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { useSelector } from 'react-redux';
2+
import { selectLocalTransactionsByHash } from '../../selectors/activity';
3+
4+
/**
5+
* Used for enriching activity items with local-only data.
6+
* This is where `metamaskPay` and other per-transaction metadata live.
7+
*
8+
* @param hash - The activity item hash
9+
*/
10+
export function useTransactionMeta(hash: string | undefined) {
11+
const localTransactionsByHash = useSelector(selectLocalTransactionsByHash);
12+
return localTransactionsByHash.get((hash ?? '').toLowerCase())
13+
?.initialTransaction;
14+
}

ui/pages/details/components/shared.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ import { CHAINID_DEFAULT_BLOCK_EXPLORER_URL_MAP } from '../../../../shared/const
1111
import { formatBlockExplorerTransactionUrl } from '../../../../shared/lib/multichain/networks';
1212
import { isValidTransactionHash } from '../../../../shared/lib/transactions.utils';
1313

14+
/**
15+
* Fiat currency for `metamaskPay` is always USD
16+
*/
17+
export const PAY_FIAT_CURRENCY = 'usd';
18+
1419
export function getExplorerTxUrl({
1520
chainId,
1621
txHash,
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import React, { useMemo } from 'react';
2+
import { toEvmCaipChainId } from '@metamask/multichain-network-controller';
3+
import type {
4+
ActivityListItem,
5+
TokenAmount,
6+
} from '../../../../shared/lib/activity/types';
7+
import { useI18nContext } from '../../../hooks/useI18nContext';
8+
import { useFormatters } from '../../../hooks/useFormatters';
9+
import { useTransactionMeta } from '../../../hooks/activity/useTransactionMeta';
10+
import { useTransactionQuery } from '../../../hooks/activity/useTransactionQuery';
11+
import { Footer, PAY_FIAT_CURRENCY, Row, Section } from '../components/shared';
12+
import { ConvertAgainButton } from '../components/convert-again-button';
13+
import { MetadataSection, TokensSection } from '../components/sections';
14+
// eslint-disable-next-line import-x/no-restricted-paths
15+
import { TransactionDetailsProvider } from '../../confirmations/components/activity/transaction-details-context';
16+
// eslint-disable-next-line import-x/no-restricted-paths
17+
import { TransactionDetailsSummary } from '../../confirmations/components/activity/transaction-details-summary';
18+
19+
function useSentToken(
20+
baseToken: TokenAmount | undefined,
21+
transactionMeta: ReturnType<typeof useTransactionMeta>,
22+
): TokenAmount | undefined {
23+
const { sourceHash, tokenAddress, chainId } =
24+
transactionMeta?.metamaskPay ?? {};
25+
const sourceChainId = chainId ? toEvmCaipChainId(chainId) : undefined;
26+
const userAddress = transactionMeta?.txParams?.from?.toLowerCase();
27+
28+
const { data: sourceTransaction } = useTransactionQuery({
29+
chainId: sourceChainId,
30+
txHash: sourceHash,
31+
enabled: Boolean(sourceHash && sourceChainId),
32+
});
33+
34+
return useMemo(() => {
35+
if (!baseToken) {
36+
return baseToken;
37+
}
38+
const transfers = sourceTransaction?.valueTransfers ?? [];
39+
const payToken = tokenAddress?.toLowerCase();
40+
const sentTransfer =
41+
transfers.find(
42+
(transfer) =>
43+
transfer.contractAddress.toLowerCase() === payToken &&
44+
transfer.from.toLowerCase() === userAddress,
45+
) ??
46+
transfers.find(
47+
(transfer) => transfer.contractAddress.toLowerCase() === payToken,
48+
);
49+
return sentTransfer?.amount
50+
? { ...baseToken, amount: sentTransfer.amount }
51+
: baseToken;
52+
}, [baseToken, sourceTransaction, tokenAddress, userAddress]);
53+
}
54+
55+
export function ConvertDetails({
56+
item,
57+
}: {
58+
item: Extract<ActivityListItem, { type: 'convert' }>;
59+
}) {
60+
const t = useI18nContext();
61+
const { formatCurrencyWithMinThreshold } = useFormatters();
62+
const transactionMeta = useTransactionMeta(item.hash);
63+
const { networkFeeFiat, totalFiat } = transactionMeta?.metamaskPay ?? {};
64+
const sentToken = useSentToken(item.data.sourceToken, transactionMeta);
65+
66+
const formatFiat = (value?: string) =>
67+
value
68+
? formatCurrencyWithMinThreshold(Number(value), PAY_FIAT_CURRENCY)
69+
: null;
70+
71+
if (!transactionMeta) {
72+
return null;
73+
}
74+
75+
return (
76+
<div className="flex grow flex-col">
77+
<div className="divide-y divide-border-muted">
78+
<TokensSection
79+
tokens={[
80+
{ label: t('youSent'), token: sentToken },
81+
{ label: t('youReceived'), token: item.data.destinationToken },
82+
]}
83+
/>
84+
85+
<MetadataSection item={item} />
86+
87+
<Section>
88+
<Row
89+
label={t('networkFee')}
90+
testId="transaction-base-fee"
91+
value={formatFiat(networkFeeFiat)}
92+
/>
93+
<Row
94+
label={t('total')}
95+
testId="transaction-breakdown-value-amount"
96+
value={formatFiat(totalFiat)}
97+
/>
98+
</Section>
99+
100+
<Section>
101+
<TransactionDetailsProvider transactionMeta={transactionMeta}>
102+
<TransactionDetailsSummary />
103+
</TransactionDetailsProvider>
104+
</Section>
105+
</div>
106+
107+
<Footer>
108+
<ConvertAgainButton sourceToken={item.data.sourceToken} />
109+
</Footer>
110+
</div>
111+
);
112+
}

ui/pages/details/templates/perps-deposit-details.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React from 'react';
2-
import { useSelector } from 'react-redux';
32
import { toEvmCaipChainId } from '@metamask/multichain-network-controller';
43
import {
54
Button,
@@ -12,7 +11,7 @@ import type { ActivityListItem } from '../../../../shared/lib/activity/types';
1211
import { CHAIN_IDS } from '../../../../shared/constants/network';
1312
import { ActivityAvatar } from '../../../components/app/activity-list-item-avatar';
1413
import { usePerpsDepositConfirmation } from '../../../components/app/perps/hooks/usePerpsDepositConfirmation';
15-
import { selectLocalTransactionsByHash } from '../../../selectors/activity';
14+
import { useTransactionMeta } from '../../../hooks/activity/useTransactionMeta';
1615
// eslint-disable-next-line import-x/no-restricted-paths
1716
import { TransactionDetailsProvider } from '../../confirmations/components/activity/transaction-details-context';
1817
// eslint-disable-next-line import-x/no-restricted-paths
@@ -36,11 +35,6 @@ type Props = {
3635
>;
3736
};
3837

39-
function useTransactionMeta(hash: string | undefined) {
40-
const localTransactions = useSelector(selectLocalTransactionsByHash);
41-
return localTransactions.get(hash || '')?.initialTransaction;
42-
}
43-
4438
export function PerpsDepositDetails({ item }: Readonly<Props>) {
4539
const t = useI18nContext();
4640
const { trigger: triggerDeposit } = usePerpsDepositConfirmation();

ui/pages/details/templates/perps-details.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import React, { useMemo } from 'react';
2-
import { useSelector } from 'react-redux';
32
import { toEvmCaipChainId } from '@metamask/multichain-network-controller';
43
import type {
54
ActivityListItem,
@@ -9,7 +8,7 @@ import { toAssetId } from '../../../../shared/lib/asset-utils';
98
import { AccountName } from '../../../components/app/transaction/account-name';
109
import { NetworkName } from '../../../components/app/transaction/network-name';
1110
import { TransactionStatus } from '../../../components/app/transaction/transaction-status';
12-
import { selectLocalTransactionsByHash } from '../../../selectors/activity';
11+
import { useTransactionMeta } from '../../../hooks/activity/useTransactionMeta';
1312
import {
1413
ARBITRUM_USDC,
1514
PERPS_CURRENCY,
@@ -27,11 +26,6 @@ const ARBITRUM_USDC_ASSET_ID = toAssetId(
2726
toEvmCaipChainId(ARBITRUM_USDC.chainId),
2827
);
2928

30-
function useTransactionMeta(hash: string | undefined) {
31-
const localTransactions = useSelector(selectLocalTransactionsByHash);
32-
return localTransactions.get(hash || '')?.initialTransaction;
33-
}
34-
3529
export function PerpsDetails({
3630
item,
3731
}: {

ui/pages/details/templates/swap-details.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { useI18nContext } from '../../../hooks/useI18nContext';
44
import { FeesRows, TotalAmountRow } from '../components/amounts-section';
55
import { Footer, Section } from '../components/shared';
66
import { BlockExplorerButton } from '../components/block-explorer-button';
7-
import { ConvertAgainButton } from '../components/convert-again-button';
87
import { SwapAgainButton } from '../components/swap-again-button';
98
import { MetadataSection, TokensSection } from '../components/sections';
109

@@ -17,7 +16,6 @@ export function SwapDetails({
1716
type:
1817
| 'swap'
1918
| 'bridge'
20-
| 'convert'
2119
| 'lendingDeposit'
2220
| 'lendingWithdrawal'
2321
| 'wrap'
@@ -44,15 +42,10 @@ export function SwapDetails({
4442
</div>
4543
<Footer>
4644
<BlockExplorerButton chainId={item.chainId} txHash={item.hash} />
47-
48-
{item.type === 'convert' ? (
49-
<ConvertAgainButton sourceToken={item.data.sourceToken} />
50-
) : (
51-
<SwapAgainButton
52-
sourceToken={item.data.sourceToken}
53-
destinationToken={item.data.destinationToken}
54-
/>
55-
)}
45+
<SwapAgainButton
46+
sourceToken={item.data.sourceToken}
47+
destinationToken={item.data.destinationToken}
48+
/>
5649
</Footer>
5750
</div>
5851
);

ui/pages/details/templates/template-loader.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import type { ActivityListItem } from '../../../../shared/lib/activity/types';
33
import { ApprovalDetails } from './approval-details';
44
import { BridgeDetails } from './bridge-details/bridge-details';
5+
import { ConvertDetails } from './convert-details';
56
import { DefaultDetails } from './default-details';
67
import { NftDetails } from './nft-details';
78
import { PerpsDepositDetails } from './perps-deposit-details';
@@ -29,8 +30,9 @@ export function TemplateLoader({ item }: Props) {
2930
return <SendDetails item={item} />;
3031
case 'bridge':
3132
return <BridgeDetails item={item} />;
32-
case 'swap':
3333
case 'convert':
34+
return <ConvertDetails item={item} />;
35+
case 'swap':
3436
case 'lendingDeposit':
3537
case 'lendingWithdrawal':
3638
case 'wrap':

ui/pages/details/transaction-details.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import {
99
} from '../../selectors/activity';
1010
import ErrorBoundary from '../../components/app/error-boundary/error-boundary';
1111
import { useCachedEvmTransaction } from '../../hooks/activity/useCachedEvmTransaction';
12+
import { useTransactionQuery } from '../../hooks/activity/useTransactionQuery';
1213
import { Header } from './components/header';
1314
import { TemplateLoader } from './templates/template-loader';
14-
import { useTransactionQuery } from './useTransactionQuery';
1515

1616
type Props = {
1717
chainId: string | undefined;

0 commit comments

Comments
 (0)