fix: smart account creation on session requests (#442)

This commit is contained in:
tomiir 2024-02-02 03:55:16 -06:00 committed by GitHub
parent 9439c9af54
commit 544b840ede
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 42 deletions

View File

@ -100,7 +100,6 @@ export default function SmartAccountCard({
> >
{activeChainId === chainId ? `` : `🔄`} {activeChainId === chainId ? `` : `🔄`}
</Button> </Button>
{smartAccountAddress ? ( {smartAccountAddress ? (
<> <>
<Text h5 css={{ marginTop: 20 }}> <Text h5 css={{ marginTop: 20 }}>
@ -109,15 +108,17 @@ export default function SmartAccountCard({
<Text small css={{ marginTop: 5 }}> <Text small css={{ marginTop: 5 }}>
{smartAccountAddress} {smartAccountAddress}
</Text> </Text>
<Button
size="md"
css={{ marginTop: 20, width: '100%' }}
onClick={sendTestTransaction}
disabled={!isActiveChain || loading}
>
{loading ? <Loading size="sm" /> : 'Send Test TX'}
</Button>
</> </>
) : null}
{isDeployed && smartAccountAddress ? (
<Button
size="md"
css={{ marginTop: 20, width: '100%' }}
onClick={sendTestTransaction}
disabled={!isActiveChain || loading}
>
{loading ? <Loading size="sm" /> : 'Send Test TX'}
</Button>
) : ( ) : (
<> <>
<Button <Button

View File

@ -58,9 +58,9 @@ export default function useSmartAccount(signerPrivateKey: Hex, chain: Chain) {
}, [signerPrivateKey, smartAccountSponsorshipEnabled, chain]) }, [signerPrivateKey, smartAccountSponsorshipEnabled, chain])
useEffect(() => { useEffect(() => {
client?.checkIfSmartAccountDeployed() client?.init()
.then((deployed: boolean) => { .then(() => {
setIsDeployed(deployed) setIsDeployed(client?.isDeployed)
setAddress(client?.address) setAddress(client?.address)
}) })
}, [client, chain]) }, [client, chain])

View File

@ -162,8 +162,13 @@ export class SmartAccountLib {
} }
// -- Public ------------------------------------------------------------------ // -- Public ------------------------------------------------------------------
public getAccount = async () => public async init() {
privateKeyToSafeSmartAccount(this.publicClient, { await this.checkIfSmartAccountDeployed()
this.address = (await this.getAccount()).address
}
public getAccount = async () => {
const account = await privateKeyToSafeSmartAccount(this.publicClient, {
privateKey: this.#signerPrivateKey, privateKey: this.#signerPrivateKey,
safeVersion: '1.4.1', // simple version safeVersion: '1.4.1', // simple version
entryPoint: ENTRYPOINT_ADDRESSES[this.chain.name], // global entrypoint entryPoint: ENTRYPOINT_ADDRESSES[this.chain.name], // global entrypoint
@ -178,6 +183,10 @@ export class SmartAccountLib {
} }
] ]
}) })
this.address = account.address
return account;
}
static isSmartAccount = async (address: Address, chain: Chain) => { static isSmartAccount = async (address: Address, chain: Chain) => {
const client = createPublicClient({ const client = createPublicClient({
@ -263,9 +272,7 @@ export class SmartAccountLib {
this.isDeployed = Boolean(bytecode) this.isDeployed = Boolean(bytecode)
console.log(`Smart Account Deployed: ${this.isDeployed}`) console.log(`Smart Account Deployed: ${this.isDeployed}`)
if (this.isDeployed) {
this.address = smartAccountClient.account.address
}
return this.isDeployed; return this.isDeployed;
} }

View File

@ -12,33 +12,34 @@ import { SignClientTypes } from '@walletconnect/types'
import { getSdkError } from '@walletconnect/utils' import { getSdkError } from '@walletconnect/utils'
import { providers } from 'ethers' import { providers } from 'ethers'
import { Hex } from 'viem' import { Hex } from 'viem'
import { allowedChains } from './SmartAccountUtils' import { Chain, allowedChains } from './SmartAccountUtils'
type RequestEventArgs = Omit<SignClientTypes.EventArguments['session_request'], 'verifyContext'> type RequestEventArgs = Omit<SignClientTypes.EventArguments['session_request'], 'verifyContext'>
const getWallet = async (params: any) => { const getWallet = async (params: any) => {
const requestParams: Array<any> = params?.request?.params || [] console.log('get wallet params', params)
const chainId = params?.chainId?.split(':')[1]
console.log('chain id', chainId)
const eoaWallet = eip155Wallets[getWalletAddressFromParams(eip155Addresses, params)] const eoaWallet = eip155Wallets[getWalletAddressFromParams(eip155Addresses, params)]
if (eoaWallet) { if (eoaWallet) {
return eoaWallet return eoaWallet
} }
const deployedSmartAccounts = await Promise.all(Object.values(eip155Wallets).map(async (wallet) => { const smartAccountEnabledChain = allowedChains.find((chain) => chain.id.toString() === chainId) as Chain
console.log('smart account enabled chain', smartAccountEnabledChain)
const smartAccounts = await Promise.all(Object.values(eip155Wallets).map(async (wallet) => {
const smartAccount = new SmartAccountLib({ const smartAccount = new SmartAccountLib({
privateKey: wallet.getPrivateKey() as Hex, privateKey: wallet.getPrivateKey() as Hex,
chain: allowedChains[0], // TODO: FIX FOR MULTI NETWORK chain: smartAccountEnabledChain,
sponsored: true, // TODO: Sponsor for now but should be dynamic according to SettingsStore sponsored: true, // TODO: Sponsor for now but should be dynamic according to SettingsStore
}) })
const isDeployed = await smartAccount.checkIfSmartAccountDeployed() await smartAccount.init()
if (isDeployed) { return smartAccount
return smartAccount
}
return null
})); }));
const validSmartAccounts = deployedSmartAccounts.filter(Boolean) as Array<SmartAccountLib>
const smartAccountAddress = getWalletAddressFromParams(validSmartAccounts.map(acc => acc.address!), params)
return validSmartAccounts.find((smartAccount) => smartAccount?.address === smartAccountAddress) as SmartAccountLib const smartAccountAddress = getWalletAddressFromParams(smartAccounts.map(acc => acc.address!), params)
return smartAccounts.find((smartAccount) => smartAccount?.address === smartAccountAddress) as SmartAccountLib
} }

View File

@ -36,7 +36,7 @@ import { Hex } from 'viem'
import ChainSmartAddressMini from '@/components/ChainSmartAddressMini' import ChainSmartAddressMini from '@/components/ChainSmartAddressMini'
import { useSnapshot } from 'valtio' import { useSnapshot } from 'valtio'
import SettingsStore from '@/store/SettingsStore' import SettingsStore from '@/store/SettingsStore'
import { allowedChains } from '@/utils/SmartAccountUtils' import { Chain, allowedChains } from '@/utils/SmartAccountUtils'
const StyledText = styled(Text, { const StyledText = styled(Text, {
fontWeight: 400 fontWeight: 400
@ -236,18 +236,28 @@ export default function SessionProposalModal() {
}) })
// TODO: improve for multi network // TODO: improve for multi network
console.log('Checking if SA is deployed', eip155Wallets[eip155Addresses[0]]) console.log('namespaces', namespaces['eip155'])
const chainId = namespaces['eip155'].chains?.[0] const namespaceChains = namespaces['eip155'].chains?.map((c: string) => c.split(':')[1])
const smartAccountClient = new SmartAccountLib({ const smartAccountEnabledChains: Chain[] = allowedChains.filter(chain => namespaceChains?.includes(chain.id.toString()))
privateKey: eip155Wallets[eip155Addresses[0]].getPrivateKey() as Hex, // We find a request for a chain that is enabled for smart account
chain: allowedChains.find(chain => chain.id.toString() === chainId)!, if (smartAccountEnabledChains.length) {
sponsored: smartAccountSponsorshipEnabled, const signerAddress = namespaces['eip155'].accounts[0].split(':')[2]
}) const wallet = eip155Wallets[signerAddress]
const isDeployed = await smartAccountClient.checkIfSmartAccountDeployed() const chain = smartAccountEnabledChains[0]
console.log('isDeployed', isDeployed) if (wallet) {
const smartAccountClient = new SmartAccountLib({
if (isDeployed) { privateKey: wallet.getPrivateKey() as Hex,
namespaces.eip155.accounts = [...namespaces.eip155.accounts, `eip155:5:${smartAccountClient.address}`] chain,
sponsored: smartAccountSponsorshipEnabled,
})
await smartAccountClient.init()
const isDeployed = await smartAccountClient.checkIfSmartAccountDeployed()
console.log('isDeployed', isDeployed, smartAccountClient.address)
if (isDeployed) {
namespaces.eip155.accounts = [...namespaces.eip155.accounts, `eip155:${chain.id}:${smartAccountClient.address}`]
}
}
} }
console.log('approving namespaces:', namespaces) console.log('approving namespaces:', namespaces)