From bc16b728979f6a6104790c0b594ce984025adee4 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Thu, 10 Apr 2025 00:08:56 +0530 Subject: [PATCH 1/2] CSM endpoint --- .../run-tab/src/lib/actions/account.ts | 74 +++++++++++-------- .../run-tab/src/lib/components/account.tsx | 34 ++++----- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/libs/remix-ui/run-tab/src/lib/actions/account.ts b/libs/remix-ui/run-tab/src/lib/actions/account.ts index 9cef927f75b..1749fb66a6d 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/account.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/account.ts @@ -6,7 +6,7 @@ import { toChecksumAddress } from '@ethereumjs/util' import { SmartAccount } from "../types" import "viem/window" import { custom, createWalletClient, createPublicClient, http } from "viem" -import { sepolia } from "viem/chains" +import * as chains from "viem/chains" import { entryPoint07Address } from "viem/account-abstraction" const { createSmartAccountClient } = require("permissionless") /* eslint-disable-line @typescript-eslint/no-var-requires */ const { toSafeSmartAccount } = require("permissionless/accounts") /* eslint-disable-line @typescript-eslint/no-var-requires */ @@ -102,12 +102,47 @@ export const createNewBlockchainAccount = async (plugin: RunTab, dispatch: React ) } +const createSafeSmartAccount = async(safeAccount, toAddress, usePaymaster, chainObj) => { + const PIMLICO_API_KEY ='' + const chainName = chainObj.name + const BUNDLER_URL = `https://api.pimlico.io/v2/${chainName}/rpc?apikey=${PIMLICO_API_KEY}` + const paymasterClient = createPimlicoClient({ + transport: http(BUNDLER_URL), + entryPoint: { + address: entryPoint07Address, + version: "0.7", + }, + }) + + console.log('paymasterClient--->', paymasterClient) // api key is shown + + const saClient = createSmartAccountClient({ + account: safeAccount, + chainObj, + paymaster: paymasterClient, + bundlerTransport: http(BUNDLER_URL), + userOperation: { + estimateFeesPerGas: async () => (await paymasterClient.getUserOperationGasPrice()).fast, + } + }) + console.log('saClient--->', saClient) // api key is shown + + // Make a dummy tx to force smart account deployment + const useropHash = await saClient.sendUserOperation({ + calls: [{ + to: toAddress, + value: 0 + }] + }) + await saClient.waitForUserOperationReceipt({ hash: useropHash }) +} + export const createSmartAccount = async (plugin: RunTab, dispatch: React.Dispatch) => { const localStorageKey = 'smartAccounts' const PUBLIC_NODE_URL = "https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9" - const PIMLICO_API_KEY ='' - const BUNDLER_URL = `https://api.pimlico.io/v2/sepolia/rpc?apikey=${PIMLICO_API_KEY}` const safeAddresses: string[] = Object.keys(plugin.REACT_API.smartAccounts) + const network = 'sepolia' + const chain = chains[network] let salt // @ts-ignore @@ -115,12 +150,12 @@ export const createSmartAccount = async (plugin: RunTab, dispatch: React.Dispatc const walletClient = createWalletClient({ account, - chain: sepolia, + chain, transport: custom(window.ethereum!), }) const publicClient = createPublicClient({ - chain: sepolia, + chain, transport: http(PUBLIC_NODE_URL) // choose any provider here }) @@ -141,33 +176,8 @@ export const createSmartAccount = async (plugin: RunTab, dispatch: React.Dispatc saltNonce: salt, version: "1.4.1" }) - - const paymasterClient = createPimlicoClient({ - transport: http(BUNDLER_URL), - entryPoint: { - address: entryPoint07Address, - version: "0.7", - }, - }) - - const saClient = createSmartAccountClient({ - account: safeAccount, - sepolia, - paymaster: paymasterClient, - bundlerTransport: http(BUNDLER_URL), - userOperation: { - estimateFeesPerGas: async () => (await paymasterClient.getUserOperationGasPrice()).fast, - } - }) - // Make a dummy tx to force smart account deployment - const useropHash = await saClient.sendUserOperation({ - calls: [{ - to: "0xAFdAC33F6F134D46bAbE74d9125F3bf8e8AB3a44", - value: 0 - }] - }) - await saClient.waitForUserOperationReceipt({ hash: useropHash }) - + await createSafeSmartAccount(safeAccount, '0xAFdAC33F6F134D46bAbE74d9125F3bf8e8AB3a44', true, chain) + // TO verify creation, check if there is a contract code at this address const safeAddress = safeAccount.address const sAccount: SmartAccount = { diff --git a/libs/remix-ui/run-tab/src/lib/components/account.tsx b/libs/remix-ui/run-tab/src/lib/components/account.tsx index b02b39b2b99..07fc2c1ab0b 100644 --- a/libs/remix-ui/run-tab/src/lib/components/account.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/account.tsx @@ -31,23 +31,23 @@ export function AccountUI(props: AccountProps) { }, [accounts, selectedAccount]) // Uncomment this when we want to show 'Create Smart Account' button - // useEffect(() => { - // if (smartAccounts.length > 0 && networkName.includes('Sepolia')) { - // if(smartAccounts.includes(selectedAccount)) { - // setSmartAccountSelected(true) - // setEnableCSM(false) - // ownerEOA.current = props.runTabPlugin.REACT_API.smartAccounts[selectedAccount].ownerEOA - // } - // else { - // setSmartAccountSelected(false) - // setEnableCSM(true) - // ownerEOA.current = null - // } - // } else { - // setEnableCSM(false) - // setSmartAccountSelected(false) - // } - // }, [selectedAccount]) + useEffect(() => { + if (smartAccounts.length > 0 && networkName.includes('Sepolia')) { + if(smartAccounts.includes(selectedAccount)) { + setSmartAccountSelected(true) + setEnableCSM(false) + ownerEOA.current = props.runTabPlugin.REACT_API.smartAccounts[selectedAccount].ownerEOA + } + else { + setSmartAccountSelected(false) + setEnableCSM(true) + ownerEOA.current = null + } + } else { + setEnableCSM(false) + setSmartAccountSelected(false) + } + }, [selectedAccount]) useEffect(() => { props.setAccount('') From 8fbe989787e7f7fdda4c67fa20a0b5f39b9402e1 Mon Sep 17 00:00:00 2001 From: aniket-engg Date: Sat, 12 Apr 2025 00:46:12 +0530 Subject: [PATCH 2/2] hit endpoint --- .../run-tab/src/lib/actions/account.ts | 72 ++++++------------- 1 file changed, 20 insertions(+), 52 deletions(-) diff --git a/libs/remix-ui/run-tab/src/lib/actions/account.ts b/libs/remix-ui/run-tab/src/lib/actions/account.ts index 1749fb66a6d..e64c63eb08d 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/account.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/account.ts @@ -4,6 +4,7 @@ import { clearInstances, setAccount, setExecEnv } from "./actions" import { displayNotification, fetchAccountsListFailed, fetchAccountsListRequest, fetchAccountsListSuccess, setMatchPassphrase, setPassphrase } from "./payload" import { toChecksumAddress } from '@ethereumjs/util' import { SmartAccount } from "../types" +import axios from "axios" import "viem/window" import { custom, createWalletClient, createPublicClient, http } from "viem" import * as chains from "viem/chains" @@ -102,44 +103,10 @@ export const createNewBlockchainAccount = async (plugin: RunTab, dispatch: React ) } -const createSafeSmartAccount = async(safeAccount, toAddress, usePaymaster, chainObj) => { - const PIMLICO_API_KEY ='' - const chainName = chainObj.name - const BUNDLER_URL = `https://api.pimlico.io/v2/${chainName}/rpc?apikey=${PIMLICO_API_KEY}` - const paymasterClient = createPimlicoClient({ - transport: http(BUNDLER_URL), - entryPoint: { - address: entryPoint07Address, - version: "0.7", - }, - }) - - console.log('paymasterClient--->', paymasterClient) // api key is shown - - const saClient = createSmartAccountClient({ - account: safeAccount, - chainObj, - paymaster: paymasterClient, - bundlerTransport: http(BUNDLER_URL), - userOperation: { - estimateFeesPerGas: async () => (await paymasterClient.getUserOperationGasPrice()).fast, - } - }) - console.log('saClient--->', saClient) // api key is shown - - // Make a dummy tx to force smart account deployment - const useropHash = await saClient.sendUserOperation({ - calls: [{ - to: toAddress, - value: 0 - }] - }) - await saClient.waitForUserOperationReceipt({ hash: useropHash }) -} - export const createSmartAccount = async (plugin: RunTab, dispatch: React.Dispatch) => { const localStorageKey = 'smartAccounts' const PUBLIC_NODE_URL = "https://go.getblock.io/ee42d0a88f314707be11dd799b122cb9" + const toAddress = "0xAFdAC33F6F134D46bAbE74d9125F3bf8e8AB3a44" const safeAddresses: string[] = Object.keys(plugin.REACT_API.smartAccounts) const network = 'sepolia' const chain = chains[network] @@ -176,24 +143,25 @@ export const createSmartAccount = async (plugin: RunTab, dispatch: React.Dispatc saltNonce: salt, version: "1.4.1" }) - await createSafeSmartAccount(safeAccount, '0xAFdAC33F6F134D46bAbE74d9125F3bf8e8AB3a44', true, chain) + const response = await axios.post(`http://localhost:4000/account-abstraction/createSafeSmartAccount`, { safeAccountObj: safeAccount, toAddress, usePaymaster: true, chainObj: chain }) + console.log('response', response) // TO verify creation, check if there is a contract code at this address - const safeAddress = safeAccount.address - - const sAccount: SmartAccount = { - address : safeAccount.address, - salt, - ownerEOA: account, - timestamp: Date.now() - } - plugin.REACT_API.smartAccounts[safeAddress] = sAccount - // Save smart accounts in local storage - const smartAccountsStr = localStorage.getItem(localStorageKey) - const smartAccountsObj = JSON.parse(smartAccountsStr) - smartAccountsObj[plugin.REACT_API.chainId] = plugin.REACT_API.smartAccounts - localStorage.setItem(localStorageKey, JSON.stringify(smartAccountsObj)) - - return plugin.call('notification', 'toast', `Safe account ${safeAccount.address} created for owner ${account}`) + // const safeAddress = safeAccount.address + + // const sAccount: SmartAccount = { + // address : safeAccount.address, + // salt, + // ownerEOA: account, + // timestamp: Date.now() + // } + // plugin.REACT_API.smartAccounts[safeAddress] = sAccount + // // Save smart accounts in local storage + // const smartAccountsStr = localStorage.getItem(localStorageKey) + // const smartAccountsObj = JSON.parse(smartAccountsStr) + // smartAccountsObj[plugin.REACT_API.chainId] = plugin.REACT_API.smartAccounts + // localStorage.setItem(localStorageKey, JSON.stringify(smartAccountsObj)) + + // return plugin.call('notification', 'toast', `Safe account ${safeAccount.address} created for owner ${account}`) } catch (error) { console.error('Failed to create safe smart account: ', error) return plugin.call('notification', 'toast', `Failed to create safe smart account !!!`)