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

feat: Smart Account relay connection + paymaster base #351

Merged
merged 17 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import useSmartAccount from '@/hooks/useSmartAccount'
import { Hex } from 'viem'
import ChainAddressMini from './ChainAddressMini'
import { createOrRestoreEIP155Wallet, eip155Wallets } from '@/utils/EIP155WalletUtil'
import { Spinner } from '@nextui-org/react'
import { Chain, allowedChains } from '@/utils/SmartAccountUtils'
import { useSnapshot } from 'valtio'
import SettingsStore from '@/store/SettingsStore'

interface Props {
namespace: string
}

const getKey = (namespace?: string) => {
switch (namespace) {
case 'eip155':
createOrRestoreEIP155Wallet()
const key = Object.values(eip155Wallets)[0]?.getPrivateKey() as Hex
return key
}
}

export default function ChainSmartAddressMini({ namespace }: Props) {
const { activeChainId } = useSnapshot(SettingsStore.state)
const { address } = useSmartAccount(getKey(namespace) as `0x${string}`, allowedChains.find((c) => c.id.toString() === activeChainId) as Chain)

if (!address) return <Spinner />
return (
<ChainAddressMini address={address}/>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ interface Props {
onReject: () => void
infoBoxCondition?: boolean
infoBoxText?: string
disabledApprove?: boolean
approveLoader?: LoaderProps
rejectLoader?: LoaderProps
}
Expand All @@ -23,7 +22,6 @@ export default function ModalFooter({
rejectLoader,
infoBoxCondition,
infoBoxText,
disabledApprove
}: Props) {
const { currentRequestVerifyContext } = useSnapshot(SettingsStore.state)
const validation = currentRequestVerifyContext?.verified.validation
Expand All @@ -46,13 +44,14 @@ export default function ModalFooter({
<span>{infoBoxText || ''}</span>
</Row>
)}
<Row justify="space-between">
<Row justify="space-between" align='center'>
<Button
auto
flat
style={{ color: 'white', backgroundColor: 'grey' }}
onPress={onReject}
data-testid="session-reject-button"
disabled={rejectLoader?.active}
>
{rejectLoader && rejectLoader.active ? (
<Loading size="md" type="points" color={rejectLoader.color || 'white'} />
Expand All @@ -64,7 +63,7 @@ export default function ModalFooter({
auto
flat
color={approveButtonColor}
disabled={disabledApprove}
disabled={approveLoader?.active}
onPress={onApprove}
data-testid="session-approve-button"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { updateSignClientChainId } from '@/utils/WalletConnectUtil'
import { Avatar, Button, Text, Tooltip, Loading } from '@nextui-org/react'
import { eip155Wallets } from '@/utils/EIP155WalletUtil'
import Image from 'next/image'
import { useState, useEffect } from 'react'
import { useState } from 'react'
import { useSnapshot } from 'valtio'
import useSmartAccount from '@/hooks/useSmartAccount'
import { Chain, FAUCET_URLS, allowedChains } from '@/utils/SmartAccountUtils'

interface Props {
name: string
Expand All @@ -28,13 +29,14 @@ export default function SmartAccountCard({
}: Props) {
const [copied, setCopied] = useState(false)
const { activeChainId } = useSnapshot(SettingsStore.state)
const chain = allowedChains.find((c) => c.id.toString() === chainId.split(':')[1]) as Chain
const {
deploy,
isDeployed,
address: smartAccountAddress,
loading,
sendTestTransaction,
} = useSmartAccount(eip155Wallets[address].getPrivateKey() as `0x${string}`)
} = useSmartAccount(eip155Wallets[address].getPrivateKey() as `0x${string}`, chain)

function onCopy() {
navigator?.clipboard?.writeText(address)
Expand All @@ -56,9 +58,7 @@ export default function SmartAccountCard({
console.error(error)
}
}

const getFaucetUrl = () => `https://${name?.toLowerCase()?.replace('ethereum', '')?.trim()}faucet.com`


return (
<ChainCard rgb={rgb} flexDirection="row" alignItems="center" flexWrap="wrap">
<Avatar src={logo} />
Expand Down Expand Up @@ -124,7 +124,7 @@ export default function SmartAccountCard({
disabled={!isActiveChain || loading}
size="sm"
css={{ marginTop: 20, width: '100%' }}
onClick={() => window.open(getFaucetUrl(), '_blank')}
onClick={() => window.open(FAUCET_URLS[chain?.name], '_blank')}
>
{name} Faucet
</Button>
Expand Down
10 changes: 6 additions & 4 deletions advanced/wallets/react-wallet-v2/src/data/EIP155Data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/
export type TEIP155Chain = keyof typeof EIP155_CHAINS

export type EIP155TestChain = {
export type EIP155Chain = {
chainId: number
name: string
logo: string
Expand All @@ -21,7 +21,7 @@ export type EIP155TestChain = {
/**
* Chains
*/
export const EIP155_MAINNET_CHAINS = {
export const EIP155_MAINNET_CHAINS: Record<string, EIP155Chain> = {
'eip155:1': {
chainId: 1,
name: 'Ethereum',
Expand Down Expand Up @@ -64,7 +64,7 @@ export const EIP155_MAINNET_CHAINS = {
}
}

export const EIP155_TEST_CHAINS: Record<string,EIP155TestChain> = {
export const EIP155_TEST_CHAINS: Record<string,EIP155Chain> = {
'eip155:5': {
chainId: 5,
name: 'Ethereum Goerli',
Expand All @@ -81,6 +81,7 @@ export const EIP155_TEST_CHAINS: Record<string,EIP155TestChain> = {
rgb: '99, 125, 234',
rpc: 'https://rpc.sepolia.org',
namespace: 'eip155',
smartAccountEnabled: true,
},
'eip155:43113': {
chainId: 43113,
Expand All @@ -96,7 +97,8 @@ export const EIP155_TEST_CHAINS: Record<string,EIP155TestChain> = {
logo: '/chain-logos/eip155-137.png',
rgb: '130, 71, 229',
rpc: 'https://matic-mumbai.chainstacklabs.com',
namespace: 'eip155'
namespace: 'eip155',
smartAccountEnabled: true,
},
'eip155:420': {
chainId: 420,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function useInitialization() {
// restart transport if relayer region changes
const onRelayerRegionChange = useCallback(() => {
try {
web3wallet.core.relayer.restartTransport(relayerRegionURL)
web3wallet?.core?.relayer.restartTransport(relayerRegionURL)
prevRelayerURLValue.current = relayerRegionURL
} catch (err: unknown) {
alert(err)
Expand Down
31 changes: 23 additions & 8 deletions advanced/wallets/react-wallet-v2/src/hooks/useSmartAccount.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { SmartAccountLib } from "@/lib/SmartAccountLib";
import SettingsStore from "@/store/SettingsStore";
import { Chain, VITALIK_ADDRESS } from "@/utils/SmartAccountUtils";
import { useCallback, useEffect, useState } from "react";
import { useSnapshot } from "valtio";
import { Hex } from "viem";

export default function useSmartAccount(signerPrivateKey: `0x${string}`) {
export default function useSmartAccount(signerPrivateKey: Hex, chain: Chain) {
const [loading, setLoading] = useState(false)
const [client, setClient] = useState<SmartAccountLib>();
const [isDeployed, setIsDeployed] = useState(false)
const [address, setAddress] = useState<`0x${string}`>()
const [address, setAddress] = useState<Hex>()
const { smartAccountSponsorshipEnabled } = useSnapshot(SettingsStore.state);

const execute = useCallback(async (callback: () => void) => {
try {
setLoading(true)
await callback()
const res = await callback()
console.log('result:', res)
setLoading(false)
}
catch (e) {
Expand All @@ -26,21 +32,30 @@ export default function useSmartAccount(signerPrivateKey: `0x${string}`) {

const sendTestTransaction = useCallback(async () => {
if (!client) return
execute(client?.sendTestTransaction)
execute(() => client?.sendTransaction({
to: VITALIK_ADDRESS,
value: 0n,
data: '0x',
}))
}, [client, execute])

useEffect(() => {
const smartAccountClient = new SmartAccountLib(signerPrivateKey, 'goerli')
setClient(smartAccountClient)
}, [signerPrivateKey])
if (!signerPrivateKey || !chain) return
const smartAccountClient = new SmartAccountLib({
chain,
privateKey: signerPrivateKey,
sponsored: smartAccountSponsorshipEnabled,
})
setClient(smartAccountClient)
}, [signerPrivateKey, smartAccountSponsorshipEnabled, chain])

useEffect(() => {
client?.checkIfSmartAccountDeployed()
.then((deployed: boolean) => {
setIsDeployed(deployed)
setAddress(client?.address)
})
}, [client])
}, [client, chain])


return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export default function useWalletConnectEventsManager(initialized: boolean) {
* Set up WalletConnect event listeners
*****************************************************************************/
useEffect(() => {
if (initialized) {
if (initialized && web3wallet) {
//sign
web3wallet.on('session_proposal', onSessionProposal)
web3wallet.on('session_request', onSessionRequest)
Expand Down
2 changes: 1 addition & 1 deletion advanced/wallets/react-wallet-v2/src/lib/EIP155Lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class EIP155Lib {
return this.wallet.signMessage(message)
}

_signTypedData(domain: any, types: any, data: any) {
_signTypedData(domain: any, types: any, data: any, _primaryType?: string) {
return this.wallet._signTypedData(domain, types, data)
}

Expand Down
Loading
Loading