Skip to content

Commit

Permalink
Merge pull request #44 from ethereum-optimism/01-08-feat_show_gas_est…
Browse files Browse the repository at this point in the history
…imation_values

feat: show gas estimation values
  • Loading branch information
jakim929 authored Jan 9, 2025
2 parents 697602b + 7cdcab4 commit 6f8c7ff
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 3 deletions.
57 changes: 55 additions & 2 deletions packages/cli/src/deploy-create2/DeployCreate2Command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ import {useEffect, useState} from 'react';
import {Spinner, Badge} from '@inkjs/ui';
import {DeployCreateXCreate2Params} from '@/actions/deployCreateXCreate2';

import {Address, Chain, encodeFunctionData, Hex} from 'viem';
import {
Address,
Chain,
encodeFunctionData,
formatEther,
formatUnits,
Hex,
zeroAddress,
} from 'viem';
import {useConfig, useWaitForTransactionReceipt, useWriteContract} from 'wagmi';
import {useForgeArtifact} from '@/queries/forgeArtifact';
import {ForgeArtifact} from '@/forge/readForgeArtifact';
Expand All @@ -26,6 +34,7 @@ import {
import {useCodeForChains} from '@/deploy-create2/useCodeForChains';
import {useRefetchCodeOnReceipt} from '@/deploy-create2/useRefetchCodeOnReceipt';
import {VerifyCommandInner} from '@/commands/verify';
import {useGasEstimation} from '@/hooks/useGasEstimation';

// Prepares any required data or loading state if waiting
export const DeployCreate2Command = ({
Expand Down Expand Up @@ -249,6 +258,19 @@ const DeployStatus = ({
}),
});

const {data: gasEstimation, isLoading: isGasEstimationLoading} =
useGasEstimation({
chainId: chain.id,
to: CREATEX_ADDRESS,
account: zeroAddress,

data: encodeFunctionData({
abi: createXABI,
functionName: 'deployCreate2',
args: [baseSalt, initCode],
}),
});

if (preVerificationCheckError) {
return (
<Box gap={1}>
Expand Down Expand Up @@ -306,7 +328,12 @@ const DeployStatus = ({
return (
<Box gap={1}>
<Badge color="blue">Ready</Badge>
<Text>Contract is ready to be deployed</Text>
<Text>Estimated fees</Text>
{isGasEstimationLoading || !gasEstimation ? (
<Spinner />
) : (
<GasEstimation gasEstimation={gasEstimation} />
)}
</Box>
);
}
Expand All @@ -333,6 +360,32 @@ const DeployStatus = ({
);
};

const GasEstimation = ({
gasEstimation,
}: {
gasEstimation: {
totalFee: bigint;
estimatedL1Fee: bigint;
estimatedL2Gas: bigint;
l2GasPrice: bigint;
};
}) => {
return (
<Text>
<Text>(L1 Fee: </Text>
<Text color="green">{formatEther(gasEstimation.estimatedL1Fee)} ETH</Text>
<Text>) + (L2 Gas: </Text>
<Text color="yellow">{gasEstimation.estimatedL2Gas.toString()}</Text>
<Text> gas × L2 Gas Price: </Text>
<Text color="cyan">{formatUnits(gasEstimation.l2GasPrice, 9)} gwei</Text>
<Text>) = </Text>
<Text color="green" bold>
{formatEther(gasEstimation.totalFee)} ETH
</Text>
</Text>
);
};

const PrivateKeyExecution = ({
chain,
initCode,
Expand Down
4 changes: 3 additions & 1 deletion packages/cli/src/deploy-create2/useCodeForChains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export const useCodeForChains = (address: Address, chainIds: number[]) => {
}),
});

const isDeployedToAllChains = queries.every(query => query.data !== null);
const isDeployedToAllChains = queries.every(
query => query.data !== null && query.data !== undefined,
);

return {
isDeployedToAllChains,
Expand Down
96 changes: 96 additions & 0 deletions packages/cli/src/hooks/useGasEstimation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {useQuery} from '@tanstack/react-query';
import {Address, Hex} from 'viem';
import {estimateL1Fee} from 'viem/op-stack';
import {useEstimateGas, usePublicClient, useGasPrice} from 'wagmi';

export const useGasEstimation = ({
to,
data,
account,
chainId,
}: {
to: Address;
data: Hex;
account: Address;
chainId: number;
}) => {
const publicClient = usePublicClient({
chainId,
});

const {
data: estimatedL1Fee,
isLoading: isL1FeeEstimationLoading,
error: l1FeeEstimationError,
} = useQuery({
queryKey: ['estimateL1Fee', chainId, to, account, data],
queryFn: () => {
// @ts-expect-error
return estimateL1Fee(publicClient, {
chainId,
to,
account,
data,
});
},
});

const {
data: estimatedL2Gas,
isLoading: isL2GasEstimationLoading,
error: l2GasEstimationError,
} = useEstimateGas({
chainId,
to,
account,
data,
});

const {
data: l2GasPrice,
isLoading: isL2GasPriceLoading,
error: l2GasPriceError,
} = useGasPrice({
chainId,
});

const isLoading =
isL1FeeEstimationLoading || isL2GasEstimationLoading || isL2GasPriceLoading;

const error =
l1FeeEstimationError ||
l2GasEstimationError ||
l2GasPriceError ||
undefined;

const areValuesAvailable = estimatedL1Fee && estimatedL2Gas && l2GasPrice;

if (isLoading || !areValuesAvailable) {
return {
data: undefined,
error: null,
isLoading: true,
};
}

if (error) {
return {
data: undefined,
error: new Error('Gas estimation failed'),
isLoading: false,
};
}

const totalFee = estimatedL1Fee + estimatedL2Gas * l2GasPrice;

return {
data: {
totalFee: totalFee,
estimatedL1Fee: estimatedL1Fee,
estimatedL2Gas: estimatedL2Gas,
l2GasPrice: l2GasPrice,
},
error: null,
isLoading: false,
};
};

0 comments on commit 6f8c7ff

Please sign in to comment.