Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local aa infra without foundry chain #637

Merged
merged 12 commits into from
Jul 10, 2024
4 changes: 4 additions & 0 deletions advanced/wallets/react-wallet-v2/.env.local.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@ NEXT_PUBLIC_PROJECT_ID=
NEXT_PUBLIC_RELAY_URL=wss://relay.walletconnect.com
NEXT_PUBLIC_PIMLICO_KEY=
NEXT_PUBLIC_ZERODEV_PROJECT_ID=
#if using local AA infra then set these values
NEXT_PUBLIC_LOCAL_BUNDLER_URL=
NEXT_PUBLIC_LOCAL_PAYMASTER_URL=
NEXT_PUBLIC_LOCAL_CLIENT_URL=
4 changes: 2 additions & 2 deletions advanced/wallets/react-wallet-v2/src/consts/smartAccounts.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { KernelSmartAccountLib } from '@/lib/smart-accounts/KernelSmartAccountLib'
import { SafeSmartAccountLib } from '@/lib/smart-accounts/SafeSmartAccountLib'
import { foundry, goerli, polygonMumbai, sepolia } from 'viem/chains'
import { goerli, polygonMumbai, sepolia } from 'viem/chains'

// Types
export const allowedChains = [sepolia, polygonMumbai, goerli, foundry]
export const allowedChains = [sepolia, polygonMumbai, goerli]
// build chains so I can access them by id
export const chains = allowedChains.reduce((acc, chain) => {
acc[chain.id] = chain
Expand Down
9 changes: 0 additions & 9 deletions advanced/wallets/react-wallet-v2/src/data/EIP155Data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,6 @@ export const EIP155_TEST_CHAINS: Record<string, EIP155Chain> = {
rgb: '242, 242, 242',
rpc: 'https://testnet.era.zksync.dev/',
namespace: 'eip155'
},
'eip155:31337': {
chainId: 31337,
name: 'Foundry Testnet',
logo: '/chain-logos/eip155-1.png',
rgb: '242, 242, 242',
rpc: 'https://localhost:8545/',
namespace: 'eip155',
smartAccountEnabled: true
}
}

Expand Down
6 changes: 0 additions & 6 deletions advanced/wallets/react-wallet-v2/src/data/EIP5792Data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,5 @@ export const supportedEIP5792CapabilitiesForSCA: GetCapabilitiesResult = {
atomicBatch: {
supported: true
}
},
// foundry chain
'0x7a69': {
atomicBatch: {
supported: true
}
}
}
15 changes: 4 additions & 11 deletions advanced/wallets/react-wallet-v2/src/hooks/useSmartAccounts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,28 @@ import {
} from '@/utils/SmartAccountUtil'

import { useSnapshot } from 'valtio'
import { foundry, sepolia } from 'viem/chains'

