From 17aea367426c1f69e58ea3e0ed42fd4f3a355bf9 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Wed, 31 Jan 2024 01:10:45 +0200 Subject: [PATCH 01/10] feat(extension): update conway era tx details to the latest figma --- .../src/lib/translations/en.json | 2 +- .../src/utils/tx-inspection.ts | 16 + .../activity/helpers/common-tx-transformer.ts | 344 +++++++++--------- .../ActivityDetail/TransactionDetails.tsx | 102 ++++-- .../TransactionInputOutput.module.scss | 17 + .../ActivityDetail/TxDetailsList.tsx | 12 +- .../ActivityDetail/components/DetailRows.tsx | 29 +- .../src/ui/components/ActivityDetail/types.ts | 52 +-- packages/core/src/ui/lib/translations/en.json | 69 ++-- 9 files changed, 386 insertions(+), 257 deletions(-) diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index 32286c5987..cc41926bae 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -74,7 +74,7 @@ "sent": "Sent", "sending": "Sending", "header": "Summary of your activity", - "transactionHash": "Transaction Hash", + "transactionID": "Transaction ID", "status": "Status", "timestamp": "Timestamp", "inputs": "Inputs", diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index d7e8cbd45f..7b0d9794e2 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -231,6 +231,22 @@ export const getVoterType = (voterType: Wallet.Cardano.VoterType): VoterTypeEnum } }; +export enum CredentialTypeEnum { + KeyHash = 'KeyHash', + ScriptHash = 'ScriptHash' +} + +export const getCredentialType = (credentialType: Wallet.Cardano.CredentialType): CredentialTypeEnum => { + switch (credentialType) { + case Wallet.Cardano.CredentialType.KeyHash: + return CredentialTypeEnum.KeyHash; + case Wallet.Cardano.CredentialType.ScriptHash: + return CredentialTypeEnum.ScriptHash; + default: + return CredentialTypeEnum.ScriptHash; + } +}; + export enum VotesEnum { YES = 'yes', NO = 'no', 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 8674215833..f7b73a1d90 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 @@ -1,7 +1,8 @@ +/* eslint-disable complexity */ import BigNumber from 'bignumber.js'; import { Wallet } from '@lace/cardano'; import { CurrencyInfo, TxDirections } from '@types'; -import { inspectTxValues, inspectTxType, getVoterType, VoterTypeEnum, getVote } from '@src/utils/tx-inspection'; +import { inspectTxValues, inspectTxType, getVoterType, getCredentialType, getVote } 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'; @@ -198,36 +199,6 @@ export const txTransformer = async ({ ]; }; -type TransactionCertificate = { - __typename: Wallet.Cardano.CertificateType; - deposit?: BigInt; - dRep?: Wallet.Cardano.DelegateRepresentative; - coldCredential?: Wallet.Cardano.Credential; - hotCredential?: Wallet.Cardano.Credential; - dRepCredential?: Wallet.Cardano.Credential; - anchor?: Wallet.Cardano.Anchor; -}; - -type TransactionGovernanceProposal = { - deposit: BigInt; - rewardAccount: Wallet.Cardano.RewardAccount; - anchor: Wallet.Cardano.Anchor; - governanceAction: { - __typename: Wallet.Cardano.GovernanceActionType; - governanceActionId?: Wallet.Cardano.GovernanceActionId; - protocolParamUpdate?: Wallet.Cardano.ProtocolParametersUpdate; - protocolVersion?: Wallet.Cardano.ProtocolVersion; - withdrawals?: Set<{ - rewardAccount: Wallet.Cardano.RewardAccount; - coin: BigInt; - }>; - membersToBeRemoved?: Set; - membersToBeAdded?: Set; - newQuorumThreshold?: Wallet.Cardano.Fraction; - constitution?: Wallet.Cardano.Constitution; - }; -}; - const drepMapper = (drep: Wallet.Cardano.DelegateRepresentative) => { if (Wallet.Cardano.isDRepAlwaysAbstain(drep)) { return 'alwaysAbstain'; @@ -241,7 +212,7 @@ const drepMapper = (drep: Wallet.Cardano.DelegateRepresentative) => { export const certificateTransformer = ( cardanoCoin: Wallet.CoinId, - certificates?: TransactionCertificate[] + certificates?: Wallet.Cardano.Certificate[] ): TxDetails[] => // Currently only show enhanced certificate info for conway era certificates pending further discussion certificates @@ -255,14 +226,55 @@ export const certificateTransformer = ( { title: 'certificateType', details: [conwayEraCertificate.__typename] } ]; - if (conwayEraCertificate.anchor) { + if ('coldCredential' in conwayEraCertificate) { + transformedCertificate.push({ + title: 'coldCredential', + details: [conwayEraCertificate.coldCredential.hash.toString()] + }); + } + + if ('hotCredential' in conwayEraCertificate) { transformedCertificate.push({ - title: 'anchor', - details: [conwayEraCertificate.anchor.url, conwayEraCertificate.anchor.dataHash] + title: 'hotCredential', + details: [conwayEraCertificate.hotCredential.hash.toString()] + }); + } + + if ('stakeCredential' in conwayEraCertificate) { + transformedCertificate.push({ + title: 'stakeKey', + details: [conwayEraCertificate.stakeCredential.hash.toString()] }); } - if (conwayEraCertificate.dRep) { + if ('dRepCredential' in conwayEraCertificate) { + transformedCertificate.push({ + title: 'drepId', + details: [conwayEraCertificate.dRepCredential.hash.toString()] + }); + } + + if ('anchor' in conwayEraCertificate && conwayEraCertificate.anchor) { + transformedCertificate.push( + { + title: 'anchorUrl', + details: [conwayEraCertificate.anchor.url] + }, + { + title: 'anchorHash', + details: [conwayEraCertificate.anchor.dataHash.toString()] + } + ); + } + + if ('poolId' in conwayEraCertificate) { + transformedCertificate.push({ + title: 'poolId', + details: [conwayEraCertificate.poolId.toString()] + }); + } + + if ('dRep' in conwayEraCertificate) { transformedCertificate.push({ title: 'drep', details: [drepMapper(conwayEraCertificate.dRep)] @@ -309,25 +321,25 @@ export const votingProceduresTransformer = ( votingProcedures?.forEach((procedure) => procedure.votes.forEach((vote) => { - const voterType = getVoterType(procedure.voter.__typename); - const voterCredential = - voterType === VoterTypeEnum.DREP - ? drepIDasBech32FromHash(procedure.voter.credential.hash) - : procedure.voter.credential.hash; - const detail: TxDetails = [ + const detail: TxDetails = []; + if (vote.votingProcedure.anchor) { + detail.push( + { title: 'anchorHash', details: [vote.votingProcedure.anchor.dataHash.toString()] }, + { title: 'anchorURL', details: [vote.votingProcedure.anchor.url] } + ); + } + + detail.push( { title: 'voterType', - details: [voterType] + details: [getVoterType(procedure.voter.__typename)] }, { - title: 'voterCredential', - details: [voterCredential] + title: 'credentialType', + details: [getCredentialType(procedure.voter.credential.type)] }, - { title: 'vote', details: [getVote(vote.votingProcedure.vote)] }, - { ...(!!vote.votingProcedure.anchor && { title: 'anchor', details: [vote.votingProcedure.anchor.url] }) }, - { title: 'proposalTxHash', details: [vote.actionId.id] }, - { title: 'actionIndex', details: [vote.actionId.actionIndex.toString()] } - ]; + { title: 'voteTypes', details: [getVote(vote.votingProcedure.vote)] } + ); votingProcedureDetails.push(detail.filter((el: TxDetail) => !isEmpty(el))); }) @@ -338,135 +350,129 @@ export const votingProceduresTransformer = ( export const governanceProposalsTransformer = ( cardanoCoin: Wallet.CoinId, - proposalProcedures?: TransactionGovernanceProposal[] + proposalProcedures?: Wallet.Cardano.ProposalProcedure[] ): TxDetails[] => - proposalProcedures?.map( - ({ - governanceAction: { - __typename, - governanceActionId: { id: actionId, actionIndex }, - protocolParamUpdate, - protocolVersion: { major, minor, patch }, - withdrawals, - membersToBeRemoved, - membersToBeAdded, - newQuorumThreshold, - constitution + proposalProcedures?.map((procedure) => { + // Default details across all proposals + const transformedProposal: TxDetails = [ + { title: 'type', details: [procedure.governanceAction.__typename] }, + { + ...(procedure.governanceAction.__typename === GovernanceActionType.parameter_change_action && { + title: 'deposit', + details: [`${Wallet.util.lovelacesToAdaString(procedure.deposit.toString())} ${cardanoCoin.symbol}`] + }) }, - deposit, - anchor, - rewardAccount - }) => { - // Default details across all proposals - const transformedProposal: TxDetails = [ - { title: 'type', details: [__typename] }, - { - title: 'governanceActionId', - details: [Wallet.util.lovelacesToAdaString(deposit.toString()) + cardanoCoin.symbol] - }, + { title: 'anchorHash', details: [procedure.anchor.dataHash.toString()] }, + { title: 'anchorURL', details: [procedure.anchor.url] } + ]; + + if ('governanceActionId' in procedure.governanceAction) { + transformedProposal.push({ + title: 'governanceActionIndex', + details: [procedure.governanceAction.governanceActionId.actionIndex.toString()] + }); + } + + if ('withdrawals' in procedure.governanceAction) { + procedure.governanceAction.withdrawals.forEach(({ rewardAccount, coin }) => { + transformedProposal.push({ + header: 'withdrawal', + details: [ + { + title: 'withdrawalRewardAccount', + details: [rewardAccount] + }, + { + title: 'withdrawalAmount', + details: [`${Wallet.util.lovelacesToAdaString(coin.toString())} ${cardanoCoin.symbol}`] + } + ] + }); + }); + } + + if ('constitution' in procedure.governanceAction) { + transformedProposal.push( { - title: 'rewardAccount', - details: [rewardAccount] + title: 'constitutionAnchorURL', + details: [procedure.governanceAction.constitution.anchor.url] }, { - title: 'anchor', - details: [anchor.url, anchor.dataHash] + title: 'constitutionScriptHash', + details: [procedure.governanceAction.constitution.scriptHash.toString()] } - ]; + ); + } - // Proposal-specific properties - switch (__typename) { - case GovernanceActionType.parameter_change_action: { - transformedProposal.push({ - title: 'protocolParamUpdate', - details: Object.entries(protocolParamUpdate).map( - ([parameter, proposedValue]) => `${parameter}: ${proposedValue.toString()}` - ) - }); - break; - } - case GovernanceActionType.hard_fork_initiation_action: { - const compiledProtovolVersion = [major, minor, patch].filter((x) => !!x).join('.'); - if (actionId) { - transformedProposal.push({ - title: 'governanceActionId', - details: [actionId, actionIndex.toString()] - }); + if ('membersToBeAdded' in procedure.governanceAction) { + const membersToBeAdded: TxDetail[] = []; + procedure.governanceAction.membersToBeAdded.forEach(({ coldCredential, epoch }) => { + membersToBeAdded.push( + { + title: 'coldCredentialHash', + details: [coldCredential.hash] + }, + { + title: 'epoch', + details: [epoch.toString()] } + ); + }); - transformedProposal.push({ - title: 'protocolVersion', - details: [compiledProtovolVersion] - }); - break; - } - case GovernanceActionType.treasury_withdrawals_action: { - const treasuryWithdrawals: string[] = []; - - withdrawals.forEach(({ rewardAccount: withdrawalRewardAccount, coin }) => { - treasuryWithdrawals.push( - `${withdrawalRewardAccount}: ${Wallet.util.lovelacesToAdaString(coin.toString()) + cardanoCoin.symbol}` - ); - }); - - transformedProposal.push({ - title: 'withdrawals', - details: treasuryWithdrawals - }); - break; - } - case GovernanceActionType.no_confidence: { - if (actionId) { - transformedProposal.push({ - title: 'governanceActionId', - details: [actionId, actionIndex.toString()] - }); - } - break; - } - case GovernanceActionType.update_committee: { - const membersToBeRemovedDetails: string[] = []; - const membersToBeAddedDetails: string[] = []; - - membersToBeRemoved.forEach(({ hash }) => { - membersToBeRemovedDetails.push(hash); - }); - - membersToBeAdded.forEach(({ coldCredential }) => { - membersToBeAddedDetails.push(coldCredential.hash); - }); - - if (actionId) { - transformedProposal.push({ - title: 'governanceActionId', - details: [actionId, actionIndex.toString()] - }); - } + if (membersToBeAdded.length > 0) { + transformedProposal.push({ + header: 'membersToBeAdded', + details: membersToBeAdded + }); + } + } - transformedProposal.push( - { - title: 'membersToBeAdded', - details: membersToBeAddedDetails - }, - { - title: 'membersToBeRemoved', - details: membersToBeRemovedDetails - }, - { - title: 'newQuorumThreshold', - details: [`${newQuorumThreshold.numerator}\\${newQuorumThreshold.denominator}`] - } - ); - break; - } - case GovernanceActionType.new_constitution: { - transformedProposal.push({ - title: 'constitutionAnchor', - details: [constitution.anchor.url, constitution.anchor.dataHash] - }); - } + if ('membersToBeRemoved' in procedure.governanceAction) { + const membersToBeRemoved: TxDetail[] = []; + procedure.governanceAction.membersToBeRemoved.forEach(({ hash }) => { + membersToBeRemoved.push({ + title: 'hash', + details: [hash.toString()] + }); + }); + + if (membersToBeRemoved.length > 0) { + transformedProposal.push({ + header: 'membersToBeRemoved', + details: membersToBeRemoved + }); } + } - return transformedProposal; + if ('protocolVersion' in procedure.governanceAction) { + transformedProposal.push( + { + title: 'protocolVersionMajor', + details: [procedure.governanceAction.protocolVersion.major.toString()] + }, + { + title: 'protocolVersionMinor', + details: [procedure.governanceAction.protocolVersion.minor.toString()] + } + ); + if (procedure.governanceAction.protocolVersion.patch) { + transformedProposal.push({ + title: 'protocolVersionPatch', + details: [procedure.governanceAction.protocolVersion.patch.toString()] + }); + } } - ); + + // Proposal-specific properties + // case GovernanceActionType.parameter_change_action: { + // transformedProposal.push({ + // title: 'protocolParamUpdate', + // details: Object.entries(protocolParamUpdate).map( + // ([parameter, proposedValue]) => `${parameter}: ${proposedValue.toString()}` + // ) + // }); + // break; + // } + + return transformedProposal; + }); diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 0b4982d6c9..e7704984bb 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -16,7 +16,8 @@ import { TxDetailsVotingProceduresTitles, TxDetailsProposalProceduresTitles, TxDetailsCertificateTitles, - TxDetails + TxDetails, + TxDetail } from './types'; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -129,22 +130,44 @@ export const TransactionDetails = ({ // Translate certificate typenames const translatedCertificates = certificates?.map((certificate) => - certificate?.map((detail) => ({ - ...detail, - ...(detail.title === 'certificateType' && { - details: [t(`package.core.assetActivityItem.entry.certificates.typenames.${detail.details[0]}`)] - }) - })) + certificate?.map( + (detail) => + ({ + ...detail, + ...('title' in detail && + detail.title === 'certificateType' && { + details: [t(`package.core.assetActivityItem.entry.certificates.typenames.${detail.details[0]}`)] + }) + } as TxDetail) + ) ); // Translate governance proposal typenames const translatedProposalProcedures = proposalProcedures?.map((proposal) => - proposal?.map((p) => ({ - ...p, - ...(p.title === 'type' && { - details: [t(`package.core.activityDetails.governanceActions.${p.details[0]}`)] - }) - })) + proposal?.map( + (p) => + ({ + ...p, + ...('title' in p && + p.title === 'type' && { + details: [t(`package.core.activityDetails.governanceActions.${p.details[0]}`)] + }) + } as TxDetail) + ) + ); + + // Translate voting procedure typenames + const translatedVotingProcedures = votingProcedures?.map((proposal) => + proposal?.map( + (p) => + ({ + ...p, + ...('title' in p && + ['voterType', 'credentialType', 'voteTypes'].includes(p.title) && { + details: [t(`package.core.activityDetails.${p.title}.${p.details[0]}`)] + }) + } as TxDetail) + ) ); const renderDepositValueSection = ({ value, label }: { value: string; label: string }) => ( @@ -169,7 +192,7 @@ export const TransactionDetails = ({
-
{t('package.core.activityDetails.transactionHash')}
+
{t('package.core.activityDetails.transactionID')}
testId="voting-procedures" title={t('package.core.activityDetails.votingProcedures')} - lists={votingProcedures} + subTitle={t('package.core.activityDetails.votingProcedure')} + lists={translatedVotingProcedures} translations={{ voterType: t('package.core.activityDetails.votingProcedureTitles.voterType'), - voterCredential: t('package.core.activityDetails.votingProcedureTitles.voterCredential'), - vote: t('package.core.activityDetails.votingProcedureTitles.vote'), - anchor: t('package.core.activityDetails.votingProcedureTitles.anchor'), - proposalTxHash: t('package.core.activityDetails.votingProcedureTitles.proposalTxHash'), - actionIndex: t('package.core.activityDetails.votingProcedureTitles.actionIndex') + credentialType: t('package.core.activityDetails.votingProcedureTitles.credentialType'), + voteTypes: t('package.core.activityDetails.votingProcedureTitles.voteTypes'), + anchorHash: t('package.core.activityDetails.votingProcedureTitles.anchorHash'), + anchorURL: t('package.core.activityDetails.votingProcedureTitles.proposalTxHash') }} withSeparatorLine /> @@ -331,36 +354,51 @@ export const TransactionDetails = ({ testId="proposal-procedures" title={t('package.core.activityDetails.proposalProcedures')} + subTitle={t('package.core.activityDetails.proposalProcedure')} lists={translatedProposalProcedures} withSeparatorLine translations={{ type: t('package.core.activityDetails.proposalProcedureTitles.type'), - governanceActionId: t('package.core.activityDetails.proposalProcedureTitles.governanceActionId'), - rewardAccount: t('package.core.activityDetails.proposalProcedureTitles.rewardAccount'), - anchor: t('package.core.activityDetails.proposalProcedureTitles.anchor'), - protocolParamUpdate: t('package.core.activityDetails.proposalProcedureTitles.protocolParamUpdate'), - protocolVersion: t('package.core.activityDetails.proposalProcedureTitles.protocolVersion'), - withdrawals: t('package.core.activityDetails.proposalProcedureTitles.withdrawals'), - membersToBeRemoved: t('package.core.activityDetails.proposalProcedureTitles.membersToBeRemoved'), + deposit: t('package.core.activityDetails.proposalProcedureTitles.deposit'), + anchorHash: t('package.core.activityDetails.proposalProcedureTitles.anchorHash'), + anchorURL: t('package.core.activityDetails.proposalProcedureTitles.anchorURL'), + governanceActionIndex: t('package.core.activityDetails.proposalProcedureTitles.governanceActionIndex'), + withdrawal: t('package.core.activityDetails.proposalProcedureTitles.withdrawal'), + withdrawalRewardAccount: t( + 'package.core.activityDetails.proposalProcedureTitles.withdrawalRewardAccount' + ), + withdrawalAmount: t('package.core.activityDetails.proposalProcedureTitles.withdrawalAmount'), + constitutionAnchorURL: t('package.core.activityDetails.proposalProcedureTitles.constitutionAnchorURL'), + constitutionScriptHash: t('package.core.activityDetails.proposalProcedureTitles.constitutionScriptHash'), + coldCredentialHash: t('package.core.activityDetails.proposalProcedureTitles.coldCredentialHash'), + epoch: t('package.core.activityDetails.proposalProcedureTitles.epoch'), membersToBeAdded: t('package.core.activityDetails.proposalProcedureTitles.membersToBeAdded'), - newQuorumThreshold: t('package.core.activityDetails.proposalProcedureTitles.newQuorumThreshold'), - constitutionAnchor: t('package.core.activityDetails.proposalProcedureTitles.constitutionAnchor') + hash: t('package.core.activityDetails.proposalProcedureTitles.hash'), + membersToBeRemoved: t('package.core.activityDetails.proposalProcedureTitles.membersToBeRemoved'), + protocolVersionMajor: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionMajor'), + protocolVersionMinor: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionMinor'), + protocolVersionPatch: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionPatch') }} /> )} {certificates?.length > 0 && ( title={t('package.core.activityDetails.certificates')} + subTitle={t('package.core.activityDetails.certificate')} testId="certificates" lists={translatedCertificates} withSeparatorLine translations={{ + certificate: t('package.core.activityDetails.certificateTitles.certificate'), certificateType: t('package.core.activityDetails.certificateTitles.certificateType'), - drep: t('package.core.activityDetails.certificateTitles.drep'), - anchor: t('package.core.activityDetails.certificateTitles.anchor'), coldCredential: t('package.core.activityDetails.certificateTitles.coldCredential'), hotCredential: t('package.core.activityDetails.certificateTitles.hotCredential'), - drepCredential: t('package.core.activityDetails.certificateTitles.drepCredential'), + stakeKey: t('package.core.activityDetails.certificateTitles.stakeKey'), + drepId: t('package.core.activityDetails.certificateTitles.drepId'), + anchorUrl: t('package.core.activityDetails.certificateTitles.anchorUrl'), + anchorHash: t('package.core.activityDetails.certificateTitles.anchorHash'), + poolId: t('package.core.activityDetails.certificateTitles.poolId'), + drep: t('package.core.activityDetails.certificateTitles.drep'), depositPaid: t('package.core.activityDetails.certificateTitles.depositPaid') }} /> diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss index d0e2e8db43..5b117fbf1f 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss @@ -115,3 +115,20 @@ border-top: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid-grey)); padding-top: size_unit(3); } + + +.listHeader { + color: var(--text-color-primary, #ffffff); + display: flex; + justify-content: space-between; + margin-bottom: size_unit(4); + width: 100%; + + .listHeaderTitle { + display: flex; + flex: 0 0 50%; + align-self: baseline; + color: var(--text-color-primary, #ffffff); + @include text-body-bold; + } +} diff --git a/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx b/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx index 1db6110cb0..fb15fbda0b 100644 --- a/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx @@ -1,3 +1,4 @@ +/* eslint-disable react/no-multi-comp */ import { Tooltip } from 'antd'; import cn from 'classnames'; import React, { useState } from 'react'; @@ -22,20 +23,22 @@ const rotateClose: React.CSSProperties = { interface TxDetailListProps { testId: string; title: string; + subTitle: string; lists: TxDetails[]; translations: TranslationsFor; tooltipContent?: React.ReactNode; withSeparatorLine?: boolean; } -export const TxDetailList = function TxDetailList({ +export const TxDetailList = ({ testId, title, + subTitle, lists, tooltipContent, withSeparatorLine, translations -}: TxDetailListProps): React.ReactElement { +}: TxDetailListProps): React.ReactElement => { const [isVisible, setIsVisible] = useState(); const animation = isVisible ? rotateOpen : rotateClose; @@ -66,6 +69,11 @@ export const TxDetailList = function TxDetailList({
{lists.map((list, idx) => (
0 })}> + {lists.length > 1 && ( +
+
{`${subTitle} ${idx + 1}`}
+
+ )} translations={translations} testId={testId} list={list} />
))} diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx index d13b2f8446..ee86553c10 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx @@ -1,9 +1,9 @@ -/* eslint-disable react/no-multi-comp, sonarjs/no-identical-functions */ - import React from 'react'; +import cn from 'classnames'; import { DetailRow } from './DetailRow'; import { TxDetails } from '../types'; import { TranslationsFor } from '@src/ui/utils/types'; +import styles from '../TransactionInputOutput.module.scss'; type DetailRowsProps = { list: TxDetails; @@ -18,14 +18,23 @@ export const DetailRows = function DetailRows({ }: DetailRowsProps): React.ReactElement { return ( <> - {list.map(({ title, details }) => ( - - ))} + {list.map((item, index) => + 'title' in item ? ( + + ) : ( + <> +
+
{`${item.header} ${index + 1}`}
+
+ + + ) + )} ); }; diff --git a/packages/core/src/ui/components/ActivityDetail/types.ts b/packages/core/src/ui/components/ActivityDetail/types.ts index 96a1685b03..6797fc46ad 100644 --- a/packages/core/src/ui/components/ActivityDetail/types.ts +++ b/packages/core/src/ui/components/ActivityDetail/types.ts @@ -43,40 +43,50 @@ export enum TransactionActivityType { export type TxDetailsCertificateTitles = | 'certificateType' - | 'drep' - | 'anchor' | 'coldCredential' | 'hotCredential' - | 'drepCredential' - | 'depositPaid'; + | 'stakeKey' + | 'drepId' + | 'anchorUrl' + | 'anchorHash' + | 'poolId' + | 'drep' + | 'depositPaid' + | 'certificate'; export type TxDetailsProposalProceduresTitles = | 'type' - | 'governanceActionId' - | 'rewardAccount' - | 'anchor' - | 'protocolParamUpdate' - | 'protocolVersion' - | 'withdrawals' - | 'membersToBeRemoved' + | 'deposit' + | 'anchorHash' + | 'anchorURL' + | 'governanceActionIndex' + | 'withdrawal' + | 'withdrawalRewardAccount' + | 'withdrawalAmount' + | 'constitutionAnchorURL' + | 'constitutionScriptHash' + | 'coldCredentialHash' + | 'epoch' | 'membersToBeAdded' - | 'newQuorumThreshold' - | 'constitutionAnchor'; + | 'hash' + | 'membersToBeRemoved' + | 'protocolVersionMajor' + | 'protocolVersionMinor' + | 'protocolVersionPatch'; -export type TxDetailsVotingProceduresTitles = - | 'voterType' - | 'voterCredential' - | 'vote' - | 'anchor' - | 'proposalTxHash' - | 'actionIndex'; +export type TxDetailsVotingProceduresTitles = 'voterType' | 'credentialType' | 'voteTypes' | 'anchorHash' | 'anchorURL'; export type TxDetail = { title: T; details: string[]; }; -export type TxDetails = TxDetail[]; +export type TxDetaisList = { + header: T; + details: TxDetail[]; +}; + +export type TxDetails = (TxDetail | TxDetaisList)[]; export type GovernanceTransactionTypes = | ConwayEraCertificatesTypes diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/core/src/ui/lib/translations/en.json index 2f7cc1faa3..f7437e177b 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/core/src/ui/lib/translations/en.json @@ -101,7 +101,7 @@ "sent": "Sent", "sending": "Sending", "header": "Summary of your activity", - "transactionHash": "Transaction Hash", + "transactionID": "Transaction ID", "status": "Status", "timestamp": "Timestamp", "inputs": "Inputs", @@ -136,37 +136,48 @@ "vote": "Vote Signing", "submitProposal": "Governance Proposal", "certificates": "Certificates", + "certificate": "Certificate", "certificateTitles": { - "certificateType": "Certificate type", + "certificateType": "Type", + "stakeKey": "Stake Key", + "poolId": "Pool ID", "drep": "DRep", - "anchor": "Anchor", + "drepId": "Drep ID", + "depositPaid": "Deposit paid", + "anchorUrl": "Anchor URL", + "anchorHash": "Anchor Hash", "coldCredential": "Cold credential", - "hotCredential": "Hot credential", - "drepCredential": "DRep credential", - "depositPaid": "Deposit paid" + "hotCredential": "Hot credential" }, "votingProcedures": "Voting Procedures", "votingProcedureTitles": { - "voterType": "Voter type", - "voterCredential": "Voter Credential", "vote": "Vote", - "anchor": "Anchor", - "proposalTxHash": "Proposal Tx hash", - "actionIndex": "Governance action index" + "voterType": "Voter type", + "credentialType": "Credential Type", + "anchorUrl": "Anchor URL", + "anchorHash": "Anchor Hash", + "voteTypes": "Vote" }, "proposalProcedures": "Proposal Procedures", + "proposalProcedure": "Procedure", "proposalProcedureTitles": { - "type": "Procedure type", - "governanceActionId": "Governance action ID", - "rewardAccount": "Reward account", - "anchor": "Anchor", - "protocolParamUpdate": "Protocol parameter update(s)", - "protocolVersion": "Protocol version", - "withdrawals": "Withdrawals", - "membersToBeRemoved": "Members to remove", - "membersToBeAdded": "Members to add", - "newQuorumThreshold": "New quorum threshold", - "constitutionAnchor": "Constitution anchor" + "deposit": "Deposit", + "anchorHash": "Anchor Hash", + "anchorURL": "Anchor URL", + "governanceActionIndex": "Governance Action Index", + "withdrawal": "Withdrawal", + "withdrawalRewardAccount": "Withdrawal Reward Account", + "withdrawalAmount": "Withdrawal Amount", + "constitutionAnchorURL": "Constitution Anchor URL", + "constitutionScriptHash": "Constitution Script Hash", + "coldCredentialHash": "Cold Credential Hash", + "epoch": "Epoch", + "membersToBeAdded": "Members To Be Added", + "hash": "Hash", + "membersToBeRemoved": "Members To Be Removed", + "protocolVersionMajor": "Protocol Version Major", + "protocolVersionMinor": "Protocol Version Minor", + "protocolVersionPatch": "Protocol Version Patch" }, "governanceActions": { "info_action": "Info Action", @@ -176,6 +187,20 @@ "no_confidence": "No Confidence", "update_committee": "Update Committee", "new_constitution": "New Constitution" + }, + "voterType": { + "constitutionalCommittee": "Constitutional Committee", + "spo": "SPO", + "drep": "DRep" + }, + "voteTypes": { + "yes": "Yes", + "no": "No", + "abstain": "Abstain" + }, + "credentialType": { + "KeyHash": "Keyhash", + "ScriptHash": "Scripthash" } }, "authorizeDapp": { From 525810edb3655cc297f6ad787b86ea83649baed2 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Wed, 31 Jan 2024 08:58:23 +0200 Subject: [PATCH 02/10] feat(extension): handle multiline row items with subitems --- .../stores/slices/activity-detail-slice.ts | 2 +- .../activity/helpers/common-tx-transformer.ts | 35 +++++++------------ .../ActivityDetail/TransactionDetails.tsx | 3 +- .../components/DetailRow.module.scss | 12 +++++++ .../ActivityDetail/components/DetailRow.tsx | 16 ++++++--- .../components/DetailRowSubitems.tsx | 17 +++++++++ .../ActivityDetail/components/DetailRows.tsx | 1 + .../ActivityDetail/components/InfoItem.tsx | 19 ++++++++++ .../src/ui/components/ActivityDetail/types.ts | 4 ++- packages/core/src/ui/lib/translations/en.json | 5 +-- 10 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx create mode 100644 packages/core/src/ui/components/ActivityDetail/components/InfoItem.tsx 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 7600ed34ee..60b79f610a 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 @@ -223,7 +223,7 @@ const buildGetActivityDetail = // TODO: store the raw data here and transform it later so we always have the raw data when needed.(LW-9570) votingProcedures: votingProceduresTransformer(tx.body.votingProcedures), proposalProcedures: governanceProposalsTransformer(cardanoCoin, tx.body.proposalProcedures), - certificates: certificateTransformer(cardanoCoin, tx.body.certificates) + certificates: certificateTransformer(cardanoCoin, coinPrices, fiatCurrency, tx.body.certificates) }; if (type === DelegationActivityType.delegation && delegationInfo) { 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 f7b73a1d90..b8a4248fb1 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 @@ -20,6 +20,7 @@ import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; import isEmpty from 'lodash/isEmpty'; import { drepIDasBech32FromHash } from '@src/features/dapp/components/confirm-transaction/utils'; +import { PriceResult } from '@hooks'; const { util, GovernanceActionType } = Wallet.Cardano; @@ -212,6 +213,8 @@ const drepMapper = (drep: Wallet.Cardano.DelegateRepresentative) => { export const certificateTransformer = ( cardanoCoin: Wallet.CoinId, + coinPrices: PriceResult, + fiatCurrency: CurrencyInfo, certificates?: Wallet.Cardano.Certificate[] ): TxDetails[] => // Currently only show enhanced certificate info for conway era certificates pending further discussion @@ -281,32 +284,18 @@ export const certificateTransformer = ( }); } - if (conwayEraCertificate.coldCredential) { - transformedCertificate.push({ - title: 'coldCredential', - details: [conwayEraCertificate.coldCredential.hash] - }); - } - - if (conwayEraCertificate.hotCredential) { - transformedCertificate.push({ - title: 'hotCredential', - details: [conwayEraCertificate.hotCredential.hash] - }); - } - - if (conwayEraCertificate.dRepCredential) { - transformedCertificate.push({ - title: 'drepCredential', - details: [drepIDasBech32FromHash(conwayEraCertificate.dRepCredential.hash)] - }); - } - - if (conwayEraCertificate.deposit) { + if ('deposit' in conwayEraCertificate) { + const depositPaidInAda = Wallet.util.lovelacesToAdaString(conwayEraCertificate.deposit.toString()); transformedCertificate.push({ title: 'depositPaid', + info: 'depositPaidInfo', details: [ - `${Wallet.util.lovelacesToAdaString(conwayEraCertificate.deposit.toString())} ${cardanoCoin.symbol}` + [ + `${depositPaidInAda} ${cardanoCoin.symbol}`, + `${Wallet.util.convertAdaToFiat({ ada: depositPaidInAda, fiat: coinPrices?.cardano?.price })} ${ + fiatCurrency?.code + }` + ] ] }); } diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index e7704984bb..ddd6431501 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -399,7 +399,8 @@ export const TransactionDetails = ({ anchorHash: t('package.core.activityDetails.certificateTitles.anchorHash'), poolId: t('package.core.activityDetails.certificateTitles.poolId'), drep: t('package.core.activityDetails.certificateTitles.drep'), - depositPaid: t('package.core.activityDetails.certificateTitles.depositPaid') + depositPaid: t('package.core.activityDetails.certificateTitles.depositPaid'), + depositPaidInfo: t('package.core.activityDetails.certificateTitles.depositPaidInfo') }} /> )} diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRow.module.scss b/packages/core/src/ui/components/ActivityDetail/components/DetailRow.module.scss index 56029d936f..83b9354ec2 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRow.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRow.module.scss @@ -9,6 +9,8 @@ width: 100%; .title { + align-items: center; + gap: 8px; display: flex; flex: 0 0 50%; align-self: baseline; @@ -29,5 +31,15 @@ @media (max-width: $breakpoint-popup) { flex-direction: column; } + + .subitems { + display: flex; + flex-direction: column; + width: 100%; + align-items: flex-end; + .subitem { + color: var(--text-color-secondary, #878e9e); + } + } } } diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx index e260057327..61f2e3f9b9 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx @@ -1,18 +1,26 @@ import React from 'react'; import styles from './DetailRow.module.scss'; +import { DetailRowSubitems } from './DetailRowSubitems'; +import { InfoItem } from './InfoItem'; type DetailsRowProps = { title: string; + info?: string; dataTestId?: string; - details: string[]; + details: (string | [string, string])[]; }; -export const DetailRow = ({ title, details, dataTestId }: DetailsRowProps): React.ReactElement => ( +export const DetailRow = ({ title, info, details, dataTestId }: DetailsRowProps): React.ReactElement => (
-
{title}
+
+ {title} + {info && } +
{details.map((detail, idx) => ( - {detail} + + {typeof detail === 'string' ? detail : } + ))}
diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx new file mode 100644 index 0000000000..d6834706a7 --- /dev/null +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx @@ -0,0 +1,17 @@ +/* eslint-disable no-magic-numbers */ +import React from 'react'; +import styles from './DetailRow.module.scss'; + +export interface DetailRowSubitems { + item: string; + subitem: string; + dataTestId?: string; +} +export const DetailRowSubitems = ({ item, subitem, dataTestId }: DetailRowSubitems): React.ReactElement => ( +
+ {item} + + {subitem} + +
+); diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx index ee86553c10..c8e348a8c3 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx @@ -24,6 +24,7 @@ export const DetailRows = function DetailRows({ key={`${testId}-${item.title}`} dataTestId={`${testId}-${item.title}`} title={translations[item.title]} + info={translations[item.info]} details={item.details} /> ) : ( diff --git a/packages/core/src/ui/components/ActivityDetail/components/InfoItem.tsx b/packages/core/src/ui/components/ActivityDetail/components/InfoItem.tsx new file mode 100644 index 0000000000..143510eab0 --- /dev/null +++ b/packages/core/src/ui/components/ActivityDetail/components/InfoItem.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { InfoCircleOutlined } from '@ant-design/icons'; +import { Tooltip } from 'antd'; + +import { ReactComponent as Info } from '../../../assets/icons/info-icon.component.svg'; + +export interface InfoItemProps { + title: string; + dataTestId?: string; +} +export const InfoItem = ({ title, dataTestId = '' }: InfoItemProps): React.ReactElement => ( + + {Info ? ( + + ) : ( + + )} + +); diff --git a/packages/core/src/ui/components/ActivityDetail/types.ts b/packages/core/src/ui/components/ActivityDetail/types.ts index 6797fc46ad..55dac2dc50 100644 --- a/packages/core/src/ui/components/ActivityDetail/types.ts +++ b/packages/core/src/ui/components/ActivityDetail/types.ts @@ -52,6 +52,7 @@ export type TxDetailsCertificateTitles = | 'poolId' | 'drep' | 'depositPaid' + | 'depositPaidInfo' | 'certificate'; export type TxDetailsProposalProceduresTitles = @@ -78,7 +79,8 @@ export type TxDetailsVotingProceduresTitles = 'voterType' | 'credentialType' | ' export type TxDetail = { title: T; - details: string[]; + info?: T; + details: (string | [string, string])[]; }; export type TxDetaisList = { diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/core/src/ui/lib/translations/en.json index f7437e177b..2905d308e8 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/core/src/ui/lib/translations/en.json @@ -144,6 +144,7 @@ "drep": "DRep", "drepId": "Drep ID", "depositPaid": "Deposit paid", + "depositPaidInfo": "Deposit paid", "anchorUrl": "Anchor URL", "anchorHash": "Anchor Hash", "coldCredential": "Cold credential", @@ -158,8 +159,8 @@ "anchorHash": "Anchor Hash", "voteTypes": "Vote" }, - "proposalProcedures": "Proposal Procedures", - "proposalProcedure": "Procedure", + "proposalProcedures": "Governance Actions", + "proposalProcedure": "Action", "proposalProcedureTitles": { "deposit": "Deposit", "anchorHash": "Anchor Hash", From 6c21d1781bff06217556d25eb82dce4f18deb23d Mon Sep 17 00:00:00 2001 From: vetalcore Date: Wed, 31 Jan 2024 13:15:22 +0200 Subject: [PATCH 03/10] feat(extension): handle parameter_change_action --- .../src/lib/translations/en.json | 2 + .../activity/helpers/common-tx-transformer.ts | 263 +++++++++++++++++- .../ActivityDetail/TransactionDetails.tsx | 75 ++++- .../TransactionInputOutput.module.scss | 1 - .../ActivityDetail/TxDetailsList.tsx | 7 +- .../ActivityDetail/components/DetailRows.tsx | 5 +- .../src/ui/components/ActivityDetail/types.ts | 47 +++- packages/core/src/ui/lib/translations/en.json | 1 + 8 files changed, 380 insertions(+), 21 deletions(-) diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index cc41926bae..6b0758d0b4 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -1319,6 +1319,8 @@ "eMax": "EMax", "nOpt": "NOpt", "costModels": "Cost Models", + "PlutusV1": "PlutusV1", + "PlutusV2": "PlutusV2", "collateralPercentage": "Coll Percentage", "tooltip": { "a0": "Pool pledge influence", 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 b8a4248fb1..220b332cdd 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 @@ -1,3 +1,4 @@ +/* eslint-disable sonarjs/cognitive-complexity */ /* eslint-disable complexity */ import BigNumber from 'bignumber.js'; import { Wallet } from '@lace/cardano'; @@ -19,10 +20,10 @@ import { import capitalize from 'lodash/capitalize'; import dayjs from 'dayjs'; import isEmpty from 'lodash/isEmpty'; -import { drepIDasBech32FromHash } from '@src/features/dapp/components/confirm-transaction/utils'; import { PriceResult } from '@hooks'; +import { formatPercentages } from '@lace/common'; -const { util, GovernanceActionType } = Wallet.Cardano; +const { util, GovernanceActionType, PlutusLanguageVersion } = Wallet.Cardano; export interface TxTransformerInput { tx: Wallet.TxInFlight | Wallet.Cardano.HydratedTx; @@ -217,7 +218,6 @@ export const certificateTransformer = ( fiatCurrency: CurrencyInfo, certificates?: Wallet.Cardano.Certificate[] ): TxDetails[] => - // Currently only show enhanced certificate info for conway era certificates pending further discussion certificates ?.filter((certificate) => Object.values(ConwayEraCertificatesTypes).includes( @@ -342,7 +342,6 @@ export const governanceProposalsTransformer = ( proposalProcedures?: Wallet.Cardano.ProposalProcedure[] ): TxDetails[] => proposalProcedures?.map((procedure) => { - // Default details across all proposals const transformedProposal: TxDetails = [ { title: 'type', details: [procedure.governanceAction.__typename] }, { @@ -452,16 +451,252 @@ export const governanceProposalsTransformer = ( } } - // Proposal-specific properties - // case GovernanceActionType.parameter_change_action: { - // transformedProposal.push({ - // title: 'protocolParamUpdate', - // details: Object.entries(protocolParamUpdate).map( - // ([parameter, proposedValue]) => `${parameter}: ${proposedValue.toString()}` - // ) - // }); - // break; - // } + if (procedure.governanceAction.__typename === GovernanceActionType.parameter_change_action) { + const { + protocolParamUpdate: { + maxExecutionUnitsPerTransaction, + maxExecutionUnitsPerBlock, + maxBlockBodySize, + maxTxSize, + maxBlockHeaderSize, + maxValueSize, + maxCollateralInputs, + minFeeCoefficient, + minFeeConstant, + stakeKeyDeposit, + poolDeposit, + monetaryExpansion, + treasuryExpansion, + minPoolCost, + coinsPerUtxoByte, + poolInfluence, + poolRetirementEpochBound, + desiredNumberOfPools, + collateralPercentage, + costModels, + governanceActionValidityPeriod, + governanceActionDeposit, + dRepDeposit, + dRepInactivityPeriod, + minCommitteeSize, + committeeTermLimit, + dRepVotingThresholds + } + } = procedure.governanceAction; + transformedProposal.push( + { + header: 'maxTxExUnits', + details: [ + { + title: 'memory', + details: [maxExecutionUnitsPerTransaction.memory.toString()] + }, + { + title: 'step', + details: [maxExecutionUnitsPerTransaction.steps.toString()] + } + ] + }, + { + header: 'maxBlockExUnits', + details: [ + { + title: 'memory', + details: [maxExecutionUnitsPerBlock.memory.toString()] + }, + { + title: 'step', + details: [maxExecutionUnitsPerBlock.steps.toString()] + } + ] + }, + { + header: 'networkGroup', + details: [ + { + title: 'maxBBSize', + details: [maxBlockBodySize?.toString()] + }, + { + title: 'maxTxSize', + details: [maxTxSize?.toString()] + }, + { + title: 'maxBHSize', + details: [maxBlockHeaderSize?.toString()] + }, + { + title: 'maxValSize', + details: [maxValueSize?.toString()] + }, + { + title: 'maxCollateralInputs', + details: [maxCollateralInputs?.toString()] + } + ] + }, + { + header: 'economicGroup', + details: [ + { + title: 'minFeeA', + details: [minFeeCoefficient?.toString()] + }, + { + title: 'minFeeB', + details: [minFeeConstant?.toString()] + }, + { + title: 'keyDeposit', + details: [stakeKeyDeposit?.toString()] + }, + { + title: 'poolDeposit', + details: [poolDeposit?.toString()] + }, + { + title: 'rho', + details: [monetaryExpansion?.toString()] + }, + { + title: 'tau', + details: [treasuryExpansion?.toString()] + }, + { + title: 'minPoolCost', + details: [minPoolCost?.toString()] + }, + { + title: 'coinsPerUTxOByte', + details: [coinsPerUtxoByte?.toString()] + } + ] + }, + { + header: 'technicalGroup', + details: [ + { + title: 'a0', + details: [poolInfluence?.toString()] + }, + { + title: 'eMax', + details: [poolRetirementEpochBound?.toString()] + }, + { + title: 'nOpt', + details: [desiredNumberOfPools?.toString()] + }, + { + title: 'collateralPercentage', + details: [collateralPercentage?.toString()] + } + ] + }, + { + header: 'costModels', + details: [ + { + title: 'PlutusV1', + details: costModels.get(PlutusLanguageVersion.V1).map((model) => model.toString()) + }, + { + title: 'PlutusV2', + details: costModels.get(PlutusLanguageVersion.V2).map((model) => model.toString()) + } + ] + }, + { + header: 'governanceGroup', + details: [ + { + title: 'govActionLifetime', + details: [governanceActionValidityPeriod?.toString()] + }, + { + title: 'govActionDeposit', + details: [governanceActionDeposit?.toString()] + }, + { + title: 'drepDeposit', + details: [dRepDeposit?.toString()] + }, + { + title: 'drepActivity', + details: [dRepInactivityPeriod?.toString()] + }, + { + title: 'ccMinSize', + details: [minCommitteeSize?.toString()] + }, + { + title: 'ccMaxTermLength', + details: [committeeTermLimit?.toString()] + } + ] + } + ); + + if (dRepVotingThresholds) { + const { + motionNoConfidence, + committeeNormal, + commiteeNoConfidence, + hardForkInitiation, + ppNetworkGroup, + ppEconomicGroup, + ppTechnicalGroup, + ppGovernanceGroup, + treasuryWithdrawal, + updateConstitution + } = dRepVotingThresholds; + transformedProposal.push({ + header: 'dRepVotingThresholds', + details: [ + { + title: 'motionNoConfidence', + details: [formatPercentages(motionNoConfidence.numerator / motionNoConfidence.denominator)] + }, + { + title: 'committeeNormal', + details: [formatPercentages(committeeNormal.numerator / committeeNormal.denominator)] + }, + { + title: 'committeeNoConfidence', + details: [formatPercentages(commiteeNoConfidence.numerator / commiteeNoConfidence.denominator)] + }, + { + title: 'updateConstitution', + details: [formatPercentages(updateConstitution.numerator / updateConstitution.denominator)] + }, + { + title: 'hardForkInitiation', + details: [formatPercentages(hardForkInitiation.numerator / hardForkInitiation.denominator)] + }, + { + title: 'ppNetworkGroup', + details: [formatPercentages(ppNetworkGroup.numerator / ppNetworkGroup.denominator)] + }, + { + title: 'ppEconomicGroup', + details: [formatPercentages(ppEconomicGroup.numerator / ppEconomicGroup.denominator)] + }, + { + title: 'ppTechnicalGroup', + details: [formatPercentages(ppTechnicalGroup.numerator / ppTechnicalGroup.denominator)] + }, + { + title: 'ppGovernanceGroup', + details: [formatPercentages(ppGovernanceGroup.numerator / ppGovernanceGroup.denominator)] + }, + { + title: 'treasuryWithdrawal', + details: [formatPercentages(treasuryWithdrawal.numerator / treasuryWithdrawal.denominator)] + } + ] + }); + } + } return transformedProposal; }); diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index ddd6431501..5e3eeaa9cb 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -377,7 +377,80 @@ export const TransactionDetails = ({ membersToBeRemoved: t('package.core.activityDetails.proposalProcedureTitles.membersToBeRemoved'), protocolVersionMajor: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionMajor'), protocolVersionMinor: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionMinor'), - protocolVersionPatch: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionPatch') + protocolVersionPatch: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionPatch'), + maxTxExUnits: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxExUnits'), + maxBlockExUnits: t( + 'core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBlockExUnits' + ), + networkGroup: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.title'), + economicGroup: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.title'), + technicalGroup: t('core.ProposalProcedure.governanceAction.technicalGroup.title'), + costModels: t('core.ProposalProcedure.governanceAction.technicalGroup.costModels'), + PlutusV1: t('core.ProposalProcedure.governanceAction.technicalGroup.PlutusV1'), + PlutusV2: t('core.ProposalProcedure.governanceAction.technicalGroup.PlutusV2'), + governanceGroup: t('core.ProposalProcedure.governanceAction.governanceGroup.title'), + dRepVotingThresholds: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.title' + ), + memory: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.memory'), + step: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.step'), + maxBBSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBBSize'), + maxTxSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxSize'), + maxBHSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBHSize'), + maxValSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxValSize'), + maxCollateralInputs: t( + 'core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxCollateralInputs' + ), + minFeeA: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeA'), + minFeeB: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeB'), + keyDeposit: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.keyDeposit'), + poolDeposit: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.poolDeposit'), + rho: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.rho'), + tau: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tau'), + minPoolCost: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minPoolCost'), + coinsPerUTxOByte: t( + 'core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.coinsPerUTxOByte' + ), + a0: t('core.ProposalProcedure.governanceAction.technicalGroup.a0'), + eMax: t('core.ProposalProcedure.governanceAction.technicalGroup.eMax'), + nOpt: t('core.ProposalProcedure.governanceAction.technicalGroup.nOpt'), + collateralPercentage: t('core.ProposalProcedure.governanceAction.technicalGroup.collateralPercentage'), + govActionLifetime: t('core.ProposalProcedure.governanceAction.governanceGroup.govActionLifetime'), + govActionDeposit: t('core.ProposalProcedure.governanceAction.governanceGroup.govActionDeposit'), + drepDeposit: t('core.ProposalProcedure.governanceAction.governanceGroup.drepDeposit'), + drepActivity: t('core.ProposalProcedure.governanceAction.governanceGroup.drepActivity'), + ccMinSize: t('core.ProposalProcedure.governanceAction.governanceGroup.ccMinSize'), + ccMaxTermLength: t('core.ProposalProcedure.governanceAction.governanceGroup.ccMaxTermLength'), + motionNoConfidence: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.motionNoConfidence' + ), + committeeNormal: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.committeeNormal' + ), + committeeNoConfidence: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.committeeNoConfidence' + ), + updateConstitution: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.updateConstitution' + ), + hardForkInitiation: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.hardForkInitiation' + ), + ppNetworkGroup: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppNetworkGroup' + ), + ppEconomicGroup: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppEconomicGroup' + ), + ppTechnicalGroup: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppTechnicalGroup' + ), + ppGovernanceGroup: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppGovernanceGroup' + ), + treasuryWithdrawal: t( + 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.treasuryWithdrawal' + ) }} /> )} diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss index 5b117fbf1f..31599bcdda 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss @@ -116,7 +116,6 @@ padding-top: size_unit(3); } - .listHeader { color: var(--text-color-primary, #ffffff); display: flex; diff --git a/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx b/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx index fb15fbda0b..c9e9cacbb1 100644 --- a/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TxDetailsList.tsx @@ -68,14 +68,15 @@ export const TxDetailList = ({ {isVisible && (
{lists.map((list, idx) => ( -
0 })}> + +
0 })} /> {lists.length > 1 && ( -
+
{`${subTitle} ${idx + 1}`}
)} translations={translations} testId={testId} list={list} /> -
+ ))}
)} diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx index c8e348a8c3..a5d06d4e75 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx @@ -29,7 +29,10 @@ export const DetailRows = function DetailRows({ /> ) : ( <> -
+
0 })} + >
{`${item.header} ${index + 1}`}
diff --git a/packages/core/src/ui/components/ActivityDetail/types.ts b/packages/core/src/ui/components/ActivityDetail/types.ts index 55dac2dc50..1f1c34800b 100644 --- a/packages/core/src/ui/components/ActivityDetail/types.ts +++ b/packages/core/src/ui/components/ActivityDetail/types.ts @@ -73,7 +73,52 @@ export type TxDetailsProposalProceduresTitles = | 'membersToBeRemoved' | 'protocolVersionMajor' | 'protocolVersionMinor' - | 'protocolVersionPatch'; + | 'protocolVersionPatch' + | 'maxTxExUnits' + | 'maxBlockExUnits' + | 'networkGroup' + | 'economicGroup' + | 'technicalGroup' + | 'costModels' + | 'governanceGroup' + | 'dRepVotingThresholds' + | 'memory' + | 'step' + | 'maxBBSize' + | 'maxTxSize' + | 'maxBHSize' + | 'maxValSize' + | 'maxCollateralInputs' + | 'minFeeA' + | 'minFeeB' + | 'keyDeposit' + | 'poolDeposit' + | 'rho' + | 'tau' + | 'minPoolCost' + | 'coinsPerUTxOByte' + | 'a0' + | 'eMax' + | 'nOpt' + | 'collateralPercentage' + | 'PlutusV1' + | 'PlutusV2' + | 'govActionLifetime' + | 'govActionDeposit' + | 'drepDeposit' + | 'drepActivity' + | 'ccMinSize' + | 'ccMaxTermLength' + | 'motionNoConfidence' + | 'committeeNormal' + | 'committeeNoConfidence' + | 'updateConstitution' + | 'hardForkInitiation' + | 'ppNetworkGroup' + | 'ppEconomicGroup' + | 'ppTechnicalGroup' + | 'ppGovernanceGroup' + | 'treasuryWithdrawal'; export type TxDetailsVotingProceduresTitles = 'voterType' | 'credentialType' | 'voteTypes' | 'anchorHash' | 'anchorURL'; diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/core/src/ui/lib/translations/en.json index 2905d308e8..6b968e8619 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/core/src/ui/lib/translations/en.json @@ -151,6 +151,7 @@ "hotCredential": "Hot credential" }, "votingProcedures": "Voting Procedures", + "votingProcedure": "Voting Procedure", "votingProcedureTitles": { "vote": "Vote", "voterType": "Voter type", From 8ff93c850dcdf05098e6d4e5ebe787cdf9444417 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Thu, 1 Feb 2024 17:38:11 +0200 Subject: [PATCH 04/10] fix(extension): resolve pr comments --- .../src/utils/tx-inspection.ts | 10 +++++----- .../features/activity/helpers/common-tx-transformer.ts | 10 +++++----- .../ActivityDetail/components/DetailRowSubitems.tsx | 1 - 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/apps/browser-extension-wallet/src/utils/tx-inspection.ts b/apps/browser-extension-wallet/src/utils/tx-inspection.ts index 7b0d9794e2..a6f18f2edf 100644 --- a/apps/browser-extension-wallet/src/utils/tx-inspection.ts +++ b/apps/browser-extension-wallet/src/utils/tx-inspection.ts @@ -231,19 +231,19 @@ export const getVoterType = (voterType: Wallet.Cardano.VoterType): VoterTypeEnum } }; -export enum CredentialTypeEnum { +export enum CredentialType { KeyHash = 'KeyHash', ScriptHash = 'ScriptHash' } -export const getCredentialType = (credentialType: Wallet.Cardano.CredentialType): CredentialTypeEnum => { +export const getCredentialType = (credentialType: Wallet.Cardano.CredentialType): CredentialType => { switch (credentialType) { case Wallet.Cardano.CredentialType.KeyHash: - return CredentialTypeEnum.KeyHash; + return CredentialType.KeyHash; case Wallet.Cardano.CredentialType.ScriptHash: - return CredentialTypeEnum.ScriptHash; + return CredentialType.ScriptHash; default: - return CredentialTypeEnum.ScriptHash; + return CredentialType.ScriptHash; } }; 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 220b332cdd..731044d38d 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 @@ -285,16 +285,16 @@ export const certificateTransformer = ( } if ('deposit' in conwayEraCertificate) { - const depositPaidInAda = Wallet.util.lovelacesToAdaString(conwayEraCertificate.deposit.toString()); transformedCertificate.push({ title: 'depositPaid', info: 'depositPaidInfo', details: [ [ - `${depositPaidInAda} ${cardanoCoin.symbol}`, - `${Wallet.util.convertAdaToFiat({ ada: depositPaidInAda, fiat: coinPrices?.cardano?.price })} ${ - fiatCurrency?.code - }` + Wallet.util.getFormattedAmount({ amount: conwayEraCertificate.deposit.toString(), cardanoCoin }), + `${Wallet.util.convertLovelaceToFiat({ + lovelaces: conwayEraCertificate.deposit.toString(), + fiat: coinPrices?.cardano?.price + })} ${fiatCurrency?.code}` ] ] }); diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx index d6834706a7..3adf723831 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRowSubitems.tsx @@ -1,4 +1,3 @@ -/* eslint-disable no-magic-numbers */ import React from 'react'; import styles from './DetailRow.module.scss'; From 43b1959a6a519f3af2b041e297a5fdada9d9826b Mon Sep 17 00:00:00 2001 From: vetalcore Date: Thu, 22 Feb 2024 14:07:09 +0200 Subject: [PATCH 05/10] fix(extension): update to the latest figma/AC --- .../src/lib/translations/en.json | 14 +- .../stores/slices/activity-detail-slice.ts | 7 +- .../activity/helpers/common-tx-transformer.ts | 139 ++- .../ActivityDetailHeader.module.scss | 2 +- .../TransactionDetails.module.scss | 8 +- .../TransactionDetails.stories.tsx | 892 ++++++++++++++++++ .../ActivityDetail/TransactionDetails.tsx | 179 ++-- .../ActivityDetail/TransactionFee.module.scss | 4 +- .../TransactionInputOutput.module.scss | 5 +- .../ActivityDetail/components/DetailRow.tsx | 2 +- .../ActivityDetail/components/DetailRows.tsx | 2 +- .../src/ui/components/ActivityDetail/types.ts | 15 +- packages/core/src/ui/lib/translations/en.json | 215 ++++- 13 files changed, 1328 insertions(+), 156 deletions(-) create mode 100644 packages/core/src/ui/components/ActivityDetail/TransactionDetails.stories.tsx diff --git a/apps/browser-extension-wallet/src/lib/translations/en.json b/apps/browser-extension-wallet/src/lib/translations/en.json index cd0c2675e7..7ffc8c56f6 100644 --- a/apps/browser-extension-wallet/src/lib/translations/en.json +++ b/apps/browser-extension-wallet/src/lib/translations/en.json @@ -54,18 +54,6 @@ "deposit": "Deposit paid", "coldCredential": "Cold credential", "hotCredential": "Hot credential" - }, - "typenames": { - "VoteDelegationCertificate": "Vote Delegation", - "StakeVoteDelegationCertificate": "Stake Vote Delegation", - "StakeRegistrationDelegationCertificate": "Stake Registration Delegate", - "VoteRegistrationDelegationCertificate": "Vote Registration Delegate", - "StakeVoteRegistrationDelegationCertificate": "Stake Vote Registration Delegation", - "AuthorizeCommitteeHotCertificate": "Authorize Committee", - "ResignCommitteeColdCertificate": "Resign Committee", - "RegisterDelegateRepresentativeCertificate": "Register Delegate Representative", - "UnregisterDelegateRepresentativeCertificate": "Unregister Delegate Representative", - "UpdateDelegateRepresentativeCertificate": "Update Delegate Representative" } } } @@ -1340,7 +1328,7 @@ "ccMinSize": "CC Min Size", "ccMaxTermLength": "CC Max Term Length", "dRepVotingThresholds": { - "title": "Governance voting thresholds", + "title": "Governance Voting Thresholds", "motionNoConfidence": "Motion No Conf", "committeeNormal": "Comm Normal", "committeeNoConfidence": "Comm No Conf", 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 60b79f610a..9930766a4e 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 @@ -222,7 +222,12 @@ const buildGetActivityDetail = includedUtcTime: blocks?.utcTime, // TODO: store the raw data here and transform it later so we always have the raw data when needed.(LW-9570) votingProcedures: votingProceduresTransformer(tx.body.votingProcedures), - proposalProcedures: governanceProposalsTransformer(cardanoCoin, tx.body.proposalProcedures), + proposalProcedures: governanceProposalsTransformer( + cardanoCoin, + coinPrices, + fiatCurrency, + tx.body.proposalProcedures + ), certificates: certificateTransformer(cardanoCoin, coinPrices, fiatCurrency, tx.body.certificates) }; 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 731044d38d..309898fb39 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 @@ -1,3 +1,4 @@ +/* eslint-disable max-statements */ /* eslint-disable sonarjs/cognitive-complexity */ /* eslint-disable complexity */ import BigNumber from 'bignumber.js'; @@ -23,7 +24,7 @@ import isEmpty from 'lodash/isEmpty'; import { PriceResult } from '@hooks'; import { formatPercentages } from '@lace/common'; -const { util, GovernanceActionType, PlutusLanguageVersion } = Wallet.Cardano; +const { util, GovernanceActionType, PlutusLanguageVersion, CertificateType } = Wallet.Cardano; export interface TxTransformerInput { tx: Wallet.TxInFlight | Wallet.Cardano.HydratedTx; @@ -259,13 +260,13 @@ export const certificateTransformer = ( if ('anchor' in conwayEraCertificate && conwayEraCertificate.anchor) { transformedCertificate.push( - { - title: 'anchorUrl', - details: [conwayEraCertificate.anchor.url] - }, { title: 'anchorHash', details: [conwayEraCertificate.anchor.dataHash.toString()] + }, + { + title: 'anchorUrl', + details: [conwayEraCertificate.anchor.url] } ); } @@ -285,9 +286,13 @@ export const certificateTransformer = ( } if ('deposit' in conwayEraCertificate) { + const depositTitle = + conwayEraCertificate.__typename === CertificateType.UnregisterDelegateRepresentative + ? 'depositReturned' + : 'depositPaid'; transformedCertificate.push({ - title: 'depositPaid', - info: 'depositPaidInfo', + title: depositTitle, + info: `${depositTitle}Info`, details: [ [ Wallet.util.getFormattedAmount({ amount: conwayEraCertificate.deposit.toString(), cardanoCoin }), @@ -310,15 +315,7 @@ export const votingProceduresTransformer = ( votingProcedures?.forEach((procedure) => procedure.votes.forEach((vote) => { - const detail: TxDetails = []; - if (vote.votingProcedure.anchor) { - detail.push( - { title: 'anchorHash', details: [vote.votingProcedure.anchor.dataHash.toString()] }, - { title: 'anchorURL', details: [vote.votingProcedure.anchor.url] } - ); - } - - detail.push( + const detail: TxDetails = [ { title: 'voterType', details: [getVoterType(procedure.voter.__typename)] @@ -327,8 +324,16 @@ export const votingProceduresTransformer = ( title: 'credentialType', details: [getCredentialType(procedure.voter.credential.type)] }, - { title: 'voteTypes', details: [getVote(vote.votingProcedure.vote)] } - ); + { title: 'voteTypes', details: [getVote(vote.votingProcedure.vote)] }, + { title: 'drepId', details: [getVote(vote.votingProcedure.vote)] } + ]; + + if (vote.votingProcedure.anchor) { + detail.push( + { title: 'anchorURL', details: [vote.votingProcedure.anchor.url] }, + { title: 'anchorHash', details: [vote.votingProcedure.anchor.dataHash.toString()] } + ); + } votingProcedureDetails.push(detail.filter((el: TxDetail) => !isEmpty(el))); }) @@ -339,6 +344,8 @@ export const votingProceduresTransformer = ( export const governanceProposalsTransformer = ( cardanoCoin: Wallet.CoinId, + coinPrices: PriceResult, + fiatCurrency: CurrencyInfo, proposalProcedures?: Wallet.Cardano.ProposalProcedure[] ): TxDetails[] => proposalProcedures?.map((procedure) => { @@ -347,18 +354,34 @@ export const governanceProposalsTransformer = ( { ...(procedure.governanceAction.__typename === GovernanceActionType.parameter_change_action && { title: 'deposit', - details: [`${Wallet.util.lovelacesToAdaString(procedure.deposit.toString())} ${cardanoCoin.symbol}`] + info: 'deposit', + details: [ + [ + Wallet.util.getFormattedAmount({ amount: procedure.deposit.toString(), cardanoCoin }), + `${Wallet.util.convertLovelaceToFiat({ + lovelaces: procedure.deposit.toString(), + fiat: coinPrices?.cardano?.price + })} ${fiatCurrency?.code}` + ] + ] }) }, - { title: 'anchorHash', details: [procedure.anchor.dataHash.toString()] }, - { title: 'anchorURL', details: [procedure.anchor.url] } + { title: 'rewardAccount', details: [procedure.anchor.dataHash.toString()] }, + { title: 'anchorURL', details: [procedure.anchor.url] }, + { title: 'anchorHash', details: [procedure.anchor.dataHash.toString()] } ]; - if ('governanceActionId' in procedure.governanceAction) { - transformedProposal.push({ - title: 'governanceActionIndex', - details: [procedure.governanceAction.governanceActionId.actionIndex.toString()] - }); + if ('governanceActionId' in procedure.governanceAction && procedure.governanceAction.governanceActionId) { + transformedProposal.push( + { + title: 'governanceActionID', + details: [procedure.governanceAction.governanceActionId.id.toString()] + }, + { + title: 'actionIndex', + details: [procedure.governanceAction.governanceActionId.actionIndex.toString()] + } + ); } if ('withdrawals' in procedure.governanceAction) { @@ -432,6 +455,18 @@ export const governanceProposalsTransformer = ( } } + if ('newQuorumThreshold' in procedure.governanceAction) { + transformedProposal.push({ + title: 'newQuorumThreshold', + details: [ + `${formatPercentages( + procedure.governanceAction.newQuorumThreshold.numerator / + procedure.governanceAction.newQuorumThreshold.denominator + )}%` + ] + }); + } + if ('protocolVersion' in procedure.governanceAction) { transformedProposal.push( { @@ -572,6 +607,19 @@ export const governanceProposalsTransformer = ( } ] }, + { + header: 'costModels', + details: [ + { + title: 'PlutusV1', + details: costModels.get(PlutusLanguageVersion.V1).map((model) => model.toString()) + }, + { + title: 'PlutusV2', + details: costModels.get(PlutusLanguageVersion.V2).map((model) => model.toString()) + } + ] + }, { header: 'technicalGroup', details: [ @@ -593,19 +641,6 @@ export const governanceProposalsTransformer = ( } ] }, - { - header: 'costModels', - details: [ - { - title: 'PlutusV1', - details: costModels.get(PlutusLanguageVersion.V1).map((model) => model.toString()) - }, - { - title: 'PlutusV2', - details: costModels.get(PlutusLanguageVersion.V2).map((model) => model.toString()) - } - ] - }, { header: 'governanceGroup', details: [ @@ -615,11 +650,13 @@ export const governanceProposalsTransformer = ( }, { title: 'govActionDeposit', - details: [governanceActionDeposit?.toString()] + // TODO: is it in Ada or lovelaces? + details: [`${governanceActionDeposit?.toString()} ${cardanoCoin.symbol}`] }, { title: 'drepDeposit', - details: [dRepDeposit?.toString()] + // TODO: is it in Ada or lovelaces? + details: [`${dRepDeposit?.toString()} ${cardanoCoin.symbol}`] }, { title: 'drepActivity', @@ -655,43 +692,43 @@ export const governanceProposalsTransformer = ( details: [ { title: 'motionNoConfidence', - details: [formatPercentages(motionNoConfidence.numerator / motionNoConfidence.denominator)] + details: [`${formatPercentages(motionNoConfidence.numerator / motionNoConfidence.denominator)}%`] }, { title: 'committeeNormal', - details: [formatPercentages(committeeNormal.numerator / committeeNormal.denominator)] + details: [`${formatPercentages(committeeNormal.numerator / committeeNormal.denominator)}%`] }, { title: 'committeeNoConfidence', - details: [formatPercentages(commiteeNoConfidence.numerator / commiteeNoConfidence.denominator)] + details: [`${formatPercentages(commiteeNoConfidence.numerator / commiteeNoConfidence.denominator)}%`] }, { title: 'updateConstitution', - details: [formatPercentages(updateConstitution.numerator / updateConstitution.denominator)] + details: [`${formatPercentages(updateConstitution.numerator / updateConstitution.denominator)}%`] }, { title: 'hardForkInitiation', - details: [formatPercentages(hardForkInitiation.numerator / hardForkInitiation.denominator)] + details: [`${formatPercentages(hardForkInitiation.numerator / hardForkInitiation.denominator)}%`] }, { title: 'ppNetworkGroup', - details: [formatPercentages(ppNetworkGroup.numerator / ppNetworkGroup.denominator)] + details: [`${formatPercentages(ppNetworkGroup.numerator / ppNetworkGroup.denominator)}%`] }, { title: 'ppEconomicGroup', - details: [formatPercentages(ppEconomicGroup.numerator / ppEconomicGroup.denominator)] + details: [`${formatPercentages(ppEconomicGroup.numerator / ppEconomicGroup.denominator)}%`] }, { title: 'ppTechnicalGroup', - details: [formatPercentages(ppTechnicalGroup.numerator / ppTechnicalGroup.denominator)] + details: [`${formatPercentages(ppTechnicalGroup.numerator / ppTechnicalGroup.denominator)}%`] }, { title: 'ppGovernanceGroup', - details: [formatPercentages(ppGovernanceGroup.numerator / ppGovernanceGroup.denominator)] + details: [`${formatPercentages(ppGovernanceGroup.numerator / ppGovernanceGroup.denominator)}%`] }, { title: 'treasuryWithdrawal', - details: [formatPercentages(treasuryWithdrawal.numerator / treasuryWithdrawal.denominator)] + details: [`${formatPercentages(treasuryWithdrawal.numerator / treasuryWithdrawal.denominator)}%`] } ] }); diff --git a/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.module.scss b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.module.scss index c9da701fb8..2efbf074c6 100644 --- a/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/ActivityDetailHeader.module.scss @@ -7,7 +7,7 @@ gap: size_unit(1); .type { - @include text-heading; + @include text-subHeading-bold; color: var(--text-color-primary, #3d3b39); } .assets { diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.module.scss index 73fdb278f2..4372e0edaf 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.module.scss @@ -15,7 +15,7 @@ $border-bottom: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid- .header { color: var(--text-color-secondary, #878e9e); - @include text-bodyLarge-medium; + @include text-body-medium; margin-bottom: size_unit(9); @media (max-width: $breakpoint-popup) { @@ -26,10 +26,6 @@ $border-bottom: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid- } } - * { - margin: 0; - } - .block { border-bottom: $border-bottom; @@ -185,7 +181,7 @@ $border-bottom: 1px solid var(--light-mode-light-grey-plus, var(--dark-mode-mid- } .hashLabel { - max-width: auto; + max-width: initial; @media (max-width: $breakpoint-popup) { max-width: 85px; overflow-wrap: break-word; diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.stories.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.stories.tsx new file mode 100644 index 0000000000..76b4aeb9cd --- /dev/null +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.stories.tsx @@ -0,0 +1,892 @@ +/* eslint-disable sonarjs/no-duplicate-string */ +import type { Meta, StoryObj } from '@storybook/react'; + +import { TransactionDetails } from './TransactionDetails'; +import { ComponentProps } from 'react'; +import { ActivityStatus } from '../Activity/AssetActivityItem'; +import { Wallet } from '@lace/cardano'; +import { ConwayEraCertificatesTypes } from './types'; + +const meta: Meta = { + title: 'Sanchonet/ActivityDetail/TransactionDetails', + component: TransactionDetails, + parameters: { + layout: 'centered' + } +}; + +export default meta; +type Story = StoryObj; + +const adaPrice = 0.470_588_235_294_117_6; + +const data: ComponentProps = { + hash: '639a43144dc2c0ead16f2fb753360f4b4f536502dbdb8aa5e424b00abb7534ff', + name: 'Stake Vote Delegation Certificate', + status: ActivityStatus.SUCCESS, + includedDate: '00/00/0000', + includedTime: '00:00:00', + fee: '0.17', + addrInputs: [ + { + amount: '9975.13', + assetList: [], + addr: 'addr_test1qqwhys44c506gsyqnwx3cy6nrhmalajfanqsg0ult5aj4pg8unnmf7l2w7pwz6nej0qj463w7mpytey22ag0h64fs5gs8zw2jg' + } + ], + addrOutputs: [ + { + amount: '1.00', + assetList: [], + addr: 'addr_test1qqwhys44c506gsyqnwx3cy6nrhmalajfanqsg0ult5aj4pg8unnmf7l2w7pwz6nej0qj463w7mpytey22ag0h64fs5gs8zw2jg' + }, + { + amount: '9971.96', + assetList: [], + addr: 'addr_test1qqwhys44c506gsyqnwx3cy6nrhmalajfanqsg0ult5aj4pg8unnmf7l2w7pwz6nej0qj463w7mpytey22ag0h64fs5gs8zw2jg' + } + ], + txSummary: [], + coinSymbol: 'ADA', + addressToNameMap: new Map(), + isPopupView: false, + votingProcedures: [], + amountTransformer: (amount) => `${Number(amount) * adaPrice} USD`, + openExternalLink: () => void 0 +}; + +const stakeVoteDelegationCertificate = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.StakeVoteDelegation] + }, + { + title: 'stakeKey', + details: ['stake1u929x2y7nnfm797upl7v9rc39pqg87pk5cygvnn2edqmvuq6h48su'] + }, + { + title: 'poolId', + details: ['pool1k0ucs0fau2vhr3p7qh7mnpfgrllwwda7petxjz2gzzaxkyp8f88'] + }, + { + title: 'drep', + details: ['drep1cs234l5mtapethapx8cq97nkpa27xf84phruh5f6jqxa78ymlp4'] + } +]; +export const StakeVoteDelegationCertificate: Story = { + args: { + ...data, + certificates: [stakeVoteDelegationCertificate] + } +}; + +export const StakeVoteDelegationCertificates: Story = { + args: { + ...data, + certificates: [stakeVoteDelegationCertificate, stakeVoteDelegationCertificate] + } +}; + +const stakeRegistrationDelegationCertificate = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.StakeRegistrationDelegation] + }, + { + title: 'stakeKey', + details: ['stake1u929x2y7nnfm797upl7v9rc39pqg87pk5cygvnn2edqmvuq6h48su'] + }, + { + title: 'poolId', + details: ['pool1k0ucs0fau2vhr3p7qh7mnpfgrllwwda7petxjz2gzzaxkyp8f88'] + }, + { + title: 'depositPaid', + info: 'depositPaidInfo', + details: [['2.00 ADA', '0.08 USD']] + } +]; + +export const StakeRegistrationDelegationCertificate: Story = { + args: { + ...data, + name: 'Stake Registration Delegation Certificate', + certificates: [stakeRegistrationDelegationCertificate] + } +}; + +const voteRegistrationDelegationCertificate = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.VoteRegistrationDelegation] + }, + { + title: 'stakeKey', + details: ['stake1u929x2y7nnfm797upl7v9rc39pqg87pk5cygvnn2edqmvuq6h48su'] + }, + { + title: 'drep', + details: ['drep1cs234l5mtapethapx8cq97nkpa27xf84phruh5f6jqxa78ymlp4'] + }, + { + title: 'depositPaid', + info: 'depositPaidInfo', + details: [['2.00 ADA', '0.08 USD']] + } +]; + +export const VoteRegistrationDelegationCertificate: Story = { + args: { + ...data, + name: 'Vote Registration Delegation Certificate', + certificates: [voteRegistrationDelegationCertificate] + } +}; + +const stakeVoteRegistrationDelegationCertificate = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.StakeVoteRegistrationDelegation] + }, + { + title: 'stakeKey', + details: ['stake1u929x2y7nnfm797upl7v9rc39pqg87pk5cygvnn2edqmvuq6h48su'] + }, + { + title: 'poolId', + details: ['pool1k0ucs0fau2vhr3p7qh7mnpfgrllwwda7petxjz2gzzaxkyp8f88'] + }, + { + title: 'drep', + details: ['drep1cs234l5mtapethapx8cq97nkpa27xf84phruh5f6jqxa78ymlp4'] + }, + { + title: 'depositPaid', + info: 'depositPaidInfo', + details: [['2.00 ADA', '0.08 USD']] + } +]; + +export const StakeVoteRegistrationDelegationCertificate: Story = { + args: { + ...data, + name: 'Stake Vote Registration Delegation Certificate', + certificates: [stakeVoteRegistrationDelegationCertificate] + } +}; + +const updateDRep = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.UpdateDelegateRepresentative] + }, + { + title: 'drepId', + details: ['65ge6g54g5dd5'] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'anchorUrl', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + } +]; + +export const UpdateDRep: Story = { + name: 'Update DRep', + args: { + ...data, + name: 'Update DRep', + certificates: [updateDRep] + } +}; + +const resignCommittee = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.ResignCommitteeCold] + }, + { + title: 'coldCredential', + details: ['65ge6g54g5dd5'] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'anchorUrl', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + } +]; + +export const ResignCommittee: Story = { + args: { + ...data, + name: 'Resign Committee', + certificates: [resignCommittee] + } +}; + +const authorizeCommittee = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.AuthorizeCommitteeHot] + }, + { + title: 'coldCredential', + details: ['cc_cold 65ge6g54g5dd5'] + }, + { + title: 'hotCredential', + details: ['cc_hot stake1u929x2y7nnfm797upl7v9rc39pqg87pk5cygvnn2edqmvuq6h48su'] + } +]; + +export const AuthorizeCommittee: Story = { + args: { + ...data, + name: 'Authorize Committee', + certificates: [authorizeCommittee] + } +}; + +const dRepRegistration = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.RegisterDelegateRepresentative] + }, + { + title: 'drepId', + details: ['drep170ef53apap7dadzemkcd7lujlzk5hyzvzzjj7f3sx89ecn3ft6u'] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'anchorUrl', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'depositPaid', + info: 'depositPaidInfo', + details: [['0.35 ADA', '0.08 USD']] + } +]; + +export const DRepRegistration: Story = { + name: 'DRep Registration', + args: { + ...data, + name: 'DRep Registration', + certificates: [dRepRegistration] + } +}; + +const dRepDeRegistration = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.UnregisterDelegateRepresentative] + }, + { + title: 'drepId', + details: ['drep170ef53apap7dadzemkcd7lujlzk5hyzvzzjj7f3sx89ecn3ft6u'] + }, + { + title: 'depositReturned', + info: 'depositReturnedInfo', + details: [['0.35 ADA', '0.08 USD']] + } +]; + +export const DRepDeRegistration: Story = { + name: 'DRep De-Registration', + args: { + ...data, + name: 'DRep De-Registration', + certificates: [dRepDeRegistration] + } +}; + +const voteDelegation = [ + { + title: 'certificateType', + details: [ConwayEraCertificatesTypes.VoteDelegation] + }, + { + title: 'stakeKey', + details: ['stake1u929x2y7nnfm797upl7v9rc39pqg87pk5cygvnn2edqmvuq6h48su'] + }, + { + title: 'drepId', + details: ['drep1cs234l5mtapethapx8cq97nkpa27xf84phruh5f6jqxa78ymlp4'] + } +]; + +export const VoteDelegation: Story = { + args: { + ...data, + name: 'Vote Delegation', + certificates: [voteDelegation] + } +}; + +const confirmVote = [ + { + title: 'voterType', + details: ['drep'] + }, + { + title: 'credentialType', + details: ['drep1cs234l5mtapethapx8cq97nkpa27xf84phruh5f6jqxa78ymlp4'] + }, + { + title: 'voteTypes', + details: ['yes'] + }, + { + title: 'drepId', + details: ['drep1cs234l5mtapethapx8cq97nkpa27xf84phruh5f6jqxa78ymlp4'] + }, + { + title: 'anchorURL', + details: ['https://shorturl.at/eK145'] + }, + { + title: 'anchorHash', + details: ['9067f223838d88b83f660c05eedf7f6f65c45de31e522c1bcb6a1eb287b17e89'] + } +]; + +export const ConfirmVote: Story = { + args: { + ...data, + name: 'Confirm Vote', + votingProcedures: [confirmVote, confirmVote] + } +}; + +const parameterChangeAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.parameter_change_action] + }, + { + title: 'deposit', + details: ['stake1u89sa...css5vgr'] + }, + { + title: 'rewardAccount', + details: ['https://www.someurl.io'] + }, + { + title: 'anchorURL', + details: ['https://www.someurl.io'] + }, + { + title: 'anchorHash', + details: ['000000...0000'] + }, + { + header: 'maxTxExUnits', + details: [ + { + title: 'memory', + details: ['100000000'] + }, + { + title: 'step', + details: ['10000000000000'] + } + ] + }, + { + header: 'maxBlockExUnits', + details: [ + { + title: 'memory', + details: ['50000000'] + }, + { + title: 'step', + details: ['40000000000'] + } + ] + }, + { + header: 'networkGroup', + details: [ + { + title: 'maxBBSize', + details: ['65536'] + }, + { + title: 'maxTxSize', + details: ['16384'] + }, + { + title: 'maxBHSize', + details: ['1100'] + }, + { + title: 'maxValSize', + details: ['5000'] + }, + { + title: 'maxCollateralInputs', + details: ['3'] + } + ] + }, + { + header: 'economicGroup', + details: [ + { + title: 'minFeeA', + details: ['44'] + }, + { + title: 'minFeeB', + details: ['155381'] + }, + { + title: 'keyDeposit', + details: ['2000000'] + }, + { + title: 'poolDeposit', + details: ['500000000'] + }, + { + title: 'rho', + details: ['0.003'] + }, + { + title: 'tau', + details: ['0.2'] + }, + { + title: 'minPoolCost', + details: ['340000000'] + }, + { + title: 'coinsPerUTxOByte', + details: ['34482'] + } + ] + }, + { + header: 'costModels', + details: [ + { + title: 'PlutusV1', + details: ['197209'] + }, + { + title: 'PlutusV2', + details: ['197209'] + } + ] + }, + { + header: 'technicalGroup', + details: [ + { + title: 'a0', + details: ['0.3'] + }, + { + title: 'eMax', + details: ['18'] + }, + { + title: 'nOpt', + details: ['150'] + }, + { + title: 'collateralPercentage', + details: ['150'] + } + ] + }, + { + header: 'governanceGroup', + details: [ + { + title: 'govActionLifetime', + details: ['10'] + }, + { + title: 'govActionDeposit', + details: ['500 ADA'] + }, + { + title: 'drepDeposit', + details: ['1000 ADA'] + }, + { + title: 'drepActivity', + details: ['5'] + }, + { + title: 'ccMinSize', + details: ['7'] + }, + { + title: 'ccMaxTermLength', + details: ['25'] + } + ] + }, + { + header: 'dRepVotingThresholds', + details: [ + { + title: 'motionNoConfidence', + details: ['51%'] + }, + { + title: 'committeeNormal', + details: ['67%'] + }, + { + title: 'committeeNoConfidence', + details: ['80%'] + }, + { + title: 'updateConstitution', + details: ['75%'] + }, + { + title: 'hardForkInitiation', + details: ['90%'] + }, + { + title: 'ppNetworkGroup', + details: ['70%'] + }, + { + title: 'ppEconomicGroup', + details: ['70%'] + }, + { + title: 'ppTechnicalGroup', + details: ['70%'] + }, + { + title: 'ppGovernanceGroup', + details: ['70%'] + }, + { + title: 'treasuryWithdrawal', + details: ['51%'] + } + ] + } +]; + +export const ParameterChangeAction: Story = { + args: { + ...data, + name: 'Parameter Change Action', + proposalProcedures: [parameterChangeAction] + } +}; + +const hardForkInitiationAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.hard_fork_initiation_action] + }, + { + title: 'deposit', + info: 'deposit', + details: [['2.00 ADA', '0.18 USD']] + }, + { title: 'rewardAccount', details: ['23bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175'] }, + { + title: 'anchorURL', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'governanceActionID', + details: ['d0b1f7be72731a97e9728e0f1c358d576fd28aa9f290d53ce1ef803a1a753ba8'] + }, + { + title: 'actionIndex', + details: ['0'] + }, + { + title: 'protocolVersionMajor', + details: ['1'] + }, + { + title: 'protocolVersionMinor', + details: ['2'] + }, + { + title: 'protocolVersionPatch', + details: ['3'] + } +]; + +export const HardForkInitiationAction: Story = { + args: { + ...data, + name: 'Hard Fork Initiation Action', + proposalProcedures: [hardForkInitiationAction] + } +}; + +const infoAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.info_action] + }, + { + title: 'deposit', + info: 'deposit', + details: [['2.00 ADA', '0.18 USD']] + }, + { + title: 'anchorURL', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'governanceActionID', + details: ['d0b1f7be72731a97e9728e0f1c358d576fd28aa9f290d53ce1ef803a1a753ba8'] + }, + { + title: 'actionIndex', + details: ['0'] + } +]; + +export const InfoAction: Story = { + args: { + ...data, + name: 'Info Action', + proposalProcedures: [infoAction] + } +}; + +const newConstitutionAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.new_constitution] + }, + { + title: 'anchorURL', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'governanceActionID', + details: ['d0b1f7be72731a97e9728e0f1c358d576fd28aa9f290d53ce1ef803a1a753ba8'] + }, + { + title: 'actionIndex', + details: ['0'] + }, + { + title: 'constitutionAnchorURL', + details: ['https://www.someurl.io'] + }, + { + title: 'constitutionScriptHash', + details: ['cb0ec2692497b458e46812c8a5bfa2931d1a2d965a99893828ec810f'] + } +]; + +export const NewConstitutionAction: Story = { + args: { + ...data, + name: 'Info Action', + proposalProcedures: [newConstitutionAction] + } +}; + +const noConfidenceAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.no_confidence] + }, + { title: 'rewardAccount', details: ['23bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175'] }, + { + title: 'anchorURL', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'governanceActionID', + details: ['d0b1f7be72731a97e9728e0f1c358d576fd28aa9f290d53ce1ef803a1a753ba8'] + }, + { + title: 'actionIndex', + details: ['0'] + } +]; + +export const NoConfidenceAction: Story = { + args: { + ...data, + name: 'No Confidence Action', + proposalProcedures: [noConfidenceAction] + } +}; + +const updateCommitteeAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.update_committee] + }, + { + title: 'deposit', + info: 'deposit', + details: [['2.00 ADA', '0.18 USD']] + }, + { title: 'rewardAccount', details: ['23bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175'] }, + { + title: 'anchorURL', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'governanceActionID', + details: ['d0b1f7be72731a97e9728e0f1c358d576fd28aa9f290d53ce1ef803a1a753ba8'] + }, + { + title: 'actionIndex', + details: ['0'] + }, + { + header: 'membersToBeAdded', + details: [ + { + title: 'coldCredentialHash', + details: ['30000000000000000000000000000000000000000000000000000000'] + }, + { + title: 'epoch', + details: ['1'] + }, + { + title: 'coldCredentialHash', + details: ['40000000000000000000000000000000000000000000000000000000'] + }, + { + title: 'epoch', + details: ['2'] + } + ] + }, + { + header: 'membersToBeRemoved', + details: [ + { + title: 'hash', + details: ['00000000000000000000000000000000000000000000000000000000'] + } + ] + }, + { + title: 'newQuorumThreshold', + details: ['0.4%'] + } +]; + +export const UpdateCommitteeAction: Story = { + args: { + ...data, + name: 'Update Committee Action', + proposalProcedures: [updateCommitteeAction] + } +}; + +const treasuryWithdrawalsAction = [ + { + title: 'type', + details: [Wallet.Cardano.GovernanceActionType.treasury_withdrawals_action] + }, + { + title: 'deposit', + info: 'deposit', + details: [['2.00 ADA', '0.18 USD']] + }, + { title: 'rewardAccount', details: ['23bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175'] }, + { + title: 'anchorURL', + details: [ + 'https://raw.githubusercontent.com/Ryun1/gov-metadata/main/governace-action/metadata.jsonldr1q99...uqvzlalu' + ] + }, + { + title: 'anchorHash', + details: ['3d2a9d15382c14f5ca260a2f5bfb645fe148bfe10c1d0e1d305b7b1393e2bd97'] + }, + { + title: 'governanceActionID', + details: ['d0b1f7be72731a97e9728e0f1c358d576fd28aa9f290d53ce1ef803a1a753ba8'] + }, + { + title: 'actionIndex', + details: ['0'] + }, + { + header: 'withdrawal', + details: [ + { + title: 'withdrawalRewardAccount', + details: ['23bcf2892e8182a68e3aac6f9f42ed3317d115ebad12a17232681175'] + }, + { + title: 'withdrawalAmount', + details: ['1030939916423 ADA'] + } + ] + } +]; + +export const TreasuryWithdrawalsAction: Story = { + args: { + ...data, + name: 'Treasury Withdrawals Action', + proposalProcedures: [treasuryWithdrawalsAction] + } +}; diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx index 5e3eeaa9cb..7e2ea0ba7c 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx +++ b/packages/core/src/ui/components/ActivityDetail/TransactionDetails.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /* eslint-disable no-magic-numbers */ import React from 'react'; import cn from 'classnames'; @@ -136,13 +137,14 @@ export const TransactionDetails = ({ ...detail, ...('title' in detail && detail.title === 'certificateType' && { - details: [t(`package.core.assetActivityItem.entry.certificates.typenames.${detail.details[0]}`)] + details: [t(`package.core.assetActivityItem.entry.name.${detail.details[0]}`)] }) } as TxDetail) ) ); // Translate governance proposal typenames + // TODO: find a way to translate in the mappers const translatedProposalProcedures = proposalProcedures?.map((proposal) => proposal?.map( (p) => @@ -151,8 +153,27 @@ export const TransactionDetails = ({ ...('title' in p && p.title === 'type' && { details: [t(`package.core.activityDetails.governanceActions.${p.details[0]}`)] - }) - } as TxDetail) + }), + ...('header' in p && { + details: p.details.map((detail) => ({ + ...detail, + ...('title' in detail && + ['govActionLifetime', 'drepActivity', 'ccMaxTermLength'].includes(detail.title) && { + details: [ + ` + ${Number(detail.details[0])} + ${t( + // eslint-disable-next-line sonarjs/no-nested-template-literals + `package.core.activityDetails.${ + Number(detail.details[0]) === 0 || Number(detail.details[0]) > 1 ? 'epochs' : 'epoch' + }` + )} + ` + ] + }) + })) + }) + } as unknown as TxDetail) ) ); @@ -342,10 +363,11 @@ export const TransactionDetails = ({ lists={translatedVotingProcedures} translations={{ voterType: t('package.core.activityDetails.votingProcedureTitles.voterType'), + drepId: t('package.core.activityDetails.votingProcedureTitles.drepId'), credentialType: t('package.core.activityDetails.votingProcedureTitles.credentialType'), voteTypes: t('package.core.activityDetails.votingProcedureTitles.voteTypes'), anchorHash: t('package.core.activityDetails.votingProcedureTitles.anchorHash'), - anchorURL: t('package.core.activityDetails.votingProcedureTitles.proposalTxHash') + anchorURL: t('package.core.activityDetails.votingProcedureTitles.anchorUrl') }} withSeparatorLine /> @@ -360,9 +382,12 @@ export const TransactionDetails = ({ translations={{ type: t('package.core.activityDetails.proposalProcedureTitles.type'), deposit: t('package.core.activityDetails.proposalProcedureTitles.deposit'), + rewardAccount: t('package.core.activityDetails.proposalProcedureTitles.rewardAccount'), anchorHash: t('package.core.activityDetails.proposalProcedureTitles.anchorHash'), anchorURL: t('package.core.activityDetails.proposalProcedureTitles.anchorURL'), - governanceActionIndex: t('package.core.activityDetails.proposalProcedureTitles.governanceActionIndex'), + governanceActionID: t('package.core.activityDetails.proposalProcedureTitles.governanceActionID'), + actionIndex: t('package.core.activityDetails.proposalProcedureTitles.actionIndex'), + newQuorumThreshold: t('package.core.activityDetails.proposalProcedureTitles.newQuorumThreshold'), withdrawal: t('package.core.activityDetails.proposalProcedureTitles.withdrawal'), withdrawalRewardAccount: t( 'package.core.activityDetails.proposalProcedureTitles.withdrawalRewardAccount' @@ -378,78 +403,120 @@ export const TransactionDetails = ({ protocolVersionMajor: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionMajor'), protocolVersionMinor: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionMinor'), protocolVersionPatch: t('package.core.activityDetails.proposalProcedureTitles.protocolVersionPatch'), - maxTxExUnits: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxExUnits'), + maxTxExUnits: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxExUnits' + ), maxBlockExUnits: t( - 'core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBlockExUnits' - ), - networkGroup: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.title'), - economicGroup: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.title'), - technicalGroup: t('core.ProposalProcedure.governanceAction.technicalGroup.title'), - costModels: t('core.ProposalProcedure.governanceAction.technicalGroup.costModels'), - PlutusV1: t('core.ProposalProcedure.governanceAction.technicalGroup.PlutusV1'), - PlutusV2: t('core.ProposalProcedure.governanceAction.technicalGroup.PlutusV2'), - governanceGroup: t('core.ProposalProcedure.governanceAction.governanceGroup.title'), + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBlockExUnits' + ), + networkGroup: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.title'), + economicGroup: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.title' + ), + technicalGroup: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.title' + ), + costModels: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.costModels' + ), + PlutusV1: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.PlutusV1' + ), + PlutusV2: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.PlutusV2' + ), + governanceGroup: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.title' + ), dRepVotingThresholds: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.title' - ), - memory: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.memory'), - step: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.step'), - maxBBSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBBSize'), - maxTxSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxSize'), - maxBHSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBHSize'), - maxValSize: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxValSize'), + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.title' + ), + memory: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.memory'), + step: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.step'), + maxBBSize: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBBSize' + ), + maxTxSize: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxTxSize' + ), + maxBHSize: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxBHSize' + ), + maxValSize: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxValSize' + ), maxCollateralInputs: t( - 'core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxCollateralInputs' - ), - minFeeA: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeA'), - minFeeB: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeB'), - keyDeposit: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.keyDeposit'), - poolDeposit: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.poolDeposit'), - rho: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.rho'), - tau: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tau'), - minPoolCost: t('core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minPoolCost'), + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.networkGroup.maxCollateralInputs' + ), + minFeeA: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeA'), + minFeeB: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minFeeB'), + keyDeposit: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.keyDeposit' + ), + poolDeposit: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.poolDeposit' + ), + rho: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.rho'), + tau: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.tau'), + minPoolCost: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.minPoolCost' + ), coinsPerUTxOByte: t( - 'core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.coinsPerUTxOByte' - ), - a0: t('core.ProposalProcedure.governanceAction.technicalGroup.a0'), - eMax: t('core.ProposalProcedure.governanceAction.technicalGroup.eMax'), - nOpt: t('core.ProposalProcedure.governanceAction.technicalGroup.nOpt'), - collateralPercentage: t('core.ProposalProcedure.governanceAction.technicalGroup.collateralPercentage'), - govActionLifetime: t('core.ProposalProcedure.governanceAction.governanceGroup.govActionLifetime'), - govActionDeposit: t('core.ProposalProcedure.governanceAction.governanceGroup.govActionDeposit'), - drepDeposit: t('core.ProposalProcedure.governanceAction.governanceGroup.drepDeposit'), - drepActivity: t('core.ProposalProcedure.governanceAction.governanceGroup.drepActivity'), - ccMinSize: t('core.ProposalProcedure.governanceAction.governanceGroup.ccMinSize'), - ccMaxTermLength: t('core.ProposalProcedure.governanceAction.governanceGroup.ccMaxTermLength'), + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.economicGroup.coinsPerUTxOByte' + ), + a0: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.a0'), + eMax: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.eMax'), + nOpt: t('package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.nOpt'), + collateralPercentage: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.technicalGroup.collateralPercentage' + ), + govActionLifetime: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.govActionLifetime' + ), + govActionDeposit: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.govActionDeposit' + ), + drepDeposit: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.drepDeposit' + ), + drepActivity: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.drepActivity' + ), + ccMinSize: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.ccMinSize' + ), + ccMaxTermLength: t( + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.ccMaxTermLength' + ), motionNoConfidence: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.motionNoConfidence' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.motionNoConfidence' ), committeeNormal: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.committeeNormal' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.committeeNormal' ), committeeNoConfidence: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.committeeNoConfidence' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.committeeNoConfidence' ), updateConstitution: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.updateConstitution' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.updateConstitution' ), hardForkInitiation: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.hardForkInitiation' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.hardForkInitiation' ), ppNetworkGroup: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppNetworkGroup' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppNetworkGroup' ), ppEconomicGroup: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppEconomicGroup' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppEconomicGroup' ), ppTechnicalGroup: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppTechnicalGroup' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppTechnicalGroup' ), ppGovernanceGroup: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.ppGovernanceGroup' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.ppGovernanceGroup' ), treasuryWithdrawal: t( - 'core.ProposalProcedure.governanceAction.governanceGroup.dRepVotingThresholds.treasuryWithdrawal' + 'package.core.ProposalProcedure.governanceAction.protocolParamUpdate.governanceGroup.dRepVotingThresholds.treasuryWithdrawal' ) }} /> @@ -473,7 +540,9 @@ export const TransactionDetails = ({ poolId: t('package.core.activityDetails.certificateTitles.poolId'), drep: t('package.core.activityDetails.certificateTitles.drep'), depositPaid: t('package.core.activityDetails.certificateTitles.depositPaid'), - depositPaidInfo: t('package.core.activityDetails.certificateTitles.depositPaidInfo') + depositPaidInfo: t('package.core.activityDetails.certificateTitles.depositPaidInfo'), + depositReturned: t('package.core.activityDetails.certificateTitles.depositReturned'), + depositReturnedInfo: t('package.core.activityDetails.certificateTitles.depositReturnedInfo') }} /> )} diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss index 7ba4758637..ce8e0a0aee 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/TransactionFee.module.scss @@ -10,9 +10,7 @@ .txfee { color: var(--text-color-primary); - font-size: var(--body, 16px); - font-weight: 600; - line-height: size_unit(3); + @include text-body-semi-bold; } .details { diff --git a/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss index 31599bcdda..5e37c46c23 100644 --- a/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss +++ b/packages/core/src/ui/components/ActivityDetail/TransactionInputOutput.module.scss @@ -8,13 +8,10 @@ .expanderHeader { display: flex; - font-size: var(--bodyLarge); - font-weight: 700; justify-content: space-between; - line-height: 32px; padding: size_unit(3) 0px; - color: var(--text-color-primary); + @include text-bodyLarge-bold; .label { @include text-bodyLarge-bold; diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx index 61f2e3f9b9..d9f5d28051 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRow.tsx @@ -19,7 +19,7 @@ export const DetailRow = ({ title, info, details, dataTestId }: DetailsRowProps)
{details.map((detail, idx) => ( - {typeof detail === 'string' ? detail : } + {typeof detail === 'string' ? detail : } ))}
diff --git a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx index a5d06d4e75..1b28c598d9 100644 --- a/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx +++ b/packages/core/src/ui/components/ActivityDetail/components/DetailRows.tsx @@ -33,7 +33,7 @@ export const DetailRows = function DetailRows({ key={`${testId}-list-header`} className={cn(styles.listHeader, { [styles.topBorderContent]: index > 0 })} > -
{`${item.header} ${index + 1}`}
+
{translations[item.header]}
diff --git a/packages/core/src/ui/components/ActivityDetail/types.ts b/packages/core/src/ui/components/ActivityDetail/types.ts index c682195ea6..2e03ffbcff 100644 --- a/packages/core/src/ui/components/ActivityDetail/types.ts +++ b/packages/core/src/ui/components/ActivityDetail/types.ts @@ -54,14 +54,19 @@ export type TxDetailsCertificateTitles = | 'drep' | 'depositPaid' | 'depositPaidInfo' + | 'depositReturned' + | 'depositReturnedInfo' | 'certificate'; export type TxDetailsProposalProceduresTitles = | 'type' | 'deposit' + | 'rewardAccount' | 'anchorHash' | 'anchorURL' - | 'governanceActionIndex' + | 'governanceActionID' + | 'actionIndex' + | 'newQuorumThreshold' | 'withdrawal' | 'withdrawalRewardAccount' | 'withdrawalAmount' @@ -121,7 +126,13 @@ export type TxDetailsProposalProceduresTitles = | 'ppGovernanceGroup' | 'treasuryWithdrawal'; -export type TxDetailsVotingProceduresTitles = 'voterType' | 'credentialType' | 'voteTypes' | 'anchorHash' | 'anchorURL'; +export type TxDetailsVotingProceduresTitles = + | 'voterType' + | 'credentialType' + | 'voteTypes' + | 'drepId' + | 'anchorHash' + | 'anchorURL'; export type TxDetail = { title: T; diff --git a/packages/core/src/ui/lib/translations/en.json b/packages/core/src/ui/lib/translations/en.json index 05098aa1ca..05ff47eb04 100644 --- a/packages/core/src/ui/lib/translations/en.json +++ b/packages/core/src/ui/lib/translations/en.json @@ -50,18 +50,6 @@ "coldCredential": "Cold credential", "hotCredential": "Hot credential", "drepCredential": "DRep credential" - }, - "typenames": { - "VoteDelegationCertificate": "Vote Delegation", - "StakeVoteDelegationCertificate": "Stake Vote Delegation", - "StakeRegistrationDelegationCertificate": "Stake Registration Delegate", - "VoteRegistrationDelegationCertificate": "Vote Registration Delegate", - "StakeVoteRegistrationDelegationCertificate": "Stake Vote Registration Delegation", - "AuthorizeCommitteeHotCertificate": "Authorize Committee", - "ResignCommitteeColdCertificate": "Resign Committee", - "RegisterDelegateRepresentativeCertificate": "Register Delegate Representative", - "UnregisterDelegateRepresentativeCertificate": "Unregister Delegate Representative", - "UpdateDelegateRepresentativeCertificate": "Update Delegate Representative" } } } @@ -123,6 +111,7 @@ "poolId": "Pool ID", "rewards": "Rewards", "rewardsDescription": "When available, your rewards will be withdrawn automatically every time you send Tokens.", + "summary": "Summary", "copiedToClipboard": "Copied to clipboard", "pools": "Pool(s)", "self": "Self Transaction", @@ -147,28 +136,34 @@ "drepId": "Drep ID", "depositPaid": "Deposit paid", "depositPaidInfo": "Deposit paid", + "depositReturned": "Deposit returned", + "depositReturnedInfo": "Deposit returned", "anchorUrl": "Anchor URL", "anchorHash": "Anchor Hash", "coldCredential": "Cold credential", "hotCredential": "Hot credential" }, - "votingProcedures": "Voting Procedures", - "votingProcedure": "Voting Procedure", + "votingProcedures": "Vote", + "votingProcedure": "Vote", "votingProcedureTitles": { "vote": "Vote", "voterType": "Voter type", - "credentialType": "Credential Type", + "credentialType": "Voter Credential", + "drepId": "DRep ID", "anchorUrl": "Anchor URL", "anchorHash": "Anchor Hash", "voteTypes": "Vote" }, - "proposalProcedures": "Governance Actions", + "proposalProcedures": "Action", "proposalProcedure": "Action", "proposalProcedureTitles": { + "type": "Type", "deposit": "Deposit", + "rewardAccount": "Reward Account", "anchorHash": "Anchor Hash", "anchorURL": "Anchor URL", - "governanceActionIndex": "Governance Action Index", + "actionIndex": "Action Index", + "governanceActionID": "Governance Action ID", "withdrawal": "Withdrawal", "withdrawalRewardAccount": "Withdrawal Reward Account", "withdrawalAmount": "Withdrawal Amount", @@ -186,12 +181,14 @@ "governanceActions": { "info_action": "Info Action", "hard_fork_initiation_action": "Hard Fork Initiation", - "parameter_change_action": "Parameter Change", + "parameter_change_action": "Protocol Parameter Update", "treasury_withdrawals_action": "Treasury Withdrawals", "no_confidence": "No Confidence", "update_committee": "Update Committee", "new_constitution": "New Constitution" }, + "epoch": "epoch", + "epochs": "epochs", "voterType": { "constitutionalCommittee": "Constitutional Committee", "spo": "SPO", @@ -207,6 +204,188 @@ "ScriptHash": "Scripthash" } }, + "ProposalProcedure": { + "dRepId": "DRep ID", + "txDetails": { + "deposit": "Deposit", + "rewardAccount": "Reward account", + "title": "Transaction Details", + "txType": "Transaction Type" + }, + "procedure": { + "anchor": { + "hash": "Anchor Hash", + "url": "Anchor URL" + }, + "title": "Procedure", + "dRepId": "DRep ID" + }, + "governanceAction": { + "actionId": { + "title": "Action ID", + "index": "Index", + "txId": "TX ID" + }, + "hardForkInitiation": { + "title": "Hard Fork Initiation", + "protocolVersion": { + "major": "Protocol Version Major", + "minor": "Protocol Version Minor", + "patch": "Protocol Version Patch" + } + }, + "newConstitutionAction": { + "title": "New Constitution Action", + "constitution": { + "title": "Constitution Details", + "anchor": { + "dataHash": "Anchor Data Hash", + "url": "Constitution Anchor URL" + }, + "scriptHash": "Constitution Script Hash" + } + }, + "infoAction": { + "title": "Info Action" + }, + "noConfidenceAction": { + "title": "No Confidence" + }, + "protocolParamUpdate": { + "title": "Protocol Parameter Update", + "memory": "Memory", + "step": "Step", + "networkGroup": { + "title": "Network group", + "maxBBSize": "Max BB Size", + "maxTxSize": "Max Tx Size", + "maxBHSize": "Max BH Size", + "maxValSize": "Max Val Size", + "maxTxExUnits": "Max TX Ex Units", + "maxBlockExUnits": "Max Blk Ex Units", + "maxCollateralInputs": "Max Coll Inputs", + "tooltip": { + "maxBBSize": "Max block body size", + "maxTxSize": "Max transaction size", + "maxBHSize": "Max block header size", + "maxValSize": "Max size of a serialized asset value", + "maxTxExUnits": "Max script execution units in a single transaction", + "maxBlockExUnits": "Max script execution units in a single block", + "maxCollateralInputs": "Max number of collateral inputs" + } + }, + "economicGroup": { + "title": "Economic group", + "minFeeA": "Min Fee A", + "minFeeB": "Min Fee B", + "keyDeposit": "Key Deposit", + "poolDeposit": "Pool Deposit", + "rho": "Rho", + "tau": "Tau", + "minPoolCost": "Min Pool Cost", + "coinsPerUTxOByte": "Coins/UTxO Byte", + "prices": "Price", + "tooltip": { + "minFeeA": "Min fee coefficient", + "minFeeB": "Min fee constant", + "keyDeposit": "Delegation key Lovelace deposit", + "poolDeposit": "Pool registration Lovelace deposit", + "rho": "Monetary expansion", + "tau": "Treasury expansion", + "minPoolCost": "Min fixed rewards cut for pools", + "coinsPerUTxOByte": "Min Lovelace deposit per byte of serialized UTxO", + "prices": "Prices of Plutus execution units" + } + }, + "technicalGroup": { + "title": "Technical group", + "a0": "A0", + "eMax": "EMax", + "nOpt": "NOpt", + "costModels": "Cost Models", + "PlutusV1": "PlutusV1", + "PlutusV2": "PlutusV2", + "collateralPercentage": "Coll Percentage", + "tooltip": { + "a0": "Pool pledge influence", + "eMax": "Pool retirement maximum epoch", + "nOpt": "Desired number of pools", + "costModels": "Plutus execution cost models", + "collateralPercentage": "Proportion of collateral needed for scripts" + } + }, + "governanceGroup": { + "title": "Governance group", + "govActionLifetime": "Gov Act Lifetime", + "govActionDeposit": "Gov Act Deposit", + "drepDeposit": "DRep Deposit", + "drepActivity": "DRep Activity", + "ccMinSize": "CC Min Size", + "ccMaxTermLength": "CC Max Term Length", + "dRepVotingThresholds": { + "title": "Governance Voting Thresholds", + "motionNoConfidence": "Motion No Conf", + "committeeNormal": "Comm Normal", + "committeeNoConfidence": "Comm No Conf", + "updateConstitution": "Update Const", + "hardForkInitiation": "Hard Fork Init", + "ppNetworkGroup": "PP Network Grp", + "ppEconomicGroup": "PP Economic Grp", + "ppTechnicalGroup": "PP Technical Grp", + "ppGovernanceGroup": "PP Governance Grp", + "treasuryWithdrawal": "Treasury Withdraw" + }, + "tooltip": { + "govActionLifetime": "governance action maximum lifetime in epochs", + "govActionDeposit": "governance action deposit", + "drepDeposit": "DRep deposit amount", + "drepActivity": "DRep activity period in epochs", + "ccMinSize": "Min constitutional committee size", + "ccMaxTermLength": "Max term length (in epochs) for the constitutional committee members", + "dRepVotingThresholds": { + "title": "Governance voting thresholds", + "motionNoConfidence": "1. Motion of no-confidence", + "committeeNormal": "2a. New committee/threshold (normal state)", + "committeeNoConfidence": "2b. New committee/threshold (state of no-confidence)", + "updateConstitution": "3. Update to the Constitution or proposal policy", + "hardForkInitiation": "4. Hard-fork initiation", + "ppNetworkGroup": "5a. Protocol parameter changes, network group", + "ppEconomicGroup": "5b. Protocol parameter changes, economic group", + "ppTechnicalGroup": "5c. Protocol parameter changes, technical group", + "ppGovernanceGroup": "5d. Protocol parameter changes, governance group", + "treasuryWithdrawal": "6. Treasury withdrawal" + } + } + } + }, + "treasuryWithdrawals": { + "title": "Treasury Withdrawals", + "withdrawals": { + "lovelace": "Withdrawal Amount", + "rewardAccount": "Withdrawal Reward Account" + } + }, + "updateCommitteeAction": { + "title": "Update Committee Action", + "membersToBeAdded": { + "title": "Members To Be Added", + "coldCredential": { + "hash": "Cold Credential Hash", + "epoch": "Epoch" + } + }, + "membersToBeRemoved": { + "title": "Members To Be Removed", + "hash": "Hash" + }, + "newQuorumThreshold": { + "title": "New Quorum Threshold", + "denominator": "Denominator", + "numerator": "Numerator" + } + } + } + }, "authorizeDapp": { "title": "Allow this site to", "seeNetwork": "See which network the wallet is connected to", From b00c039987d346ff122787eb43953193ecae8ce9 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Thu, 22 Feb 2024 15:53:14 +0200 Subject: [PATCH 06/10] fix(extension): resolve pr comments --- .../src/stores/slices/activity-detail-slice.ts | 6 +++--- .../activity/helpers/common-tx-transformer.ts | 17 +++++++++++------ 2 files changed, 14 insertions(+), 9 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 9930766a4e..e304ee0e71 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 @@ -222,12 +222,12 @@ const buildGetActivityDetail = includedUtcTime: blocks?.utcTime, // TODO: store the raw data here and transform it later so we always have the raw data when needed.(LW-9570) votingProcedures: votingProceduresTransformer(tx.body.votingProcedures), - proposalProcedures: governanceProposalsTransformer( + proposalProcedures: governanceProposalsTransformer({ cardanoCoin, coinPrices, fiatCurrency, - tx.body.proposalProcedures - ), + proposalProcedures: tx.body.proposalProcedures + }), certificates: certificateTransformer(cardanoCoin, coinPrices, fiatCurrency, tx.body.certificates) }; 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 309898fb39..70e0968cc5 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 @@ -342,12 +342,17 @@ export const votingProceduresTransformer = ( return votingProcedureDetails; }; -export const governanceProposalsTransformer = ( - cardanoCoin: Wallet.CoinId, - coinPrices: PriceResult, - fiatCurrency: CurrencyInfo, - proposalProcedures?: Wallet.Cardano.ProposalProcedure[] -): TxDetails[] => +export const governanceProposalsTransformer = ({ + cardanoCoin, + coinPrices, + fiatCurrency, + proposalProcedures +}: { + cardanoCoin: Wallet.CoinId; + coinPrices: PriceResult; + fiatCurrency: CurrencyInfo; + proposalProcedures?: Wallet.Cardano.ProposalProcedure[]; +}): TxDetails[] => proposalProcedures?.map((procedure) => { const transformedProposal: TxDetails = [ { title: 'type', details: [procedure.governanceAction.__typename] }, From fe91c59d426cef55d689991743bcc740146f8159 Mon Sep 17 00:00:00 2001 From: vetalcore Date: Mon, 26 Feb 2024 00:14:17 +0200 Subject: [PATCH 07/10] fix(extension): resolve sanchonet pr comments --- .../features/dapp/components/DappError.tsx | 10 +-- .../collateral/CreateCollateral.tsx | 5 +- .../ConfirmDRepRegistrationContainer.tsx | 9 +- .../ConfirmDRepRetirementContainer.tsx | 50 +++++------ ...rmStakeRegistrationDelegationContainer.tsx | 7 +- ...akeVoteRegistrationDelegationContainer.tsx | 7 +- .../ConfirmTransaction.tsx | 15 ++-- .../ConfirmTransactionContent.tsx | 60 ++++++------- ...irmVoteRegistrationDelegationContainer.tsx | 7 +- .../ProposalProceduresContainer.tsx | 84 +++++++------------ .../__tests__/utils.test.tsx | 17 ---- .../components/confirm-transaction/hooks.ts | 4 +- .../HardForkInitiationActionContainer.tsx | 5 +- .../NewConstitutionActionContainer.tsx | 5 +- .../NoConfidenceActionContainer.tsx | 5 +- .../ParameterChangeActionContainer.tsx | 6 +- .../TreasuryWithdrawalsActionContainer.tsx | 10 ++- .../UpdateCommitteeActionContainer.tsx | 5 +- .../components/confirm-transaction/utils.ts | 21 +---- .../src/lib/translations/en.json | 9 ++ .../src/routes/DappConnectorView.tsx | 5 +- .../activity/helpers/common-tx-transformer.ts | 7 +- .../AssetDetailsDrawer/AssetDetails.tsx | 5 +- .../send-transaction/components/Form/util.ts | 5 +- .../Collateral/send/CollateralStepSend.tsx | 5 +- .../StakePoolConfirmation.tsx | 10 ++- .../components/CatalystRegistrationFlow.tsx | 12 ++- .../TransactionInputOutput.module.scss | 10 +++ .../ActivityDetail/TxDetailsList.tsx | 22 +++-- .../ParameterChangeAction/EconomicGroup.tsx | 9 +- .../ParameterChangeAction.tsx | 9 +- .../Drawer/confirmation/AmountInfo.tsx | 8 +- 32 files changed, 228 insertions(+), 220 deletions(-) diff --git a/apps/browser-extension-wallet/src/features/dapp/components/DappError.tsx b/apps/browser-extension-wallet/src/features/dapp/components/DappError.tsx index 9c5c85e8d6..042c74a5ab 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/DappError.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/DappError.tsx @@ -1,4 +1,4 @@ -import React, { ReactNode, useCallback, useEffect } from 'react'; +import React, { ReactNode, useCallback } from 'react'; import { Image } from 'antd'; import { useTranslation } from 'react-i18next'; import Empty from '../../../assets/icons/empty.svg'; @@ -10,7 +10,6 @@ type DappErrorProps = { description: ReactNode; closeButtonLabel?: string; onCloseClick?: () => void; - onMount?: () => void; containerTestId: string; imageTestId: string; titleTestId: string; @@ -22,7 +21,6 @@ export const DappError = ({ description, closeButtonLabel, onCloseClick, - onMount, containerTestId, imageTestId, titleTestId, @@ -32,14 +30,8 @@ export const DappError = ({ const { t } = useTranslation(); const handleClose = useCallback(() => { onCloseClick?.(); - window.close(); }, [onCloseClick]); - useEffect(() => { - onMount?.(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - return (
diff --git a/apps/browser-extension-wallet/src/features/dapp/components/collateral/CreateCollateral.tsx b/apps/browser-extension-wallet/src/features/dapp/components/collateral/CreateCollateral.tsx index c0b9261e77..e436a77772 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/collateral/CreateCollateral.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/collateral/CreateCollateral.tsx @@ -135,7 +135,10 @@ export const CreateCollateral = ({ })}
{renderAmountInfo( - `${Wallet.util.lovelacesToAdaString(collateralTx.fee.toString())} ${cardanoCoin.symbol}`, + Wallet.util.getFormattedAmount({ + amount: collateralTx.fee.toString(), + cardanoCoin + }), `${Wallet.util.convertAdaToFiat({ ada: Wallet.util.lovelacesToAdaString(collateralTx.fee.toString()), fiat: priceResult?.cardano?.price || 0 diff --git a/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmDRepRegistrationContainer.tsx b/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmDRepRegistrationContainer.tsx index e9f317129d..d5e6a09528 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmDRepRegistrationContainer.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmDRepRegistrationContainer.tsx @@ -21,10 +21,13 @@ export const ConfirmDRepRegistrationContainer = ({ signTxData, errorMessage }: P const certificate = certificateInspectorFactory( CertificateType.RegisterDelegateRepresentative )(signTxData.tx); - const depositPaidWithCardanoSymbol = `${Wallet.util.lovelacesToAdaString(certificate.deposit.toString())} ${ - cardanoCoin.symbol - }`; + const depositPaidWithCardanoSymbol = Wallet.util.getFormattedAmount({ + amount: certificate.deposit.toString(), + cardanoCoin + }); + + // TODO: might be changed in scope of https://input-output.atlassian.net/browse/LW-9034 return ( void; } -export const disallowSignTx = (): void => { - exposeApi>( - { - api$: of({ - async allowSignTx(): Promise { - return Promise.reject(new ApiError(APIErrorCode.InvalidRequest, 'DRep ID mismatch')); - } - }), - baseChannel: DAPP_CHANNELS.userPrompt, - properties: { allowSignTx: RemoteApiPropertyType.MethodReturningPromise } - }, - { logger: console, runtime } - ); -}; - export const ConfirmDRepRetirementContainer = ({ signTxData, onError, errorMessage }: Props): React.ReactElement => { const { t } = useTranslation(); const { @@ -44,11 +23,25 @@ export const ConfirmDRepRetirementContainer = ({ signTxData, onError, errorMessa const certificate = certificateInspectorFactory( Wallet.Cardano.CertificateType.UnregisterDelegateRepresentative )(signTxData.tx); - const depositPaidWithCardanoSymbol = `${Wallet.util.lovelacesToAdaString(certificate.deposit.toString())} ${ - cardanoCoin.symbol - }`; + const depositPaidWithCardanoSymbol = Wallet.util.getFormattedAmount({ + amount: certificate.deposit.toString(), + cardanoCoin + }); + const { loading: loadingOwnPubDRepKeyHash, ownPubDRepKeyHash } = useGetOwnPubDRepKeyHash(); const isNotOwnDRepKey = certificate.dRepCredential.hash !== ownPubDRepKeyHash; + const disallow = useDisallowSignTx(); + + useEffect(() => { + if (isNotOwnDRepKey) { + disallow({ error: 'DRep ID mismatch' }); + onError(); + } + }, [disallow, isNotOwnDRepKey, onError]); + + const onCloseClick = useCallback(() => { + window.close(); + }, []); if (loadingOwnPubDRepKeyHash) { return ; @@ -59,11 +52,8 @@ export const ConfirmDRepRetirementContainer = ({ signTxData, onError, errorMessa { - disallowSignTx(); - onError(); - }} containerTestId="drep-id-mismatch-container" + onCloseClick={onCloseClick} imageTestId="drep-id-mismatch-image" titleTestId="drep-id-mismatch-heading" descriptionTestId="drep-id-mismatch-description" diff --git a/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmStakeRegistrationDelegationContainer.tsx b/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmStakeRegistrationDelegationContainer.tsx index 0dd467f1e0..38718a6d1d 100644 --- a/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmStakeRegistrationDelegationContainer.tsx +++ b/apps/browser-extension-wallet/src/features/dapp/components/confirm-transaction/ConfirmStakeRegistrationDelegationContainer.tsx @@ -25,9 +25,10 @@ export const ConfirmStakeRegistrationDelegationContainer = ({ const certificate = certificateInspectorFactory( CertificateType.StakeRegistrationDelegation )(signTxData.tx); - const depositPaidWithCardanoSymbol = `${Wallet.util.lovelacesToAdaString(certificate.deposit.toString())} ${ - cardanoCoin.symbol - }`; + const depositPaidWithCardanoSymbol = Wallet.util.getFormattedAmount({ + amount: certificate.deposit.toString(), + cardanoCoin + }); return ( { const disallowSignTx = useDisallowSignTx(); const { isConfirmingTx, signWithHardwareWallet } = useSignWithHardwareWallet(); const txType = signTxData ? getTxType(signTxData.tx) : undefined; - const title = txType ? t(getTitleKey(txType)) : ''; const onConfirm = () => { analytics.sendEventToPostHog(PostHogAction.SendTransactionSummaryConfirmClick, { [TX_CREATION_TYPE_KEY]: TxCreationType.External @@ -62,16 +61,20 @@ export const ConfirmTransaction = (): React.ReactElement => { useOnBeforeUnload(disallowSignTx); + const onError = useCallback(() => { + setConfirmTransactionError(true); + }, []); + return ( setConfirmTransactionError(true)} + onError={onError} errorMessage={getSignTxDataError} /> {!confirmTransactionError && ( @@ -90,7 +93,7 @@ export const ConfirmTransaction = (): React.ReactElement => {