From fa4c13099a699462136bbe8c4f8e030dd8af71f3 Mon Sep 17 00:00:00 2001 From: karooolis Date: Sun, 27 Oct 2024 10:23:37 +0200 Subject: [PATCH] add value, calls always an array --- .../observe/TransactionTableRow.tsx | 30 ++++++++-------- .../observe/TransactionsTable.tsx | 2 +- .../observe/TransactionsWatcher.tsx | 34 ++++++++++-------- .../worlds/[worldAddress]/observe/helpers.ts | 36 ++++++++++++++----- .../observe/useObservedTransactions.ts | 4 +-- packages/explorer/src/observer/decorator.ts | 33 ++++++++--------- packages/explorer/src/observer/messages.ts | 9 ++--- packages/explorer/src/observer/store.ts | 5 ++- 8 files changed, 87 insertions(+), 66 deletions(-) diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx index baa849259f..6176719908 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionTableRow.tsx @@ -82,23 +82,21 @@ export function TransactionTableRow({ row }: { row: Row })

Inputs

- {(Array.isArray(data.calls) && data.calls.length > 0) || data.calls ? ( + {data.calls.length > 0 ? (
- {(Array.isArray(data.calls) ? data.calls : [data.calls]).map((call, idx) => { - return ( -
- {call.functionName}: - {call.args?.map((arg, idx) => ( -
- arg {idx + 1}: - - {typeof arg === "object" && arg !== null ? JSON.stringify(arg, null, 2) : String(arg)} - -
- ))} -
- ); - })} + {data.calls.map((call, idx) => ( +
+ {call.functionName}: + {call.args?.map((arg, argIdx) => ( +
+ arg {argIdx + 1}: + + {typeof arg === "object" && arg !== null ? JSON.stringify(arg, null, 2) : String(arg)} + +
+ ))} +
+ ))}
) : (

No inputs

diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsTable.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsTable.tsx index d6b90976de..902a9920fb 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsTable.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsTable.tsx @@ -53,7 +53,7 @@ export const columns = [ return (
- {(Array.isArray(calls) ? calls : [calls]).map(({ functionName }, idx) => ( + {calls.map(({ functionName }, idx) => ( {functionName} diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsWatcher.tsx b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsWatcher.tsx index 1b8a85e9dd..d67f2b5bdb 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsWatcher.tsx +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsWatcher.tsx @@ -20,7 +20,7 @@ import { useChain } from "../../../../hooks/useChain"; import { useWorldAbiQuery } from "../../../../queries/useWorldAbiQuery"; import { store as worldStore } from "../store"; import { userOperationEventAbi } from "./abis"; -import { getCalls } from "./helpers"; +import { getDecodedUserOperationCalls } from "./helpers"; export function TransactionsWatcher() { const { id: chainId } = useChain(); @@ -58,13 +58,19 @@ export function TransactionsWatcher() { }); const { functionName: decodedFunctionName, args: decodedArgs } = decodedSmartAccountCall; - const calls = getCalls(decodedFunctionName, decodedArgs, transaction); + const calls = getDecodedUserOperationCalls({ + functionName: decodedFunctionName, + decodedArgs, + transaction, + }).filter(({ to }) => to && getAddress(to) === getAddress(worldAddress)); // TODO: filter earlier + if (calls.length === 0) return; + const logs = parseEventLogs({ abi: [...abi, userOperationEventAbi], logs: receipt.logs, }); - console.log("calls", calls); + console.log("RECEIPT", receipt); setTransaction({ hash, @@ -76,11 +82,11 @@ export function TransactionsWatcher() { receipt, logs, value: transaction.value, - status: receipt.status, // TODO: correct status check + status: receipt.status, error: undefined, // TODO: transactionError as BaseError, }); }, - [abi, setTransaction], + [abi, setTransaction, worldAddress], ); const handleUserOperations = useCallback( @@ -94,14 +100,12 @@ export function TransactionsWatcher() { data: transaction.input, }); - // decodedEntryPointCall.args[0] is an array of UserOperation<"0.7"> - // decodedEntryPointCall.args[1] is `beneficiary` const userOperations = decodedEntryPointCall.args[0] as never as UserOperation<"0.7">[]; for (const userOperation of userOperations) { handleUserOperation({ hash, writeId, timestamp, receipt, transaction, userOperation }); } }, - [abi, observerWrites, handleUserOperation, wagmiConfig], + [abi, handleUserOperation, wagmiConfig], ); const handleAuthenticTransaction = useCallback( @@ -116,7 +120,7 @@ export function TransactionsWatcher() { timestamp: bigint; transaction: Transaction; }) => { - if (!abi) return; + if (!abi || !transaction.to) return; let functionName: string | undefined; let args: readonly unknown[] | undefined; @@ -138,11 +142,13 @@ export function TransactionsWatcher() { timestamp, transaction, status: "pending", - calls: { - to: transaction.to, - functionName, - args, - }, + calls: [ + { + to: transaction.to, + functionName, + args, + }, + ], value: transaction.value, }); diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/helpers.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/helpers.ts index dfcf611e97..470aca4bde 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/helpers.ts +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/helpers.ts @@ -1,22 +1,41 @@ import { Address, Hex, Transaction, decodeFunctionData } from "viem"; +import { DecodedUserOperationCall } from "../../../../../../observer/messages"; import { doomWorldAbi } from "./abis"; -export function getCalls(decodedFunctionName: string, decodedArgs: readonly unknown[], transaction: Transaction) { - if (decodedFunctionName === "execute") { +export function getDecodedUserOperationCalls({ + functionName, + decodedArgs, + transaction, +}: { + functionName: string; + decodedArgs: readonly unknown[]; + transaction: Transaction; +}) { + if (functionName === "execute") { const target = decodedArgs[0] as Address; - // const value = decodedArgs[1]; // TODO: handle value + const value = decodedArgs[1] as bigint; const data = decodedArgs[2] as Hex; - return getCall(target, data, transaction); - } else if (decodedFunctionName === "executeBatch") { - return (decodedArgs[0] as { target: Address; data: Hex }[]).map((worldFunction) => - getCall(worldFunction.target, worldFunction.data, transaction), + return [getDecodedUserOperationCall({ target, data, transaction, value })]; + } else if (functionName === "executeBatch") { + return (decodedArgs[0] as { target: Address; data: Hex; value: bigint }[]).map(({ target, data, value }) => + getDecodedUserOperationCall({ target, data, transaction, value }), ); } return []; } -function getCall(target: Address, data: Hex, transaction: Transaction) { +function getDecodedUserOperationCall({ + target, + data, + transaction, + value, +}: { + target: Address; + data: Hex; + transaction: Transaction; + value: bigint; +}): DecodedUserOperationCall { let functionName: string | undefined; let args: readonly unknown[] | undefined; try { @@ -31,5 +50,6 @@ function getCall(target: Address, data: Hex, transaction: Transaction) { to: target, functionName, args, + value, }; } diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts index fe3c7a69e9..7dbd8b84ab 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts @@ -1,7 +1,7 @@ import { Address, BaseError, Hex, Log, Transaction, TransactionReceipt } from "viem"; import { useStore } from "zustand"; import { useMemo } from "react"; -import { Message, UserOperationCall } from "../../../../../../observer/messages"; +import { DecodedUserOperationCall, Message } from "../../../../../../observer/messages"; import { type Write, store as observerStore } from "../../../../../../observer/store"; import { store as worldStore } from "../store"; @@ -11,7 +11,7 @@ export type ObservedTransaction = { from?: Address; timestamp?: bigint; transaction?: Transaction; - calls: UserOperationCall | UserOperationCall[]; + calls: DecodedUserOperationCall[]; value?: bigint; receipt?: TransactionReceipt; status: "pending" | "success" | "reverted" | "rejected" | "unknown"; diff --git a/packages/explorer/src/observer/decorator.ts b/packages/explorer/src/observer/decorator.ts index ea32e1cba0..72cb1f842d 100644 --- a/packages/explorer/src/observer/decorator.ts +++ b/packages/explorer/src/observer/decorator.ts @@ -2,10 +2,9 @@ import { Account, Chain, Client, Hex, Transport, WalletActions } from "viem"; import { BundlerActions, sendUserOperation, waitForUserOperationReceipt } from "viem/account-abstraction"; import { waitForTransactionReceipt, writeContract } from "viem/actions"; import { getAction } from "viem/utils"; -import { isDefined } from "@latticexyz/common/utils"; import { createBridge } from "./bridge"; import { ReceiptSummary } from "./common"; -import { UserOperationCall } from "./messages"; +import { DecodedUserOperationCall } from "./messages"; export type WaitForTransaction = (hash: Hex) => Promise; @@ -31,22 +30,20 @@ export function observer({ explorerUrl = "http://localhost:13690", waitForTransa const writeId = `${client.uid}-${++writeCounter}`; const write = getAction(client, sendUserOperation, "sendUserOperation")(args); - let calls: UserOperationCall[] = []; + let calls: DecodedUserOperationCall[] = []; if ("calls" in args && args.calls) { - calls = args.calls - .map((call) => { - // TODO: make this nicer - if (call && typeof call === "object" && "functionName" in call && "args" in call && "to" in call) { - return { - to: call.to, - functionName: call.functionName, - args: call.args, - } as UserOperationCall; - } - - return undefined; - }) - .filter(isDefined); + calls = args.calls.map((call) => { + return { + // @ts-expect-error TODO: fix + to: call.to, + // @ts-expect-error TODO: fix + functionName: call.functionName, + // @ts-expect-error TODO: fix + args: call.args, + // @ts-expect-error TODO: fix + value: call.value, + }; + }); } emit("write", { @@ -87,9 +84,9 @@ export function observer({ explorerUrl = "http://localhost:13690", waitForTransa to: args.address, functionName: args.functionName, args: (args.args ?? []) as never, + value: args.value, }, ], - value: args.value, // TODO: how to handle value? }); Promise.allSettled([write]).then(([result]) => { emit("write:result", { ...result, writeId }); diff --git a/packages/explorer/src/observer/messages.ts b/packages/explorer/src/observer/messages.ts index cb5570782c..f27fa8f2a9 100644 --- a/packages/explorer/src/observer/messages.ts +++ b/packages/explorer/src/observer/messages.ts @@ -3,10 +3,11 @@ import { UserOperationReceipt } from "viem/account-abstraction"; import { ReceiptSummary } from "./common"; // TODO: fix type, move elsewhere -export type UserOperationCall = { - to: Address | null; +export type DecodedUserOperationCall = { + to?: Address; functionName: string; - args: unknown; + args: unknown[]; + value?: bigint; }; export type Messages = { @@ -18,7 +19,7 @@ export type Messages = { write: { writeId: string; from: Address; - calls: UserOperationCall[]; + calls: DecodedUserOperationCall[]; value?: bigint; }; "write:result": PromiseSettledResult & { writeId: string }; diff --git a/packages/explorer/src/observer/store.ts b/packages/explorer/src/observer/store.ts index 981a397227..a03fd3ecb0 100644 --- a/packages/explorer/src/observer/store.ts +++ b/packages/explorer/src/observer/store.ts @@ -4,7 +4,7 @@ import { Address, Hash } from "viem"; import { createStore } from "zustand/vanilla"; import { relayChannelName } from "./common"; import { debug } from "./debug"; -import { Message, MessageType, UserOperationCall } from "./messages"; +import { DecodedUserOperationCall, Message, MessageType } from "./messages"; export type Write = { writeId: string; @@ -13,8 +13,7 @@ export type Write = { userOpHash?: Hash; from: Address; time: number; - calls: UserOperationCall | UserOperationCall[]; - value?: bigint; + calls: DecodedUserOperationCall[]; events: Message>[]; error?: Error; };