Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { ConfirmDRepRegistration } from '@lace/core';
import { SignTxData } from './types';
import { dRepRegistrationInspector, drepIDasBech32FromHash } from './utils';
import { certificateInspectorFactory, drepIDasBech32FromHash } from './utils';
import { Wallet } from '@lace/cardano';
import { useWalletStore } from '@src/stores';

const { CertificateType } = Wallet.Cardano;

interface Props {
signTxData: SignTxData;
errorMessage?: string;
}

export const ConfirmDRepRegistrationContainer = ({ signTxData, errorMessage }: Props): React.ReactElement => {
const { t } = useTranslation();
const certificate = dRepRegistrationInspector(signTxData.tx);
const {
walletUI: { cardanoCoin }
} = useWalletStore();

const certificate = certificateInspectorFactory<Wallet.Cardano.RegisterDelegateRepresentativeCertificate>(
CertificateType.RegisterDelegateRepresentative
)(signTxData.tx);
const depositPaidWithCardanoSymbol = `${Wallet.util.lovelacesToAdaString(certificate.deposit.toString())} ${
cardanoCoin.symbol
}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,27 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { ConfirmDRepRetirement } from '@lace/core';
import { SignTxData } from './types';
import { dRepRetirementInspector, drepIDasBech32FromHash, getOwnRetirementMessageKey } from './utils';
import { certificateInspectorFactory, drepIDasBech32FromHash, getOwnRetirementMessageKey } from './utils';
import { Wallet } from '@lace/cardano';
import { useWalletStore } from '@src/stores';
import { useIsOwnPubDRepKey } from './hooks';

const { CertificateType } = Wallet.Cardano;

interface Props {
signTxData: SignTxData;
errorMessage?: string;
}

export const ConfirmDRepRetirementContainer = ({ signTxData, errorMessage }: Props): React.ReactElement => {
const { t } = useTranslation();
const certificate = dRepRetirementInspector(signTxData.tx);
const {
walletUI: { cardanoCoin },
inMemoryWallet
} = useWalletStore();

const certificate = certificateInspectorFactory<Wallet.Cardano.UnRegisterDelegateRepresentativeCertificate>(
CertificateType.UnregisterDelegateRepresentative
)(signTxData.tx);
const depositPaidWithCardanoSymbol = `${Wallet.util.lovelacesToAdaString(certificate.deposit.toString())} ${
cardanoCoin.symbol
}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DappTransactionContainer } from './DappTransactionContainer';
import { TxType } from './utils';
import { SignTxData } from './types';
import { ConfirmDRepRetirementContainer } from './ConfirmDRepRetirementContainer';
import { ConfirmVoteDelegationContainer } from './ConfirmVoteDelegationContainer';
import { VotingProceduresContainer } from './VotingProceduresContainer';

