Skip to content

Commit

Permalink
send user op via observer
Browse files Browse the repository at this point in the history
  • Loading branch information
karooolis committed Oct 24, 2024
1 parent 6a927e8 commit fe86e95
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 95 deletions.
172 changes: 88 additions & 84 deletions packages/explorer/src/observer/decorator.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
import {
Account,
Chain,
Client,
Hex,
Transport,
WalletActions,
decodeFunctionData,
getAbiItem,
parseAbi,
parseEventLogs,
} from "viem";
import {
entryPoint07Abi,
entryPoint07Address,
getUserOperation,
getUserOperationHash,
sendUserOperation,
waitForUserOperationReceipt,
} from "viem/account-abstraction";
import { Account, Chain, Client, Hex, Transport, WalletActions, decodeFunctionData, getAbiItem, parseAbi } from "viem";
import { entryPoint07Abi, entryPoint07Address, sendUserOperation } from "viem/account-abstraction";
import { getTransaction, waitForTransactionReceipt, writeContract } from "viem/actions";
import { formatAbiItem, getAction } from "viem/utils";
import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json";
import {
doomWorldAbi,
userOperationEventAbi,
} from "../app/(explorer)/[chainName]/worlds/[worldAddress]/observe/TransactionsWatcher";
import { createBridge } from "./bridge";
import { ReceiptSummary } from "./common";
import { getUserOperationHashV07 } from "./utils";

export type WaitForTransaction = (hash: Hex) => Promise<ReceiptSummary>;

