From daf08303aa5b7d105e5a8004bf779c79c8628f16 Mon Sep 17 00:00:00 2001 From: jorbuedo Date: Thu, 24 Oct 2024 15:25:37 +0200 Subject: [PATCH] refactor certification types --- .../ReviewTx/common/hooks/useFormattedTx.tsx | 15 +-- .../features/ReviewTx/common/operations.tsx | 20 ++-- .../src/features/ReviewTx/common/types.ts | 96 ++++++++----------- 3 files changed, 57 insertions(+), 74 deletions(-) diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx index 419c218b1c..133c96b4e6 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/hooks/useFormattedTx.tsx @@ -1,4 +1,3 @@ -// import {CredKind} from '@emurgo/csl-mobile-bridge' import {CredKind} from '@emurgo/cross-csl-core' import {isNonNullable} from '@yoroi/common' import {infoExtractName} from '@yoroi/portfolio' @@ -14,8 +13,7 @@ import {asQuantity} from '../../../../yoroi-wallets/utils/utils' import {usePortfolioTokenInfos} from '../../../Portfolio/common/hooks/usePortfolioTokenInfos' import {useSelectedWallet} from '../../../WalletManager/common/hooks/useSelectedWallet' import { - Certificates, - FormattedCertificates, + FormattedCertificate, FormattedFee, FormattedInputs, FormattedOutputs, @@ -52,7 +50,7 @@ export const useFormattedTx = (data: TransactionBody): FormattedTx => { const formattedInputs = useFormattedInputs(wallet, inputs, portfolioTokenInfos) const formattedOutputs = useFormattedOutputs(wallet, outputs, portfolioTokenInfos) const formattedFee = formatFee(wallet, data) - const formattedCertificates = formatCertificates(data.certs as Certificates) + const formattedCertificates = formatCertificates(data.certs) return { inputs: formattedInputs, @@ -223,8 +221,13 @@ export const formatFee = (wallet: YoroiWallet, data: TransactionBody): Formatted } } -const formatCertificates = (certificates: Certificates) => { - return certificates.flatMap(Object.entries) as FormattedCertificates +const formatCertificates = (certificates: TransactionBody['certs']) => { + return ( + certificates?.map((cert) => { + const [type, certificate] = Object.entries(cert)[0] + return {type, certificate} as unknown as FormattedCertificate + }) ?? null + ) } const deriveAddress = async (address: string, chainId: number) => { diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx b/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx index e36e76288d..3c37ed4762 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx +++ b/apps/wallet-mobile/src/features/ReviewTx/common/operations.tsx @@ -12,7 +12,7 @@ import {asQuantity} from '../../../yoroi-wallets/utils/utils' import {useSelectedNetwork} from '../../WalletManager/common/hooks/useSelectedNetwork' import {useSelectedWallet} from '../../WalletManager/common/hooks/useSelectedWallet' import {useStrings} from './hooks/useStrings' -import {Certificate, CertificateTypes, FormattedCertificates} from './types' +import {CertificateType, FormattedTx} from './types' export const StakeRegistrationOperation = () => { const {styles} = useStyles() @@ -119,25 +119,25 @@ export const VoteDelegationOperation = ({drepID}: {drepID: string}) => { ) } -export const useOperations = (certificates: FormattedCertificates | null) => { +export const useOperations = (certificates: FormattedTx['certificates']) => { if (certificates === null) return [] - return certificates.reduce((acc, [certificateKind, CertificateData], index) => { - switch (certificateKind) { - case CertificateTypes.StakeRegistration: + return certificates.reduce((acc, certificate, index) => { + switch (certificate.type) { + case CertificateType.StakeRegistration: return [...acc, ] - case CertificateTypes.StakeDeregistration: + case CertificateType.StakeDeregistration: return [...acc, ] - case CertificateTypes.StakeDelegation: { - const poolKeyHash = (CertificateData as Certificate[CertificateTypes.StakeDelegation]).pool_keyhash ?? null + case CertificateType.StakeDelegation: { + const poolKeyHash = certificate.value.pool_keyhash ?? null if (poolKeyHash == null) return acc return [...acc, ] } - case CertificateTypes.VoteDelegation: { - const drep = (CertificateData as Certificate[CertificateTypes.VoteDelegation]).drep + case CertificateType.VoteDelegation: { + const drep = certificate.value.drep if (drep === 'AlwaysAbstain') return [...acc, ] if (drep === 'AlwaysNoConfidence') return [...acc, ] diff --git a/apps/wallet-mobile/src/features/ReviewTx/common/types.ts b/apps/wallet-mobile/src/features/ReviewTx/common/types.ts index 95d7a4ce05..fa11a20cf3 100644 --- a/apps/wallet-mobile/src/features/ReviewTx/common/types.ts +++ b/apps/wallet-mobile/src/features/ReviewTx/common/types.ts @@ -1,24 +1,8 @@ import { - CommitteeColdResignJSON, - CommitteeHotAuthJSON, - DRepDeregistrationJSON, - DRepRegistrationJSON, - DRepUpdateJSON, - GenesisKeyDelegationJSON, - MoveInstantaneousRewardsCertJSON, - PoolRegistrationJSON, - PoolRetirementJSON, - StakeAndVoteDelegationJSON, - StakeDelegationJSON, - StakeDeregistrationJSON, - StakeRegistrationAndDelegationJSON, - StakeRegistrationJSON, - StakeVoteRegistrationAndDelegationJSON, + CertificateJSON, TransactionBodyJSON, TransactionInputsJSON, TransactionOutputsJSON, - VoteDelegationJSON, - VoteRegistrationAndDelegationJSON, } from '@emurgo/cardano-serialization-lib-nodejs' import {CredKind} from '@emurgo/cross-csl-core' import {Balance, Portfolio} from '@yoroi/types' @@ -73,7 +57,7 @@ export type FormattedTx = { inputs: FormattedInputs outputs: FormattedOutputs fee: FormattedFee - certificates: FormattedCertificates | null + certificates: FormattedCertificate[] | null } export type FormattedMetadata = { @@ -81,45 +65,41 @@ export type FormattedMetadata = { metadata: {msg: Array} | null } -export type Certificates = Array -export type FormattedCertificates = Array<[CertificateTypes, Certificate[CertificateTypes]]> +type AssertEqual = T extends Expected + ? Expected extends T + ? true + : ['Type', Expected, 'is not equal to', T] + : ['Type', T, 'is not equal to', Expected] -export type Certificate = { - StakeRegistration: StakeRegistrationJSON - StakeDeregistration: StakeDeregistrationJSON - StakeDelegation: StakeDelegationJSON - PoolRegistration: PoolRegistrationJSON - PoolRetirement: PoolRetirementJSON - GenesisKeyDelegation: GenesisKeyDelegationJSON - MoveInstantaneousRewardsCert: MoveInstantaneousRewardsCertJSON - CommitteeHotAuth: CommitteeHotAuthJSON - CommitteeColdResign: CommitteeColdResignJSON - DRepDeregistration: DRepDeregistrationJSON - DRepRegistration: DRepRegistrationJSON - DRepUpdate: DRepUpdateJSON - StakeAndVoteDelegation: StakeAndVoteDelegationJSON - StakeRegistrationAndDelegation: StakeRegistrationAndDelegationJSON - StakeVoteRegistrationAndDelegation: StakeVoteRegistrationAndDelegationJSON - VoteDelegation: VoteDelegationJSON - VoteRegistrationAndDelegation: VoteRegistrationAndDelegationJSON -} +type UnionToIntersection = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never -export enum CertificateTypes { - StakeRegistration = 'StakeRegistration', - StakeDeregistration = 'StakeDeregistration', - StakeDelegation = 'StakeDelegation', - PoolRegistration = 'PoolRegistration', - PoolRetirement = 'PoolRetirement', - GenesisKeyDelegation = 'GenesisKeyDelegation', - MoveInstantaneousRewardsCert = 'MoveInstantaneousRewardsCert', - CommitteeHotAuth = 'CommitteeHotAuth', - CommitteeColdResign = 'CommitteeColdResign', - DRepDeregistration = 'DRepDeregistration', - DRepRegistration = 'DRepRegistration', - DRepUpdate = 'DRepUpdate', - StakeAndVoteDelegation = 'StakeAndVoteDelegation', - StakeRegistrationAndDelegation = 'StakeRegistrationAndDelegation', - StakeVoteRegistrationAndDelegation = 'StakeVoteRegistrationAndDelegation', - VoteDelegation = 'VoteDelegation', - VoteRegistrationAndDelegation = 'VoteRegistrationAndDelegation', -} +type Transformed = { + [K in keyof UnionToIntersection]: {type: K; value: UnionToIntersection[K]} +}[keyof UnionToIntersection] + +export type FormattedCertificate = Transformed + +export const CertificateType = { + StakeRegistration: 'StakeRegistration', + StakeDeregistration: 'StakeDeregistration', + StakeDelegation: 'StakeDelegation', + PoolRegistration: 'PoolRegistration', + PoolRetirement: 'PoolRetirement', + GenesisKeyDelegation: 'GenesisKeyDelegation', + MoveInstantaneousRewardsCert: 'MoveInstantaneousRewardsCert', + CommitteeHotAuth: 'CommitteeHotAuth', + CommitteeColdResign: 'CommitteeColdResign', + DRepDeregistration: 'DRepDeregistration', + DRepRegistration: 'DRepRegistration', + DRepUpdate: 'DRepUpdate', + StakeAndVoteDelegation: 'StakeAndVoteDelegation', + StakeRegistrationAndDelegation: 'StakeRegistrationAndDelegation', + StakeVoteRegistrationAndDelegation: 'StakeVoteRegistrationAndDelegation', + VoteDelegation: 'VoteDelegation', + VoteRegistrationAndDelegation: 'VoteRegistrationAndDelegation', +} as const + +export type CerificateType = (typeof CertificateType)[keyof typeof CertificateType] + +// Makes sure CertificateType lists all the certificates in CertificateJSON +export type AssertAllImplementedCertTypes = AssertEqual>