From 4b9d7086472be7ed27165dbaee0f29be58d1e7e4 Mon Sep 17 00:00:00 2001 From: keating Date: Tue, 28 Nov 2023 09:57:05 -0500 Subject: [PATCH 1/2] Add ENS support --- config.ts | 4 ++-- hooks/useL2Delegate.ts | 5 ++++- pages/[id]/delegate.tsx | 30 ++++++++++++++++++++++++------ util/ens.ts | 20 ++++++++++++++++++++ 4 files changed, 50 insertions(+), 9 deletions(-) create mode 100644 util/ens.ts diff --git a/config.ts b/config.ts index d3a08e9..23de976 100644 --- a/config.ts +++ b/config.ts @@ -1,6 +1,6 @@ -import { goerli, optimismGoerli } from 'wagmi/chains'; +import { goerli, optimismGoerli, mainnet } from 'wagmi/chains'; -export const chains = [goerli, optimismGoerli]; +export const chains = [goerli, optimismGoerli, mainnet]; export enum DaoId { PoolTogether = 'pool-together', diff --git a/hooks/useL2Delegate.ts b/hooks/useL2Delegate.ts index 26d6432..3b0a74c 100644 --- a/hooks/useL2Delegate.ts +++ b/hooks/useL2Delegate.ts @@ -6,9 +6,10 @@ import { parseAbi } from 'viem'; type Props = { delegatorAddress?: `0x${string}`; + enabled?: boolean; }; -export const useL2Delegate = ({ delegatorAddress }: Props) => { +export const useL2Delegate = ({ delegatorAddress, enabled }: Props) => { let { address } = useAccount(); if (delegatorAddress !== undefined) { address = delegatorAddress; @@ -23,6 +24,8 @@ export const useL2Delegate = ({ delegatorAddress }: Props) => { functionName: 'delegates', args: [address], chainId: l2.chain.id, + watch: true, + enabled: enabled, }); return { data, error, isLoading }; }; diff --git a/pages/[id]/delegate.tsx b/pages/[id]/delegate.tsx index 1125d1a..b8d8b76 100644 --- a/pages/[id]/delegate.tsx +++ b/pages/[id]/delegate.tsx @@ -5,7 +5,7 @@ import { InformationCircleIcon } from '@heroicons/react/24/outline'; import type { NextPage } from 'next'; import Head from 'next/head'; import Image from 'next/image'; -import { useAccount, useNetwork, useWalletClient } from 'wagmi'; +import { useAccount, useEnsAvatar, useEnsName, useNetwork, useWalletClient } from 'wagmi'; import { isAddress, formatUnits } from 'viem'; import { useForm } from 'react-hook-form'; import { useBalances } from '@/hooks/useBalances'; @@ -18,6 +18,7 @@ import { ZERO_ADDRESS } from '@/util/constants'; import CardWithHeader from '@/components/CardWithHeader'; import Spinner from '@/components/Spinner'; import { switchChain } from '@/util'; +import { getEnsAddress } from '@/util/ens'; import { Tooltip } from 'react-tooltip'; import { useTokenInfo } from '@/hooks/useTokenInfo'; import { ConnectButton } from '@rainbow-me/rainbowkit'; @@ -35,7 +36,6 @@ const Delegate: NextPage = () => { const { data: walletClient, isLoading: walletIsLoading } = useWalletClient(); const { chain } = useNetwork(); const [delegateAddress, setDelegateAddress] = useState(address); - const { data: delegatee } = useL2Delegate({}); const { data: l2VotingWeight } = useL2CurrentVotingWeight({ voterAddress: address || ZERO_ADDRESS, }); @@ -47,8 +47,11 @@ const Delegate: NextPage = () => { const { register, handleSubmit, - formState: { errors }, + formState: { errors, isValid }, } = useForm({ mode: 'onChange' }); + const { data: delegatee } = useL2Delegate({ enabled: isValid }); + const { data: delegateEnsName } = useEnsName({ address: delegatee, chainId: 1 }); + const { data: delegateEnsAvatar } = useEnsAvatar({ name: delegateEnsName, chainId: 1 }); const l2VotingWeightFormatted = formatUnits( l2VotingWeight || BigInt(0), @@ -147,7 +150,14 @@ const Delegate: NextPage = () => {
{mounted && delegatee !== ZERO_ADDRESS ? (
- {delegatee}{' '} + {delegateEnsAvatar && ( + + )} + {delegateEnsName || delegatee}{' '} { aria-invalid="true" aria-describedby="address-error" {...register('delegateAddress', { - onChange: (e) => { - setDelegateAddress(e.target.value); + onChange: async (e) => { + const val = await getEnsAddress(e.target.value); + setDelegateAddress(val || e.target.value); }, validate: async (value) => { + if (value?.includes('.eth')) { + const val = await getEnsAddress(value); + if (val !== null) { + value = val; + } + } + const validAddress = isAddress(value); const isBalanceNonzero = (l2.token?.value || BigInt(0)) > BigInt(0); if (validAddress && isBalanceNonzero) return true; diff --git a/util/ens.ts b/util/ens.ts new file mode 100644 index 0000000..dc7bece --- /dev/null +++ b/util/ens.ts @@ -0,0 +1,20 @@ +import { normalize } from 'viem/ens'; +import { createPublicClient, http } from 'viem'; +import { mainnet } from 'viem/chains'; + +export const getEnsAddress = async (name: string) => { + const client = createPublicClient({ + chain: mainnet, + transport: http(), + }); + try { + const ensAddress = await client.getEnsAddress({ + name: normalize(name), + }); + return ensAddress; + } catch (e) { + const err = e as Error; + console.error(err.message); + } + return null; +}; From 4fa7d4f1ceff2523f71fc7aad36bbbe30c69ff82 Mon Sep 17 00:00:00 2001 From: keating Date: Mon, 4 Dec 2023 11:28:01 -0500 Subject: [PATCH 2/2] Update formatting --- pages/[id]/delegate.tsx | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pages/[id]/delegate.tsx b/pages/[id]/delegate.tsx index b8d8b76..30f6224 100644 --- a/pages/[id]/delegate.tsx +++ b/pages/[id]/delegate.tsx @@ -150,13 +150,13 @@ const Delegate: NextPage = () => {
{mounted && delegatee !== ZERO_ADDRESS ? (
- {delegateEnsAvatar && ( - - )} + {delegateEnsAvatar && ( + + )} {delegateEnsName || delegatee}{' '} { aria-describedby="address-error" {...register('delegateAddress', { onChange: async (e) => { - const val = await getEnsAddress(e.target.value); + const val = await getEnsAddress(e.target.value); setDelegateAddress(val || e.target.value); }, validate: async (value) => { - if (value?.includes('.eth')) { - const val = await getEnsAddress(value); - if (val !== null) { - value = val; - } + if (value?.includes('.eth')) { + const val = await getEnsAddress(value); + if (val !== null) { + value = val; } + } const validAddress = isAddress(value); const isBalanceNonzero = (l2.token?.value || BigInt(0)) > BigInt(0);