Expand All @@ -48,64 +24,92 @@ export function observer({ explorerUrl = "http://localhost:13690", waitForTransa
const emit = createBridge({ url: `${explorerUrl}/internal/observer-relay` });

return (client) => {
// if (client.type === "bundlerClient") {
// return {
// async sendUserOperation(args) {
// console.log("observerWrite sendUserOperation args:", args);

// const write = getAction(client, sendUserOperation, "sendUserOperation")(args);
// const calls = args.calls;

// // for (const call of calls) {
// const call = calls[0];
// const writeId = `${client.uid}-${++writeCounter}`; // TODO: rename write to send ?
// const { to, args: functionArgs, abi, functionName } = call;

// console.log("observerWrite call", call);

// const functionAbiItem = getAbiItem({
// abi,
// name: functionName,
// args,
// } as never)!;

// emit("write", {
// writeId,
// address: to,
// from: client.account!.address,
// functionSignature: formatAbiItem(functionAbiItem),
// args: (functionArgs.args ?? []) as never,
// value: functionArgs.value,
// });

// write.then((hash) => {
// const receipt = getAction(client, waitForUserOperationReceipt, "waitForUserOperationReceipt")({ hash });
// Promise.allSettled([receipt]).then(async ([result]) => {
// console.log("observerWrite waitForUserOperationReceipt result:", result);

// const logs = result.value?.logs;
// const parsedLogs = parseEventLogs({
// abi: [...doomWorldAbi, userOperationEventAbi],
// logs,
// });

// const receiptLogs = result.value?.receipt?.logs;
// const parsedReceiptLogs = parseEventLogs({
// abi: [...doomWorldAbi, userOperationEventAbi],
// logs: receiptLogs,
// });

// console.log("observerWrite parsedLogs:", parsedLogs);
// console.log("observerWrite parsedReceiptLogs:", parsedReceiptLogs);

// // TODO: emit("waitForTransactionReceipt", { hash: txHash, writeId });
// });
// });

// return write;
// },
// };
// }
if (client.type === "bundlerClient") {
return {
async sendUserOperation(args) {
console.log("observerWrite sendUserOperation args:", args);

const writeId = `${client.uid}-${++writeCounter}`; // TODO: rename write to send ?
const write = getAction(client, sendUserOperation, "sendUserOperation")(args);
const calls = args.calls;

emit("send", {
writeId,
calls: calls.map((call) => {
const functionAbiItem = getAbiItem({
abi: call.abi,
name: call.functionName,
args: call.args,
} as never)!;

return {
to: call.to,
functionSignature: formatAbiItem(functionAbiItem),
args: call.args,
};
}),
});

// emit("write", {
// writeId,

// address: args.address,
// from: client.account!.address,
// functionSignature: "batch call", // formatAbiItem(functionAbiItem),
// args: (args.args ?? []) as never,
// value: args.value,
// });

// // for (const call of calls) {
// const call = calls[0];
//
// const { to, args: functionArgs, abi, functionName } = call;

// console.log("observerWrite call", call);

// const functionAbiItem = getAbiItem({
// abi,
// name: functionName,
// args,
// } as never)!;

// emit("write", {
// writeId,
// address: to,
// from: client.account!.address,
// functionSignature: formatAbiItem(functionAbiItem),
// args: (functionArgs.args ?? []) as never,
// value: functionArgs.value,
// });

// write.then((hash) => {
// const receipt = getAction(client, waitForUserOperationReceipt, "waitForUserOperationReceipt")({ hash });
// Promise.allSettled([receipt]).then(async ([result]) => {
// console.log("observerWrite waitForUserOperationReceipt result:", result);

// const logs = result.value?.logs;
// const parsedLogs = parseEventLogs({
// abi: [...doomWorldAbi, userOperationEventAbi],
// logs,
// });

// const receiptLogs = result.value?.receipt?.logs;
// const parsedReceiptLogs = parseEventLogs({
// abi: [...doomWorldAbi, userOperationEventAbi],
// logs: receiptLogs,
// });

// console.log("observerWrite parsedLogs:", parsedLogs);
// console.log("observerWrite parsedReceiptLogs:", parsedReceiptLogs);

// // TODO: emit("waitForTransactionReceipt", { hash: txHash, writeId });
// });
// });

return write;
},
};
}

return {
async writeContract(args) {
Expand Down
8 changes: 8 additions & 0 deletions packages/explorer/src/observer/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ import { ReceiptSummary } from "./common";

export type Messages = {
ping: {};
send: {
writeId: string;
calls: {
to: Address;
functionSignature: string;
args: unknown[];
}[];
};
write: {
writeId: string;
address: Address;
Expand Down
49 changes: 38 additions & 11 deletions packages/explorer/src/observer/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,59 @@ export type Write = {
error?: Error;
};

export type Send = {
writeId: string;
calls: {
to: Address;
functionSignature: string;
args: unknown[];
}[];
};

export type State = {
writes: {
[id: string]: Write;
};
sends: {
[id: string]: Send;
};
};

export const store = createStore<State>(() => ({
writes: {},
sends: {},
}));

debug("listening for relayed messages", relayChannelName);
const channel = new BroadcastChannel(relayChannelName);
channel.addEventListener("message", ({ data }: MessageEvent<Message>) => {
if (data.type === "ping") return;
store.setState((state) => {
const write = data.type === "write" ? ({ ...data, events: [] } satisfies Write) : state.writes[data.writeId];
return {
writes: {
...state.writes,
[data.writeId]: {
...write,
type: data.type,
hash: data.type === "waitForTransactionReceipt" ? data.hash : write.hash,
events: [...write.events, data],
if (data.type === "send") {
return {
...state,
sends: {
...state.sends,
[data.writeId]: {
writeId: data.writeId,
calls: data.calls,
},
},
};
} else {
const write = data.type === "write" ? ({ ...data, events: [] } satisfies Write) : state.writes[data.writeId];
return {
...state,
writes: {
...state.writes,
[data.writeId]: {
...write,
type: data.type,
hash: data.type === "waitForTransactionReceipt" ? data.hash : write.hash,
events: [...write.events, data],
},
},
},
};
};
}
});
});

0 comments on commit fe86e95

Please sign in to comment.