interface Props {
Expand All @@ -23,6 +24,9 @@ export const ConfirmTransactionContent = ({ txType, signTxData, errorMessage }:
if (txType === TxType.DRepRetirement) {
return <ConfirmDRepRetirementContainer signTxData={signTxData} errorMessage={errorMessage} />;
}
if (txType === TxType.VoteDelegation) {
return <ConfirmVoteDelegationContainer signTxData={signTxData} errorMessage={errorMessage} />;
}
if (txType === TxType.VotingProcedures) {
return <VotingProceduresContainer signTxData={signTxData} errorMessage={errorMessage} />;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ConfirmVoteDelegation } from '@lace/core';
import { SignTxData } from './types';
import { certificateInspectorFactory } from './utils';
import { Wallet } from '@lace/cardano';

const { CertificateType } = Wallet.Cardano;

interface Props {
signTxData: SignTxData;
errorMessage?: string;
}

export const ConfirmVoteDelegationContainer = ({ signTxData, errorMessage }: Props): React.ReactElement => {
const { t } = useTranslation();
const certificate = certificateInspectorFactory<Wallet.Cardano.VoteDelegationCertificate>(
CertificateType.VoteDelegation
)(signTxData.tx);
const dRep = certificate.dRep;

return (
<ConfirmVoteDelegation
dappInfo={signTxData.dappInfo}
metadata={{
alwaysAbstain: Wallet.Cardano.isDRepAlwaysAbstain(dRep),
alwaysNoConfidence: Wallet.Cardano.isDRepAlwaysNoConfidence(dRep),
...(Wallet.Cardano.isDRepCredential(dRep) ? { drepId: dRep.hash } : {})
}}
translations={{
metadata: t('core.voteDelegation.metadata'),
option: t('core.voteDelegation.option'),
labels: {
drepId: t('core.voteDelegation.drepId'),
alwaysAbstain: t('core.voteDelegation.alwaysAbstain'),
alwaysNoConfidence: t('core.voteDelegation.alwaysNoConfidence')
}
}}
errorMessage={errorMessage}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { runtime } from 'webextension-polyfill';
import { of } from 'rxjs';
import { sectionTitle, DAPP_VIEWS } from '../../config';

const { CertificateType } = Wallet.Cardano;

const DAPP_TOAST_DURATION = 50;

export enum TxType {
Expand All @@ -16,6 +18,7 @@ export enum TxType {
Burn = 'Burn',
DRepRegistration = 'DRepRegistration',
DRepRetirement = 'DRepRetirement',
VoteDelegation = 'VoteDelegation',
VotingProcedures = 'VotingProcedures'
}

Expand All @@ -28,6 +31,10 @@ export const getTitleKey = (txType: TxType): string => {
return 'core.drepRetirement.title';
}

if (txType === TxType.VoteDelegation) {
return 'core.voteDelegation.title';
}

if (txType === TxType.VotingProcedures) {
return 'core.votingProcedures.title';
}
Expand Down Expand Up @@ -79,25 +86,10 @@ export const getTransactionAssetsId = (outputs: CardanoTxOut[]): Wallet.Cardano.
return assetIds;
};

const isDRepRegistrationCertificate = (type: Wallet.Cardano.CertificateType) =>
type === Wallet.Cardano.CertificateType.RegisterDelegateRepresentative;

const isDRepRetirementCertificate = (type: Wallet.Cardano.CertificateType) =>
type === Wallet.Cardano.CertificateType.UnregisterDelegateRepresentative;

export const dRepRegistrationInspector = (
tx: Wallet.Cardano.Tx
): Wallet.Cardano.RegisterDelegateRepresentativeCertificate | undefined =>
tx?.body?.certificates?.find(({ __typename }) => isDRepRegistrationCertificate(__typename)) as
| Wallet.Cardano.RegisterDelegateRepresentativeCertificate
| undefined;

export const dRepRetirementInspector = (
tx: Wallet.Cardano.Tx
): Wallet.Cardano.UnRegisterDelegateRepresentativeCertificate | undefined =>
tx?.body?.certificates?.find(({ __typename }) => isDRepRetirementCertificate(__typename)) as
| Wallet.Cardano.UnRegisterDelegateRepresentativeCertificate
| undefined;
export const certificateInspectorFactory =
<T extends Wallet.Cardano.Certificate>(type: Wallet.Cardano.CertificateType) =>
(tx: Wallet.Cardano.Tx): T | undefined =>
tx?.body?.certificates?.find((certificate) => certificate.__typename === type) as T | undefined;

export const votingProceduresInspector = (tx: Wallet.Cardano.Tx): Wallet.Cardano.VotingProcedures | undefined =>
tx?.body?.votingProcedures;
Expand All @@ -106,12 +98,13 @@ export const getTxType = (tx: Wallet.Cardano.Tx): TxType => {
const inspector = createTxInspector({
minted: assetsMintedInspector,
burned: assetsBurnedInspector,
dRepRegistration: dRepRegistrationInspector,
dRepRetirement: dRepRetirementInspector,
votingProcedures: votingProceduresInspector
votingProcedures: votingProceduresInspector,
dRepRegistration: certificateInspectorFactory(CertificateType.RegisterDelegateRepresentative),
dRepRetirement: certificateInspectorFactory(CertificateType.UnregisterDelegateRepresentative),
voteDelegation: certificateInspectorFactory(CertificateType.VoteDelegation)
});

const { minted, burned, dRepRegistration, dRepRetirement, votingProcedures } = inspector(
const { minted, burned, dRepRegistration, dRepRetirement, voteDelegation, votingProcedures } = inspector(
tx as Wallet.Cardano.HydratedTx
);
const isMintTransaction = minted.length > 0;
Expand All @@ -137,6 +130,10 @@ export const getTxType = (tx: Wallet.Cardano.Tx): TxType => {
return TxType.DRepRetirement;
}

if (voteDelegation) {
return TxType.VoteDelegation;
}

return TxType.Send;
};

Expand Down
8 changes: 8 additions & 0 deletions apps/browser-extension-wallet/src/lib/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,14 @@
"isOwnRetirement": "This is your DRep retirement.",
"isNotOwnRetirement": "The presented DRepID does not match your wallet's DRepID."
},
"voteDelegation": {
"title": "Confirm vote delegation",
"metadata": "Metadata",
"drepId": "Drep ID",
"alwaysAbstain": "Abstain",
"alwaysNoConfidence": "No Confidence",
"option": "Yes"
},
"destinationAddressInput": {
"recipientAddress": "Recipient's address or $handle"
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ export * from '@ui/components/MnemonicWordsAutoComplete';
export * from '@ui/components/AddressCard';
export * from '@ui/components/ConfirmDRepRegistration';
export * from '@ui/components/ConfirmDRepRetirement';
export * from '@ui/components/ConfirmVoteDelegation';
export * from '@ui/components/VotingProcedures';
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import type { Meta, StoryObj } from '@storybook/react';

import { ConfirmVoteDelegation } from './ConfirmVoteDelegation';
import { ComponentProps } from 'react';

const meta: Meta<typeof ConfirmVoteDelegation> = {
title: 'ConfirmVoteDelegation',
component: ConfirmVoteDelegation,
parameters: {
layout: 'centered'
}
};

export default meta;
type Story = StoryObj<typeof ConfirmVoteDelegation>;

const data: ComponentProps<typeof ConfirmVoteDelegation> = {
dappInfo: {
logo: 'https://cdn.mint.handle.me/favicon.png',
name: 'Mint',
url: 'https://preprod.mint.handle.me'
},
translations: {
labels: {
drepId: 'Drep ID',
alwaysAbstain: 'Abstain',
alwaysNoConfidence: 'No Confidence'
},
option: 'Yes',
metadata: 'Metadata'
},
metadata: {
drepId: 'drep1ruvgm0auzdplfn7g2jf3kcnpnw5mlhwxaxj8crag8h6t2ye9y9g',
alwaysAbstain: false,
alwaysNoConfidence: false
}
};

export const Overview: Story = {
args: {
...data
}
};
export const WithError: Story = {
args: {
...data,
errorMessage: 'Something went wrong'
}
};

export const WithAbstain: Story = {
args: {
...data,
metadata: {
alwaysAbstain: true,
alwaysNoConfidence: false
}
}
};

export const WithNoConfidence: Story = {
args: {
...data,
metadata: {
alwaysAbstain: false,
alwaysNoConfidence: true
}
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React from 'react';
import { Box, Cell, Grid, TransactionSummary, Flex } from '@lace/ui';
import { DappInfo, DappInfoProps } from '../DappInfo';
import { ErrorPane } from '@lace/common';

interface Props {
dappInfo: Omit<DappInfoProps, 'className'>;
errorMessage?: string;
translations: {
labels: {
drepId: string;
alwaysAbstain: string;
alwaysNoConfidence: string;
};
option: string;
metadata: string;
};
metadata: {
drepId?: string;
alwaysAbstain: boolean;
alwaysNoConfidence: boolean;
};
}

export const ConfirmVoteDelegation = ({ dappInfo, errorMessage, translations, metadata }: Props): JSX.Element => (
<Flex h="$fill" flexDirection="column">
<Box mb={'$28'} mt={'$32'}>
<DappInfo {...dappInfo} />
</Box>
{errorMessage && (
<Box my={'$16'}>
<ErrorPane error={errorMessage} />
</Box>
)}
<Grid columns="$1" gutters="$20">
<Cell>
<TransactionSummary.Metadata label={translations.metadata} text="" />
</Cell>
{metadata.drepId && (
<Cell>
<TransactionSummary.Address label={translations.labels.drepId} address={metadata.drepId} />
</Cell>
)}
{metadata.alwaysAbstain && (
<Cell>
<TransactionSummary.Address label={translations.labels.alwaysAbstain} address={translations.option} />
</Cell>
)}
{metadata.alwaysNoConfidence && (
<Cell>
<TransactionSummary.Address label={translations.labels.alwaysNoConfidence} address={translations.option} />
</Cell>
)}
</Grid>
</Flex>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ConfirmVoteDelegation } from './ConfirmVoteDelegation';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { Fragment } from 'react';
import { Box, Cell, Grid, Flex, Metadata, MetadataLink, Text, Divider, sx } from '@lace/ui';
import { DappInfo, DappInfoProps } from '../DappInfo';
import { ErrorPane, Ellipsis } from '@lace/common';
import { ErrorPane } from '@lace/common';

type VotingProcedure = {
voter: {
Expand Down
Loading