export default function useSmartAccounts() {
const {
smartAccountEnabled,
kernelSmartAccountEnabled,
safeSmartAccountEnabled,
biconomySmartAccountEnabled,
localAAInfraEnabled
biconomySmartAccountEnabled
} = useSnapshot(SettingsStore.state)

const initializeSmartAccounts = async (privateKey: string) => {
const chain = localAAInfraEnabled ? foundry : sepolia
if (smartAccountEnabled) {
if (kernelSmartAccountEnabled) {
const { kernelSmartAccountAddress } = await createOrRestoreKernelSmartAccount(
privateKey,
chain
)
const { kernelSmartAccountAddress } = await createOrRestoreKernelSmartAccount(privateKey)
SettingsStore.setKernelSmartAccountAddress(kernelSmartAccountAddress)
}
if (safeSmartAccountEnabled) {
const { safeSmartAccountAddress } = await createOrRestoreSafeSmartAccount(privateKey, chain)
const { safeSmartAccountAddress } = await createOrRestoreSafeSmartAccount(privateKey)
SettingsStore.setSafeSmartAccountAddress(safeSmartAccountAddress)
}
if (biconomySmartAccountEnabled) {
const { biconomySmartAccountAddress } = await createOrRestoreBiconomySmartAccount(
privateKey,
chain
privateKey
)
SettingsStore.setBiconomySmartAccountAddress(biconomySmartAccountAddress)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,19 @@ export abstract class SmartAccountLib implements EIP155Wallet {
entryPointVersion = 6
}: SmartAccountLibOptions) {
const apiKey = process.env.NEXT_PUBLIC_PIMLICO_KEY
const publicClientRPCUrl = process.env.NEXT_PUBLIC_LOCAL_CLIENT_URL || publicRPCUrl({ chain })
const paymasterUrl = ({ chain }: UrlConfig) => {
if (chain.id === foundry.id) {
return `http://localhost:3000`
const localPaymasterUrl = process.env.NEXT_PUBLIC_LOCAL_PAYMASTER_URL
if (localPaymasterUrl) {
return localPaymasterUrl
}
return `https://api.pimlico.io/v2/${PIMLICO_NETWORK_NAMES[chain.name]}/rpc?apikey=${apiKey}`
}

const bundlerUrl = ({ chain }: UrlConfig) => {
if (chain.id === foundry.id) {
return `http://localhost:4337`
const localBundlerUrl = process.env.NEXT_PUBLIC_LOCAL_BUNDLER_URL
if (localBundlerUrl) {
return localBundlerUrl
}
return `https://api.pimlico.io/v1/${PIMLICO_NETWORK_NAMES[chain.name]}/rpc?apikey=${apiKey}`
}
Expand All @@ -101,7 +104,7 @@ export abstract class SmartAccountLib implements EIP155Wallet {
this.paymasterUrl = http(paymasterUrl({ chain: this.chain }))

this.publicClient = createPublicClient({
transport: http(publicRPCUrl({ chain: this.chain }))
transport: http(publicClientRPCUrl)
}).extend(bundlerActions(this.entryPoint))

this.paymasterClient = createPimlicoPaymasterClient({
Expand Down
20 changes: 1 addition & 19 deletions advanced/wallets/react-wallet-v2/src/pages/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ export default function SettingsPage() {
kernelSmartAccountEnabled,
safeSmartAccountEnabled,
biconomySmartAccountEnabled,
moduleManagementEnabled,
localAAInfraEnabled
moduleManagementEnabled
} = useSnapshot(SettingsStore.state)

return (
Expand Down Expand Up @@ -142,23 +141,6 @@ export default function SettingsPage() {
/>
<Text>{moduleManagementEnabled ? 'Enabled' : 'Disabled'}</Text>
</Row>
<Divider y={2} />
<Text h4 css={{ marginBottom: '$5', cursor: 'pointer' }}>
Local AA Infra
</Text>
<Row justify="space-between" align="center">
<Switch
disabled={
!kernelSmartAccountEnabled &&
!safeSmartAccountEnabled &&
!biconomySmartAccountEnabled
}
checked={localAAInfraEnabled}
onChange={SettingsStore.toggleLocalAAInfra}
data-testid="settings-toggle-local-aa-infra"
/>
<Text>{localAAInfraEnabled ? 'Enabled' : 'Disabled'}</Text>
</Row>
</>
) : null}
</>
Expand Down
129 changes: 21 additions & 108 deletions advanced/wallets/react-wallet-v2/src/store/SettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ import {
} from '@/utils/SmartAccountUtil'
import { Verify, SessionTypes } from '@walletconnect/types'
import { proxy } from 'valtio'
import { foundry, sepolia } from 'viem/chains'

const TEST_NETS_ENABLED_KEY = 'TEST_NETS'
const SMART_ACCOUNTS_ENABLED_KEY = 'SMART_ACCOUNTS'
const ZERO_DEV_SMART_ACCOUNTS_ENABLED_KEY = 'ZERO_DEV_SMART_ACCOUNTS'
const SAFE_SMART_ACCOUNTS_ENABLED_KEY = 'SAFE_SMART_ACCOUNTS'
const BICONOMY_SMART_ACCOUNTS_ENABLED_KEY = 'BICONOMY_SMART_ACCOUNTS'
const MODULE_MANAGEMENT_ENABLED_KEY = 'MODULE_MANAGEMENT'
const LOCAL_AA_INFRA_ENABLED_KEY = 'LOCAL_AA_INFRA'

/**
* Types
Expand Down Expand Up @@ -45,7 +43,6 @@ interface State {
safeSmartAccountEnabled: boolean
biconomySmartAccountEnabled: boolean
moduleManagementEnabled: boolean
localAAInfraEnabled: boolean
}

/**
Expand Down Expand Up @@ -92,10 +89,6 @@ const state = proxy<State>({
moduleManagementEnabled:
typeof localStorage !== 'undefined'
? Boolean(localStorage.getItem(MODULE_MANAGEMENT_ENABLED_KEY))
: false,
localAAInfraEnabled:
typeof localStorage !== 'undefined'
? Boolean(localStorage.getItem(LOCAL_AA_INFRA_ENABLED_KEY))
: false
})

Expand Down Expand Up @@ -199,82 +192,18 @@ const SettingsStore = {
localStorage.removeItem(MODULE_MANAGEMENT_ENABLED_KEY)
}
},
async toggleLocalAAInfra() {
try {
state.localAAInfraEnabled = !state.localAAInfraEnabled

// Update local storage based on the state
state.localAAInfraEnabled
? localStorage.setItem(LOCAL_AA_INFRA_ENABLED_KEY, 'YES')
: localStorage.removeItem(LOCAL_AA_INFRA_ENABLED_KEY)

// Define account types with corresponding properties
const accountTypes = [
{
enabled: state.safeSmartAccountEnabled,
address: SettingsStore.state.safeSmartAccountAddress,
createOrRestore: createOrRestoreSafeSmartAccount,
setter: SettingsStore.setSafeSmartAccountAddress
},
{
enabled: state.kernelSmartAccountEnabled,
address: SettingsStore.state.kernelSmartAccountAddress,
createOrRestore: createOrRestoreKernelSmartAccount,
setter: SettingsStore.setKernelSmartAccountAddress
},
{
enabled: state.biconomySmartAccountEnabled,
address: SettingsStore.state.biconomySmartAccountAddress,
createOrRestore: createOrRestoreBiconomySmartAccount,
setter: SettingsStore.setBiconomySmartAccountAddress
}
]

// Create or restore EIP-155 wallet
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const privateKey = eip155Wallets[eip155Addresses[0]].getPrivateKey()
const newChain = state.localAAInfraEnabled ? foundry : sepolia
const oldChain = state.localAAInfraEnabled ? sepolia : foundry

// Process account types concurrently
await Promise.all(
accountTypes.map(async account => {
// Remove smart account from the old chain
removeSmartAccount(account.address, oldChain)

if (account.enabled) {
// Create or restore account on the new chain
const result = await account.createOrRestore(privateKey, newChain)
const [newAddress] = Object.values(result)
account.setter(newAddress)
}
})
)
} catch (e) {
state.localAAInfraEnabled = false
localStorage.removeItem(LOCAL_AA_INFRA_ENABLED_KEY)
}
},

async toggleKernelSmartAccountsEnabled() {
state.kernelSmartAccountEnabled = !state.kernelSmartAccountEnabled
if (state.kernelSmartAccountEnabled) {
try {
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const chain = state.localAAInfraEnabled ? foundry : sepolia
const { kernelSmartAccountAddress } = await createOrRestoreKernelSmartAccount(
eip155Wallets[eip155Addresses[0]].getPrivateKey(),
chain
)
SettingsStore.setKernelSmartAccountAddress(kernelSmartAccountAddress)
localStorage.setItem(ZERO_DEV_SMART_ACCOUNTS_ENABLED_KEY, 'YES')
} catch (e) {
state.kernelSmartAccountEnabled = false
localStorage.removeItem(ZERO_DEV_SMART_ACCOUNTS_ENABLED_KEY)
}
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const { kernelSmartAccountAddress } = await createOrRestoreKernelSmartAccount(
eip155Wallets[eip155Addresses[0]].getPrivateKey()
)
SettingsStore.setKernelSmartAccountAddress(kernelSmartAccountAddress)
localStorage.setItem(ZERO_DEV_SMART_ACCOUNTS_ENABLED_KEY, 'YES')
} else {
const chain = state.localAAInfraEnabled ? foundry : sepolia
removeSmartAccount(SettingsStore.state.kernelSmartAccountAddress, chain)
removeSmartAccount(SettingsStore.state.kernelSmartAccountAddress)
SettingsStore.setKernelSmartAccountAddress('')
state.moduleManagementEnabled = false
localStorage.removeItem(MODULE_MANAGEMENT_ENABLED_KEY)
Expand All @@ -285,22 +214,14 @@ const SettingsStore = {
async toggleSafeSmartAccountsEnabled() {
state.safeSmartAccountEnabled = !state.safeSmartAccountEnabled
if (state.safeSmartAccountEnabled) {
try {
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const chain = state.localAAInfraEnabled ? foundry : sepolia
const { safeSmartAccountAddress } = await createOrRestoreSafeSmartAccount(
eip155Wallets[eip155Addresses[0]].getPrivateKey(),
chain
)
SettingsStore.setSafeSmartAccountAddress(safeSmartAccountAddress)
localStorage.setItem(SAFE_SMART_ACCOUNTS_ENABLED_KEY, 'YES')
} catch (e) {
state.safeSmartAccountEnabled = false
localStorage.removeItem(SAFE_SMART_ACCOUNTS_ENABLED_KEY)
}
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const { safeSmartAccountAddress } = await createOrRestoreSafeSmartAccount(
eip155Wallets[eip155Addresses[0]].getPrivateKey()
)
SettingsStore.setSafeSmartAccountAddress(safeSmartAccountAddress)
localStorage.setItem(SAFE_SMART_ACCOUNTS_ENABLED_KEY, 'YES')
} else {
const chain = state.localAAInfraEnabled ? foundry : sepolia
removeSmartAccount(SettingsStore.state.safeSmartAccountAddress, chain)
removeSmartAccount(SettingsStore.state.safeSmartAccountAddress)
SettingsStore.setSafeSmartAccountAddress('')
state.moduleManagementEnabled = false
localStorage.removeItem(MODULE_MANAGEMENT_ENABLED_KEY)
Expand All @@ -311,22 +232,14 @@ const SettingsStore = {
async toggleBiconomySmartAccountsEnabled() {
state.biconomySmartAccountEnabled = !state.biconomySmartAccountEnabled
if (state.biconomySmartAccountEnabled) {
try {
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const chain = state.localAAInfraEnabled ? foundry : sepolia
const { biconomySmartAccountAddress } = await createOrRestoreBiconomySmartAccount(
eip155Wallets[eip155Addresses[0]].getPrivateKey(),
chain
)
SettingsStore.setBiconomySmartAccountAddress(biconomySmartAccountAddress)
localStorage.setItem(BICONOMY_SMART_ACCOUNTS_ENABLED_KEY, 'YES')
} catch (e) {
state.biconomySmartAccountEnabled = false
localStorage.removeItem(BICONOMY_SMART_ACCOUNTS_ENABLED_KEY)
}
const { eip155Addresses, eip155Wallets } = createOrRestoreEIP155Wallet()
const { biconomySmartAccountAddress } = await createOrRestoreBiconomySmartAccount(
eip155Wallets[eip155Addresses[0]].getPrivateKey()
)
SettingsStore.setBiconomySmartAccountAddress(biconomySmartAccountAddress)
localStorage.setItem(BICONOMY_SMART_ACCOUNTS_ENABLED_KEY, 'YES')
} else {
const chain = state.localAAInfraEnabled ? foundry : sepolia
removeSmartAccount(SettingsStore.state.biconomySmartAccountAddress, chain)
removeSmartAccount(SettingsStore.state.biconomySmartAccountAddress)
SettingsStore.setBiconomySmartAccountAddress('')
state.moduleManagementEnabled = false
localStorage.removeItem(MODULE_MANAGEMENT_ENABLED_KEY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,21 @@ import { getSdkError } from '@walletconnect/utils'
import SettingsStore from '@/store/SettingsStore'
import EIP155Lib from '@/lib/EIP155Lib'
import {
ENTRYPOINT_ADDRESS_V06,
ENTRYPOINT_ADDRESS_V07,
GetUserOperationReceiptReturnType,
createBundlerClient
} from 'permissionless'
import { http, toHex } from 'viem'
import { foundry } from 'viem/chains'
type RequestEventArgs = Omit<SignClientTypes.EventArguments['session_request'], 'verifyContext'>

const getCallsReceipt = async (getCallParams: GetCallsParams, chainId: string) => {
const getCallsReceipt = async (getCallParams: GetCallsParams) => {
/**
* This is hardcode implementation of wallet_getCallsStatus
* as we are not maintaining the data for calls bundled right now.
* Getting directly from bundler the receipt on sepolia chain.
*/
const apiKey = process.env.NEXT_PUBLIC_PIMLICO_KEY
let bundlerUrl = `https://api.pimlico.io/v1/sepolia/rpc?apikey=${apiKey}`

if (chainId.split(':')[1] === foundry.id.toString()) {
bundlerUrl = 'http://localhost:4337'
}

const localBundlerUrl = process.env.NEXT_PUBLIC_LOCAL_BUNDLER_URL
const bundlerUrl = localBundlerUrl || `https://api.pimlico.io/v1/sepolia/rpc?apikey=${apiKey}`
const bundlerClient = createBundlerClient({
entryPoint: ENTRYPOINT_ADDRESS_V07,
transport: http(bundlerUrl)
Expand Down Expand Up @@ -89,7 +82,7 @@ export async function approveEIP5792Request(requestEvent: RequestEventArgs) {
case EIP5792_METHODS.WALLET_GET_CALLS_STATUS: {
try {
const getCallParams = request.params[0] as GetCallsParams
const receipt = await getCallsReceipt(getCallParams, chainId)
const receipt = await getCallsReceipt(getCallParams)
return formatJsonRpcResult(id, receipt)
} catch (error: any) {
console.error(error)
Expand Down
Loading
Loading