Skip to content

Commit

Permalink
fix: [lw-12362] view cbor in dapp confirmation (#1747)
Browse files Browse the repository at this point in the history
  • Loading branch information
vetalcore authored Feb 28, 2025
1 parent f5127ea commit d29ac45
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, useEffect, useMemo } from 'react';
import { logger, useObservable } from '@lace/common';
import {
DappTransaction,
TxDetailsCBOR,
TxDetailsCertificates,
TxDetailsProposalProcedures,
TxDetailsVotingProcedures
Expand Down Expand Up @@ -82,6 +83,7 @@ export const DappTransactionContainer = withAddressBookContext(
const { inputResolver } = getProviders();

const tx = useMemo(() => req?.transaction.toCore(), [req?.transaction]);
const txCBOR = useMemo(() => req?.transaction.toCbor(), [req?.transaction]);

useEffect(() => {
if (userAckNonRegisteredState || !tx?.body?.votingProcedures) return () => void 0;
Expand Down Expand Up @@ -188,6 +190,7 @@ export const DappTransactionContainer = withAddressBookContext(
ownAddresses={allWalletsAddresses.length > 0 ? allWalletsAddresses : ownAddresses}
addressToNameMap={addressToNameMap}
/>
<TxDetailsCBOR cbor={txCBOR} />
{tx?.body?.certificates?.length > 0 && (
<TxDetailsCertificates
cardanoCoin={cardanoCoin}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ describe('Testing ConfirmTransaction component', () => {
request: {
transaction: {
toCore: jest.fn().mockReturnValue({ id: 'test-tx-id' }),
toCbor: jest.fn().mockReturnValue('cbor'),
getId: jest.fn().mockReturnValue({ id: 'test-tx-id' })
}
},
Expand All @@ -171,6 +172,7 @@ describe('Testing ConfirmTransaction component', () => {
signContext: { sender: { tab: { id: 'tabid', favIconUrl: 'favIconUrl' } } },
transaction: {
toCore: jest.fn().mockReturnValue({ id: 'test-tx-id' }),
toCbor: jest.fn().mockReturnValue('cbor'),
getId: jest.fn().mockReturnValue({ id: 'test-tx-id' })
}
});
Expand Down Expand Up @@ -211,6 +213,7 @@ describe('Testing ConfirmTransaction component', () => {
request: {
transaction: {
getId: jest.fn().mockReturnValue({ id: 'test-tx-id' }),
toCbor: jest.fn().mockReturnValue('cbor'),
toCore: jest.fn().mockReturnValue(signTxData.tx)
}
},
Expand All @@ -222,6 +225,7 @@ describe('Testing ConfirmTransaction component', () => {
signContext: { sender: { tab: { id: 'tabid', favIconUrl: 'favIconUrl' } } },
transaction: {
getId: jest.fn().mockReturnValue({ id: 'test-tx-id' }),
toCbor: jest.fn().mockReturnValue('cbor'),
toCore: jest.fn().mockReturnValue(signTxData.tx)
}
});
Expand Down Expand Up @@ -280,6 +284,7 @@ describe('Testing ConfirmTransaction component', () => {
request: {
transaction: {
getId: jest.fn().mockReturnValue({ id: 'test-tx-id' }),
toCbor: jest.fn().mockReturnValue('cbor'),
toCore: jest.fn().mockReturnValue(signTxData.tx)
}
},
Expand All @@ -291,6 +296,7 @@ describe('Testing ConfirmTransaction component', () => {
signContext: { sender: { tab: { id: 'tabid', favIconUrl: 'favIconUrl' } } },
transaction: {
getId: jest.fn().mockReturnValue({ id: 'test-tx-id' }),
toCbor: jest.fn().mockReturnValue('cbor'),
toCore: jest.fn().mockReturnValue(signTxData.tx)
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const mockUseCurrencyStore = jest.fn().mockReturnValue({ fiatCurrency: { code: '
const mockUseFetchCoinPrice = jest.fn().mockReturnValue({ priceResult: { cardano: { price: 2 }, tokens: new Map() } });
const mockUseComputeTxCollateral = jest.fn().mockReturnValue(BigInt(1_000_000));
import * as React from 'react';
import { cleanup, render } from '@testing-library/react';
import { cleanup, render, fireEvent } from '@testing-library/react';
import { DappTransactionContainer } from '../DappTransactionContainer';
import '@testing-library/jest-dom';
import { BehaviorSubject } from 'rxjs';
Expand Down Expand Up @@ -287,6 +287,7 @@ describe('Testing DappTransactionContainer component', () => {

const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(buildMockTx({ certificates: [drepRegistrationcertificate] }))
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand Down Expand Up @@ -416,11 +417,41 @@ describe('Testing DappTransactionContainer component', () => {
);
});

it('should display raw transaction section', async () => {
let queryByTestId: any;
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(buildMockTx())
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;

mockUseViewsFlowContext.mockImplementation(() => ({
signTxRequest: { request, set: jest.fn() },
dappInfo
}));

await act(async () => {
({ queryByTestId } = render(<DappTransactionContainer />, {
wrapper: getWrapper()
}));
});

expect(queryByTestId('cbor-detail')).toBeInTheDocument();

await act(async () => {
fireEvent.click(queryByTestId('cbor-detail_toggle'));
});

expect(queryByTestId('cbor')).toHaveTextContent('cbor');
});

it('should display drep registration certificate', async () => {
let queryByTestId: any;
const drepRegistrationTx = buildMockTx({ certificates: [drepRegistrationcertificate] });
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(drepRegistrationTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -445,6 +476,7 @@ describe('Testing DappTransactionContainer component', () => {
const drepRetirementCertificateTx = buildMockTx({ certificates: [drepRetirementCertificate] });
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(drepRetirementCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -468,6 +500,7 @@ describe('Testing DappTransactionContainer component', () => {
const drepUpdateCertificateTx = buildMockTx({ certificates: [drepUpdateCertificate] });
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(drepUpdateCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -494,6 +527,7 @@ describe('Testing DappTransactionContainer component', () => {
});
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(stakeRegistrationDelegationCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -518,6 +552,7 @@ describe('Testing DappTransactionContainer component', () => {
const stakeVoteDelegationCertificateTx = buildMockTx({ certificates: [stakeVoteDelegationCertificate] });
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(stakeVoteDelegationCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -543,6 +578,7 @@ describe('Testing DappTransactionContainer component', () => {
});
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(stakeVoteRegistrationDelegationCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -566,6 +602,7 @@ describe('Testing DappTransactionContainer component', () => {
const voteDelegationCertificateTx = buildMockTx({ certificates: [voteDelegationCertificate] });
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(voteDelegationCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand All @@ -591,6 +628,7 @@ describe('Testing DappTransactionContainer component', () => {
});
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(voteRegistrationDelegationCertificateTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand Down Expand Up @@ -641,6 +679,7 @@ describe('Testing DappTransactionContainer component', () => {
});
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(votingTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand Down Expand Up @@ -682,6 +721,7 @@ describe('Testing DappTransactionContainer component', () => {
});
const request = {
transaction: {
toCbor: jest.fn().mockReturnValue('transaction-cbor'),
toCore: jest.fn().mockReturnValue(proposalProceduresTx)
} as any
} as TransactionWitnessRequest<Wallet.WalletMetadata, Wallet.AccountMetadata>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
flex-direction: column;
}

&.isOpen {
padding-bottom: 20px;
}

.expanderHeader {
display: flex;
justify-content: space-between;
Expand All @@ -24,6 +28,10 @@
color: var(--text-color-primary);
}
}

&.separatorLine {
margin-bottom: 20px;
}
}

.addressContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DownOutlined, InfoCircleOutlined } from '@ant-design/icons';
import { Button } from '@lace/common';
import { ReactComponent as BracketDown } from '../../assets/icons/bracket-down.component.svg';
import styles from './TransactionInputOutput.module.scss';
import { Text } from '@input-output-hk/lace-ui-toolkit';
import { Flex, Text } from '@input-output-hk/lace-ui-toolkit';

interface TxDetailsGroupProps {
testId: string;
Expand Down Expand Up @@ -37,16 +37,19 @@ export const TxDetailsGroup = ({
);

return (
<div data-testid={testId} className={cn(styles.transactionInOut, { [styles.separatorLine]: withSeparatorLine })}>
<div
data-testid={testId}
className={cn(styles.transactionInOut, { [styles.separatorLine]: withSeparatorLine, [styles.isOpen]: isVisible })}
>
<div className={styles.expanderHeader}>
<div className={styles.title}>
<Text.Body.Large weight="$bold">{title}</Text.Body.Large>
<Flex alignItems="center" className={styles.title}>
<Text.Body.Normal weight="$semibold">{title}</Text.Body.Normal>
{tooltipContent && (
<Tooltip title={tooltipContent}>
<InfoCircleOutlined className={styles.infoIcon} />
</Tooltip>
)}
</div>
</Flex>

<Button
variant="outlined"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@import '../../../../styles/theme.scss';
@import '../../../../../../../common/src/ui/styles/abstracts/typography';

.cbor {
word-break: break-all;
width: 100%;
display: -webkit-box;
-webkit-box-orient: vertical;
line-clamp: 3;
-webkit-line-clamp: 3;
overflow: hidden;
}

.copyButton {
color: var(--dark-mode-mid-grey, var(--light-mode-light-grey));
font-size: 26px;
cursor: pointer;
opacity: .5;
&:hover {
opacity: 1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React, { useCallback } from 'react';
import { TxDetailsGroup } from '../../TxDetailsGroup';
import { useTranslation } from 'react-i18next';
import { Flex, Text } from '@input-output-hk/lace-ui-toolkit';
import { ReactComponent as CopyIcon } from '../../../../assets/icons/copy-icon.svg';
import styles from './TxDetailsCBOR.module.scss';
import CopyToClipboard from 'react-copy-to-clipboard';
import { toast } from '@lace/common';

interface TxDetailsCBORProps {
cbor: string;
}

export const TxDetailsCBOR = ({ cbor }: TxDetailsCBORProps): React.ReactElement => {
const { t } = useTranslation();

const doToast = useCallback(() => {
toast.notify({
text: t('core.addressCard.handle.copy.notification'),
icon: CopyIcon
});
}, [t]);

return (
<TxDetailsGroup title={t('core.activityDetails.CBOR')} testId="cbor-detail" withSeparatorLine>
<Flex flexDirection="column" gap="$20">
<Flex w="$fill" justifyContent="flex-end">
<CopyToClipboard text={cbor}>
<CopyIcon className={styles.copyButton} data-testid="copy-address-btn" onClick={doToast} />
</CopyToClipboard>
</Flex>
<Text.Body.Normal data-testid="cbor" className={styles.cbor} weight="$medium">
{cbor}
</Text.Body.Normal>
</Flex>
</TxDetailsGroup>
);
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './TxDetailsCertificates/TxDetailsCertificates';
export * from './TxDetailsCBOR/TxDetailsCBOR';
export * from './TxDetailsProposalProcedures';
export * from './TxDetailsVotingProcedures';
1 change: 1 addition & 0 deletions packages/translation/src/lib/translations/core/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"core.activityDetails.AuthorizeCommitteeHotCertificate": "Authorize Committee",
"core.activityDetails.certificate": "Certificate",
"core.activityDetails.certificates": "Certificates",
"core.activityDetails.CBOR": "Raw Transaction (CBOR)",
"core.activityDetails.certificateTitles.anchorHash": "Anchor Hash",
"core.activityDetails.certificateTitles.anchorURL": "Anchor URL",
"core.activityDetails.certificateTitles.certificateType": "Type",
Expand Down

0 comments on commit d29ac45

Please sign in to comment.