From b4132dbd1d7d700811b082d38089973c6e9685fe Mon Sep 17 00:00:00 2001 From: v1rtl Date: Wed, 30 Oct 2024 03:23:44 +0200 Subject: [PATCH] wip gas estimation --- .../input/BulkRenewal/BulkRenewal-flow.tsx | 80 ++++++++++++++++--- src/transaction-flow/transaction/index.ts | 2 + 2 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/transaction-flow/input/BulkRenewal/BulkRenewal-flow.tsx b/src/transaction-flow/input/BulkRenewal/BulkRenewal-flow.tsx index e708353ac..e330142ad 100644 --- a/src/transaction-flow/input/BulkRenewal/BulkRenewal-flow.tsx +++ b/src/transaction-flow/input/BulkRenewal/BulkRenewal-flow.tsx @@ -1,18 +1,21 @@ import { useState } from 'react' import { useTranslation } from 'react-i18next' import styled, { css } from 'styled-components' -import { useClient, useReadContract } from 'wagmi' +import { useAccount, useBalance, useClient, useEstimateGas, useReadContract } from 'wagmi' import { NameWithRelation } from '@ensdomains/ensjs/subgraph' import { Dialog, Heading, Helper, OutlinkSVG, Typography } from '@ensdomains/thorin' +import { CacheableComponent } from '@app/components/@atoms/CacheableComponent' import { Calendar } from '@app/components/@atoms/Calendar/Calendar' -import { InvoiceItem } from '@app/components/@atoms/Invoice/Invoice' +import { Invoice, InvoiceItem } from '@app/components/@atoms/Invoice/Invoice' import { PlusMinusControl } from '@app/components/@atoms/PlusMinusControl/PlusMinusControl' import { EligibleForTokens } from '@app/components/pages/migrate/EligibleForTokens' +import { useEstimateGasWithStateOverride } from '@app/hooks/chain/useEstimateGasWithStateOverride' import { createTransactionItem } from '@app/transaction-flow/transaction' import { bulkRenewalContract } from '@app/transaction-flow/transaction/bulkRenew' -import { REBATE_DATE } from '@app/utils/constants' +import { CURRENCY_FLUCTUATION_BUFFER_PERCENTAGE, REBATE_DATE } from '@app/utils/constants' +import useUserConfig from '@app/utils/useUserConfig' import { formatDurationOfDates } from '@app/utils/utils' export type Props = { data: { names: NameWithRelation[] } } @@ -106,15 +109,29 @@ const YearsViewSwitch = styled.button( `, ) -const BulkRenewalFlow = ({ data }: Props) => { - // Sort from the ones that expire earlier to later - const sortedNames = data.names.toSorted((a, b) => a.expiryDate!.value! - b.expiryDate!.value!) +const GasEstimationCacheableComponent = styled(CacheableComponent)( + ({ theme }) => css` + width: 100%; + gap: ${theme.space['4']}; + display: flex; + flex-direction: column; + `, +) +const BulkRenewalFlow = ({ data }: Props) => { const [date, setDate] = useState(REBATE_DATE) const [durationType, setDurationType] = useState<'years' | 'date'>('date') const client = useClient() + const { address } = useAccount() + + const { data: balance } = useBalance({ + address, + }) + + const dateAsBigInt = BigInt(date.getTime() / 1000) + const { data: expiryData, error, @@ -123,13 +140,52 @@ const BulkRenewalFlow = ({ data }: Props) => { abi, address: bulkRenewalContract[client.chain.id!]!, functionName: 'getTargetExpiryPriceData', - args: [data.names.map((name) => name.labelName!), BigInt(date.getTime() / 1000)], + args: [data.names.map((name) => name.labelName!), dateAsBigInt], + }) + + const [total, durations, prices] = expiryData! as [bigint, bigint[], bigint[]] + + const { + data: { gasEstimate: estimatedGasLimit, gasCost: transactionFee }, + error: estimateGasLimitError, + isLoading: isEstimateGasLoading, + gasPrice, + } = useEstimateGasWithStateOverride({ + transactions: [ + { + name: 'bulkRenew', + data: { + names: data.names.map((name) => name.labelhash), + durations, + prices, + }, + stateOverride: [{ address: address! }], + }, + ], }) - const { t } = useTranslation() + const { t } = useTranslation(['transactionFlow', 'common']) const now = new Date() + const { userConfig, setCurrency } = useUserConfig() + const currencyDisplay = userConfig.currency === 'fiat' ? userConfig.fiat : 'eth' + + const items: InvoiceItem[] = [ + { + label: t('input.extendNames.invoice.extension', { + time: formatDurationOfDates({ startDate: now, endDate: date, t }), + }), + value: dateAsBigInt, + bufferPercentage: CURRENCY_FLUCTUATION_BUFFER_PERCENTAGE, + }, + { + label: t('input.extendNames.invoice.transaction'), + value: transactionFee, + bufferPercentage: CURRENCY_FLUCTUATION_BUFFER_PERCENTAGE, + }, + ] + return ( <> @@ -179,8 +235,14 @@ const BulkRenewalFlow = ({ data }: Props) => { - {status} {error ? {error.message} : null} + + + {(!!estimateGasLimitError || + (!!estimatedGasLimit && !!balance?.value && balance.value < estimatedGasLimit)) && ( + {t('input.extendNames.gasLimitError')} + )} + ) diff --git a/src/transaction-flow/transaction/index.ts b/src/transaction-flow/transaction/index.ts index 96a04cc5d..6a9dda0ac 100644 --- a/src/transaction-flow/transaction/index.ts +++ b/src/transaction-flow/transaction/index.ts @@ -2,6 +2,7 @@ import approveDnsRegistrar from './approveDnsRegistrar' import approveNameWrapper from './approveNameWrapper' import approveNameWrapperForMigration from './approveNameWrapperForMigration' import approveRegistrarForMigration from './approveRegistrarForMigration' +import bulkRenew from './bulkRenew' import burnFuses from './burnFuses' import changePermissions from './changePermissions' import claimDnsName from './claimDnsName' @@ -37,6 +38,7 @@ export const transactions = { approveRegistrarForMigration, approveNameWrapper, burnFuses, + bulkRenew, changePermissions, claimDnsName, commitName,