From 2ceb3a2b631fb220ce89fa0d9ff7c925ef8610f9 Mon Sep 17 00:00:00 2001 From: wilsoncusack Date: Sat, 26 Aug 2023 22:08:18 -0400 Subject: [PATCH] add method to getWithdrawalMessages from a transaciton (#21) --- .../public/getL2HashesForDepositTx.test.ts} | 2 +- .../public/getWithdrawalMessages.test.ts | 24 +++++++++ src/actions/public/getWithdrawalMessages.ts | 49 +++++++++++++++++++ src/decorators/publicOpStack.ts | 7 ++- 4 files changed, 80 insertions(+), 2 deletions(-) rename src/{_test/index.test.ts => actions/public/getL2HashesForDepositTx.test.ts} (89%) create mode 100644 src/actions/public/getWithdrawalMessages.test.ts create mode 100644 src/actions/public/getWithdrawalMessages.ts diff --git a/src/_test/index.test.ts b/src/actions/public/getL2HashesForDepositTx.test.ts similarity index 89% rename from src/_test/index.test.ts rename to src/actions/public/getL2HashesForDepositTx.test.ts index 242f9b7e..44c8575d 100644 --- a/src/_test/index.test.ts +++ b/src/actions/public/getL2HashesForDepositTx.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest' import { createPublicClient, http } from 'viem' import { mainnet } from '@wagmi/chains' -import { publicOpStackActions } from '../decorators/publicOpStack' +import { publicOpStackActions } from '../../decorators/publicOpStack' test('correctly retrieves L2 hash', async () => { const client = createPublicClient({ diff --git a/src/actions/public/getWithdrawalMessages.test.ts b/src/actions/public/getWithdrawalMessages.test.ts new file mode 100644 index 00000000..8dcd9485 --- /dev/null +++ b/src/actions/public/getWithdrawalMessages.test.ts @@ -0,0 +1,24 @@ +import { test, expect } from 'vitest' +import { createPublicClient, http } from 'viem' +import { base } from '@wagmi/chains' +import { publicOpStackActions } from '../../decorators/publicOpStack' + +test('correctly retrieves L2 hash', async () => { + const client = createPublicClient({ + chain: base, + transport: http(), + }).extend(publicOpStackActions) + + const messages = await client.getWithdrawalMessages({ + hash: + '0x999bab960dbdf600c51371ae819957063337a50cec2eb8032412739defadabe7', + }) + expect(messages.length).toEqual(1) + expect(messages[0].nonce).toBeDefined() + expect(messages[0].gasLimit).toBeDefined() + expect(messages[0].data).toBeDefined() + expect(messages[0].value).toBeDefined() + expect(messages[0].sender).toBeDefined() + expect(messages[0].target).toBeDefined() + expect(messages[0].withdrawalHash).toBeDefined() +}) diff --git a/src/actions/public/getWithdrawalMessages.ts b/src/actions/public/getWithdrawalMessages.ts new file mode 100644 index 00000000..67d6ac43 --- /dev/null +++ b/src/actions/public/getWithdrawalMessages.ts @@ -0,0 +1,49 @@ +import { type PublicClient, Chain, Transport, Hash, Address, Hex, decodeEventLog } from 'viem' +import { l2ToL1MessagePasserABI } from '@eth-optimism/contracts-ts' + +export type MessagePassedEvent = { + nonce: bigint, + sender: Address, + target: Address, + value: bigint, + gasLimit: bigint, + data: Hex, + withdrawalHash: Hex +} + +export type GetWithdrawalMessagesParameters = { + hash: Hash +} + +export type GetWithdrawalMessagesReturnType = MessagePassedEvent[] + +/** + * Retrieves all MessagePassed events from a withdrawal transaction + * + * @param client - Public client to use + * @param parameters - {@link GetWithdrawalMessagesParameters} + * @returns An array of all MessagePassed events emitted in this transaction. {@link GetWithdrawalMessagesReturnType} + */ +export async function getWithdrawalMessages( + client: PublicClient, + { hash }: GetWithdrawalMessagesParameters, +): Promise { + const receipt = await client.getTransactionReceipt({ hash }) + const events: MessagePassedEvent[] = [] + for (const log of receipt.logs) { + /// These transactions will contain events from several contracts + /// this decode will revert for events not from l2ToL1MessagePasserABI + /// we are OK ignoring these events + try { + const event = decodeEventLog({ + abi: l2ToL1MessagePasserABI, + data: log.data, + topics: log.topics, + }) + if (event.eventName === 'MessagePassed') { + events.push(event.args) + } + } catch {} + } + return events; +} diff --git a/src/decorators/publicOpStack.ts b/src/decorators/publicOpStack.ts index c579963a..682aaaed 100644 --- a/src/decorators/publicOpStack.ts +++ b/src/decorators/publicOpStack.ts @@ -1,9 +1,10 @@ -import { Account, Chain, Client, type PublicClient, Transport } from 'viem' +import { Chain, type PublicClient, Transport } from 'viem' import { GetL2HashesForDepositTxParamters, GetL2HashesForDepositTxReturnType, getL2HashesForDepositTx, } from '../actions/public/getL2HashesForDepositTx' +import { GetWithdrawalMessagesParameters, GetWithdrawalMessagesReturnType, getWithdrawalMessages } from '../actions/public/getWithdrawalMessages' /// NOTE We don't currently need account for exisiting actions but keeping in case export type PublicOpStackActions< @@ -13,6 +14,9 @@ export type PublicOpStackActions< getL2HashesForDepositTx: ( args: GetL2HashesForDepositTxParamters, ) => Promise + getWithdrawalMessages: ( + args: GetWithdrawalMessagesParameters, + ) => Promise } export function publicOpStackActions< @@ -23,5 +27,6 @@ export function publicOpStackActions< ): PublicOpStackActions { return { getL2HashesForDepositTx: (args) => getL2HashesForDepositTx(client, args), + getWithdrawalMessages: (args) => getWithdrawalMessages(client, args), } }