Skip to content

Commit

Permalink
added wagmi impl for ERC5792 and ERC7677 on laboratory (#2322)
Browse files Browse the repository at this point in the history
  • Loading branch information
KannuSingh authored May 29, 2024
1 parent f1cfe6d commit 427914c
Show file tree
Hide file tree
Showing 7 changed files with 522 additions and 0 deletions.
102 changes: 102 additions & 0 deletions apps/laboratory/src/components/Wagmi/WagmiGetCallsStatusTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Button, Stack, Text, Input } from '@chakra-ui/react'
import { useAccount, useConnections } from 'wagmi'
import { EthereumProvider } from '@walletconnect/ethereum-provider'
import { useState, useEffect } from 'react'
import { useChakraToast } from '../Toast'
import { EIP_5792_RPC_METHODS } from '../../utils/EIP5792Utils'
import { bigIntReplacer } from '../../utils/CommonUtils'
import { useCallsStatus } from 'wagmi/experimental'

export function WagmiGetCallsStatusTest() {
const [ethereumProvider, setEthereumProvider] =
useState<Awaited<ReturnType<(typeof EthereumProvider)['init']>>>()
const [enableGetCallsStatus, setEnableGetCallsStatus] = useState(false)
const [batchCallId, setBatchCallId] = useState('')

const { status, address } = useAccount()
const isConnected = status === 'connected'
const connection = useConnections()
const toast = useChakraToast()
const {
isLoading,
isFetched,
error,
data: callsStatusResult
} = useCallsStatus({
id: batchCallId,
query: {
enabled: enableGetCallsStatus && isConnected
}
})

useEffect(() => {
if (isConnected) {
fetchProvider()
}
}, [isConnected])
useEffect(() => {
if (enableGetCallsStatus && isFetched && callsStatusResult) {
toast({
title: 'GetCallsStatus Success',
description: JSON.stringify(callsStatusResult, bigIntReplacer),
type: 'success'
})
setEnableGetCallsStatus(false)
}
if (error) {
toast({
title: 'GetCallsStatus Error',
description: 'Failed to get calls status',
type: 'error'
})
setEnableGetCallsStatus(false)
}
}, [enableGetCallsStatus, isFetched, error, callsStatusResult])

function isGetCallsStatusSupported(): boolean {
return Boolean(
ethereumProvider?.signer?.session?.namespaces?.['eip155']?.methods?.includes(
EIP_5792_RPC_METHODS.WALLET_GET_CALLS_STATUS
)
)
}
async function fetchProvider() {
const connectedProvider = await connection?.[0]?.connector?.getProvider()
if (connectedProvider instanceof EthereumProvider) {
setEthereumProvider(connectedProvider)
}
}

if (!isConnected || !ethereumProvider || !address) {
return (
<Text fontSize="md" color="yellow">
Wallet not connected
</Text>
)
}
if (!isGetCallsStatusSupported()) {
return (
<Text fontSize="md" color="yellow">
Wallet does not support wallet_getCallsStatus rpc method
</Text>
)
}

return (
<Stack direction={['column', 'column', 'row']}>
<Input
placeholder="0xf34ffa..."
onChange={e => setBatchCallId(e.target.value)}
value={batchCallId}
isDisabled={isLoading}
/>
<Button
data-test-id="get-calls-status-button"
onClick={() => setEnableGetCallsStatus(true)}
isDisabled={isLoading || !batchCallId}
>
Get Calls Status
</Button>
</Stack>
)
}
143 changes: 143 additions & 0 deletions apps/laboratory/src/components/Wagmi/WagmiSendCallsTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { Button, Stack, Text } from '@chakra-ui/react'
import { EthereumProvider } from '@walletconnect/ethereum-provider'
import { useAccount, type Connector } from 'wagmi'
import { useSendCalls } from 'wagmi/experimental'
import { useCallback, useState, useEffect } from 'react'
import { useChakraToast } from '../Toast'
import { parseGwei, type Address, type Chain, type WalletCapabilities } from 'viem'
import { vitalikEthAddress } from '../../utils/DataUtil'
import {
EIP_5792_RPC_METHODS,
WALLET_CAPABILITIES,
getFilteredCapabilitySupportedChainInfo,
getProviderCachedCapabilities
} from '../../utils/EIP5792Utils'

