Skip to content

Commit

Permalink
Bridge Tx Confirmation V2 (#1812)
Browse files Browse the repository at this point in the history
  • Loading branch information
vutuanlinh2k2 authored Nov 2, 2023
1 parent 4b6435c commit 92250e9
Show file tree
Hide file tree
Showing 53 changed files with 1,445 additions and 1,594 deletions.
31 changes: 17 additions & 14 deletions apps/bridge-dapp/src/components/RelayerFeeDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { FeeDetails } from '@webb-tools/webb-ui-components/components/FeeDetails
import type { FeeItem } from '@webb-tools/webb-ui-components/components/FeeDetails/types';
import { Typography } from '@webb-tools/webb-ui-components/typography/Typography';
import { formatEther } from 'viem';
import getRelayerFeePercentage from '../utils/getRelayerFeePercentage';
import { useMemo } from 'react';
import { getRelayerFeePercentage } from '../utils';
import { type FC, useMemo } from 'react';
import { calculateTypedChainId } from '@webb-tools/sdk-core/typed-chain-id';

const RelayerFeeDetails = (props: {
interface RelayerFeeDetailsProps {
totalFeeWei: bigint | undefined;
totalFeeToken: string | undefined;
gasFeeInfo: bigint | undefined;
Expand All @@ -21,18 +21,20 @@ const RelayerFeeDetails = (props: {
srcChainCfg: ChainConfig | undefined;
fungibleCfg: CurrencyConfig | undefined;
activeRelayer: OptionalActiveRelayer;
}) => {
const {
activeRelayer,
fungibleCfg,
gasFeeInfo,
isFeeLoading,
relayerFeeInfo,
srcChainCfg,
totalFeeToken,
totalFeeWei,
} = props;
info?: string;
}

const RelayerFeeDetails: FC<RelayerFeeDetailsProps> = ({
activeRelayer,
fungibleCfg,
gasFeeInfo,
isFeeLoading,
relayerFeeInfo,
srcChainCfg,
totalFeeToken,
totalFeeWei,
info,
}) => {
const relayerFeePercentage = useMemo(() => {
if (!activeRelayer || !srcChainCfg) {
return;
Expand All @@ -48,6 +50,7 @@ const RelayerFeeDetails = (props: {

return (
<FeeDetails
info={info}
isTotalLoading={isFeeLoading}
totalFee={
typeof totalFeeWei === 'bigint'
Expand Down
1 change: 0 additions & 1 deletion apps/bridge-dapp/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export * from './EducationCard';
export * from './Header';
export * from './InteractiveFeedbackView';
export { default as RelayerFeeDetails } from './RelayerFeeDetails';
export { default as SlideAnimation } from './SlideAnimation';
export { default as SubmittedTxModal } from './SubmittedTxModal';
export { default as TxInfoItem } from './TxInfoItem';
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import {
Transaction,
TransactionState,
} from '@webb-tools/abstract-api-provider';
import { GasStationFill } from '@webb-tools/icons';
import { chainsConfig } from '@webb-tools/dapp-config/chains/chain-config';
import { useWebContext } from '@webb-tools/api-provider-environment/webb-context';
import { downloadString } from '@webb-tools/browser-utils';
import { getExplorerURI } from '@webb-tools/api-provider-environment/transaction/utils';
import { useBalancesFromNotes } from '@webb-tools/react-hooks/currency/useBalancesFromNotes';
import { handleStoreNote } from '../../utils';
import { useVAnchor } from '@webb-tools/react-hooks';
import { Note } from '@webb-tools/sdk-core';
import { isViemError } from '@webb-tools/web3-api-provider';
import { DepositConfirm } from '@webb-tools/webb-ui-components';
import { FeeDetails, DepositConfirm } from '@webb-tools/webb-ui-components';
import { forwardRef, useCallback, useMemo, useState } from 'react';
import { ContractFunctionRevertedError, formatUnits } from 'viem';
import { ContractFunctionRevertedError, formatUnits, formatEther } from 'viem';
import { useEnqueueSubmittedTx } from '../../hooks';
import useInProgressTxInfo from '../../hooks/useInProgressTxInfo';
import {
Expand All @@ -30,12 +33,12 @@ const DepositConfirmContainer = forwardRef<
(
{
amount,
destChain,
fungibleTokenId,
note,
onResetState,
onClose,
sourceChain,
sourceTypedChainId: sourceTypedChainIdProp,
destTypedChainId: destTypedChainIdProp,
wrappableTokenId,
},
ref
Expand All @@ -55,6 +58,8 @@ const DepositConfirmContainer = forwardRef<

const { api: txQueueApi } = txQueue;

const { balances } = useBalancesFromNotes();

const fungibleToken = useMemo(() => {
return new Currency(apiConfig.currencies[fungibleTokenId]);
}, [apiConfig.currencies, fungibleTokenId]);
Expand Down Expand Up @@ -83,14 +88,40 @@ const DepositConfirmContainer = forwardRef<
txStatusMessage,
} = useInProgressTxInfo(wrappingFlow, onResetState);

// Download for the deposit confirm
const downloadNote = useCallback((note: Note) => {
const noteStr = note.serialize();
downloadString(
JSON.stringify(noteStr),
noteStr.slice(-noteStr.length) + '.json'
);
}, []);
const sourceTypedChainId = useMemo(
() => sourceTypedChainIdProp ?? +note.note.sourceChainId,
[sourceTypedChainIdProp, note.note.sourceChainId]
);

const destTypedChainId = useMemo(
() => destTypedChainIdProp ?? +note.note.targetChainId,
[destTypedChainIdProp, note.note.targetChainId]
);

const newBalance = useMemo(() => {
const balance = balances?.[fungibleTokenId]?.[destTypedChainId];
if (!balance) return amount;
return Number(formatEther(balance)) + amount;
}, [balances, fungibleTokenId, destTypedChainId, note, amount]);

const poolAddress = useMemo(
() => apiConfig.anchors[fungibleTokenId][destTypedChainId],
[apiConfig, fungibleTokenId, destTypedChainId]
);

const poolExplorerUrl = useMemo(() => {
const blockExplorerUrl =
chainsConfig[destTypedChainId]?.blockExplorers?.default.url;

if (!blockExplorerUrl) return undefined;

return getExplorerURI(
blockExplorerUrl,
poolAddress,
'address',
'web3'
).toString();
}, [destTypedChainId, poolAddress]);

const handleExecuteDeposit = useCallback(
async () => {
Expand Down Expand Up @@ -185,8 +216,7 @@ const DepositConfirmContainer = forwardRef<

const transactionHash = await api.transact(...args);

downloadNote(note);
await addNoteToNoteManager(note);
await handleStoreNote(note, addNoteToNoteManager);

enqueueSubmittedTx(
transactionHash,
Expand Down Expand Up @@ -236,7 +266,7 @@ const DepositConfirmContainer = forwardRef<
}
},
// prettier-ignore
[activeAccount?.address, activeApi, activeChain, addNoteToNoteManager, api, apiConfig, downloadNote, enqueueSubmittedTx, fungibleTokenId, inProgressTxId.length, note, onResetState, removeNoteFromNoteManager, setInProgressTxId, setTotalStep, startNewTransaction, txQueueApi, wrappableToken]
[activeAccount?.address, activeApi, activeChain, addNoteToNoteManager, api, apiConfig, enqueueSubmittedTx, fungibleTokenId, inProgressTxId.length, note, onResetState, removeNoteFromNoteManager, setInProgressTxId, setTotalStep, startNewTransaction, txQueueApi, wrappableToken]
);

return (
Expand All @@ -261,12 +291,16 @@ const DepositConfirmContainer = forwardRef<
}}
totalProgress={totalStep}
progress={currentStep}
onDownload={() => downloadNote(note)}
amount={amount}
wrappingAmount={String(amount)}
wrappingAmount={amount}
fungibleTokenSymbol={fungibleToken.view.symbol}
sourceChain={sourceChain}
destChain={destChain}
sourceTypedChainId={sourceTypedChainId}
destTypedChainId={destTypedChainId}
sourceAddress={activeAccount?.address ?? ''}
destAddress={note.note.targetIdentifyingData}
poolAddress={poolAddress}
poolExplorerUrl={poolExplorerUrl}
newBalance={newBalance}
wrappableTokenSymbol={wrappableToken?.view.symbol}
txStatusColor={
txStatus === 'completed'
Expand All @@ -277,6 +311,17 @@ const DepositConfirmContainer = forwardRef<
}
txStatusMessage={txStatusMessage}
onClose={onClose}
feesSection={
<FeeDetails
info="The fee pays for the transaction to be processed on the network."
items={[
{
name: 'Gas',
Icon: <GasStationFill />,
},
]}
/>
}
/>
);
}
Expand Down
11 changes: 2 additions & 9 deletions apps/bridge-dapp/src/containers/DepositConfirmContainer/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ChainGroup } from '@webb-tools/dapp-config/chains/chain-config.interface';
import { Note } from '@webb-tools/sdk-core/note';
import { PropsOf } from '@webb-tools/webb-ui-components/types';

Expand All @@ -16,18 +15,12 @@ export interface DepositConfirmContainerProps extends PropsOf<'div'> {
/**
* The source chain
*/
sourceChain?: {
type: ChainGroup;
name: string;
};
sourceTypedChainId?: number;

/**
* The destination chain
*/
destChain?: {
type: ChainGroup;
name: string;
};
destTypedChainId?: number;

/**
* The fungible token id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import {
TransferTransactionPayloadType,
} from '@webb-tools/abstract-api-provider';
import { useWebContext } from '@webb-tools/api-provider-environment';
import { chainsConfig } from '@webb-tools/dapp-config/chains/chain-config';
import { getExplorerURI } from '@webb-tools/api-provider-environment/transaction/utils';
import { useBalancesFromNotes } from '@webb-tools/react-hooks/currency/useBalancesFromNotes';
import { LoggerService } from '@webb-tools/app-util';
import { ZERO_BIG_INT } from '@webb-tools/dapp-config';
import { WebbError, WebbErrorCodes } from '@webb-tools/dapp-types/WebbError';
Expand All @@ -21,10 +24,12 @@ import {
TransferConfirm,
getRoundedAmountString,
} from '@webb-tools/webb-ui-components';
import RelayerFeeDetails from '../../components/RelayerFeeDetails';
import { forwardRef, useMemo, useState, type ComponentProps } from 'react';
import type { Hash } from 'viem';
import { ContractFunctionRevertedError, formatEther } from 'viem';
import { useEnqueueSubmittedTx } from '../../hooks';
import useTransferFeeCalculation from '../../hooks/useTransferFeeCalculation';
import useInProgressTxInfo from '../../hooks/useInProgressTxInfo';
import {
captureSentryException,
Expand Down Expand Up @@ -69,7 +74,9 @@ const TransferConfirmContainer = forwardRef<
// State for tracking the status of the change note checkbox
const [isChecked, setIsChecked] = useState(false);

const { activeApi, activeChain } = useWebContext();
const { apiConfig, activeApi, activeChain, noteManager } = useWebContext();

const { balances } = useBalancesFromNotes();

const {
cardTitle,
Expand All @@ -85,11 +92,34 @@ const TransferConfirmContainer = forwardRef<
onResetState
);

const srcTypedChainId = useMemo(
() => calculateTypedChainId(activeChain!.chainType, activeChain!.id),
[]
);

const targetChainId = useMemo(
() => calculateTypedChainId(destChain.chainType, destChain.id),
[destChain]
);

const poolAddress = useMemo(
() => apiConfig.anchors[currency.id][targetChainId],
[apiConfig, currency.id, targetChainId]
);

const poolExplorerUrl = useMemo(() => {
const blockExplorerUrl =
chainsConfig[targetChainId]?.blockExplorers?.default.url;

if (!blockExplorerUrl) return undefined;
return getExplorerURI(
blockExplorerUrl,
poolAddress,
'address',
'web3'
).toString();
}, [targetChainId, poolAddress]);

const {
relayersState: { activeRelayer },
} = useRelayers({
Expand Down Expand Up @@ -118,6 +148,26 @@ const TransferConfirmContainer = forwardRef<
targetTypedChainId: targetChainId,
});

const {
gasFeeInfo,
isLoading: isFeeLoading,
relayerFeeInfo,
totalFeeToken,
totalFeeWei,
} = useTransferFeeCalculation({
activeRelayer,
recipientErrorMsg: undefined,
typedChainId: srcTypedChainId,
});

const newBalance = useMemo(() => {
const currentBalance = balances?.[currency.id]?.[srcTypedChainId];
if (!currentBalance) return undefined;
const updatedBalance = Number(formatEther(currentBalance)) - amount;
if (updatedBalance < 0) return undefined;
return updatedBalance;
}, [balances, currency.id, srcTypedChainId, amount]);

const formattedFee = useMemo(() => {
if (!feeInWei) {
return undefined;
Expand All @@ -140,15 +190,13 @@ const TransferConfirmContainer = forwardRef<
progress={currentStep}
amount={amount}
changeAmount={changeAmount}
sourceChain={{
name: activeChain?.name ?? '',
type: activeChain?.group ?? 'webb-dev',
}}
destChain={{
name: destChain.name,
type: destChain.group ?? 'webb-dev',
}}
note={changeNote?.serialize()}
sourceTypedChainId={srcTypedChainId}
destTypedChainId={targetChainId}
sourceAddress={noteManager?.getKeypair().toString() ?? ''}
destAddress={recipient}
poolAddress={poolAddress}
poolExplorerUrl={poolExplorerUrl}
recipientTitleProps={{
info: <RecipientPublicKeyTooltipContent />,
}}
Expand All @@ -163,7 +211,6 @@ const TransferConfirmContainer = forwardRef<
feeToken={feeToken}
onClose={onClose}
checkboxProps={{
children: 'I have copied the change note',
isChecked,
onChange: () => setIsChecked((prev) => !prev),
}}
Expand All @@ -183,10 +230,28 @@ const TransferConfirmContainer = forwardRef<
txStatusMessage={txStatusMessage}
refundAmount={
typeof refundAmount === 'bigint'
? formatEther(refundAmount)
? Number(formatEther(refundAmount))
: undefined
}
refundToken={refundToken}
refundRecipient={refundRecipient}
newBalance={newBalance}
feesSection={
<RelayerFeeDetails
totalFeeWei={totalFeeWei}
totalFeeToken={totalFeeToken}
gasFeeInfo={gasFeeInfo}
relayerFeeInfo={relayerFeeInfo}
isFeeLoading={isFeeLoading}
srcChainCfg={apiConfig.chains[srcTypedChainId]}
fungibleCfg={apiConfig.getCurrencyBySymbolAndTypedChainId(
currency.view.symbol,
srcTypedChainId
)}
activeRelayer={activeRelayer}
info="Amount deducted from the transfer to cover transaction costs within the shielded pool."
/>
}
/>
);
}
Expand Down
Loading

0 comments on commit 92250e9

Please sign in to comment.