Compare commits

..
Author SHA1 Message Date
Bill He 4e7527b797 remove testnet cctp chains 2024-01-03 11:38:32 -08:00
Jared Vu 29526b927f Update deposit and withdrawal receipts (#212)
* Update receipts

* Remove duplicate const

* Restore env

* format

* Try using raw

* Use 3 spaces T.T

* copy from main

* Update abacus, display proper toAmount and toAmountMin

* nits
2024-01-03 09:56:01 -08:00
13 changed files with 156 additions and 125 deletions
+1 -1
View File
@@ -39,7 +39,7 @@
"@cosmjs/proto-signing": "^0.31.0", "@cosmjs/proto-signing": "^0.31.0",
"@cosmjs/stargate": "^0.31.0", "@cosmjs/stargate": "^0.31.0",
"@cosmjs/tendermint-rpc": "^0.31.0", "@cosmjs/tendermint-rpc": "^0.31.0",
"@dydxprotocol/v4-abacus": "^1.1.31", "@dydxprotocol/v4-abacus": "^1.1.32",
"@dydxprotocol/v4-client-js": "^1.0.11", "@dydxprotocol/v4-client-js": "^1.0.11",
"@dydxprotocol/v4-localization": "^1.1.5", "@dydxprotocol/v4-localization": "^1.1.5",
"@ethersproject/providers": "^5.7.2", "@ethersproject/providers": "^5.7.2",
+9 -5
View File
@@ -27,8 +27,8 @@ dependencies:
specifier: ^0.31.0 specifier: ^0.31.0
version: 0.31.0 version: 0.31.0
'@dydxprotocol/v4-abacus': '@dydxprotocol/v4-abacus':
specifier: ^1.1.31 specifier: ^1.1.32
version: 1.1.31 version: 1.1.32
'@dydxprotocol/v4-client-js': '@dydxprotocol/v4-client-js':
specifier: ^1.0.11 specifier: ^1.0.11
version: 1.0.11 version: 1.0.11
@@ -988,8 +988,8 @@ packages:
resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==} resolution: {integrity: sha512-RpfLEtTlyIxeNPGKcokS+p3BZII/Q3bYxryFRglh5H3A3T8q9fsLYm72VYAMEOOIBLEa8o93kFLiBDUWKrwXZA==}
dev: true dev: true
/@dydxprotocol/v4-abacus@1.1.31: /@dydxprotocol/v4-abacus@1.1.32:
resolution: {integrity: sha512-CBfK78u/y2/9KR/w2f7IGhU6tKt/seoKHlsal0vk2WlJsjXnlTKoOQ3HpCSGoMmI5ZLQeqbFClvNH4RZLhEwzg==} resolution: {integrity: sha512-1KM3ILBg/YrdiVhCp/DXUgyCnJurxeYAIwL6+MWZisEGtdhPf9R7MNKUyVcTeNwEyiyxh4AzXNLRp3IPeHAsAw==}
dev: false dev: false
/@dydxprotocol/v4-client-js@1.0.11: /@dydxprotocol/v4-client-js@1.0.11:
@@ -7986,7 +7986,7 @@ packages:
resolution: {integrity: sha512-WIdaQ8uW1vIbYvNnAVunkC6yxTrneJC7VQ5UUQ0kuw8b0C0A39KTIpoQHCfc8tV7o9vF4niwRhdXEdfAgQEsQQ==} resolution: {integrity: sha512-WIdaQ8uW1vIbYvNnAVunkC6yxTrneJC7VQ5UUQ0kuw8b0C0A39KTIpoQHCfc8tV7o9vF4niwRhdXEdfAgQEsQQ==}
dependencies: dependencies:
cosmos-directory-types: 0.0.6 cosmos-directory-types: 0.0.6
node-fetch-native: 1.4.1 node-fetch-native: 1.6.1
dev: false dev: false
/cosmos-directory-types@0.0.6: /cosmos-directory-types@0.0.6:
@@ -11752,6 +11752,10 @@ packages:
resolution: {integrity: sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w==} resolution: {integrity: sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w==}
dev: false dev: false
/node-fetch-native@1.6.1:
resolution: {integrity: sha512-bW9T/uJDPAJB2YNYEpWzE54U5O3MQidXsOyTfnbKYtTtFexRvGzb1waphBN4ZwP6EcIvYYEOwW0b72BpAqydTw==}
dev: false
/node-fetch@2.6.12: /node-fetch@2.6.12:
resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
engines: {node: 4.x || >=6.0.0} engines: {node: 4.x || >=6.0.0}
-29
View File
@@ -4,38 +4,9 @@
"tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "tokenAddress": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"name": "Ethereum" "name": "Ethereum"
}, },
{
"chainId": "421613",
"tokenAddress": "0xfd064a18f3bf249cf1f87fc203e90d8f650f2d63",
"name": "Arbitrum Goerli"
},
{
"chainId": "43113",
"tokenAddress": "0x5425890298aed601595a70AB815c96711a31Bc65",
"name": "Avalanche Fuji"
},
{
"chainId": "84531",
"tokenAddress": "0xf175520c52418dfe19c8098071a252da48cd1c19",
"name": "Base Goerli"
},
{ {
"chainId": "5", "chainId": "5",
"tokenAddress": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F", "tokenAddress": "0x07865c6E87B9F70255377e024ace6630C1Eaa37F",
"name": "Ethereum Goerli" "name": "Ethereum Goerli"
},
{
"chainId": "grand-1",
"tokenAddress": "uusdc",
"name": "Noble Testnet"
},
{
"chainId": "420",
"tokenAddress": "0xe05606174bac4a6364b31bd0eca4bf4dd368f8c6",
"name": "OP Goerli"
},
{
"chainId": "103",
"name": "Solana Devnet"
} }
] ]
+4
View File
@@ -1,6 +1,10 @@
import { type TooltipStrings, TOOLTIP_STRING_KEYS } from '@/constants/localization'; import { type TooltipStrings, TOOLTIP_STRING_KEYS } from '@/constants/localization';
export const depositTooltips: TooltipStrings = { export const depositTooltips: TooltipStrings = {
'minimum-deposit-amount': ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_DEPOSIT_AMOUNT_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_DEPOSIT_AMOUNT_BODY }),
}),
swap: ({ stringGetter }) => ({ swap: ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_TITLE }), title: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_BODY }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.SWAP_BODY }),
+4
View File
@@ -5,6 +5,10 @@ export const withdrawTooltips: TooltipStrings = {
title: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_TITLE }), title: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_BODY }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.FAST_WITHDRAW_FEE_BODY }),
}), }),
'minimum-amount-received': ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_AMOUNT_RECEIVED_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.MINIMUM_AMOUNT_RECEIVED_BODY }),
}),
'withdraw-types': ({ stringGetter }) => ({ 'withdraw-types': ({ stringGetter }) => ({
title: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_TITLE }), title: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_TITLE }),
body: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_BODY }), body: stringGetter({ key: TOOLTIP_STRING_KEYS.WITHDRAW_TYPES_BODY }),
+2 -2
View File
@@ -157,8 +157,8 @@ export const notificationTypes: NotificationTypeConfig[] = [
const isFinished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing'; const isFinished = Boolean(status) && status?.squidTransactionStatus !== 'ongoing';
const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />; const icon = <Icon iconName={isFinished ? IconName.Transfer : IconName.Clock} />;
const transferType = type ?? const transferType =
fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId type ?? fromChainId === ENVIRONMENT_CONFIG_MAP[selectedNetwork].dydxChainId
? TransferNotificationTypes.Withdrawal ? TransferNotificationTypes.Withdrawal
: TransferNotificationTypes.Deposit; : TransferNotificationTypes.Deposit;
-4
View File
@@ -56,10 +56,6 @@ class DydxChainTransactions implements AbacusDYDXChainTransactionsProtocol {
this.store = undefined; this.store = undefined;
} }
get isNobleClientConnected(): boolean {
return this.nobleClient?.isConnected ?? false;
}
setStore(store: RootStore): void { setStore(store: RootStore): void {
this.store = store; this.store = store;
} }
-1
View File
@@ -83,7 +83,6 @@ export const HorizontalPanel = ({ isOpen = true, setIsOpen }: ElementProps) => {
const tabItems = useMemo( const tabItems = useMemo(
() => [ () => [
{ {
asChild: true,
value: InfoSection.Position, value: InfoSection.Position,
label: stringGetter({ label: stringGetter({
key: showCurrentMarket ? STRING_KEYS.POSITION : STRING_KEYS.POSITIONS, key: showCurrentMarket ? STRING_KEYS.POSITION : STRING_KEYS.POSITIONS,
@@ -18,11 +18,7 @@ type ElementProps = {
onSelectChain: (chain: string) => void; onSelectChain: (chain: string) => void;
}; };
export const ChainSelectMenu = ({ export const ChainSelectMenu = ({ label, selectedChain, onSelectChain }: ElementProps) => {
label,
selectedChain,
onSelectChain,
}: ElementProps) => {
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { type, depositOptions, withdrawalOptions, resources } = const { type, depositOptions, withdrawalOptions, resources } =
useSelector(getTransferInputs, shallowEqual) || {}; useSelector(getTransferInputs, shallowEqual) || {};
@@ -38,7 +34,7 @@ export const ChainSelectMenu = ({
slotBefore: <Styled.Img src={chain.iconUrl} alt="" />, slotBefore: <Styled.Img src={chain.iconUrl} alt="" />,
})); }));
const selectedOption = chains.find((item) => item.type === selectedChain); const selectedOption = chains.find((item) => item.type === selectedChain);
return ( return (
<SearchSelectMenu <SearchSelectMenu
@@ -81,4 +77,4 @@ Styled.ChainRow = styled.div`
gap: 0.5rem; gap: 0.5rem;
color: var(--color-text-2); color: var(--color-text-2);
font: var(--font-base-book); font: var(--font-base-book);
`; `;
@@ -235,10 +235,6 @@ export const DepositForm = ({ onDeposit, onError }: DepositFormProps) => {
throw new Error('Missing request payload'); throw new Error('Missing request payload');
} }
if (isCctp && !abacusStateManager.chainTransactions.isNobleClientConnected) {
throw new Error('Noble RPC endpoint unaccessible');
}
setIsLoading(true); setIsLoading(true);
await validateTokenApproval(); await validateTokenApproval();
@@ -1,21 +1,16 @@
import { type Dispatch, type SetStateAction, useState, type ReactNode } from 'react'; import { type Dispatch, type ReactNode, type SetStateAction, useState, useMemo } from 'react';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import type { RouteData } from '@0xsquid/sdk'; import type { RouteData } from '@0xsquid/sdk';
import { formatUnits } from 'viem';
import { import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons';
ButtonAction,
ButtonShape,
ButtonSize,
ButtonState,
ButtonType,
} from '@/constants/buttons';
import { TransferInputTokenResource } from '@/constants/abacus'; import { TransferInputTokenResource } from '@/constants/abacus';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { NumberSign } from '@/constants/numbers'; import { NumberSign, TOKEN_DECIMALS } from '@/constants/numbers';
import { useStringGetter } from '@/hooks'; import { useStringGetter, useTokenConfigs } from '@/hooks';
import { useMatchingEvmNetwork } from '@/hooks/useMatchingEvmNetwork'; import { useMatchingEvmNetwork } from '@/hooks/useMatchingEvmNetwork';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
@@ -85,6 +80,7 @@ export const DepositButtonAndReceipt = ({
useSelector(getSubaccountBuyingPower, shallowEqual) || {}; useSelector(getSubaccountBuyingPower, shallowEqual) || {};
const { isCctp, summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {}; const { isCctp, summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {};
const { usdcDecimals, usdcLabel } = useTokenConfigs();
const feeSubitems: DetailsItem[] = []; const feeSubitems: DetailsItem[] = [];
@@ -99,7 +95,7 @@ export const DepositButtonAndReceipt = ({
if (typeof summary?.bridgeFee === 'number') { if (typeof summary?.bridgeFee === 'number') {
feeSubitems.push({ feeSubitems.push({
key: 'bridge-fees', key: 'bridge-fees',
label: <span>Bridge Fee</span>, label: <span>{stringGetter({ key: STRING_KEYS.BRIDGE_FEE })}</span>,
value: <Output type={OutputType.Fiat} value={summary?.bridgeFee} />, value: <Output type={OutputType.Fiat} value={summary?.bridgeFee} />,
}); });
} }
@@ -112,12 +108,68 @@ export const DepositButtonAndReceipt = ({
const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0); const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0);
const { toAmount, toAmountMin } = useMemo(() => {
if (isCctp) {
return {
toAmount: summary?.toAmount,
toAmountMin: summary?.toAmountMin,
};
} else {
return {
toAmount: summary?.toAmount && formatUnits(BigInt(summary.toAmount), usdcDecimals),
toAmountMin: summary?.toAmountMin && formatUnits(BigInt(summary.toAmountMin), usdcDecimals),
};
}
}, [isCctp, summary]);
const submitButtonReceipt = [ const submitButtonReceipt = [
{
key: 'expected-deposit-amount',
label: (
<span>
{stringGetter({ key: STRING_KEYS.EXPECTED_DEPOSIT_AMOUNT })} <Tag>{usdcLabel}</Tag>
</span>
),
value: <Output type={OutputType.Fiat} fractionDigits={TOKEN_DECIMALS} value={toAmount} />,
subitems: [
{
key: 'minimum-deposit-amount',
label: (
<span>
{stringGetter({ key: STRING_KEYS.MINIMUM_DEPOSIT_AMOUNT })} <Tag>{usdcLabel}</Tag>
</span>
),
value: (
<Output type={OutputType.Fiat} fractionDigits={TOKEN_DECIMALS} value={toAmountMin} />
),
tooltip: 'minimum-deposit-amount',
},
],
},
{
key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value:
typeof summary?.exchangeRate === 'number' ? (
<Styled.ExchangeRate>
<Output
type={OutputType.Asset}
value={1}
fractionDigits={0}
tag={sourceToken?.symbol}
/>
=
<Output type={OutputType.Asset} value={summary?.exchangeRate} tag={usdcLabel} />
</Styled.ExchangeRate>
) : (
<Output type={OutputType.Asset} />
),
},
{ {
key: 'equity', key: 'equity',
label: ( label: (
<span> <span>
{stringGetter({ key: STRING_KEYS.EQUITY })} <Tag>USDC</Tag> {stringGetter({ key: STRING_KEYS.EQUITY })} <Tag>{usdcLabel}</Tag>
</span> </span>
), ),
value: ( value: (
@@ -134,7 +186,7 @@ export const DepositButtonAndReceipt = ({
key: 'buying-power', key: 'buying-power',
label: ( label: (
<span> <span>
{stringGetter({ key: STRING_KEYS.BUYING_POWER })} <Tag>USDC</Tag> {stringGetter({ key: STRING_KEYS.BUYING_POWER })} <Tag>{usdcLabel}</Tag>
</span> </span>
), ),
value: ( value: (
@@ -147,17 +199,6 @@ export const DepositButtonAndReceipt = ({
/> />
), ),
}, },
{
key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value: typeof summary?.exchangeRate === 'number' && (
<Styled.ExchangeRate>
<Output type={OutputType.Asset} value={1} fractionDigits={0} tag={sourceToken?.symbol} />
=
<Output type={OutputType.Asset} value={summary?.exchangeRate} tag="USDC" />
</Styled.ExchangeRate>
),
},
!isCctp && { !isCctp && {
key: 'total-fees', key: 'total-fees',
label: <span>{stringGetter({ key: STRING_KEYS.TOTAL_FEES })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.TOTAL_FEES })}</span>,
@@ -179,18 +220,22 @@ export const DepositButtonAndReceipt = ({
{ {
key: 'estimatedRouteDuration', key: 'estimatedRouteDuration',
label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>,
value: typeof summary?.estimatedRouteDuration === 'number' && ( value: (
<Output <Output
type={OutputType.Text} type={OutputType.Text}
value={stringGetter({ value={
key: STRING_KEYS.X_MINUTES_LOWERCASED, typeof summary?.estimatedRouteDuration === 'number'
params: { ? stringGetter({
X: key: STRING_KEYS.X_MINUTES_LOWERCASED,
summary?.estimatedRouteDuration < 60 params: {
? '< 1' X:
: Math.round(summary?.estimatedRouteDuration / 60), summary?.estimatedRouteDuration < 60
}, ? '< 1'
})} : Math.round(summary?.estimatedRouteDuration / 60),
},
})
: null
}
/> />
), ),
}, },
@@ -148,10 +148,6 @@ export const WithdrawForm = () => {
throw new Error('Invalid request payload'); throw new Error('Invalid request payload');
} }
if (isCctp && !abacusStateManager.chainTransactions.isNobleClientConnected) {
throw new Error('Noble RPC endpoint unaccessible');
}
setIsLoading(true); setIsLoading(true);
setError(undefined); setError(undefined);
@@ -1,4 +1,4 @@
import { useState } from 'react'; import { useMemo, useState } from 'react';
import { shallowEqual, useSelector } from 'react-redux'; import { shallowEqual, useSelector } from 'react-redux';
import styled, { type AnyStyledComponent } from 'styled-components'; import styled, { type AnyStyledComponent } from 'styled-components';
import { formatUnits } from 'viem'; import { formatUnits } from 'viem';
@@ -6,14 +6,11 @@ import { formatUnits } from 'viem';
import { TransferInputTokenResource } from '@/constants/abacus'; import { TransferInputTokenResource } from '@/constants/abacus';
import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons'; import { ButtonAction, ButtonShape, ButtonSize, ButtonType } from '@/constants/buttons';
import { STRING_KEYS } from '@/constants/localization'; import { STRING_KEYS } from '@/constants/localization';
import { NumberSign } from '@/constants/numbers'; import { NumberSign, TOKEN_DECIMALS } from '@/constants/numbers';
import { formatSeconds } from '@/lib/timeUtils';
import { layoutMixins } from '@/styles/layoutMixins'; import { layoutMixins } from '@/styles/layoutMixins';
import { useStringGetter } from '@/hooks'; import { useStringGetter, useTokenConfigs } from '@/hooks';
import { useAccountBalance } from '@/hooks/useAccountBalance';
import { Button } from '@/components/Button'; import { Button } from '@/components/Button';
@@ -58,13 +55,9 @@ export const WithdrawButtonAndReceipt = ({
const stringGetter = useStringGetter(); const stringGetter = useStringGetter();
const { leverage } = useSelector(getSubaccount, shallowEqual) || {}; const { leverage } = useSelector(getSubaccount, shallowEqual) || {};
const { summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {}; const { isCctp, summary, requestPayload } = useSelector(getTransferInputs, shallowEqual) || {};
const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual); const canAccountTrade = useSelector(calculateCanAccountTrade, shallowEqual);
const { usdcLabel } = useTokenConfigs();
const toAmount =
summary?.toAmount &&
withdrawToken?.decimals &&
formatUnits(BigInt(summary.toAmount), withdrawToken?.decimals);
const feeSubitems: DetailsItem[] = []; const feeSubitems: DetailsItem[] = [];
@@ -92,6 +85,26 @@ export const WithdrawButtonAndReceipt = ({
const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0); const totalFees = (summary?.bridgeFee || 0) + (summary?.gasFee || 0);
const { toAmount, toAmountMin } = useMemo(() => {
if (isCctp) {
return {
toAmount: summary?.toAmount,
toAmountMin: summary?.toAmountMin,
};
} else {
return {
toAmount:
summary?.toAmount &&
withdrawToken?.decimals &&
formatUnits(BigInt(summary.toAmount), withdrawToken.decimals),
toAmountMin:
summary?.toAmountMin &&
withdrawToken?.decimals &&
formatUnits(BigInt(summary.toAmountMin), withdrawToken.decimals),
};
}
}, [isCctp, summary, withdrawToken]);
const submitButtonReceipt = [ const submitButtonReceipt = [
{ {
key: 'total-fees', key: 'total-fees',
@@ -99,24 +112,12 @@ export const WithdrawButtonAndReceipt = ({
value: <Output type={OutputType.Fiat} value={totalFees} />, value: <Output type={OutputType.Fiat} value={totalFees} />,
subitems: feeSubitems, subitems: feeSubitems,
}, },
{
key: 'slippage',
label: <span>{stringGetter({ key: STRING_KEYS.MAX_SLIPPAGE })}</span>,
value: (
<SlippageEditor
disabled
slippage={slippage}
setIsEditing={setIsEditingSlipapge}
setSlippage={setSlippage}
/>
),
},
{ {
key: 'exchange-rate', key: 'exchange-rate',
label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.EXCHANGE_RATE })}</span>,
value: withdrawToken && typeof summary?.exchangeRate === 'number' && ( value: withdrawToken && typeof summary?.exchangeRate === 'number' && (
<Styled.ExchangeRate> <Styled.ExchangeRate>
<Output type={OutputType.Asset} value={1} fractionDigits={0} tag="USDC" /> <Output type={OutputType.Asset} value={1} fractionDigits={0} tag={usdcLabel} />
= =
<Output <Output
type={OutputType.Asset} type={OutputType.Asset}
@@ -127,7 +128,7 @@ export const WithdrawButtonAndReceipt = ({
), ),
}, },
{ {
key: 'estimatedRouteDuration', key: 'estimated-route-duration',
label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>, label: <span>{stringGetter({ key: STRING_KEYS.ESTIMATED_TIME })}</span>,
value: typeof summary?.estimatedRouteDuration === 'number' && ( value: typeof summary?.estimatedRouteDuration === 'number' && (
<Output <Output
@@ -145,20 +146,39 @@ export const WithdrawButtonAndReceipt = ({
), ),
}, },
{ {
key: 'wallet', key: 'expected-amount-received',
label: ( label: (
<span> <span>
{stringGetter({ key: STRING_KEYS.MINIMUM_AMOUNT_RECEIVED })}{' '} {stringGetter({ key: STRING_KEYS.EXPECTED_AMOUNT_RECEIVED })}{' '}
{withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>} {withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>}
</span> </span>
), ),
value: <Output type={OutputType.Asset} value={toAmount} fractionDigits={TOKEN_DECIMALS} />,
subitems: [
{
key: 'minimum-amount-received',
label: (
<span>
{stringGetter({ key: STRING_KEYS.MINIMUM_AMOUNT_RECEIVED })}{' '}
{withdrawToken && <Tag>{withdrawToken?.symbol}</Tag>}
</span>
),
value: (
<Output type={OutputType.Asset} value={toAmountMin} fractionDigits={TOKEN_DECIMALS} />
),
tooltip: 'minimum-amount-received',
},
],
},
{
key: 'slippage',
label: <span>{stringGetter({ key: STRING_KEYS.MAX_SLIPPAGE })}</span>,
value: ( value: (
<Styled.DiffOutput <SlippageEditor
type={OutputType.Asset} disabled
value={'0'} slippage={slippage}
newValue={toAmount} setIsEditing={setIsEditingSlipapge}
sign={NumberSign.Positive} setSlippage={setSlippage}
withDiff={Boolean(toAmount)}
/> />
), ),
}, },