const TEST_TX_1 = {
to: vitalikEthAddress as Address,
value: parseGwei('0.001')
}
const TEST_TX_2 = {
to: vitalikEthAddress as Address,
data: '0xdeadbeef' as `0x${string}`
}

export function WagmiSendCallsTest() {
const [ethereumProvider, setEthereumProvider] =
useState<Awaited<ReturnType<(typeof EthereumProvider)['init']>>>()
const [availableCapabilities, setAvailableCapabilities] = useState<
Record<number, WalletCapabilities> | undefined
>()
const [isLoading, setLoading] = useState(false)
const { status, chain, address, connector } = useAccount()
const toast = useChakraToast()

const isConnected = status === 'connected'
const atomicBatchSupportedChains = availableCapabilities
? getFilteredCapabilitySupportedChainInfo(
WALLET_CAPABILITIES.ATOMIC_BATCH,
availableCapabilities
)
: []
const atomicBatchSupportedChainsName = atomicBatchSupportedChains
.map(ci => ci.chainName)
.join(', ')
const currentChainsInfo = atomicBatchSupportedChains.find(
chainInfo => chainInfo.chainId === Number(chain?.id)
)

useEffect(() => {
if (isConnected && connector && address && chain) {
fetchProviderAndAccountCapabilities(address, connector, chain)
}
}, [isConnected, connector, address])
const { sendCalls } = useSendCalls({
mutation: {
onSuccess: hash => {
setLoading(false)
toast({
title: 'SendCalls Success',
description: hash,
type: 'success'
})
},
onError: () => {
setLoading(false)
toast({
title: 'SendCalls Error',
description: 'Failed to send calls',
type: 'error'
})
}
}
})
const onSendCalls = useCallback(() => {
setLoading(true)
sendCalls({
calls: [TEST_TX_1, TEST_TX_2]
})
}, [sendCalls])

function isSendCallsSupported(): boolean {
return Boolean(
ethereumProvider?.signer?.session?.namespaces?.['eip155']?.methods?.includes(
EIP_5792_RPC_METHODS.WALLET_SEND_CALLS
)
)
}

async function fetchProviderAndAccountCapabilities(
connectedAccount: `0x${string}`,
connectedConnector: Connector,
connectedChain: Chain
) {
const connectedProvider = await connectedConnector.getProvider({
chainId: connectedChain.id
})
if (connectedProvider instanceof EthereumProvider) {
setEthereumProvider(connectedProvider)
let walletCapabilities = undefined
walletCapabilities = getProviderCachedCapabilities(connectedAccount, connectedProvider)
setAvailableCapabilities(walletCapabilities)
}
}

if (!isConnected || !ethereumProvider || !address) {
return (
<Text fontSize="md" color="yellow">
Wallet not connected
</Text>
)
}
if (!isSendCallsSupported()) {
return (
<Text fontSize="md" color="yellow">
Wallet does not support wallet_sendCalls rpc method
</Text>
)
}
if (atomicBatchSupportedChains.length === 0) {
return (
<Text fontSize="md" color="yellow">
Account does not support atomic batch feature
</Text>
)
}

return currentChainsInfo ? (
<Stack direction={['column', 'column', 'row']}>
<Button
data-test-id="send-calls-button"
onClick={onSendCalls}
disabled={!sendCalls}
isDisabled={isLoading}
>
Send Batch Calls to Vitalik
</Button>
</Stack>
) : (
<Text fontSize="md" color="yellow">
Switch to {atomicBatchSupportedChainsName} to test this feature
</Text>
)
}
Loading

0 comments on commit 427914c

Please sign in to comment.