diff --git a/.changeset/mighty-lions-move.md b/.changeset/mighty-lions-move.md new file mode 100644 index 0000000000..410c17f656 --- /dev/null +++ b/.changeset/mighty-lions-move.md @@ -0,0 +1,5 @@ +--- +"@latticexyz/explorer": patch +--- + +Transactions in `Observe` tab now display decoded `callFrom` function calls. 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 72eebc95b3..8d808b3430 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 @@ -8,7 +8,7 @@ import { cn } from "../../../../../../utils"; import { Confirmations } from "./Confirmations"; import { TimingRowExpanded } from "./TimingRowExpanded"; import { columns } from "./TransactionsTable"; -import { ObservedTransaction } from "./useObservedTransactions"; +import { ObservedTransaction } from "./useMergedTransactions"; function TransactionTableRowDataCell({ label, 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 902a9920fb..3568f6b215 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 @@ -12,7 +12,7 @@ import { BlockExplorerLink } from "./BlockExplorerLink"; import { TimeAgo } from "./TimeAgo"; import { TimingRowHeader } from "./TimingRowHeader"; import { TransactionTableRow } from "./TransactionTableRow"; -import { ObservedTransaction, useObservedTransactions } from "./useObservedTransactions"; +import { ObservedTransaction, useMergedTransactions } from "./useMergedTransactions"; const columnHelper = createColumnHelper(); export const columns = [ @@ -101,7 +101,7 @@ export const columns = [ ]; export function TransactionsTable() { - const transactions = useObservedTransactions(); + const transactions = useMergedTransactions(); const [expanded, setExpanded] = useState({}); const table = useReactTable({ 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 31f013d285..1af163b118 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 @@ -74,7 +74,7 @@ export function TransactionsWatcher() { setTransaction({ hash, writeId: writeId ?? hash, - from: transaction.from, + from: calls[0]?.from ?? transaction.from, timestamp, transaction, calls, diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useMergedTransactions.ts similarity index 97% rename from packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts rename to packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useMergedTransactions.ts index 76f4bf58ee..10344a89a7 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions.ts +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useMergedTransactions.ts @@ -8,6 +8,7 @@ import { store as worldStore } from "../store"; export type DecodedUserOperationCall = { to?: Address; + from?: Address; functionName: string; args?: readonly unknown[]; value?: bigint; @@ -28,7 +29,7 @@ export type ObservedTransaction = { error?: BaseError; }; -export function useObservedTransactions() { +export function useMergedTransactions() { const { worldAddress } = useParams<{ worldAddress: string }>(); const transactions = useStore(worldStore, (state) => state.transactions); const observerWrites = useStore(observerStore, (state) => state.writes); diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/utils/getDecodedUserOperationCalls.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/utils/getDecodedUserOperationCalls.ts index cf8b3ff735..d47260a9a4 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/utils/getDecodedUserOperationCalls.ts +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/observe/utils/getDecodedUserOperationCalls.ts @@ -1,5 +1,5 @@ import { Abi, Address, Hex, decodeFunctionData } from "viem"; -import { DecodedUserOperationCall } from "../useObservedTransactions"; +import { DecodedUserOperationCall } from "../useMergedTransactions"; export function getDecodedUserOperationCalls({ abi, @@ -36,16 +36,27 @@ function getDecodedUserOperationCall({ }): DecodedUserOperationCall { let functionName: string | undefined; let args: readonly unknown[] | undefined; + let from: Address | undefined; + try { const functionData = decodeFunctionData({ abi, data: data }); functionName = functionData.functionName; args = functionData.args; + + if (functionName === "callFrom") { + const [delegator, , data] = args as [Address, Hex, Hex]; + const decodedCallData = decodeFunctionData({ abi, data }); + functionName = decodedCallData.functionName; + args = decodedCallData.args; + from = delegator; + } } catch (error) { functionName = data.length > 10 ? data.slice(0, 10) : "unknown"; } return { to: target, + from, functionName, args, value, diff --git a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/store.ts b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/store.ts index 007159fcf1..c018e391b9 100644 --- a/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/store.ts +++ b/packages/explorer/src/app/(explorer)/[chainName]/worlds/[worldAddress]/store.ts @@ -1,5 +1,5 @@ import { createStore } from "zustand"; -import { ObservedTransaction } from "./observe/useObservedTransactions"; +import { ObservedTransaction } from "./observe/useMergedTransactions"; export type State = { transactions: ObservedTransaction[]; diff --git a/packages/explorer/src/observer/decorator.ts b/packages/explorer/src/observer/decorator.ts index ef6f912b63..26bd5032d5 100644 --- a/packages/explorer/src/observer/decorator.ts +++ b/packages/explorer/src/observer/decorator.ts @@ -49,7 +49,9 @@ export function observer({ explorerUrl = "http://localhost:13690", waitForTransa emit("write", { writeId, - from: client.account!.address, + // TODO: type as SessionClient once available from entrykit + // eslint-disable-next-line @typescript-eslint/no-explicit-any + from: (client as any).userAddress ?? client.account!.address, calls, }); Promise.allSettled([write]).then(([result]) => { diff --git a/packages/explorer/src/observer/messages.ts b/packages/explorer/src/observer/messages.ts index 196e657948..4943818e95 100644 --- a/packages/explorer/src/observer/messages.ts +++ b/packages/explorer/src/observer/messages.ts @@ -1,6 +1,6 @@ import { Address, Hash } from "viem"; import { UserOperationReceipt } from "viem/account-abstraction"; -import { DecodedUserOperationCall } from "../app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions"; +import { DecodedUserOperationCall } from "../app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useMergedTransactions"; import { ReceiptSummary } from "./common"; export type Messages = { diff --git a/packages/explorer/src/observer/store.ts b/packages/explorer/src/observer/store.ts index 5b56ece47c..8fc547b194 100644 --- a/packages/explorer/src/observer/store.ts +++ b/packages/explorer/src/observer/store.ts @@ -2,7 +2,7 @@ import { Address, Hash } from "viem"; import { createStore } from "zustand/vanilla"; -import { DecodedUserOperationCall } from "../app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useObservedTransactions"; +import { DecodedUserOperationCall } from "../app/(explorer)/[chainName]/worlds/[worldAddress]/observe/useMergedTransactions"; import { isPromiseFulfilled } from "../utils"; import { relayChannelName } from "./common"; import { debug } from "./debug"; @@ -12,8 +12,8 @@ export type Write = { writeId: string; type: MessageType; hash?: Hash; - userOpHash?: Hash; from: Address; + userOpHash?: Hash; time: number; calls: DecodedUserOperationCall[]; events: Message>[];