From 5a341c11e2387651131b3f8b02a8752a3e8280f0 Mon Sep 17 00:00:00 2001 From: Doug <4741454+douglance@users.noreply.github.com> Date: Thu, 29 Feb 2024 07:36:25 -0500 Subject: [PATCH] refactor: clean up validation and add factory getters (#32) Co-authored-by: spsjvc --- ...eateRollupEnoughCustomFeeTokenAllowance.ts | 11 ++------- src/createRollupFetchCoreContracts.ts | 8 +------ src/createRollupFetchTransactionHash.ts | 11 +++++---- ...ustomFeeTokenApprovalTransactionRequest.ts | 12 ++++------ src/createRollupPrepareTransactionRequest.ts | 11 ++++----- ...okenBridgeEnoughCustomFeeTokenAllowance.ts | 11 ++------- ...ateTokenBridgeFetchTokenBridgeContracts.ts | 10 ++------ ...ustomFeeTokenApprovalTransactionRequest.ts | 12 ++++------ ...PrepareSetWethGatewayTransactionRequest.ts | 8 ++----- ...ateTokenBridgePrepareTransactionRequest.ts | 11 ++++----- src/prepareNodeConfig.ts | 8 ++----- src/setValidKeyset.ts | 8 ++----- ...setValidKeysetPrepareTransactionRequest.ts | 8 ++----- src/types/ParentChain.ts | 18 +++++++++++--- src/utils/getters.ts | 24 +++++++++++++++++++ 15 files changed, 77 insertions(+), 94 deletions(-) create mode 100644 src/utils/getters.ts diff --git a/src/createRollupEnoughCustomFeeTokenAllowance.ts b/src/createRollupEnoughCustomFeeTokenAllowance.ts index 6aa1891d..1ce3c325 100644 --- a/src/createRollupEnoughCustomFeeTokenAllowance.ts +++ b/src/createRollupEnoughCustomFeeTokenAllowance.ts @@ -1,8 +1,7 @@ import { Address, PublicClient } from 'viem'; -import { rollupCreator } from './contracts'; -import { validParentChainId } from './types/ParentChain'; import { fetchAllowance } from './utils/erc20'; +import { getRollupCreatorAddress } from './utils/getters'; import { createRollupDefaultRetryablesFees } from './constants'; import { Prettify } from './types/utils'; @@ -22,16 +21,10 @@ export async function createRollupEnoughCustomFeeTokenAllowance({ publicClient, rollupCreatorAddressOverride, }: CreateRollupEnoughCustomFeeTokenAllowanceParams) { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } - const allowance = await fetchAllowance({ address: nativeToken, owner: account, - spender: rollupCreatorAddressOverride ?? rollupCreator.address[chainId], + spender: rollupCreatorAddressOverride ?? getRollupCreatorAddress(publicClient), publicClient, }); diff --git a/src/createRollupFetchCoreContracts.ts b/src/createRollupFetchCoreContracts.ts index bb78d600..76d8253b 100644 --- a/src/createRollupFetchCoreContracts.ts +++ b/src/createRollupFetchCoreContracts.ts @@ -1,5 +1,5 @@ import { Address, PublicClient } from 'viem'; -import { validParentChainId } from './types/ParentChain'; + import { CoreContracts } from './types/CoreContracts'; import { createRollupFetchTransactionHash } from './createRollupFetchTransactionHash'; import { createRollupPrepareTransactionReceipt } from './createRollupPrepareTransactionReceipt'; @@ -13,12 +13,6 @@ export async function createRollupFetchCoreContracts({ rollup, publicClient, }: CreateRollupFetchCoreContractsParams): Promise { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } - // getting core contract addresses const transactionHash = await createRollupFetchTransactionHash({ rollup, diff --git a/src/createRollupFetchTransactionHash.ts b/src/createRollupFetchTransactionHash.ts index ca8b3844..461add76 100644 --- a/src/createRollupFetchTransactionHash.ts +++ b/src/createRollupFetchTransactionHash.ts @@ -1,7 +1,7 @@ import { Address, PublicClient } from 'viem'; import { AbiEvent } from 'abitype'; -import { ParentChainId } from './types/ParentChain'; +import { validateParentChain } from './types/ParentChain'; import { mainnet, arbitrumOne, @@ -56,19 +56,21 @@ export async function createRollupFetchTransactionHash({ rollup, publicClient, }: CreateRollupFetchTransactionHashParams) { - // Find the RollupInitialized event from that Rollup contract - const chainId = await publicClient.getChainId(); + const chainId = validateParentChain(publicClient); + const fromBlock = chainId in Object.keys(earliestRollupCreatorDeploymentBlockNumber) - ? earliestRollupCreatorDeploymentBlockNumber[chainId as ParentChainId] + ? earliestRollupCreatorDeploymentBlockNumber[chainId] : 'earliest'; + // Find the RollupInitialized event from that Rollup contract const rollupInitializedEvents = await publicClient.getLogs({ address: rollup, event: RollupInitializedEventAbi, fromBlock, toBlock: 'latest', }); + if (rollupInitializedEvents.length !== 1) { throw new Error( `Expected to find 1 RollupInitialized event for rollup address ${rollup} but found ${rollupInitializedEvents.length}`, @@ -77,6 +79,7 @@ export async function createRollupFetchTransactionHash({ // Get the transaction hash that emitted that event const transactionHash = rollupInitializedEvents[0].transactionHash; + if (!transactionHash) { throw new Error( `No transactionHash found in RollupInitialized event for rollup address ${rollup}`, diff --git a/src/createRollupPrepareCustomFeeTokenApprovalTransactionRequest.ts b/src/createRollupPrepareCustomFeeTokenApprovalTransactionRequest.ts index e3e1e390..be2524ef 100644 --- a/src/createRollupPrepareCustomFeeTokenApprovalTransactionRequest.ts +++ b/src/createRollupPrepareCustomFeeTokenApprovalTransactionRequest.ts @@ -1,8 +1,8 @@ import { Address, PublicClient } from 'viem'; import { approvePrepareTransactionRequest } from './utils/erc20'; -import { validParentChainId } from './types/ParentChain'; -import { rollupCreator } from './contracts'; +import { validateParentChain } from './types/ParentChain'; +import { getRollupCreatorAddress } from './utils/getters'; import { createRollupDefaultRetryablesFees } from './constants'; import { Prettify } from './types/utils'; @@ -24,16 +24,12 @@ export async function createRollupPrepareCustomFeeTokenApprovalTransactionReques publicClient, rollupCreatorAddressOverride, }: CreateRollupPrepareCustomFeeTokenApprovalTransactionRequestParams) { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } + const chainId = validateParentChain(publicClient); const request = await approvePrepareTransactionRequest({ address: nativeToken, owner: account, - spender: rollupCreatorAddressOverride ?? rollupCreator.address[chainId], + spender: rollupCreatorAddressOverride ?? getRollupCreatorAddress(publicClient), amount, publicClient, }); diff --git a/src/createRollupPrepareTransactionRequest.ts b/src/createRollupPrepareTransactionRequest.ts index ea04e70f..85cfc712 100644 --- a/src/createRollupPrepareTransactionRequest.ts +++ b/src/createRollupPrepareTransactionRequest.ts @@ -4,10 +4,11 @@ import { defaults } from './createRollupDefaults'; import { createRollupGetCallValue } from './createRollupGetCallValue'; import { createRollupGetMaxDataSize } from './createRollupGetMaxDataSize'; import { rollupCreator } from './contracts'; -import { validParentChainId } from './types/ParentChain'; +import { validateParentChain } from './types/ParentChain'; import { isCustomFeeTokenAddress } from './utils/isCustomFeeTokenAddress'; import { ChainConfig } from './types/ChainConfig'; import { isAnyTrustChainConfig } from './utils/isAnyTrustChainConfig'; +import { getRollupCreatorAddress } from './utils/getters'; import { fetchDecimals } from './utils/erc20'; import { TransactionRequestGasOverrides, applyPercentIncrease } from './utils/gasOverrides'; @@ -42,11 +43,7 @@ export async function createRollupPrepareTransactionRequest({ gasOverrides, rollupCreatorAddressOverride, }: CreateRollupPrepareTransactionRequestParams) { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error(`"publicClient.chain" can't be undefined.`); - } + const chainId = validateParentChain(publicClient); if (params.batchPoster === zeroAddress) { throw new Error(`"params.batchPoster" can't be set to the zero address.`); @@ -79,7 +76,7 @@ export async function createRollupPrepareTransactionRequest({ const request = await publicClient.prepareTransactionRequest({ chain: publicClient.chain, - to: rollupCreatorAddressOverride ?? rollupCreator.address[chainId], + to: rollupCreatorAddressOverride ?? getRollupCreatorAddress(publicClient), data: createRollupEncodeFunctionData([paramsWithDefaults]), value: createRollupGetCallValue(paramsWithDefaults), account, diff --git a/src/createTokenBridgeEnoughCustomFeeTokenAllowance.ts b/src/createTokenBridgeEnoughCustomFeeTokenAllowance.ts index 870e4227..28fe7b50 100644 --- a/src/createTokenBridgeEnoughCustomFeeTokenAllowance.ts +++ b/src/createTokenBridgeEnoughCustomFeeTokenAllowance.ts @@ -1,12 +1,11 @@ import { Address, PublicClient } from 'viem'; -import { tokenBridgeCreator } from './contracts'; -import { validParentChainId } from './types/ParentChain'; import { fetchAllowance } from './utils/erc20'; import { createTokenBridgeDefaultRetryablesFees } from './constants'; import { Prettify } from './types/utils'; import { WithTokenBridgeCreatorAddressOverride } from './types/createTokenBridgeTypes'; +import { getTokenBridgeCreatorAddress } from './utils/getters'; export type CreateTokenBridgeEnoughCustomFeeTokenAllowanceParams = Prettify< WithTokenBridgeCreatorAddressOverride<{ @@ -22,16 +21,10 @@ export async function createTokenBridgeEnoughCustomFeeTokenAllowance({ publicClient, tokenBridgeCreatorAddressOverride, }: CreateTokenBridgeEnoughCustomFeeTokenAllowanceParams) { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } - const allowance = await fetchAllowance({ address: nativeToken, owner, - spender: tokenBridgeCreatorAddressOverride ?? tokenBridgeCreator.address[chainId], + spender: tokenBridgeCreatorAddressOverride ?? getTokenBridgeCreatorAddress(publicClient), publicClient, }); diff --git a/src/createTokenBridgeFetchTokenBridgeContracts.ts b/src/createTokenBridgeFetchTokenBridgeContracts.ts index 9a81d711..01e5b8c2 100644 --- a/src/createTokenBridgeFetchTokenBridgeContracts.ts +++ b/src/createTokenBridgeFetchTokenBridgeContracts.ts @@ -4,8 +4,8 @@ import { tokenBridgeCreator } from './contracts'; import { Prettify } from './types/utils'; import { WithTokenBridgeCreatorAddressOverride } from './types/createTokenBridgeTypes'; -import { validParentChainId } from './types/ParentChain'; import { TokenBridgeContracts } from './types/TokenBridgeContracts'; +import { getTokenBridgeCreatorAddress } from './utils/getters'; export type CreateTokenBridgeFetchTokenBridgeContractsParams = Prettify< WithTokenBridgeCreatorAddressOverride<{ @@ -19,14 +19,8 @@ export async function createTokenBridgeFetchTokenBridgeContracts({ parentChainPublicClient, tokenBridgeCreatorAddressOverride, }: CreateTokenBridgeFetchTokenBridgeContractsParams): Promise { - const chainId = parentChainPublicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } - const tokenBridgeCreatorAddress = - tokenBridgeCreatorAddressOverride ?? tokenBridgeCreator.address[chainId]; + tokenBridgeCreatorAddressOverride ?? getTokenBridgeCreatorAddress(parentChainPublicClient); // getting parent chain addresses const [ diff --git a/src/createTokenBridgePrepareCustomFeeTokenApprovalTransactionRequest.ts b/src/createTokenBridgePrepareCustomFeeTokenApprovalTransactionRequest.ts index 566ac671..9c95a191 100644 --- a/src/createTokenBridgePrepareCustomFeeTokenApprovalTransactionRequest.ts +++ b/src/createTokenBridgePrepareCustomFeeTokenApprovalTransactionRequest.ts @@ -1,11 +1,11 @@ import { Address, PublicClient, maxInt256 } from 'viem'; import { approvePrepareTransactionRequest } from './utils/erc20'; -import { validParentChainId } from './types/ParentChain'; -import { tokenBridgeCreator } from './contracts'; import { Prettify } from './types/utils'; +import { validateParentChain } from './types/ParentChain'; import { WithTokenBridgeCreatorAddressOverride } from './types/createTokenBridgeTypes'; +import { getTokenBridgeCreatorAddress } from './utils/getters'; export type CreateTokenBridgePrepareCustomFeeTokenApprovalTransactionRequestParams = Prettify< WithTokenBridgeCreatorAddressOverride<{ @@ -23,16 +23,12 @@ export async function createTokenBridgePrepareCustomFeeTokenApprovalTransactionR publicClient, tokenBridgeCreatorAddressOverride, }: CreateTokenBridgePrepareCustomFeeTokenApprovalTransactionRequestParams) { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } + const chainId = validateParentChain(publicClient); const request = await approvePrepareTransactionRequest({ address: nativeToken, owner, - spender: tokenBridgeCreatorAddressOverride ?? tokenBridgeCreator.address[chainId], + spender: tokenBridgeCreatorAddressOverride ?? getTokenBridgeCreatorAddress(publicClient), amount, publicClient, }); diff --git a/src/createTokenBridgePrepareSetWethGatewayTransactionRequest.ts b/src/createTokenBridgePrepareSetWethGatewayTransactionRequest.ts index f42c5a6b..36c56a54 100644 --- a/src/createTokenBridgePrepareSetWethGatewayTransactionRequest.ts +++ b/src/createTokenBridgePrepareSetWethGatewayTransactionRequest.ts @@ -8,7 +8,7 @@ import { publicClientToProvider } from './ethers-compat/publicClientToProvider'; import { getEstimateForSettingGateway } from './createTokenBridge-ethers'; import { GasOverrideOptions, applyPercentIncrease } from './utils/gasOverrides'; import { Prettify } from './types/utils'; -import { validParentChainId } from './types/ParentChain'; +import { validateParentChain } from './types/ParentChain'; import { WithTokenBridgeCreatorAddressOverride } from './types/createTokenBridgeTypes'; export type TransactionRequestRetryableGasOverrides = { @@ -96,11 +96,7 @@ export async function createTokenBridgePrepareSetWethGatewayTransactionRequest({ retryableGasOverrides, tokenBridgeCreatorAddressOverride, }: CreateTokenBridgePrepareRegisterWethGatewayTransactionRequestParams) { - const chainId = parentChainPublicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } + const chainId = validateParentChain(parentChainPublicClient); // check for custom fee token chain if ( diff --git a/src/createTokenBridgePrepareTransactionRequest.ts b/src/createTokenBridgePrepareTransactionRequest.ts index 9f102dd0..ba8b4798 100644 --- a/src/createTokenBridgePrepareTransactionRequest.ts +++ b/src/createTokenBridgePrepareTransactionRequest.ts @@ -1,7 +1,7 @@ import { Address, PublicClient, encodeFunctionData } from 'viem'; import { tokenBridgeCreator } from './contracts'; -import { validParentChainId } from './types/ParentChain'; +import { validateParentChain } from './types/ParentChain'; import { createTokenBridgeGetInputs } from './createTokenBridge-ethers'; import { publicClientToProvider } from './ethers-compat/publicClientToProvider'; import { isCustomFeeTokenChain } from './utils/isCustomFeeTokenChain'; @@ -13,6 +13,7 @@ import { import { Prettify } from './types/utils'; import { WithTokenBridgeCreatorAddressOverride } from './types/createTokenBridgeTypes'; +import { getTokenBridgeCreatorAddress } from './utils/getters'; export type TransactionRequestRetryableGasOverrides = { maxSubmissionCostForFactory?: GasOverrideOptions; @@ -42,14 +43,10 @@ export async function createTokenBridgePrepareTransactionRequest({ retryableGasOverrides, tokenBridgeCreatorAddressOverride, }: CreateTokenBridgePrepareTransactionRequestParams) { - const chainId = parentChainPublicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } + const chainId = validateParentChain(parentChainPublicClient); const tokenBridgeCreatorAddress = - tokenBridgeCreatorAddressOverride ?? tokenBridgeCreator.address[chainId]; + tokenBridgeCreatorAddressOverride ?? getTokenBridgeCreatorAddress(parentChainPublicClient); const parentChainProvider = publicClientToProvider(parentChainPublicClient); const orbitChainProvider = publicClientToProvider(orbitChainPublicClient); diff --git a/src/prepareNodeConfig.ts b/src/prepareNodeConfig.ts index 7651e8ab..04806070 100644 --- a/src/prepareNodeConfig.ts +++ b/src/prepareNodeConfig.ts @@ -5,7 +5,7 @@ import { } from './types/NodeConfig'; import { ChainConfig } from './types/ChainConfig'; import { CoreContracts } from './types/CoreContracts'; -import { ParentChainId, validParentChainId } from './types/ParentChain'; +import { ParentChainId, validateParentChain } from './types/ParentChain'; import { mainnet, arbitrumOne, @@ -66,17 +66,13 @@ export function prepareNodeConfig({ parentChainId: number; parentChainRpcUrl: string; }): NodeConfig { - if (!validParentChainId(parentChainId)) { - throw new Error(`[prepareNodeConfig] invalid parent chain id: ${parentChainId}`); - } - const config: NodeConfig = { 'chain': { 'info-json': stringifyInfoJson([ { 'chain-id': chainConfig.chainId, 'parent-chain-id': parentChainId, - 'parent-chain-is-arbitrum': parentChainIsArbitrum(parentChainId), + 'parent-chain-is-arbitrum': parentChainIsArbitrum(validateParentChain(parentChainId)), 'chain-name': chainName, 'chain-config': chainConfig, 'rollup': { diff --git a/src/setValidKeyset.ts b/src/setValidKeyset.ts index 1cf6d55b..167ae813 100644 --- a/src/setValidKeyset.ts +++ b/src/setValidKeyset.ts @@ -1,7 +1,7 @@ import { PublicClient, WalletClient } from 'viem'; import { upgradeExecutor } from './contracts'; -import { validParentChainId } from './types/ParentChain'; +import { validateParentChain } from './types/ParentChain'; import { CoreContracts } from './types/CoreContracts'; import { setValidKeysetEncodeFunctionData } from './setValidKeysetEncodeFunctionData'; @@ -18,13 +18,9 @@ export async function setValidKeyset({ publicClient, walletClient, }: SetValidKeysetParams) { - const chainId = publicClient.chain?.id; + validateParentChain(publicClient); const account = walletClient.account?.address; - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } - if (typeof account === 'undefined') { throw new Error('account is undefined'); } diff --git a/src/setValidKeysetPrepareTransactionRequest.ts b/src/setValidKeysetPrepareTransactionRequest.ts index 1ed2fe2a..927226c1 100644 --- a/src/setValidKeysetPrepareTransactionRequest.ts +++ b/src/setValidKeysetPrepareTransactionRequest.ts @@ -1,6 +1,6 @@ import { Address } from 'viem'; -import { validParentChainId } from './types/ParentChain'; +import { validateParentChain } from './types/ParentChain'; import { SetValidKeysetParams } from './setValidKeyset'; import { setValidKeysetEncodeFunctionData } from './setValidKeysetEncodeFunctionData'; import { upgradeExecutorEncodeFunctionData } from './upgradeExecutor'; @@ -18,11 +18,7 @@ export async function setValidKeysetPrepareTransactionRequest({ account, publicClient, }: SetValidKeysetPrepareTransactionRequestParams) { - const chainId = publicClient.chain?.id; - - if (!validParentChainId(chainId)) { - throw new Error('chainId is undefined'); - } + const chainId = validateParentChain(publicClient); const request = await publicClient.prepareTransactionRequest({ chain: publicClient.chain, diff --git a/src/types/ParentChain.ts b/src/types/ParentChain.ts index 7baef329..1b82b49c 100644 --- a/src/types/ParentChain.ts +++ b/src/types/ParentChain.ts @@ -1,11 +1,23 @@ +import { PublicClient } from 'viem'; import { chains } from '../chains'; export type ParentChain = (typeof chains)[number]; export type ParentChainId = ParentChain['id']; -export function validParentChainId( - parentChainId: number | undefined, -): parentChainId is ParentChainId { +function isValidParentChainId(parentChainId: number | undefined): parentChainId is ParentChainId { const ids = chains.map((chain) => chain.id) as Number[]; return ids.includes(Number(parentChainId)); } + +export function validateParentChain(chainIdOrPublicClient: number | PublicClient): ParentChainId { + const chainId = + typeof chainIdOrPublicClient === 'number' + ? chainIdOrPublicClient + : chainIdOrPublicClient.chain?.id; + + if (!isValidParentChainId(chainId)) { + throw new Error(`Parent chain not supported: ${chainId}`); + } + + return chainId; +} diff --git a/src/utils/getters.ts b/src/utils/getters.ts new file mode 100644 index 00000000..90055f91 --- /dev/null +++ b/src/utils/getters.ts @@ -0,0 +1,24 @@ +import { PublicClient } from 'viem'; + +import { rollupCreator, tokenBridgeCreator } from '../contracts'; +import { validateParentChain } from '../types/ParentChain'; + +export function getRollupCreatorAddress(client: PublicClient) { + const chainId = validateParentChain(client); + + if (!rollupCreator.address[chainId]) { + throw new Error(`Parent chain not supported: ${chainId}`); + } + + return rollupCreator.address[chainId]; +} + +export function getTokenBridgeCreatorAddress(client: PublicClient) { + const chainId = validateParentChain(client); + + if (!tokenBridgeCreator.address[chainId]) { + throw new Error(`Parent chain not supported: ${chainId}`); + } + + return tokenBridgeCreator.address[chainId]; +}