From 6c552c8fd654f848a0973f9ac45d7681009b68c4 Mon Sep 17 00:00:00 2001 From: calvinchang Date: Mon, 18 Sep 2023 14:15:52 +0800 Subject: [PATCH 1/3] feat: add sendTx feat to UserOp template --- src/components/EvmEditor.tsx | 7 +- src/components/EvmEditors/EvmSendEditor.tsx | 18 ++--- src/components/EvmEditors/EvmUserOpEditor.tsx | 69 ++++++++++++++++--- src/scripts/evm/UserOperation.ts | 13 ++++ 4 files changed, 81 insertions(+), 26 deletions(-) diff --git a/src/components/EvmEditor.tsx b/src/components/EvmEditor.tsx index 298e8b7..21167ae 100644 --- a/src/components/EvmEditor.tsx +++ b/src/components/EvmEditor.tsx @@ -254,7 +254,12 @@ const EvmEditor = (): ReactJSXElement => { + setRequestObject({ + method: "eth_sendTransaction", + params, + }) + } account={account} /> diff --git a/src/components/EvmEditors/EvmSendEditor.tsx b/src/components/EvmEditors/EvmSendEditor.tsx index 1fc0615..3658ece 100644 --- a/src/components/EvmEditors/EvmSendEditor.tsx +++ b/src/components/EvmEditors/EvmSendEditor.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState, Dispatch, SetStateAction } from "react"; +import React, { useEffect, useState, Dispatch } from "react"; import { Box, Textarea, Grid } from "@chakra-ui/react"; import { ReactJSXElement } from "@emotion/react/types/jsx-namespace"; import type { EthereumTypes } from "@blocto/sdk"; @@ -9,7 +9,7 @@ const EvmSendEditor = ({ account, }: { setRequestObject: Dispatch< - SetStateAction + EthereumTypes.EIP1193RequestPayload["params"] | undefined >; account: string | null; }): ReactJSXElement => { @@ -36,19 +36,9 @@ const EvmSendEditor = ({ if (dataString) { sendObj.data = dataString; } - setRequestObject({ - method: "eth_sendTransaction", - params: [sendObj], - }); + setRequestObject([sendObj]); } - }, [ - account, - fromString, - toString, - dataString, - valueString, - setRequestObject, - ]); + }, [account, fromString, toString, dataString, valueString]); useEffect(() => { setFrom(account || ""); }, [account]); diff --git a/src/components/EvmEditors/EvmUserOpEditor.tsx b/src/components/EvmEditors/EvmUserOpEditor.tsx index 797534e..39f7f0f 100644 --- a/src/components/EvmEditors/EvmUserOpEditor.tsx +++ b/src/components/EvmEditors/EvmUserOpEditor.tsx @@ -22,8 +22,22 @@ import { EthereumTypes } from "@blocto/sdk"; import ParamEditor from "./ParamEditor"; import * as UserOperationTemplate from "../../scripts/evm/UserOperation"; import type { IUserOperationTemplate } from "../../scripts/evm/UserOperation"; +import EvmSendEditor from "./EvmSendEditor"; +import { AbiItem, numberToHex, isAddress, isHexStrict } from "web3-utils"; +import Web3EthAbi from "web3-eth-abi"; const MenuGroups = [{ title: "Request", templates: UserOperationTemplate }]; +const ABI: AbiItem = { + inputs: [ + { internalType: "address", name: "dest", type: "address" }, + { internalType: "uint256", name: "value", type: "uint256" }, + { internalType: "bytes", name: "func", type: "bytes" }, + ], + name: "execute", + outputs: [], + stateMutability: "nonpayable", + type: "function", +}; const EvmUserOpEditor = ({ setRequestObject, @@ -34,10 +48,13 @@ const EvmUserOpEditor = ({ >; account: string | null; }): ReactJSXElement => { + const [templateId, setTemplateId] = useState(""); const [callData, setCallData] = useState(""); const [otherParam, setOtherParam] = useState([]); + const importTemplate = useCallback((template: IUserOperationTemplate) => { - setCallData(template.userOpObj.callData || ""); + setTemplateId(template.id); + setCallData(template.userOpObj.callData); setOtherParam( Object.entries(template.userOpObj) .filter(([key]) => key !== "callData") @@ -54,6 +71,27 @@ const EvmUserOpEditor = ({ } }, [account, callData, otherParam, setRequestObject]); + const setTransactionToCallData = useCallback( + ([params]) => { + const { to, value = "0x", data = "0x" } = params; + + if (!isAddress(to) || !isHexStrict(data)) return; + + const callData = Web3EthAbi.encodeFunctionCall(ABI, [ + to, + numberToHex(value), + data, + ]); + + setCallData(callData); + setRequestObject({ + method: "eth_sendUserOperation", + params: [{ callData, ...Object.fromEntries(otherParam) }], + }); + }, + [otherParam, setRequestObject] + ); + return ( @@ -80,16 +118,25 @@ const EvmUserOpEditor = ({ - - callData: -