diff --git a/src/actions/getConfirmPeriodBlocks.ts b/src/actions/getConfirmPeriodBlocks.ts new file mode 100644 index 00000000..82c5981f --- /dev/null +++ b/src/actions/getConfirmPeriodBlocks.ts @@ -0,0 +1,29 @@ +import { Chain, PublicClient, ReadContractReturnType, Transport } from 'viem'; +import { rollupABI } from '../contracts/Rollup'; +import { WithContractAddress } from '../types/Actions'; +import { getRollupAddress } from '../getRollupAddress'; + +export type GetConfirmPeriodBlocksParameters = WithContractAddress< + {}, + 'rollupAdminLogic', + Curried +>; + +export type GetConfirmPeriodBlocksReturnType = ReadContractReturnType< + typeof rollupABI, + 'confirmPeriodBlocks' +>; + +export async function getConfirmPeriodBlocks( + client: PublicClient, + args: GetConfirmPeriodBlocksParameters, +): Promise { + const rollupAdminLogicAddress = + 'sequencerInbox' in args ? await getRollupAddress(client, args) : args.rollupAdminLogic; + + return client.readContract({ + abi: rollupABI, + functionName: 'confirmPeriodBlocks', + address: rollupAdminLogicAddress, + }); +} diff --git a/src/actions/getExtraChallengeTimeBlocks.ts b/src/actions/getExtraChallengeTimeBlocks.ts new file mode 100644 index 00000000..0a9cd4ac --- /dev/null +++ b/src/actions/getExtraChallengeTimeBlocks.ts @@ -0,0 +1,25 @@ +import { Chain, PublicClient, ReadContractReturnType, Transport } from 'viem'; +import { rollupABI } from '../contracts/Rollup'; +import { WithContractAddress } from '../types/Actions'; +import { getRollupAddress } from '../getRollupAddress'; + +export type GetExtraChallengeTimeBlocksParameters = + WithContractAddress<{}, 'rollupAdminLogic', Curried>; + +export type GetExtraChallengeTimeBlocksReturnType = ReadContractReturnType< + typeof rollupABI, + 'extraChallengeTimeBlocks' +>; + +export async function getExtraChallengeTimeBlocks( + client: PublicClient, + args: GetExtraChallengeTimeBlocksParameters, +): Promise { + const rollupAdminLogicAddress = + 'sequencerInbox' in args ? await getRollupAddress(client, args) : args.rollupAdminLogic; + return client.readContract({ + abi: rollupABI, + functionName: 'extraChallengeTimeBlocks', + address: rollupAdminLogicAddress, + }); +} diff --git a/src/actions/getMinimumAssertionPeriod.ts b/src/actions/getMinimumAssertionPeriod.ts new file mode 100644 index 00000000..b9612711 --- /dev/null +++ b/src/actions/getMinimumAssertionPeriod.ts @@ -0,0 +1,25 @@ +import { Chain, PublicClient, ReadContractReturnType, Transport } from 'viem'; +import { rollupABI } from '../contracts/Rollup'; +import { WithContractAddress } from '../types/Actions'; +import { getRollupAddress } from '../getRollupAddress'; + +export type GetMinimumAssertionPeriodParameters = + WithContractAddress<{}, 'rollupAdminLogic', Curried>; + +export type GetMinimumAssertionPeriodReturnType = ReadContractReturnType< + typeof rollupABI, + 'minimumAssertionPeriod' +>; + +export async function getMinimumAssertionPeriod( + client: PublicClient, + args: GetMinimumAssertionPeriodParameters, +): Promise { + const rollupAdminLogicAddress = + 'sequencerInbox' in args ? await getRollupAddress(client, args) : args.rollupAdminLogic; + return client.readContract({ + abi: rollupABI, + functionName: 'minimumAssertionPeriod', + address: rollupAdminLogicAddress, + }); +} diff --git a/src/actions/getWasmModuleRoot.ts b/src/actions/getWasmModuleRoot.ts new file mode 100644 index 00000000..4d5f2ea8 --- /dev/null +++ b/src/actions/getWasmModuleRoot.ts @@ -0,0 +1,28 @@ +import { Chain, PublicClient, ReadContractReturnType, Transport } from 'viem'; +import { rollupABI } from '../contracts/Rollup'; +import { WithContractAddress } from '../types/Actions'; +import { getRollupAddress } from '../getRollupAddress'; + +export type GetWasmModuleRootParameters = WithContractAddress< + {}, + 'rollupAdminLogic', + Curried +>; + +export type GetWasmModuleRootReturnType = ReadContractReturnType< + typeof rollupABI, + 'wasmModuleRoot' +>; + +export async function getWasmModuleRoot( + client: PublicClient, + args: GetWasmModuleRootParameters, +): Promise { + const rollupAdminLogicAddress = + 'sequencerInbox' in args ? await getRollupAddress(client, args) : args.rollupAdminLogic; + return client.readContract({ + abi: rollupABI, + functionName: 'wasmModuleRoot', + address: rollupAdminLogicAddress, + }); +} diff --git a/src/getRollupAddress.ts b/src/getRollupAddress.ts new file mode 100644 index 00000000..59a7428b --- /dev/null +++ b/src/getRollupAddress.ts @@ -0,0 +1,22 @@ +import { Address, Chain, PublicClient, Transport } from 'viem'; +import { sequencerInboxABI } from './contracts/SequencerInbox'; + +const cache: Record = {}; +export async function getRollupAddress( + publicClient: PublicClient, + params: { sequencerInbox: Address }, +): Promise
{ + const addressFromCache = cache[`${publicClient.chain.id}_${params.sequencerInbox}`]; + if (addressFromCache) { + return addressFromCache; + } + + // Otherwise, fetch the rollup address from sequencerInbox contract + const rollupAddress = await publicClient.readContract({ + functionName: 'rollup', + address: params.sequencerInbox, + abi: sequencerInboxABI, + }); + cache[`${publicClient.chain.id}_${params.sequencerInbox}`] = rollupAddress; + return rollupAddress; +} diff --git a/src/types/Actions.ts b/src/types/Actions.ts index 71093865..9a89614f 100644 --- a/src/types/Actions.ts +++ b/src/types/Actions.ts @@ -30,3 +30,35 @@ export type WithUpgradeExecutor = Args & { export type PrepareTransactionRequestReturnTypeWithChainId = PrepareTransactionRequestReturnType & { chainId: number; }; + +/** + * Some actions require a different contract than sequencerInbox. + * We either accept sequencerInbox to fetch the contract address + * or an override + */ +export type WithContractAddress< + Args, + ContractName extends string, + Curried extends boolean, +> = Curried extends true + ? /** + * If sequencerInbox was passed to the decorator. We accept the contract address, + * an sequencerInbox override, or no parameters + */ + | (Args & { + sequencerInbox?: Address; + }) + | (Args & { + [key in ContractName]?: Address; + }) + | void + : /** + * If sequencerInbox wasn't passed to the decorator. We need one of the address to be passed + * We either accept the contract address or an sequencerInbox override + */ + | (Args & { + sequencerInbox: Address; + }) + | (Args & { + [key in ContractName]: Address; + });